diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index 8b922e06..0ff3ea55 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -225,9 +225,9 @@ void CollisionDetection::computeNarrowPhase() { // Create the CollisionShapeInfo objects CollisionShapeInfo shape1Info(shape1, shape1->getCollisionShape(), shape1->getLocalToWorldTransform(), - shape1->getCachedCollisionData()); + pair, shape1->getCachedCollisionData()); CollisionShapeInfo shape2Info(shape2, shape2->getCollisionShape(), shape2->getLocalToWorldTransform(), - shape2->getCachedCollisionData()); + pair, shape2->getCachedCollisionData()); // Use the narrow-phase collision detection algorithm to check // if there really is a collision @@ -341,9 +341,9 @@ void CollisionDetection::computeNarrowPhaseBetweenShapes(CollisionCallback* call // Create the CollisionShapeInfo objects CollisionShapeInfo shape1Info(shape1, shape1->getCollisionShape(), shape1->getLocalToWorldTransform(), - shape1->getCachedCollisionData()); + pair, shape1->getCachedCollisionData()); CollisionShapeInfo shape2Info(shape2, shape2->getCollisionShape(), shape2->getLocalToWorldTransform(), - shape2->getCachedCollisionData()); + pair, shape2->getCachedCollisionData()); // Use the narrow-phase collision detection algorithm to check // if there really is a collision @@ -485,3 +485,13 @@ void CollisionDetection::fillInCollisionMatrix() { } } } + +// Return the world event listener +EventListener* CollisionDetection::getWorldEventListener() { + return mWorld->mEventListener; +} + +/// Return a reference to the world memory allocator +MemoryAllocator& CollisionDetection::getWorldMemoryAllocator() { + return mWorld->mMemoryAllocator; +} diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index 9dfc8931..9b198cb2 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -30,6 +30,7 @@ #include "body/CollisionBody.h" #include "broadphase/BroadPhaseAlgorithm.h" #include "engine/OverlappingPair.h" +#include "engine/EventListener.h" #include "narrowphase/DefaultCollisionDispatch.h" #include "memory/MemoryAllocator.h" #include "constraint/ContactPoint.h" @@ -108,9 +109,6 @@ class CollisionDetection { /// Compute the narrow-phase collision detection void computeNarrowPhase(); - /// Create a new contact - void createContact(OverlappingPair* overlappingPair, const ContactPointInfo* contactInfo); - /// Add a contact manifold to the linked list of contact manifolds of the two bodies /// involed in the corresponding contact. void addContactManifoldToBody(ContactManifold* contactManifold, @@ -121,10 +119,6 @@ class CollisionDetection { /// Fill-in the collision detection matrix void fillInCollisionMatrix(); - - /// Return the Narrow-phase collision detection algorithm to use between two types of shapes - NarrowPhaseAlgorithm* getCollisionAlgorithm(CollisionShapeType shape1Type, - CollisionShapeType shape2Type) const; public : @@ -139,6 +133,10 @@ class CollisionDetection { /// Set the collision dispatch configuration void setCollisionDispatch(CollisionDispatch* collisionDispatch); + /// Return the Narrow-phase collision detection algorithm to use between two types of shapes + NarrowPhaseAlgorithm* getCollisionAlgorithm(CollisionShapeType shape1Type, + CollisionShapeType shape2Type) const; + /// Add a proxy collision shape to the collision detection void addProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb); @@ -186,11 +184,23 @@ class CollisionDetection { /// Allow the broadphase to notify the collision detection about an overlapping pair. void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2); - // Compute the narrow-phase collision detection + /// Compute the narrow-phase collision detection void computeNarrowPhaseBetweenShapes(CollisionCallback* callback, const std::set& shapes1, const std::set& shapes2); + /// Return a pointer to the world + CollisionWorld* getWorld(); + + /// Return the world event listener + EventListener* getWorldEventListener(); + + /// Return a reference to the world memory allocator + MemoryAllocator& getWorldMemoryAllocator(); + + /// Create a new contact + void createContact(OverlappingPair* overlappingPair, const ContactPointInfo* contactInfo); + // -------------------- Friendship -------------------- // friend class DynamicsWorld; @@ -272,6 +282,11 @@ inline bool CollisionDetection::testAABBOverlap(const ProxyShape* shape1, return mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2); } +// Return a pointer to the world +inline CollisionWorld* CollisionDetection::getWorld() { + return mWorld; +} + } #endif diff --git a/src/collision/CollisionShapeInfo.h b/src/collision/CollisionShapeInfo.h index f1dc884d..61e6b6bf 100644 --- a/src/collision/CollisionShapeInfo.h +++ b/src/collision/CollisionShapeInfo.h @@ -32,6 +32,8 @@ /// Namespace ReactPhysics3D namespace reactphysics3d { +class OverlappingPair; + // Class CollisionShapeInfo /** * This structure regroups different things about a collision shape. This is @@ -41,15 +43,8 @@ struct CollisionShapeInfo { public: - /// Constructor - CollisionShapeInfo(ProxyShape* proxyCollisionShape, const CollisionShape* shape, - const Transform& shapeLocalToWorldTransform, - void** cachedData) - : proxyShape(proxyCollisionShape), collisionShape(shape), - shapeToWorldTransform(shapeLocalToWorldTransform), - cachedCollisionData(cachedData) { - - } + /// Broadphase overlapping pair + OverlappingPair* overlappingPair; /// Proxy shape ProxyShape* proxyShape; @@ -63,6 +58,15 @@ struct CollisionShapeInfo { /// Cached collision data of the proxy shape void** cachedCollisionData; + /// Constructor + CollisionShapeInfo(ProxyShape* proxyCollisionShape, const CollisionShape* shape, + const Transform& shapeLocalToWorldTransform, OverlappingPair* pair, + void** cachedData) + : overlappingPair(pair), proxyShape(proxyCollisionShape), collisionShape(shape), + shapeToWorldTransform(shapeLocalToWorldTransform), + cachedCollisionData(cachedData) { + + } }; } diff --git a/src/collision/ProxyShape.h b/src/collision/ProxyShape.h index fcdef1f3..7f6e7dbc 100644 --- a/src/collision/ProxyShape.h +++ b/src/collision/ProxyShape.h @@ -93,9 +93,6 @@ class ProxyShape { /// Private assignment operator ProxyShape& operator=(const ProxyShape& proxyShape); - /// Return the pointer to the cached collision data - void** getCachedCollisionData(); - public: // -------------------- Methods -------------------- // @@ -152,6 +149,9 @@ class ProxyShape { /// Return the next proxy shape in the linked list of proxy shapes const ProxyShape* getNext() const; + /// Return the pointer to the cached collision data + void** getCachedCollisionData(); + // -------------------- Friendship -------------------- // friend class OverlappingPair; diff --git a/src/collision/narrowphase/CollisionDispatch.h b/src/collision/narrowphase/CollisionDispatch.h index 2b282e09..8067a66f 100644 --- a/src/collision/narrowphase/CollisionDispatch.h +++ b/src/collision/narrowphase/CollisionDispatch.h @@ -50,7 +50,7 @@ class CollisionDispatch { virtual ~CollisionDispatch() {} /// Initialize the collision dispatch configuration - virtual void init(const CollisionDetection* collisionDetection, + virtual void init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) { } diff --git a/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp b/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp index be011c59..5067ed39 100644 --- a/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp +++ b/src/collision/narrowphase/ConcaveVsConvexAlgorithm.cpp @@ -24,9 +24,11 @@ ********************************************************************************/ // Libraries -#include "collision/shapes/ConvexShape.h" #include "collision/shapes/ConcaveShape.h" +#include "collision/shapes/TriangleShape.h" #include "ConcaveVsConvexAlgorithm.h" +#include "collision/CollisionDetection.h" +#include "engine/CollisionWorld.h" using namespace reactphysics3d; @@ -45,8 +47,8 @@ bool ConcaveVsConvexAlgorithm::testCollision(const CollisionShapeInfo& shape1Inf const CollisionShapeInfo& shape2Info, ContactPointInfo*& contactInfo) { - const ProxyShape* convexProxyShape; - const ProxyShape* concaveProxyShape; + ProxyShape* convexProxyShape; + ProxyShape* concaveProxyShape; const ConvexShape* convexShape; const ConcaveShape* concaveShape; @@ -65,7 +67,10 @@ bool ConcaveVsConvexAlgorithm::testCollision(const CollisionShapeInfo& shape1Inf } // Set the parameters of the callback object + mConvexVsTriangleCallback.setCollisionDetection(mCollisionDetection); mConvexVsTriangleCallback.setConvexShape(convexShape); + mConvexVsTriangleCallback.setProxyShapes(convexProxyShape, concaveProxyShape); + mConvexVsTriangleCallback.setOverlappingPair(shape1Info.overlappingPair); // Compute the convex shape AABB in the local-space of the concave shape AABB aabb; @@ -74,11 +79,52 @@ bool ConcaveVsConvexAlgorithm::testCollision(const CollisionShapeInfo& shape1Inf // Call the convex vs triangle callback for each triangle of the concave shape concaveShape->testAllTriangles(mConvexVsTriangleCallback, aabb); + + // TODO : Handle return value here } // Test collision between a triangle and the convex mesh shape void ConvexVsTriangleCallback::reportTriangle(const Vector3* trianglePoints) { - // Create + // Create a triangle collision shape + // TODO : Do we need to use a collision margin for a triangle ? + TriangleShape triangleShape(trianglePoints[0], trianglePoints[1], trianglePoints[2], 0.0); + // Select the collision algorithm to use between the triangle and the convex shape + NarrowPhaseAlgorithm* algo = mCollisionDetection->getCollisionAlgorithm(triangleShape.getType(), + mConvexShape->getType()); + + // Create the CollisionShapeInfo objects + CollisionShapeInfo shapeConvexInfo(mConvexProxyShape, mConvexShape, mConvexProxyShape->getLocalToWorldTransform(), + mOverlappingPair, mConvexProxyShape->getCachedCollisionData()); + CollisionShapeInfo shapeConcaveInfo(mConcaveProxyShape, mConcaveProxyShape->getCollisionShape(), + mConcaveProxyShape->getLocalToWorldTransform(), + mOverlappingPair, mConcaveProxyShape->getCachedCollisionData()); + + // Use the collision algorithm to test collision between the triangle and the other convex shape + ContactPointInfo* contactInfo = NULL; + if (algo->testCollision(shapeConvexInfo, shapeConcaveInfo, contactInfo)) { + assert(contactInfo != NULL); + + // If it is the first contact since the pair are overlapping + if (mOverlappingPair->getNbContactPoints() == 0) { + + // Trigger a callback event + if (mCollisionDetection->getWorldEventListener() != NULL) { + mCollisionDetection->getWorldEventListener()->beginContact(*contactInfo); + } + } + + // Create a new contact + mCollisionDetection->createContact(mOverlappingPair, contactInfo); + + // Trigger a callback event for the new contact + if (mCollisionDetection->getWorldEventListener() != NULL) { + mCollisionDetection->getWorldEventListener()->newContact(*contactInfo); + } + + // Delete and remove the contact info from the memory allocator + contactInfo->~ContactPointInfo(); + mCollisionDetection->getWorldMemoryAllocator().release(contactInfo, sizeof(ContactPointInfo)); + } } diff --git a/src/collision/narrowphase/ConcaveVsConvexAlgorithm.h b/src/collision/narrowphase/ConcaveVsConvexAlgorithm.h index 275b0512..a5270691 100644 --- a/src/collision/narrowphase/ConcaveVsConvexAlgorithm.h +++ b/src/collision/narrowphase/ConcaveVsConvexAlgorithm.h @@ -42,18 +42,46 @@ namespace reactphysics3d { */ class ConvexVsTriangleCallback : public TriangleCallback { - private: + protected: + + /// Pointer to the collision detection object + CollisionDetection* mCollisionDetection; /// Convex collision shape to test collision with const ConvexShape* mConvexShape; + /// Proxy shape of the convex collision shape + ProxyShape* mConvexProxyShape; + + /// Proxy shape of the concave collision shape + ProxyShape* mConcaveProxyShape; + + /// Broadphase overlapping pair + OverlappingPair* mOverlappingPair; + public: + /// Set the collision detection pointer + void setCollisionDetection(CollisionDetection* collisionDetection) { + mCollisionDetection = collisionDetection; + } + /// Set the convex collision shape to test collision with void setConvexShape(const ConvexShape* convexShape) { mConvexShape = convexShape; } + /// Set the broadphase overlapping pair + void setOverlappingPair(OverlappingPair* overlappingPair) { + mOverlappingPair = overlappingPair; + } + + /// Set the proxy shapes of the two collision shapes + void setProxyShapes(ProxyShape* convexProxyShape, ProxyShape* concaveProxyShape) { + mConvexProxyShape = convexProxyShape; + mConcaveProxyShape = concaveProxyShape; + } + /// Test collision between a triangle and the convex mesh shape virtual void reportTriangle(const Vector3* trianglePoints); diff --git a/src/collision/narrowphase/DefaultCollisionDispatch.cpp b/src/collision/narrowphase/DefaultCollisionDispatch.cpp index 9b5f0246..8aac650e 100644 --- a/src/collision/narrowphase/DefaultCollisionDispatch.cpp +++ b/src/collision/narrowphase/DefaultCollisionDispatch.cpp @@ -40,7 +40,7 @@ DefaultCollisionDispatch::~DefaultCollisionDispatch() { } /// Initialize the collision dispatch configuration -void DefaultCollisionDispatch::init(const CollisionDetection* collisionDetection, +void DefaultCollisionDispatch::init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) { // Initialize the collision algorithms diff --git a/src/collision/narrowphase/DefaultCollisionDispatch.h b/src/collision/narrowphase/DefaultCollisionDispatch.h index 525a5385..ca37ef56 100644 --- a/src/collision/narrowphase/DefaultCollisionDispatch.h +++ b/src/collision/narrowphase/DefaultCollisionDispatch.h @@ -62,7 +62,7 @@ class DefaultCollisionDispatch : public CollisionDispatch { virtual ~DefaultCollisionDispatch(); /// Initialize the collision dispatch configuration - virtual void init(const CollisionDetection* collisionDetection, + virtual void init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator); /// Select and return the narrow-phase collision detection algorithm to diff --git a/src/collision/narrowphase/GJK/GJKAlgorithm.h b/src/collision/narrowphase/GJK/GJKAlgorithm.h index 5a16295b..270899f4 100644 --- a/src/collision/narrowphase/GJK/GJKAlgorithm.h +++ b/src/collision/narrowphase/GJK/GJKAlgorithm.h @@ -92,7 +92,7 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm { ~GJKAlgorithm(); /// Initalize the algorithm - virtual void init(const CollisionDetection* collisionDetection, + virtual void init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator); /// Return true and compute a contact info if the two bounding volumes collide. @@ -108,7 +108,7 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm { }; // Initalize the algorithm -inline void GJKAlgorithm::init(const CollisionDetection* collisionDetection, +inline void GJKAlgorithm::init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) { NarrowPhaseAlgorithm::init(collisionDetection, memoryAllocator); mAlgoEPA.init(memoryAllocator); diff --git a/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp b/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp index c8948592..aeb4c301 100644 --- a/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp +++ b/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp @@ -41,7 +41,7 @@ NarrowPhaseAlgorithm::~NarrowPhaseAlgorithm() { } // Initalize the algorithm -void NarrowPhaseAlgorithm::init(const CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) { +void NarrowPhaseAlgorithm::init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) { mCollisionDetection = collisionDetection; mMemoryAllocator = memoryAllocator; } diff --git a/src/collision/narrowphase/NarrowPhaseAlgorithm.h b/src/collision/narrowphase/NarrowPhaseAlgorithm.h index 45d2b79c..7dd1bbd6 100644 --- a/src/collision/narrowphase/NarrowPhaseAlgorithm.h +++ b/src/collision/narrowphase/NarrowPhaseAlgorithm.h @@ -51,7 +51,7 @@ class NarrowPhaseAlgorithm { // -------------------- Attributes -------------------- // /// Pointer to the collision detection object - const CollisionDetection* mCollisionDetection; + CollisionDetection* mCollisionDetection; /// Pointer to the memory allocator MemoryAllocator* mMemoryAllocator; @@ -78,7 +78,7 @@ class NarrowPhaseAlgorithm { virtual ~NarrowPhaseAlgorithm(); /// Initalize the algorithm - virtual void init(const CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator); + virtual void init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator); /// Set the current overlapping pair of bodies void setCurrentOverlappingPair(OverlappingPair* overlappingPair); diff --git a/test/tests/collision/TestCollisionWorld.h b/test/tests/collision/TestCollisionWorld.h index fe89984b..b5e81b73 100644 --- a/test/tests/collision/TestCollisionWorld.h +++ b/test/tests/collision/TestCollisionWorld.h @@ -39,6 +39,8 @@ enum CollisionCategory { CATEGORY_3 = 0x0004 }; +// TODO : Add test for concave shape collision here + // Class class WorldCollisionCallback : public CollisionCallback { diff --git a/test/tests/collision/TestRaycast.h b/test/tests/collision/TestRaycast.h index bfba8c4f..2c86a7db 100644 --- a/test/tests/collision/TestRaycast.h +++ b/test/tests/collision/TestRaycast.h @@ -37,6 +37,8 @@ #include "collision/shapes/ConvexMeshShape.h" #include "collision/shapes/CylinderShape.h" +// TODO : Add test for concave shape here + /// Reactphysics3D namespace namespace reactphysics3d {