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 | 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 | 631 | // TODO: we seem to call this too often when things haven't actually changed... look into optimizing this |
| 577 | 632 | void Model::recalculateMeshBoxes(bool pickAgainstTriangles) { |
| 578 | 633 | bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid; |
| @@ -1047,7 +1102,7 @@ int Model::getLastFreeJointIndex(int jointIndex) const { · 468 unmodified lines | ||
| 1047 | 1102 | |
| 1048 | 1103 | void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bool delayLoad) { |
| 1049 | 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 | 1106 | return; |
| 1052 | 1107 | } |
| 1053 | 1108 | _url = url; |