Do not use callbacks for middle-phase collision detection

This commit is contained in:
Daniel Chappuis 2019-08-04 23:24:48 +02:00
parent 9deb90dc6f
commit db995ea52c
17 changed files with 286 additions and 481 deletions

View File

@ -120,7 +120,6 @@ SET (REACTPHYSICS3D_HEADERS
"src/collision/HalfEdgeStructure.h"
"src/collision/CollisionDetection.h"
"src/collision/ContactManifold.h"
"src/collision/MiddlePhaseTriangleCallback.h"
"src/constraint/BallAndSocketJoint.h"
"src/constraint/ContactPoint.h"
"src/constraint/FixedJoint.h"
@ -213,7 +212,6 @@ SET (REACTPHYSICS3D_SOURCES
"src/collision/HalfEdgeStructure.cpp"
"src/collision/CollisionDetection.cpp"
"src/collision/ContactManifold.cpp"
"src/collision/MiddlePhaseTriangleCallback.cpp"
"src/constraint/BallAndSocketJoint.cpp"
"src/constraint/ContactPoint.cpp"
"src/constraint/FixedJoint.cpp"

View File

@ -90,7 +90,7 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape, con
AABB(localBoundsMin, localBoundsMax),
transform, collisionShape, decimal(1), 0x0001, 0xFFFF);
bool isActive = mWorld.mCollisionBodyComponents.getIsActive(mEntity);
mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, isActive, proxyShapeComponent);
mWorld.mProxyShapesComponents.addComponent(proxyShapeEntity, !isActive, proxyShapeComponent);
mWorld.mCollisionBodyComponents.addProxyShapeToBody(mEntity, proxyShapeEntity);

View File

@ -34,7 +34,6 @@
#include "body/RigidBody.h"
#include "configuration.h"
#include "collision/CollisionCallback.h"
#include "collision/MiddlePhaseTriangleCallback.h"
#include "collision/OverlapCallback.h"
#include "collision/narrowphase/NarrowPhaseInfoBatch.h"
#include "collision/ContactManifold.h"
@ -289,26 +288,28 @@ void CollisionDetection::computeMiddlePhase(OverlappingPairMap& overlappingPairs
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
NarrowPhaseInput& narrowPhaseInput) {
RP3D_PROFILE("CollisionDetection::computeConvexVsConcaveMiddlePhase()", mProfiler);
ProxyShape* shape1 = pair->getShape1();
ProxyShape* shape2 = pair->getShape2();
ProxyShape* convexProxyShape;
ProxyShape* concaveProxyShape;
const ConvexShape* convexShape;
const ConcaveShape* concaveShape;
ConvexShape* convexShape;
ConcaveShape* concaveShape;
// Collision shape 1 is convex, collision shape 2 is concave
if (shape1->getCollisionShape()->isConvex()) {
convexProxyShape = shape1;
convexShape = static_cast<const ConvexShape*>(shape1->getCollisionShape());
convexShape = static_cast<ConvexShape*>(shape1->getCollisionShape());
concaveProxyShape = shape2;
concaveShape = static_cast<const ConcaveShape*>(shape2->getCollisionShape());
concaveShape = static_cast<ConcaveShape*>(shape2->getCollisionShape());
}
else { // Collision shape 2 is convex, collision shape 1 is concave
convexProxyShape = shape2;
convexShape = static_cast<const ConvexShape*>(shape2->getCollisionShape());
convexShape = static_cast<ConvexShape*>(shape2->getCollisionShape());
concaveProxyShape = shape1;
concaveShape = static_cast<const ConcaveShape*>(shape1->getCollisionShape());
concaveShape = static_cast<ConcaveShape*>(shape1->getCollisionShape());
}
// Select the narrow phase algorithm to use according to the two collision shapes
@ -317,25 +318,48 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
assert(algorithmType != NarrowPhaseAlgorithmType::None);
// Set the parameters of the callback object
MiddlePhaseTriangleCallback middlePhaseCallback(pair, concaveProxyShape, convexProxyShape,
concaveShape, narrowPhaseInput, algorithmType, allocator);
#ifdef IS_PROFILING_ACTIVE
// Set the profiler
middlePhaseCallback.setProfiler(mProfiler);
#endif
// Compute the convex shape AABB in the local-space of the convex shape
const Transform convexToConcaveTransform = concaveProxyShape->getLocalToWorldTransform().getInverse() *
convexProxyShape->getLocalToWorldTransform();
AABB aabb;
convexShape->computeAABB(aabb, convexToConcaveTransform);
// Call the convex vs triangle callback for each triangle of the concave shape
concaveShape->testAllTriangles(middlePhaseCallback, aabb);
// Compute the concave shape triangles that are overlapping with the convex mesh AABB
List<Vector3> triangleVertices(allocator);
List<Vector3> triangleVerticesNormals(allocator);
List<uint> shapeIds(allocator);
concaveShape->computeOverlappingTriangles(aabb, triangleVertices, triangleVerticesNormals, shapeIds, allocator);
assert(triangleVertices.size() == triangleVerticesNormals.size());
assert(shapeIds.size() == triangleVertices.size() / 3);
assert(triangleVertices.size() % 3 == 0);
assert(triangleVerticesNormals.size() % 3 == 0);
// For each overlapping triangle
for (uint i=0; i < shapeIds.size(); i++)
{
// Create a triangle collision shape (the allocated memory for the TriangleShape will be released in the
// destructor of the corresponding NarrowPhaseInfo.
TriangleShape* triangleShape = new (allocator.allocate(sizeof(TriangleShape)))
TriangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], allocator);
#ifdef IS_PROFILING_ACTIVE
// Set the profiler to the triangle shape
triangleShape->setProfiler(mProfiler);
#endif
bool isShape1Convex = pair->getShape1()->getCollisionShape()->isConvex();
ProxyShape* shape1 = isShape1Convex ? convexProxyShape : concaveProxyShape;
ProxyShape* shape2 = isShape1Convex ? concaveProxyShape : convexProxyShape;
// Create a narrow phase info for the narrow-phase collision detection
narrowPhaseInput.addNarrowPhaseTest(pair, isShape1Convex ? convexShape : triangleShape,
isShape1Convex ? triangleShape : convexShape,
shape1->getLocalToWorldTransform(), shape2->getLocalToWorldTransform(),
algorithmType, allocator);
}
}
// Execute the narrow-phase collision detection algorithm on batches

