From 955723acf10465d46991cce5d7fb141916b386bd Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 20 Apr 2015 17:21:27 +0200 Subject: [PATCH] RenderableEntityItem uses collision hull in contains --- .../src/RenderableModelEntityItem.cpp | 32 +++++++++++++++++++ .../src/RenderableModelEntityItem.h | 2 ++ libraries/shared/src/GLMHelpers.cpp | 7 ++++ libraries/shared/src/GLMHelpers.h | 2 ++ 4 files changed, 43 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 86b0be4dd8..ab823d090b 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -415,3 +415,35 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { } } +bool RenderableModelEntityItem::contains(const glm::vec3& point) const { + bool result = EntityItem::contains(point); + + if (result && _model && _model->getCollisionGeometry()) { + const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); + const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry(); + + auto checkEachPrimitive = [=](FBXMesh& mesh, QVector indices, int primitiveSize) -> bool { + 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]])) { + return false; + } + } + return true; + }; + + for (auto mesh : collisionGeometry.meshes) { + 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; + } + } + } + } + + return result; +} diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index b632357942..ea153a2dd6 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -56,6 +56,8 @@ public: bool isReadyToComputeShape(); void computeShapeInfo(ShapeInfo& info); + + virtual bool contains(const glm::vec3& point) const; private: void remapTextures(); diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 4e8fb7d3cd..aed73c1989 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -203,6 +203,13 @@ glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2) { return glm::angleAxis(angle, axis); } +bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2) { + glm::vec3 v1 = p0 - p1, v2 = p2 - p1; // Non-collinear vectors contained in the plane + glm::vec3 n = glm::cross(v1, v2); // Plane's normal vector, pointing out of the triangle + float d = -glm::dot(n, p0); // Compute plane's equation constant + return (glm::dot(n, point) + d) <= 0; +} + glm::vec3 extractTranslation(const glm::mat4& matrix) { return glm::vec3(matrix[3][0], matrix[3][1], matrix[3][2]); } diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 50393b7f5f..e3a2c383e2 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -71,6 +71,8 @@ float angleBetween(const glm::vec3& v1, const glm::vec3& v2); glm::quat rotationBetween(const glm::vec3& v1, const glm::vec3& v2); +bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2); + glm::vec3 extractTranslation(const glm::mat4& matrix); void setTranslation(glm::mat4& matrix, const glm::vec3& translation);