Compound zones fix
Showing the changes to libraries/render-utils/src/Model.cpp (1 of 5 files). Show all
Unified · Split
| @@ -573,6 +573,61 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g · 572 unmodified lines | |||
| 573 | return intersectedSomething; | 573 | return intersectedSomething; |
| 574 | } | 574 | } |
| 575 | 575 | ||
| 576 | bool Model::convexHullContains(glm::vec3 point) { | ||
| 577 | // if we aren't active, we can't compute that yet... | ||
| 578 | if (!isActive()) { | ||
| 579 | return false; | ||
| 580 | } | ||
| 581 | |||
| 582 | // extents is the entity relative, scaled, centered extents of the entity | ||
| 583 | glm::vec3 position = _translation; | ||
| 584 | glm::mat4 rotation = glm::mat4_cast(_rotation); | ||
| 585 | glm::mat4 translation = glm::translate(position); | ||
| 586 | glm::mat4 modelToWorldMatrix = translation * rotation; | ||
| 587 | glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); | ||
| 588 | |||
| 589 | Extents modelExtents = getMeshExtents(); // NOTE: unrotated | ||
| 590 | |||
| 591 | glm::vec3 dimensions = modelExtents.maximum - modelExtents.minimum; | ||
| 592 | glm::vec3 corner = -(dimensions * _registrationPoint); | ||
| 593 | AABox modelFrameBox(corner, dimensions); | ||
| 594 | |||
| 595 | glm::vec3 modelFramePoint = glm::vec3(worldToModelMatrix * glm::vec4(point, 1.0f)); | ||
| 596 | |||
| 597 | // we can use the AABox's contains() by mapping our point into the model frame | ||
| 598 | // and testing there. | ||
| 599 | if (modelFrameBox.contains(modelFramePoint)){ | ||
| 600 | if (!_calculatedMeshTrianglesValid) { | ||
| 601 | recalculateMeshBoxes(true); | ||
| 602 | } | ||
| 603 | |||
| 604 | // If we are inside the models box, then consider the submeshes... | ||
| 605 | int subMeshIndex = 0; | ||
| 606 | foreach(const AABox& subMeshBox, _calculatedMeshBoxes) { | ||
| 607 | if (subMeshBox.contains(point)) { | ||
| 608 | bool insideMesh = true; | ||
| 609 | // To be inside the sub mesh, we need to be behind every triangles' planes | ||
| 610 | const QVector<Triangle>& meshTriangles = _calculatedMeshTriangles[subMeshIndex]; | ||
| 611 | foreach (const Triangle& triangle, meshTriangles) { | ||
| 612 | if (!isPointBehindTrianglesPlane(point, triangle.v0, triangle.v1, triangle.v2)) { | ||
| 613 | // it's not behind at least one so we bail | ||
| 614 | insideMesh = false; | ||
| 615 | break; | ||
| 616 | } | ||
| 617 | |||
| 618 | } | ||
| 619 | if (insideMesh) { | ||
| 620 | // It's inside this mesh, return true. | ||
| 621 | return true; | ||
| 622 | } | ||
| 623 | } | ||
| 624 | subMeshIndex++; | ||
| 625 | } | ||
| 626 | } | ||
| 627 | // It wasn't in any mesh, return false. | ||
| 628 | return false; | ||
| 629 | } | ||
| 630 | |||
| 576 | // TODO: we seem to call this too often when things haven't actually changed... look into optimizing this | 631 | // TODO: we seem to call this too often when things haven't actually changed... look into optimizing this |
| 577 | void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { | 632 | void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { |
| 578 | bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid; | 633 | bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid; |
| @@ -1047,7 +1102,7 @@ int Model::getLastFreeJointIndex(int jointIndex) const { · 468 unmodified lines | |||
| 1047 | 1102 | ||
| 1048 | void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bool delayLoad) { | 1103 | void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bool delayLoad) { |
| 1049 | // don't recreate the geometry if it's the same URL | 1104 | // don't recreate the geometry if it's the same URL |
| 1050 | if (_url == url) { | 1105 | if (_url == url && _geometry && _geometry->getURL() == url) { |
| 1051 | return; | 1106 | return; |
| 1052 | } | 1107 | } |
| 1053 | _url = url; | 1108 | _url = url; |