View File

@ -65,21 +65,13 @@ struct ContactPointInfo {
/// Contact point of body 2 in local space of body 2
Vector3 localPoint2;
// TODO : Remove this field
/// Pointer to the next contact point info
ContactPointInfo* next;
// TODO : Remove this field
/// True if the contact point has already been inserted into a manifold
bool isUsed;
// -------------------- Methods -------------------- //
/// Constructor
ContactPointInfo(const Vector3& contactNormal, decimal penDepth,
const Vector3& localPt1, const Vector3& localPt2)
: normal(contactNormal), penetrationDepth(penDepth),
localPoint1(localPt1), localPoint2(localPt2), next(nullptr), isUsed(false) {
localPoint1(localPt1), localPoint2(localPt2) {
assert(contactNormal.lengthSquare() > decimal(0.8));
assert(penDepth > decimal(0.0));

View File

@ -1,59 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2018 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
// Libraries
#include "collision/MiddlePhaseTriangleCallback.h"
#include "engine/OverlappingPair.h"
#include "collision/shapes/TriangleShape.h"
#include "collision/narrowphase/NarrowPhaseInput.h"
using namespace reactphysics3d;
// Report collision between a triangle of a concave shape and the convex mesh shape (for middle-phase)
void MiddlePhaseTriangleCallback::testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) {
// Create a triangle collision shape (the allocated memory for the TriangleShape will be released in the
// destructor of the corresponding NarrowPhaseInfo.
TriangleShape* triangleShape = new (mAllocator.allocate(sizeof(TriangleShape)))
TriangleShape(trianglePoints, verticesNormals, shapeId, mAllocator);
#ifdef IS_PROFILING_ACTIVE
// Set the profiler to the triangle shape
triangleShape->setProfiler(mProfiler);
#endif
bool isShape1Convex = mOverlappingPair->getShape1()->getCollisionShape()->isConvex();
ProxyShape* shape1 = isShape1Convex ? mConvexProxyShape : mConcaveProxyShape;
ProxyShape* shape2 = isShape1Convex ? mConcaveProxyShape : mConvexProxyShape;
// Create a narrow phase info for the narrow-phase collision detection
mOutNarrowPhaseInput.addNarrowPhaseTest(mOverlappingPair,
isShape1Convex ? mConvexProxyShape->getCollisionShape() : triangleShape,
isShape1Convex ? triangleShape : mConvexProxyShape->getCollisionShape(),
shape1->getLocalToWorldTransform(), shape2->getLocalToWorldTransform(),
mNarrowPhaseAlgorithmType, mAllocator);
}

View File

@ -1,118 +0,0 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2018 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef REACTPHYSICS3D_MIDDLE_PHASE_TRIANGLE_CALLBACK_H
#define REACTPHYSICS3D_MIDDLE_PHASE_TRIANGLE_CALLBACK_H
#include "configuration.h"
#include "collision/shapes/ConcaveShape.h"
/// Namespace ReactPhysics3D
namespace reactphysics3d {
// Libraries
// Declarations
class ConcaveShape;
class OverlappingPair;
class NarrowPhaseAlgorithm;
class ProxyShape;
class MemoryAllocator;
class Profiler;
class NarrowPhaseInput;
enum class NarrowPhaseAlgorithmType;
struct Vector3;
// Class ConvexVsTriangleCallback
/**
* This class is used to report a collision between the triangle
* of a concave mesh shape and a convex shape during the
* middle-phase algorithm.
*/
class MiddlePhaseTriangleCallback : public TriangleCallback {
protected:
/// Broadphase overlapping pair
OverlappingPair* mOverlappingPair;
/// Pointer to the concave proxy shape
ProxyShape* mConcaveProxyShape;
/// Pointer to the convex proxy shape
ProxyShape* mConvexProxyShape;
/// Pointer to the concave collision shape
const ConcaveShape* mConcaveShape;
/// Reference to the narrow phase input
NarrowPhaseInput& mOutNarrowPhaseInput;
/// Type of narrow-phase algorithm to use
NarrowPhaseAlgorithmType mNarrowPhaseAlgorithmType;
/// Reference to the single-frame memory allocator
MemoryAllocator& mAllocator;
#ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler
Profiler* mProfiler;
#endif
public:
/// Constructor
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
ProxyShape* concaveProxyShape,
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
NarrowPhaseInput& outNarrowPhaseInput,
NarrowPhaseAlgorithmType algorithmType,
MemoryAllocator& allocator)
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
mOutNarrowPhaseInput(outNarrowPhaseInput), mNarrowPhaseAlgorithmType(algorithmType),
mAllocator(allocator) {
}
/// Test collision between a triangle and the convex mesh shape
virtual void testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) override;
#ifdef IS_PROFILING_ACTIVE
/// Set the profiler
void setProfiler(Profiler* profiler) {
mProfiler = profiler;
}
#endif
};
}
#endif

