From e1954d3e1dee87ac29aa52ec24ceab9f5cb1d17e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sun, 1 Mar 2015 15:19:26 -0800 Subject: [PATCH] spherical queries into Octree use meters --- libraries/entities/src/EntityTree.cpp | 7 ++++--- libraries/entities/src/EntityTree.h | 2 +- libraries/octree/src/Octree.cpp | 11 +++++++---- libraries/octree/src/OctreeElement.cpp | 5 ++++- libraries/octree/src/OctreeElement.h | 4 ++++ 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 1c820564f0..4c1963088c 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -476,8 +476,9 @@ public: bool EntityTree::findInSphereOperation(OctreeElement* element, void* extraData) { FindAllNearPointArgs* args = static_cast(extraData); glm::vec3 penetration; - bool sphereIntersection = element->getAACube().findSpherePenetration(args->position, - args->targetRadius, penetration); + AACube cube = element->getAACube(); + cube *= (float)TREE_SCALE; + bool sphereIntersection = cube.findSpherePenetration(args->position, args->targetRadius, penetration); // If this element contains the point, then search it... if (sphereIntersection) { @@ -493,7 +494,7 @@ bool EntityTree::findInSphereOperation(OctreeElement* element, void* extraData) // NOTE: assumes caller has handled locking void EntityTree::findEntitiesInMeters(const glm::vec3& center, float radius, QVector& foundEntities) { // position and targetRadius are in meters, so we need to convert to TreeUnits in FindNearPointArgs - FindAllNearPointArgs args = { center / (float)TREE_SCALE, radius / (float)TREE_SCALE }; + FindAllNearPointArgs args = { center, radius }; // NOTE: This should use recursion, since this is a spatial operation recurseTreeWithOperation(findInSphereOperation, &args); diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index e748df2548..f8a8262afd 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -169,7 +169,7 @@ private: bool updateEntityWithElement(EntityItem* entity, const EntityItemProperties& properties, EntityTreeElement* containingElement, bool allowLockChange); static bool findNearPointOperation(OctreeElement* element, void* extraData); - static bool findInSphereOperation(OctreeElement* element, void* extraData); + static bool findInSphereOperationInMeters(OctreeElement* element, void* extraData); static bool findInCubeOperation(OctreeElement* element, void* extraData); static bool sendEntitiesOperation(OctreeElement* element, void* extraData); diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 4a57b8047f..a1df449135 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -748,8 +748,11 @@ public: bool findSpherePenetrationOp(OctreeElement* element, void* extraData) { SphereArgs* args = static_cast(extraData); + // the details in args is in meters (world-frame) so we have to scale the element cube up + AACube box = element->getAACube(); + box *= (float)TREE_SCALE; + // coarse check against bounds - const AACube& box = element->getAACube(); if (!box.expandedContains(args->center, args->radius)) { return false; } @@ -758,7 +761,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) { if (element->findSpherePenetration(args->center, args->radius, elementPenetration, &args->penetratedObject)) { // NOTE: it is possible for this penetration accumulation algorithm to produce a // final penetration vector with zero length. - args->penetration = addPenetrations(args->penetration, elementPenetration * (float)(TREE_SCALE)); + args->penetration = addPenetrations(args->penetration, elementPenetration); args->found = true; } } @@ -772,8 +775,8 @@ bool Octree::findSpherePenetration(const glm::vec3& center, float radius, glm::v void** penetratedObject, Octree::lockType lockType, bool* accurateResult) { SphereArgs args = { - center / (float)(TREE_SCALE), - radius / (float)(TREE_SCALE), + center, + radius, penetration, false, NULL }; diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index b686796b9d..954d0b7847 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -1390,7 +1390,10 @@ bool OctreeElement::findDetailedRayIntersection(const glm::vec3& origin, const g bool OctreeElement::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject) const { - return _cube.findSpherePenetration(center, radius, penetration); + // center and radius are in meters, so we have to scale the _cube into world-frame + AACube cube = _cube; + cube *= (float)TREE_SCALE; + return cube.findSpherePenetration(center, radius, penetration); } // TODO: consider removing this, or switching to using getOrCreateChildElementContaining(const AACube& box)... diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index 8c83d9976e..e2229b2214 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -125,6 +125,10 @@ public: bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face, void** intersectedObject, bool precisionPicking, float distanceToElementCube); + /// \param center center of sphere in meters + /// \param radius radius of sphere in meters + /// \param[out] penetration pointing into cube from sphere + /// \param penetratedObject unused virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject) const;