From f3fcb749df2787b2886db9a7e8875f0f20a3cffa Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 20 Apr 2015 22:51:39 +0200 Subject: [PATCH] Fix algorithm + add comments --- .../src/RenderableModelEntityItem.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ab823d090b..e2c3de70af 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -416,34 +416,46 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { } bool RenderableModelEntityItem::contains(const glm::vec3& point) const { - bool result = EntityItem::contains(point); - - if (result && _model && _model->getCollisionGeometry()) { + if (EntityItem::contains(point) && _model && _model->getCollisionGeometry()) { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry(); auto checkEachPrimitive = [=](FBXMesh& mesh, QVector indices, int primitiveSize) -> bool { + // Check whether the point is "behind" all the primitives. for (unsigned int j = 0; j < indices.size(); j += primitiveSize) { if (!isPointBehindTrianglesPlane(point, mesh.vertices[indices[j]], mesh.vertices[indices[j + 1]], mesh.vertices[indices[j + 2]])) { + // it's not behind at least one so we bail return false; } } return true; }; + // Check that the point is contained in at least one convex mesh. for (auto mesh : collisionGeometry.meshes) { + bool insideMesh = true; + + // To be considered inside a convex mesh, + // the point needs to be "behind" all the primitives respective planes. for (auto part : mesh.parts) { // run through all the triangles and quads if (!checkEachPrimitive(mesh, part.triangleIndices, 3) || !checkEachPrimitive(mesh, part.quadIndices, 4)) { - return false; + // If not, the point is outside, bail for this mesh + insideMesh = false; + continue; } } + if (insideMesh) { + // It's inside this mesh, return true. + return true; + } } } - return result; + // It wasn't in any mesh, return false. + return false; }