From f2a66f31065c9ed9ae7444984eb6012feb763413 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 18 May 2015 13:08:11 -0700 Subject: [PATCH 1/3] Simplest fix for the grab crash that occurs with animated complex models. (e.g., clicking on air hockey props in front of a spinning windmill). --- libraries/render-utils/src/Model.cpp | 15 ++++++++++++++- libraries/render-utils/src/Model.h | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7528d1db4d..aee3bf7cc3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -527,12 +527,13 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g const FBXGeometry& geometry = _geometry->getFBXGeometry(); // If we hit the models box, then consider the submeshes... + _mutex.lock(); foreach(const AABox& subMeshBox, _calculatedMeshBoxes) { if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace)) { if (distanceToSubMesh < bestDistance) { if (pickAgainstTriangles) { - if (!_calculatedMeshTrianglesValid) { + if (!_calculatedMeshTrianglesValid) { recalculateMeshBoxes(pickAgainstTriangles); } // check our triangles here.... @@ -562,6 +563,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g } subMeshIndex++; } + _mutex.unlock(); if (intersectedSomething) { distance = bestDistance; @@ -597,6 +599,7 @@ bool Model::convexHullContains(glm::vec3 point) { // we can use the AABox's contains() by mapping our point into the model frame // and testing there. if (modelFrameBox.contains(modelFramePoint)){ + _mutex.lock(); if (!_calculatedMeshTrianglesValid) { recalculateMeshBoxes(true); } @@ -618,17 +621,23 @@ bool Model::convexHullContains(glm::vec3 point) { } if (insideMesh) { // It's inside this mesh, return true. + _mutex.unlock(); return true; } } subMeshIndex++; } + _mutex.unlock(); } // 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 +// Any script might trigger findRayIntersectionAgainstSubMeshes (and maybe convexHullContains), so these +// can occur multiple times. In addition, rendering does it's own ray picking in order to decide which +// entity-scripts to call. I think it would be best to do the picking once-per-frame (in cpu, or gpu if possible) +// and then the calls use the most recent such result. void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid; @@ -711,7 +720,9 @@ void Model::renderSetup(RenderArgs* args) { // against. We cache the results of these calculations so long as the model hasn't been // simulated and the mesh hasn't changed. if (args && !_calculatedMeshBoxesValid) { + _mutex.lock(); recalculateMeshBoxes(); + _mutex.unlock(); } // set up dilated textures on first render after load/simulate @@ -935,6 +946,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { void Model::renderDebugMeshBoxes() { int colorNdx = 0; + _mutex.unlock(); foreach(AABox box, _calculatedMeshBoxes) { if (_debugMeshBoxesID == GeometryCache::UNKNOWN_ID) { _debugMeshBoxesID = DependencyManager::get()->allocateID(); @@ -984,6 +996,7 @@ void Model::renderDebugMeshBoxes() { DependencyManager::get()->renderVertices(gpu::LINES, _debugMeshBoxesID); colorNdx++; } + _mutex.unlock(); } Extents Model::getBindExtents() const { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index dba8f5277f..8463093ac1 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -344,6 +345,7 @@ private: QVector< QVector > _calculatedMeshTriangles; // world coordinate triangles for all sub meshes bool _calculatedMeshTrianglesValid; + QMutex _mutex; void recalculateMeshBoxes(bool pickAgainstTriangles = false); From 95be6052331a35d5261c58effeefe67206feba23 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 18 May 2015 14:05:13 -0700 Subject: [PATCH 2/3] Typo: unlock=>lock in rednerDebugMeshBoxes. --- libraries/render-utils/src/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6907cad81b..616b613a97 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -971,7 +971,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { void Model::renderDebugMeshBoxes() { int colorNdx = 0; - _mutex.unlock(); + _mutex.lock(); foreach(AABox box, _calculatedMeshBoxes) { if (_debugMeshBoxesID == GeometryCache::UNKNOWN_ID) { _debugMeshBoxesID = DependencyManager::get()->allocateID(); From bb4df26690fbd482ebfc963812ded0e98509f7cd Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 18 May 2015 14:25:35 -0700 Subject: [PATCH 3/3] Fix indentation. --- libraries/render-utils/src/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 616b613a97..483ea6177e 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -558,7 +558,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace)) { if (distanceToSubMesh < bestDistance) { if (pickAgainstTriangles) { - if (!_calculatedMeshTrianglesValid) { + if (!_calculatedMeshTrianglesValid) { recalculateMeshBoxes(pickAgainstTriangles); } // check our triangles here....