spherical queries into Octree use meters

This commit is contained in:
Andrew Meadows 2015-03-01 15:19:26 -08:00
parent 7836bb4dcd
commit e1954d3e1d
5 changed files with 20 additions and 9 deletions

View file

@ -476,8 +476,9 @@ public:
bool EntityTree::findInSphereOperation(OctreeElement* element, void* extraData) {
FindAllNearPointArgs* args = static_cast<FindAllNearPointArgs*>(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<const EntityItem*>& 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);

View file

@ -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);

View file

@ -748,8 +748,11 @@ public:
bool findSpherePenetrationOp(OctreeElement* element, void* extraData) {
SphereArgs* args = static_cast<SphereArgs*>(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 };

View file

@ -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)...

View file

@ -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;