Added a more efficient convexHullContains to Model

New version computes each submesh's bounding box once and checks against it
before checking against triangles.
This commit is contained in:
Atlante45 2015-04-28 17:05:38 +02:00
parent 4911aa58bc
commit b7263eeacf
2 changed files with 56 additions and 0 deletions

View file

@ -573,6 +573,61 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
return intersectedSomething;
}
bool Model::convexHullContains(glm::vec3 point) {
// if we aren't active, we can't compute that yet...
if (!isActive()) {
return false;
}
// extents is the entity relative, scaled, centered extents of the entity
glm::vec3 position = _translation;
glm::mat4 rotation = glm::mat4_cast(_rotation);
glm::mat4 translation = glm::translate(position);
glm::mat4 modelToWorldMatrix = translation * rotation;
glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix);
Extents modelExtents = getMeshExtents(); // NOTE: unrotated
glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum;
glm::vec3 corner = -(dimensions * _registrationPoint); // since we're going to do the ray picking in the model frame of reference
AABox modelFrameBox(corner, dimensions);
glm::vec3 modelFramePoint = glm::vec3(worldToModelMatrix * glm::vec4(point, 1.0f));
// we can use the AABox's ray intersection by mapping our origin and direction into the model frame
// and testing intersection there.
if (modelFrameBox.contains(modelFramePoint)){
if (!_calculatedMeshTrianglesValid) {
recalculateMeshBoxes(true);
}
// If we are inside the models box, then consider the submeshes...
int subMeshIndex = 0;
foreach(const AABox& subMeshBox, _calculatedMeshBoxes) {
if (subMeshBox.contains(point)) {
bool insideMesh = true;
// To be inside the sub mesh, we need to be behind every triangles' planes
const QVector<Triangle>& meshTriangles = _calculatedMeshTriangles[subMeshIndex];
foreach (const Triangle& triangle, meshTriangles) {
if (!isPointBehindTrianglesPlane(point, triangle.v0, triangle.v1, triangle.v2)) {
// it's not behind at least one so we bail
insideMesh = false;
break;
}
}
if (insideMesh) {
// It's inside this mesh, return true.
return true;
}
}
subMeshIndex++;
}
}
// It wasn't in any mesh, return false.
return false;
}
// TODO: we seem to call this too often when things haven't actually changed... look into optimizing this
void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;

View file

@ -213,6 +213,7 @@ public:
bool findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
BoxFace& face, QString& extraInfo, bool pickAgainstTriangles = false);
bool convexHullContains(glm::vec3 point);
protected:
QSharedPointer<NetworkGeometry> _geometry;