store part boxes in model space and translate to world space on request

This commit is contained in:
ZappoMan 2015-06-02 21:50:33 -07:00
parent c9c434bc8c
commit 647d132d57
5 changed files with 56 additions and 35 deletions

View file

@ -706,10 +706,26 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
int i2 = part.quadIndices[vIndex++];
int i3 = part.quadIndices[vIndex++];
glm::vec3 v0 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i0], 1.0f)));
glm::vec3 v1 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i1], 1.0f)));
glm::vec3 v2 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i2], 1.0f)));
glm::vec3 v3 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i3], 1.0f)));
glm::vec3 mv0 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i0], 1.0f));
glm::vec3 mv1 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i1], 1.0f));
glm::vec3 mv2 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i2], 1.0f));
glm::vec3 mv3 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i3], 1.0f));
// track the mesh parts in model space
if (!atLeastOnePointInBounds) {
thisPartBounds.setBox(mv0, 0.0f);
atLeastOnePointInBounds = true;
} else {
thisPartBounds += mv0;
}
thisPartBounds += mv1;
thisPartBounds += mv2;
thisPartBounds += mv3;
glm::vec3 v0 = calculateScaledOffsetPoint(mv0);
glm::vec3 v1 = calculateScaledOffsetPoint(mv1);
glm::vec3 v2 = calculateScaledOffsetPoint(mv2);
glm::vec3 v3 = calculateScaledOffsetPoint(mv3);
// Sam's recommended triangle slices
Triangle tri1 = { v0, v1, v3 };
@ -722,14 +738,6 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
thisMeshTriangles.push_back(tri1);
thisMeshTriangles.push_back(tri2);
if (!atLeastOnePointInBounds) {
thisPartBounds.setBox(v0, 0.0f);
atLeastOnePointInBounds = true;
}
thisPartBounds += v0;
thisPartBounds += v1;
thisPartBounds += v2;
thisPartBounds += v3;
}
}
@ -741,21 +749,27 @@ void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
int i1 = part.triangleIndices[vIndex++];
int i2 = part.triangleIndices[vIndex++];
glm::vec3 v0 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i0], 1.0f)));
glm::vec3 v1 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i1], 1.0f)));
glm::vec3 v2 = calculateScaledOffsetPoint(glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i2], 1.0f)));
glm::vec3 mv0 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i0], 1.0f));
glm::vec3 mv1 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i1], 1.0f));
glm::vec3 mv2 = glm::vec3(mesh.modelTransform * glm::vec4(mesh.vertices[i2], 1.0f));
// track the mesh parts in model space
if (!atLeastOnePointInBounds) {
thisPartBounds.setBox(mv0, 0.0f);
atLeastOnePointInBounds = true;
} else {
thisPartBounds += mv0;
}
thisPartBounds += mv1;
thisPartBounds += mv2;
glm::vec3 v0 = calculateScaledOffsetPoint(mv0);
glm::vec3 v1 = calculateScaledOffsetPoint(mv1);
glm::vec3 v2 = calculateScaledOffsetPoint(mv2);
Triangle tri = { v0, v1, v2 };
thisMeshTriangles.push_back(tri);
if (!atLeastOnePointInBounds) {
thisPartBounds.setBox(v0, 0.0f);
atLeastOnePointInBounds = true;
}
thisPartBounds += v0;
thisPartBounds += v1;
thisPartBounds += v2;
}
}
_calculatedMeshPartBoxes[QPair<int,int>(i, j)] = thisPartBounds;
@ -1227,6 +1241,11 @@ Extents Model::calculateScaledOffsetExtents(const Extents& extents) const {
return translatedExtents;
}
/// Returns the world space equivalent of some box in model space.
AABox Model::calculateScaledOffsetAABox(const AABox& box) const {
return AABox(calculateScaledOffsetExtents(Extents(box)));
}
glm::vec3 Model::calculateScaledOffsetPoint(const glm::vec3& point) const {
// we need to include any fst scaling, translation, and rotation, which is captured in the offset matrix
glm::vec3 offsetPoint = glm::vec3(_geometry->getFBXGeometry().offset * glm::vec4(point, 1.0f));
@ -2231,10 +2250,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) {
recalculateMeshBoxes(true);
}
if (_calculatedMeshPartBoxesValid && _calculatedMeshPartBoxes.contains(QPair<int,int>(meshIndex, partIndex))) {
return _calculatedMeshPartBoxes[QPair<int,int>(meshIndex, partIndex)];
}
if (!_calculatedMeshBoxesValid && _calculatedMeshBoxes.size() > meshIndex) {
return _calculatedMeshBoxes[meshIndex];
return calculateScaledOffsetAABox(_calculatedMeshPartBoxes[QPair<int,int>(meshIndex, partIndex)]);
}
return AABox();
}

View file

@ -158,6 +158,9 @@ public:
/// Returns the scaled equivalent of some extents in model space.
Extents calculateScaledOffsetExtents(const Extents& extents) const;
/// Returns the world space equivalent of some box in model space.
AABox calculateScaledOffsetAABox(const AABox& box) const;
/// Returns the scaled equivalent of a point in model space.
glm::vec3 calculateScaledOffsetPoint(const glm::vec3& point) const;

View file

@ -42,12 +42,6 @@ glm::vec3 AABox::calcCenter() const {
return center;
}
glm::vec3 AABox::calcTopFarLeft() const {
glm::vec3 topFarLeft(_corner);
topFarLeft += _scale;
return topFarLeft;
};
void AABox::scale(float scale) {
_corner = _corner * scale;
_scale = _scale * scale;

View file

@ -47,7 +47,11 @@ public:
float getLargestDimension() const { return glm::max(_scale.x, glm::max(_scale.y, _scale.z)); }
glm::vec3 calcCenter() const;
glm::vec3 calcTopFarLeft() const;
glm::vec3 calcTopFarLeft() const { return _corner + _scale; }
const glm::vec3& getMinimum() const { return _corner; }
glm::vec3 getMaximum() const { return _corner + _scale; }
glm::vec3 getVertex(BoxVertex vertex) const;
const glm::vec3& getMinimumPoint() const { return _corner; }

View file

@ -23,6 +23,10 @@ class AABox;
class Extents {
public:
Extents(const glm::vec3& minimum, const glm::vec3& maximum) : minimum(minimum), maximum(maximum) { }
Extents() { reset(); }
Extents(const AABox& box) { reset(); add(box); }
/// set minimum and maximum to FLT_MAX and -FLT_MAX respectively
void reset();
@ -58,7 +62,7 @@ public:
/// \return new Extents which is original rotated around orign by rotation
Extents getRotated(const glm::quat& rotation) const {
Extents temp = { minimum, maximum };
Extents temp(minimum, maximum);
temp.rotate(rotation);
return temp;
}