diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index a58dd9065f..bfc0f9af30 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -11,6 +11,9 @@ #include +#include +#include + #include #include @@ -546,6 +549,33 @@ bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float rad return false; } +bool EntityTreeElement::findShapeCollisions(const Shape* shape, CollisionList& collisions) const { + bool atLeastOneCollision = false; + //AACube cube = getAACube(); + //return ShapeCollider::collideShapeWithAACubeLegacy(shape, cube.calcCenter(), cube.getScale(), collisions); + + QList::iterator entityItr = _entityItems->begin(); + QList::const_iterator entityEnd = _entityItems->end(); + while(entityItr != entityEnd) { + EntityItem* entity = (*entityItr); + glm::vec3 entityCenter = entity->getPosition(); + float entityRadius = entity->getRadius(); + + // don't collide with yourself??? + //if (entityCenter == center && entityRadius == radius) { + // return false; + //} + AACube entityAACube = entity->getMinimumAACube(); + AACubeShape aaCube(entityAACube.getScale(), entityAACube.calcCenter()); + + if (ShapeCollider::collideShapes(shape, &aaCube, collisions)) { + atLeastOneCollision = true; + } + ++entityItr; + } + return atLeastOneCollision; +} + void EntityTreeElement::updateEntityItemID(const EntityItemID& creatorTokenEntityID, const EntityItemID& knownIDEntityID) { uint16_t numberOfEntities = _entityItems->size(); for (uint16_t i = 0; i < numberOfEntities; i++) { diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index 5790903411..ab3754749b 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -142,6 +142,8 @@ public: virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject) const; + virtual bool findShapeCollisions(const Shape* shape, CollisionList& collisions) const; + const QList& getEntities() const { return *_entityItems; } QList& getEntities() { return *_entityItems; } bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; } diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index df2e40d96f..a834fb887a 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -817,9 +817,6 @@ bool findCapsulePenetrationOp(OctreeElement* element, void* extraData) { if (!box.expandedIntersectsSegment(args->start, args->end, args->radius)) { return false; } - if (!element->isLeaf()) { - return true; // recurse on children - } if (element->hasContent()) { glm::vec3 nodePenetration; if (box.findCapsulePenetration(args->start, args->end, args->radius, nodePenetration)) { @@ -827,6 +824,9 @@ bool findCapsulePenetrationOp(OctreeElement* element, void* extraData) { args->found = true; } } + if (!element->isLeaf()) { + return true; // recurse on children + } return false; } @@ -839,15 +839,15 @@ bool findShapeCollisionsOp(OctreeElement* element, void* extraData) { if (!cube.expandedContains(args->shape->getTranslation(), args->shape->getBoundingRadius())) { return false; } - if (!element->isLeaf()) { - return true; // recurse on children - } if (element->hasContent()) { - if (ShapeCollider::collideShapeWithAACubeLegacy(args->shape, cube.calcCenter(), cube.getScale(), args->collisions)) { + if (element->findShapeCollisions(args->shape, args->collisions)) { args->found = true; return true; } } + if (!element->isLeaf()) { + return true; // recurse on children + } return false; } diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index e641ddece2..61187dea03 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include #include @@ -17,7 +18,8 @@ #include #include -#include +#include +#include #include "AACube.h" #include "OctalCode.h" @@ -1369,6 +1371,10 @@ bool OctreeElement::findSpherePenetration(const glm::vec3& center, float radius, return _cube.findSpherePenetration(center, radius, penetration); } +bool OctreeElement::findShapeCollisions(const Shape* shape, CollisionList& collisions) const { + AACube cube = getAACube(); + return ShapeCollider::collideShapeWithAACubeLegacy(shape, cube.calcCenter(), cube.getScale(), collisions); +} // TODO: consider removing this, or switching to using getOrCreateChildElementContaining(const AACube& box)... OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float z, float s) { diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index 093a35720f..31a9dfddc1 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -25,6 +25,7 @@ #include "ViewFrustum.h" #include "OctreeConstants.h" +class CollisionList; class EncodeBitstreamParams; class Octree; class OctreeElement; @@ -32,6 +33,7 @@ class OctreeElementBag; class OctreeElementDeleteHook; class OctreePacketData; class ReadBitstreamToTreeParams; +class Shape; class VoxelSystem; const float SMALLEST_REASONABLE_OCTREE_ELEMENT_SCALE = (1.0f / TREE_SCALE) / 10000.0f; // 1/10,000th of a meter @@ -128,6 +130,8 @@ public: virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject) const; + virtual bool findShapeCollisions(const Shape* shape, CollisionList& collisions) const; + // Base class methods you don't need to implement const unsigned char* getOctalCode() const { return (_octcodePointer) ? _octalCode.pointer : &_octalCode.buffer[0]; } OctreeElement* getChildAtIndex(int childIndex) const;