View File

@ -642,9 +642,8 @@ void DynamicAABBTree::reportAllShapesOverlappingWithShapes(const List<int>& node
}
}
/// Report all shapes overlapping with the AABB given in parameter.
// TODO : Do not use this method anymore. Use
void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, DynamicAABBTreeOverlapCallback& callback) const {
// Report all shapes overlapping with the AABB given in parameter.
void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const {
// Create a stack with the nodes to visit
Stack<int> stack(mAllocator, 64);
@ -669,7 +668,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, Dynam
if (nodeToVisit->isLeaf()) {
// Notify the broad-phase about a new potential overlapping pair
callback.notifyOverlappingNode(nodeIDToVisit);
overlappingNodes.add(nodeIDToVisit);
}
else { // If the node is not a leaf
@ -682,7 +681,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb, Dynam
}
// Ray casting method
void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback &callback) const {
void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const {
RP3D_PROFILE("DynamicAABBTree::raycast()", mProfiler);

View File

@ -242,7 +242,7 @@ class DynamicAABBTree {
size_t endIndex, List<Pair<int, int>>& outOverlappingNodes) const;
/// Report all shapes overlapping with the AABB given in parameter.
void reportAllShapesOverlappingWithAABB(const AABB& aabb, DynamicAABBTreeOverlapCallback& callback) const;
void reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const;
/// Ray casting method
void raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const;

View File

@ -84,8 +84,7 @@ void ConcaveMeshShape::initBVHTree() {
}
// Return the three vertices coordinates (in the array outTriangleVertices) of a triangle
void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex,
Vector3* outTriangleVertices) const {
void ConcaveMeshShape::getTriangleVertices(uint subPart, uint triangleIndex, Vector3* outTriangleVertices) const {
// Get the triangle vertex array of the current sub-part
TriangleVertexArray* triangleVertexArray = mTriangleMesh->getSubpart(subPart);
@ -116,14 +115,40 @@ void ConcaveMeshShape::getTriangleVerticesNormals(uint subPart, uint triangleInd
}
// Use a callback method on all triangles of the concave shape inside a given AABB
void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const {
// Compute all the triangles of the mesh that are overlapping with the AABB in parameter
void ConcaveMeshShape::computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const {
ConvexTriangleAABBOverlapCallback overlapCallback(callback, *this, mDynamicAABBTree);
// Compute the nodes of the internal AABB tree that are overlapping with the AABB
List<int> overlappingNodes(allocator);
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(localAABB, overlappingNodes);
// Ask the Dynamic AABB Tree to report all the triangles that are overlapping
// with the AABB of the convex shape.
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(localAABB, overlapCallback);
// For each overlapping node
for (uint i=0; i < overlappingNodes.size(); i++) {
int nodeId = overlappingNodes[i];
// Get the node data (triangle index and mesh subpart index)
int32* data = mDynamicAABBTree.getNodeDataInt(nodeId);
// Get the triangle vertices for this node from the concave mesh shape
Vector3 trianglePoints[3];
getTriangleVertices(data[0], data[1], trianglePoints);
triangleVertices.add(trianglePoints[0]);
triangleVertices.add(trianglePoints[1]);
triangleVertices.add(trianglePoints[2]);
// Get the vertices normals of the triangle
Vector3 verticesNormals[3];
getTriangleVerticesNormals(data[0], data[1], verticesNormals);
triangleVerticesNormals.add(verticesNormals[0]);
triangleVerticesNormals.add(verticesNormals[1]);
triangleVerticesNormals.add(verticesNormals[2]);
// Compute the triangle shape ID
shapeIds.add(computeTriangleShapeId(data[0], data[1]));
}
}
// Raycast method with feedback information

View File

@ -155,7 +155,7 @@ class ConcaveMeshShape : public ConcaveShape {
/// Insert all the triangles into the dynamic AABB tree
void initBVHTree();
/// Return the three vertices coordinates (in the array outTriangleVertices) of a triangle
/// Return the three vertices coordinates (in the list outTriangleVertices) of a triangle
void getTriangleVertices(uint subPart, uint triangleIndex, Vector3* outTriangleVertices) const;
/// Return the three vertex normals (in the array outVerticesNormals) of a triangle
@ -164,6 +164,11 @@ class ConcaveMeshShape : public ConcaveShape {
/// Compute the shape Id for a given triangle of the mesh
uint computeTriangleShapeId(uint subPart, uint triangleIndex) const;
/// Compute all the triangles of the mesh that are overlapping with the AABB in parameter
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3> &triangleVertices,
List<Vector3> &triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const override;
public:
/// Constructor
@ -187,9 +192,6 @@ class ConcaveMeshShape : public ConcaveShape {
/// Return the local inertia tensor of the collision shape
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
/// Use a callback method on all triangles of the concave shape inside a given AABB
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override;
/// Return the string representation of the shape
virtual std::string to_string() const override;

View File

@ -99,7 +99,9 @@ class ConcaveShape : public CollisionShape {
virtual bool isPolyhedron() const override;
/// Use a callback method on all triangles of the concave shape inside a given AABB
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const=0;
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const=0;
};
// Return true if the collision shape is convex, false if it is concave

View File

@ -91,7 +91,9 @@ void HeightFieldShape::getLocalBounds(Vector3& min, Vector3& max) const {
// of the body when need to test and see against which triangles of the height-field we need
// to test for collision. We compute the sub-grid points that are inside the other body's AABB
// and then for each rectangle in the sub-grid we generate two triangles that we use to test collision.
void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const {
void HeightFieldShape::computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const {
// Compute the non-scaled AABB
Vector3 inverseScaling(decimal(1.0) / mScaling.x, decimal(1.0) / mScaling.y, decimal(1.0) / mScaling.z);
@ -141,7 +143,9 @@ void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB&
const Vector3 p4 = getVertexAt(i + 1, j + 1);
// Generate the first triangle for the current grid rectangle
Vector3 trianglePoints[3] = {p1, p2, p3};
triangleVertices.add(p1);
triangleVertices.add(p2);
triangleVertices.add(p3);
// Compute the triangle normal
Vector3 triangle1Normal = (p2 - p1).cross(p3 - p1).getUnit();
@ -153,15 +157,17 @@ void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB&
// and compute the angle of incident edges with asin(). Maybe we could also precompute the
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
// store them.
Vector3 verticesNormals1[3] = {triangle1Normal, triangle1Normal, triangle1Normal};
triangleVerticesNormals.add(triangle1Normal);
triangleVerticesNormals.add(triangle1Normal);
triangleVerticesNormals.add(triangle1Normal);
// Test collision against the first triangle
callback.testTriangle(trianglePoints, verticesNormals1, computeTriangleShapeId(i, j, 0));
// Compute the shape ID
shapeIds.add(computeTriangleShapeId(i, j, 0));
// Generate the second triangle for the current grid rectangle
trianglePoints[0] = p3;
trianglePoints[1] = p2;
trianglePoints[2] = p4;
triangleVertices.add(p3);
triangleVertices.add(p2);
triangleVertices.add(p4);
// Compute the triangle normal
Vector3 triangle2Normal = (p2 - p3).cross(p4 - p3).getUnit();
@ -173,10 +179,12 @@ void HeightFieldShape::testAllTriangles(TriangleCallback& callback, const AABB&
// and compute the angle of incident edges with asin(). Maybe we could also precompute the
// vertices normal at the HeightFieldShape constructor but it will require extra memory to
// store them.
Vector3 verticesNormals2[3] = {triangle2Normal, triangle2Normal, triangle2Normal};
triangleVerticesNormals.add(triangle2Normal);
triangleVerticesNormals.add(triangle2Normal);
triangleVerticesNormals.add(triangle2Normal);
// Test collision against the second triangle
callback.testTriangle(trianglePoints, verticesNormals2, computeTriangleShapeId(i, j, 1));
// Compute the shape ID
shapeIds.add(computeTriangleShapeId(i, j, 1));
}
}
}
@ -221,22 +229,61 @@ bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxySh
RP3D_PROFILE("HeightFieldShape::raycast()", mProfiler);
TriangleOverlapCallback triangleCallback(ray, proxyShape, raycastInfo, *this, allocator);
#ifdef IS_PROFILING_ACTIVE
// Set the profiler
triangleCallback.setProfiler(mProfiler);
#endif
// Compute the AABB for the ray
const Vector3 rayEnd = ray.point1 + ray.maxFraction * (ray.point2 - ray.point1);
const AABB rayAABB(Vector3::min(ray.point1, rayEnd), Vector3::max(ray.point1, rayEnd));
testAllTriangles(triangleCallback, rayAABB);
// Compute the triangles overlapping with the ray AABB
List<Vector3> triangleVertices(allocator);
List<Vector3> triangleVerticesNormals(allocator);
List<uint> shapeIds(allocator);
computeOverlappingTriangles(rayAABB, triangleVertices, triangleVerticesNormals, shapeIds, allocator);
return triangleCallback.getIsHit();
assert(triangleVertices.size() == triangleVerticesNormals.size());
assert(shapeIds.size() == triangleVertices.size() / 3);
assert(triangleVertices.size() % 3 == 0);
assert(triangleVerticesNormals.size() % 3 == 0);
bool isHit = false;
decimal smallestHitFraction = ray.maxFraction;
// For each overlapping triangle
for (uint i=0; i < shapeIds.size(); i++)
{
// Create a triangle collision shape
TriangleShape triangleShape(&(triangleVertices[i * 3]), &(triangleVerticesNormals[i * 3]), shapeIds[i], allocator);
triangleShape.setRaycastTestType(getRaycastTestType());
#ifdef IS_PROFILING_ACTIVE
// Set the profiler to the triangle shape
triangleShape.setProfiler(mProfiler);
#endif
// Ray casting test against the collision shape
RaycastInfo triangleRaycastInfo;
bool isTriangleHit = triangleShape.raycast(ray, triangleRaycastInfo, proxyShape, allocator);
// If the ray hit the collision shape
if (isTriangleHit && triangleRaycastInfo.hitFraction <= smallestHitFraction) {
assert(triangleRaycastInfo.hitFraction >= decimal(0.0));
raycastInfo.body = triangleRaycastInfo.body;
raycastInfo.proxyShape = triangleRaycastInfo.proxyShape;
raycastInfo.hitFraction = triangleRaycastInfo.hitFraction;
raycastInfo.worldPoint = triangleRaycastInfo.worldPoint;
raycastInfo.worldNormal = triangleRaycastInfo.worldNormal;
raycastInfo.meshSubpart = -1;
raycastInfo.triangleIndex = -1;
smallestHitFraction = triangleRaycastInfo.hitFraction;
isHit = true;
}
}
return isHit;
}
// Return the vertex (local-coordinates) of the height field at a given (x,y) position
@ -264,42 +311,6 @@ Vector3 HeightFieldShape::getVertexAt(int x, int y) const {
return vertex * mScaling;
}
// Raycast test between a ray and a triangle of the heightfield
void TriangleOverlapCallback::testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) {
// Create a triangle collision shape
TriangleShape triangleShape(trianglePoints, verticesNormals, shapeId, mAllocator);
triangleShape.setRaycastTestType(mHeightFieldShape.getRaycastTestType());
#ifdef IS_PROFILING_ACTIVE
// Set the profiler to the triangle shape
triangleShape.setProfiler(mProfiler);
#endif
// Ray casting test against the collision shape
RaycastInfo raycastInfo;
bool isTriangleHit = triangleShape.raycast(mRay, raycastInfo, mProxyShape, mAllocator);
// If the ray hit the collision shape
if (isTriangleHit && raycastInfo.hitFraction <= mSmallestHitFraction) {
assert(raycastInfo.hitFraction >= decimal(0.0));
mRaycastInfo.body = raycastInfo.body;
mRaycastInfo.proxyShape = raycastInfo.proxyShape;
mRaycastInfo.hitFraction = raycastInfo.hitFraction;
mRaycastInfo.worldPoint = raycastInfo.worldPoint;
mRaycastInfo.worldNormal = raycastInfo.worldNormal;
mRaycastInfo.meshSubpart = -1;
mRaycastInfo.triangleIndex = -1;
mSmallestHitFraction = raycastInfo.hitFraction;
mIsHit = true;
}
}
// Return the string representation of the shape
std::string HeightFieldShape::to_string() const {

View File

@ -36,57 +36,6 @@ class HeightFieldShape;
class Profiler;
class TriangleShape;
// Class TriangleOverlapCallback
/**
* This class is used for testing AABB and triangle overlap for raycasting
*/
class TriangleOverlapCallback : public TriangleCallback {
protected:
const Ray& mRay;
ProxyShape* mProxyShape;
RaycastInfo& mRaycastInfo;
bool mIsHit;
decimal mSmallestHitFraction;
const HeightFieldShape& mHeightFieldShape;
MemoryAllocator& mAllocator;
#ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler
Profiler* mProfiler;
#endif
public:
// Constructor
TriangleOverlapCallback(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo,
const HeightFieldShape& heightFieldShape, MemoryAllocator& allocator)
: mRay(ray), mProxyShape(proxyShape), mRaycastInfo(raycastInfo),
mHeightFieldShape (heightFieldShape), mAllocator(allocator) {
mIsHit = false;
mSmallestHitFraction = mRay.maxFraction;
}
bool getIsHit() const {return mIsHit;}
/// Raycast test between a ray and a triangle of the heightfield
virtual void testTriangle(const Vector3* trianglePoints, const Vector3* verticesNormals, uint shapeId) override;
#ifdef IS_PROFILING_ACTIVE
/// Set the profiler
void setProfiler(Profiler* profiler) {
mProfiler = profiler;
}
#endif
};
// Class HeightFieldShape
/**
* This class represents a static height field that can be used to represent
@ -212,7 +161,9 @@ class HeightFieldShape : public ConcaveShape {
virtual void computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const override;
/// Use a callback method on all triangles of the concave shape inside a given AABB
virtual void testAllTriangles(TriangleCallback& callback, const AABB& localAABB) const override;
virtual void computeOverlappingTriangles(const AABB& localAABB, List<Vector3>& triangleVertices,
List<Vector3>& triangleVerticesNormals, List<uint>& shapeIds,
MemoryAllocator& allocator) const override;
/// Return the string representation of the shape
virtual std::string to_string() const override;

View File

@ -180,6 +180,7 @@ class TriangleShape : public ConvexPolyhedronShape {
friend class ConcaveMeshRaycastCallback;
friend class TriangleOverlapCallback;
friend class MiddlePhaseTriangleCallback;
friend class HeightFieldShape;
};
// Return the number of bytes used by the collision shape

View File

@ -117,7 +117,7 @@ void BroadPhaseSystem::updateProxyShape(Entity proxyShapeEntity) {
uint32 index = mProxyShapesComponents.mMapEntityToComponentIndex[proxyShapeEntity];
// Update the proxy-shape component
updateProxyShapesComponents(index, index + 1);
updateProxyShapesComponents(index, 1);
}
// Update the broad-phase state of all the enabled proxy-shapes
@ -146,15 +146,17 @@ void BroadPhaseSystem::updateProxyShapeInternal(int broadPhaseId, const AABB& aa
}
// Update the broad-phase state of some proxy-shapes components
void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 endIndex) {
void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 nbItems) {
assert(startIndex <= endIndex);
assert(nbItems > 0);
assert(startIndex < mProxyShapesComponents.getNbComponents());
assert(endIndex <= mProxyShapesComponents.getNbComponents());
assert(startIndex + nbItems <= mProxyShapesComponents.getNbComponents());
// Make sure we do not update disabled components
startIndex = std::min(startIndex, mProxyShapesComponents.getNbEnabledComponents());
endIndex = std::min(endIndex, mProxyShapesComponents.getNbEnabledComponents());
uint32 endIndex = std::min(startIndex + nbItems, mProxyShapesComponents.getNbEnabledComponents());
nbItems = endIndex - startIndex;
assert(nbItems >= 0);
// Get the time step if we are in a dynamics world
DynamicsWorld* dynamicsWorld = dynamic_cast<DynamicsWorld*>(mCollisionDetection.getWorld());
@ -164,7 +166,7 @@ void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 end
}
// For each proxy-shape component to update
for (uint32 i = startIndex; i < endIndex; i++) {
for (uint32 i = startIndex; i < startIndex + nbItems; i++) {
const int broadPhaseId = mProxyShapesComponents.mBroadPhaseIds[i];
if (broadPhaseId != -1) {
@ -193,14 +195,6 @@ void BroadPhaseSystem::updateProxyShapesComponents(uint32 startIndex, uint32 end
}
}
void BroadPhaseSystem::reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const {
AABBOverlapCallback callback(overlappingNodes);
// Ask the dynamic AABB tree to report all collision shapes that overlap with this AABB
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(aabb, callback);
}
// Compute all the overlapping pairs of collision shapes
void BroadPhaseSystem::computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes) {

View File

@ -143,7 +143,7 @@ class BroadPhaseSystem {
void updateProxyShapeInternal(int broadPhaseId, const AABB& aabb, const Vector3& displacement);
/// Update the broad-phase state of some proxy-shapes components
void updateProxyShapesComponents(uint32 startIndex, uint32 endIndex);
void updateProxyShapesComponents(uint32 startIndex, uint32 nbItems);
public :
@ -182,9 +182,6 @@ class BroadPhaseSystem {
/// step and that need to be tested again for broad-phase overlapping.
void removeMovedCollisionShape(int broadPhaseID);
/// Report all the shapes that are overlapping with a given AABB
void reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const;
/// Compute all the overlapping pairs of collision shapes
void computeOverlappingPairs(MemoryManager& memoryManager, List<Pair<int, int>>& overlappingNodes);

View File

@ -31,32 +31,11 @@
#include "collision/broadphase/DynamicAABBTree.h"
#include "memory/MemoryManager.h"
#include "utils/Profiler.h"
#include <vector>
/// Reactphysics3D namespace
namespace reactphysics3d {
class TestOverlapCallback : public DynamicAABBTreeOverlapCallback {
public :
// TODO : Replace this by rp3d::List
std::vector<int> mOverlapNodes;
// Called when a overlapping node has been found during the call to
// DynamicAABBTree:reportAllShapesOverlappingWithAABB()
virtual void notifyOverlappingNode(int nodeId) override {
mOverlapNodes.push_back(nodeId);
}
void reset() {
mOverlapNodes.clear();
}
bool isOverlapping(int nodeId) const {
return std::find(mOverlapNodes.begin(), mOverlapNodes.end(), nodeId) != mOverlapNodes.end();
}
};
class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
public:
@ -78,6 +57,7 @@ class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {
}
};
// Class TestDynamicAABBTree
/**
* Unit test for the dynamic AABB tree
@ -88,8 +68,8 @@ class TestDynamicAABBTree : public Test {
// ---------- Atributes ---------- //
TestOverlapCallback mOverlapCallback;
DynamicTreeRaycastCallback mRaycastCallback;
PoolAllocator mAllocator;
public :
@ -101,6 +81,10 @@ class TestDynamicAABBTree : public Test {
}
bool isOverlapping(int nodeId, const List<int>& overlappingNodes) const {
return std::find(overlappingNodes.begin(), overlappingNodes.end(), nodeId) != overlappingNodes.end();
}
/// Run the tests
void run() {
@ -202,45 +186,47 @@ class TestDynamicAABBTree : public Test {
// ---------- Tests ---------- //
List<int> overlappingNodes(mAllocator);
// AABB overlapping nothing
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping everything
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 1 and 3
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 3 and 4
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 2
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// ---- Update the object AABBs with the initial AABBs (no reinsertion) ----- //
@ -250,44 +236,44 @@ class TestDynamicAABBTree : public Test {
tree.updateObject(object4Id, aabb4, Vector3::zero());
// AABB overlapping nothing
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping everything
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 1 and 3
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 3 and 4
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 2
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// ---- Update the object AABBs with the initial AABBs (with reinsertion) ----- //
@ -297,44 +283,44 @@ class TestDynamicAABBTree : public Test {
tree.updateObject(object4Id, aabb4, Vector3::zero());
// AABB overlapping nothing
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-10, 12, -4), Vector3(10, 50, 4)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping everything
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-15, -15, -4), Vector3(15, 15, 4)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 1 and 3
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-4, 2, -4), Vector3(-1, 7, 4)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 3 and 4
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-6, -5, -2), Vector3(2, 2, 0)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(isOverlapping(object4Id, overlappingNodes));
// AABB overlapping object 2
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(5, -10, -2), Vector3(7, 10, 9)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// ---- Move objects 2 and 3 ----- //
@ -345,20 +331,20 @@ class TestDynamicAABBTree : public Test {
tree.updateObject(object3Id, newAABB3, Vector3::zero());
// AABB overlapping object 3
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(6, -10, -2), Vector3(8, 5, 3)), mOverlapCallback);
rp3d_test(!mOverlapCallback.isOverlapping(object1Id));
rp3d_test(!mOverlapCallback.isOverlapping(object2Id));
rp3d_test(mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(6, -10, -2), Vector3(8, 5, 3)), overlappingNodes);
rp3d_test(!isOverlapping(object1Id, overlappingNodes));
rp3d_test(!isOverlapping(object2Id, overlappingNodes));
rp3d_test(isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
// AABB overlapping objects 1, 2
mOverlapCallback.reset();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-8, 5, -3), Vector3(-2, 11, 3)), mOverlapCallback);
rp3d_test(mOverlapCallback.isOverlapping(object1Id));
rp3d_test(mOverlapCallback.isOverlapping(object2Id));
rp3d_test(!mOverlapCallback.isOverlapping(object3Id));
rp3d_test(!mOverlapCallback.isOverlapping(object4Id));
overlappingNodes.clear();
tree.reportAllShapesOverlappingWithAABB(AABB(Vector3(-8, 5, -3), Vector3(-2, 11, 3)), overlappingNodes);
rp3d_test(isOverlapping(object1Id, overlappingNodes));
rp3d_test(isOverlapping(object2Id, overlappingNodes));
rp3d_test(!isOverlapping(object3Id, overlappingNodes));
rp3d_test(!isOverlapping(object4Id, overlappingNodes));
#ifdef IS_PROFILING_ACTIVE
delete profiler;