2010-09-09 22:06:57 +00:00
|
|
|
/********************************************************************************
|
2015-02-15 20:56:45 +00:00
|
|
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
2016-04-11 18:15:20 +00:00
|
|
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
2010-09-09 22:06:57 +00:00
|
|
|
*********************************************************************************
|
|
|
|
* *
|
2011-11-13 17:49:03 +00:00
|
|
|
* 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. *
|
2010-09-09 22:06:57 +00:00
|
|
|
* *
|
2011-11-13 17:49:03 +00:00
|
|
|
* 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. *
|
2010-09-09 22:06:57 +00:00
|
|
|
* *
|
|
|
|
********************************************************************************/
|
|
|
|
|
2013-04-18 20:54:36 +00:00
|
|
|
#ifndef REACTPHYSICS3D_COLLISION_DETECTION_H
|
|
|
|
#define REACTPHYSICS3D_COLLISION_DETECTION_H
|
2010-09-09 22:06:57 +00:00
|
|
|
|
|
|
|
// Libraries
|
2014-08-07 19:38:31 +00:00
|
|
|
#include "body/CollisionBody.h"
|
2012-07-25 21:31:57 +00:00
|
|
|
#include "broadphase/BroadPhaseAlgorithm.h"
|
2014-08-07 19:38:31 +00:00
|
|
|
#include "engine/OverlappingPair.h"
|
2015-09-13 11:02:05 +00:00
|
|
|
#include "engine/EventListener.h"
|
2015-08-19 16:48:08 +00:00
|
|
|
#include "narrowphase/DefaultCollisionDispatch.h"
|
2014-08-07 19:38:31 +00:00
|
|
|
#include "memory/MemoryAllocator.h"
|
|
|
|
#include "constraint/ContactPoint.h"
|
2010-09-09 22:06:57 +00:00
|
|
|
#include <vector>
|
2011-10-18 22:03:05 +00:00
|
|
|
#include <map>
|
|
|
|
#include <set>
|
|
|
|
#include <utility>
|
2010-09-09 22:06:57 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// ReactPhysics3D namespace
|
2010-09-09 22:06:57 +00:00
|
|
|
namespace reactphysics3d {
|
|
|
|
|
2011-10-18 22:03:05 +00:00
|
|
|
// Declarations
|
|
|
|
class BroadPhaseAlgorithm;
|
2012-10-03 19:00:17 +00:00
|
|
|
class CollisionWorld;
|
2014-12-27 23:54:34 +00:00
|
|
|
class CollisionCallback;
|
2012-07-25 21:31:57 +00:00
|
|
|
|
2015-11-19 06:20:43 +00:00
|
|
|
// Class TestCollisionBetweenShapesCallback
|
|
|
|
class TestCollisionBetweenShapesCallback : public NarrowPhaseCallback {
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
CollisionCallback* mCollisionCallback;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
TestCollisionBetweenShapesCallback(CollisionCallback* callback)
|
|
|
|
: mCollisionCallback(callback) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-06-20 06:40:26 +00:00
|
|
|
// Destructor
|
|
|
|
virtual ~TestCollisionBetweenShapesCallback() { }
|
|
|
|
|
2015-11-19 06:20:43 +00:00
|
|
|
// Called by a narrow-phase collision algorithm when a new contact has been found
|
|
|
|
virtual void notifyContact(OverlappingPair* overlappingPair,
|
|
|
|
const ContactPointInfo& contactInfo);
|
|
|
|
};
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
// Class CollisionDetection
|
|
|
|
/**
|
|
|
|
* This class computes the collision detection algorithms. We first
|
|
|
|
* perform a broad-phase algorithm to know which pairs of bodies can
|
|
|
|
* collide and then we run a narrow-phase algorithm to compute the
|
|
|
|
* collision contacts between bodies.
|
|
|
|
*/
|
2015-10-12 16:02:18 +00:00
|
|
|
class CollisionDetection : public NarrowPhaseCallback {
|
2012-09-18 20:09:49 +00:00
|
|
|
|
2010-09-09 22:06:57 +00:00
|
|
|
private :
|
2012-10-09 20:21:02 +00:00
|
|
|
|
|
|
|
// -------------------- Attributes -------------------- //
|
|
|
|
|
2015-08-19 16:48:08 +00:00
|
|
|
/// Collision Detection Dispatch configuration
|
|
|
|
CollisionDispatch* mCollisionDispatch;
|
|
|
|
|
|
|
|
/// Default collision dispatch configuration
|
|
|
|
DefaultCollisionDispatch mDefaultCollisionDispatch;
|
|
|
|
|
|
|
|
/// Collision detection matrix (algorithms to use)
|
|
|
|
NarrowPhaseAlgorithm* mCollisionMatrix[NB_COLLISION_SHAPE_TYPES][NB_COLLISION_SHAPE_TYPES];
|
|
|
|
|
|
|
|
/// Reference to the memory allocator
|
|
|
|
MemoryAllocator& mMemoryAllocator;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Pointer to the physics world
|
2012-10-09 20:21:02 +00:00
|
|
|
CollisionWorld* mWorld;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Broad-phase overlapping pairs
|
2014-04-11 21:50:00 +00:00
|
|
|
std::map<overlappingpairid, OverlappingPair*> mOverlappingPairs;
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2015-10-08 19:28:37 +00:00
|
|
|
/// Overlapping pairs in contact (during the current Narrow-phase collision detection)
|
|
|
|
std::map<overlappingpairid, OverlappingPair*> mContactOverlappingPairs;
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Broad-phase algorithm
|
2014-04-11 21:50:00 +00:00
|
|
|
BroadPhaseAlgorithm mBroadPhaseAlgorithm;
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Narrow-phase GJK algorithm
|
2015-08-19 16:48:08 +00:00
|
|
|
// TODO : Delete this
|
2012-10-09 20:21:02 +00:00
|
|
|
GJKAlgorithm mNarrowPhaseGJKAlgorithm;
|
|
|
|
|
2013-06-26 20:28:31 +00:00
|
|
|
/// Set of pair of bodies that cannot collide between each other
|
|
|
|
std::set<bodyindexpair> mNoCollisionPairs;
|
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
/// True if some collision shapes have been added previously
|
|
|
|
bool mIsCollisionShapesAdded;
|
|
|
|
|
2012-10-09 20:21:02 +00:00
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Private copy-constructor
|
2012-10-09 20:21:02 +00:00
|
|
|
CollisionDetection(const CollisionDetection& collisionDetection);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Private assignment operator
|
2012-10-09 20:21:02 +00:00
|
|
|
CollisionDetection& operator=(const CollisionDetection& collisionDetection);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Compute the broad-phase collision detection
|
2012-10-09 20:21:02 +00:00
|
|
|
void computeBroadPhase();
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Compute the narrow-phase collision detection
|
2013-03-14 21:47:59 +00:00
|
|
|
void computeNarrowPhase();
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2014-05-15 04:39:39 +00:00
|
|
|
/// Add a contact manifold to the linked list of contact manifolds of the two bodies
|
|
|
|
/// involed in the corresponding contact.
|
2015-10-08 19:28:37 +00:00
|
|
|
void addContactManifoldToBody(OverlappingPair* pair);
|
2014-12-27 23:54:34 +00:00
|
|
|
|
|
|
|
/// Delete all the contact points in the currently overlapping pairs
|
|
|
|
void clearContactPoints();
|
2015-08-19 16:48:08 +00:00
|
|
|
|
|
|
|
/// Fill-in the collision detection matrix
|
|
|
|
void fillInCollisionMatrix();
|
2015-10-08 19:28:37 +00:00
|
|
|
|
|
|
|
/// Add all the contact manifold of colliding pairs to their bodies
|
|
|
|
void addAllContactManifoldsToBodies();
|
2012-01-25 22:57:27 +00:00
|
|
|
|
2010-09-09 22:06:57 +00:00
|
|
|
public :
|
2012-10-09 20:21:02 +00:00
|
|
|
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Constructor
|
2013-04-01 21:43:50 +00:00
|
|
|
CollisionDetection(CollisionWorld* world, MemoryAllocator& memoryAllocator);
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Destructor
|
2012-10-09 20:21:02 +00:00
|
|
|
~CollisionDetection();
|
|
|
|
|
2015-08-19 16:48:08 +00:00
|
|
|
/// Set the collision dispatch configuration
|
|
|
|
void setCollisionDispatch(CollisionDispatch* collisionDispatch);
|
|
|
|
|
2015-09-13 11:02:05 +00:00
|
|
|
/// Return the Narrow-phase collision detection algorithm to use between two types of shapes
|
|
|
|
NarrowPhaseAlgorithm* getCollisionAlgorithm(CollisionShapeType shape1Type,
|
|
|
|
CollisionShapeType shape2Type) const;
|
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
/// Add a proxy collision shape to the collision detection
|
2014-06-10 20:46:32 +00:00
|
|
|
void addProxyCollisionShape(ProxyShape* proxyShape, const AABB& aabb);
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
/// Remove a proxy collision shape from the collision detection
|
|
|
|
void removeProxyCollisionShape(ProxyShape* proxyShape);
|
|
|
|
|
|
|
|
/// Update a proxy collision shape (that has moved for instance)
|
2014-07-02 22:13:30 +00:00
|
|
|
void updateProxyCollisionShape(ProxyShape* shape, const AABB& aabb,
|
2015-11-20 06:20:56 +00:00
|
|
|
const Vector3& displacement = Vector3(0, 0, 0), bool forceReinsert = false);
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2013-06-26 20:28:31 +00:00
|
|
|
/// Add a pair of bodies that cannot collide with each other
|
|
|
|
void addNoCollisionPair(CollisionBody* body1, CollisionBody* body2);
|
|
|
|
|
|
|
|
/// Remove a pair of bodies that cannot collide with each other
|
2014-04-11 21:50:00 +00:00
|
|
|
void removeNoCollisionPair(CollisionBody* body1, CollisionBody* body2);
|
2013-06-26 20:28:31 +00:00
|
|
|
|
2014-06-24 21:31:13 +00:00
|
|
|
/// Ask for a collision shape to be tested again during broad-phase.
|
|
|
|
void askForBroadPhaseCollisionCheck(ProxyShape* shape);
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Compute the collision detection
|
2013-03-14 21:47:59 +00:00
|
|
|
void computeCollisionDetection();
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
/// Compute the collision detection
|
|
|
|
void testCollisionBetweenShapes(CollisionCallback* callback,
|
|
|
|
const std::set<uint>& shapes1,
|
|
|
|
const std::set<uint>& shapes2);
|
|
|
|
|
|
|
|
/// Report collision between two sets of shapes
|
|
|
|
void reportCollisionBetweenShapes(CollisionCallback* callback,
|
|
|
|
const std::set<uint>& shapes1,
|
|
|
|
const std::set<uint>& shapes2) ;
|
|
|
|
|
2014-11-04 21:38:40 +00:00
|
|
|
/// Ray casting method
|
2014-12-31 00:19:14 +00:00
|
|
|
void raycast(RaycastCallback* raycastCallback, const Ray& ray,
|
|
|
|
unsigned short raycastWithCategoryMaskBits) const;
|
2014-11-04 21:38:40 +00:00
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
/// Test if the AABBs of two bodies overlap
|
|
|
|
bool testAABBOverlap(const CollisionBody* body1,
|
|
|
|
const CollisionBody* body2) const;
|
|
|
|
|
|
|
|
/// Test if the AABBs of two proxy shapes overlap
|
|
|
|
bool testAABBOverlap(const ProxyShape* shape1,
|
|
|
|
const ProxyShape* shape2) const;
|
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
/// Allow the broadphase to notify the collision detection about an overlapping pair.
|
|
|
|
void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2);
|
2014-05-15 04:39:39 +00:00
|
|
|
|
2015-09-13 11:02:05 +00:00
|
|
|
/// Compute the narrow-phase collision detection
|
2014-12-27 23:54:34 +00:00
|
|
|
void computeNarrowPhaseBetweenShapes(CollisionCallback* callback,
|
|
|
|
const std::set<uint>& shapes1,
|
|
|
|
const std::set<uint>& shapes2);
|
|
|
|
|
2015-09-13 11:02:05 +00:00
|
|
|
/// 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();
|
|
|
|
|
2015-10-12 16:02:18 +00:00
|
|
|
/// Called by a narrow-phase collision algorithm when a new contact has been found
|
2015-10-12 16:37:18 +00:00
|
|
|
virtual void notifyContact(OverlappingPair* overlappingPair, const ContactPointInfo& contactInfo);
|
2015-10-12 16:02:18 +00:00
|
|
|
|
2015-09-13 11:02:05 +00:00
|
|
|
/// Create a new contact
|
2015-10-12 16:37:18 +00:00
|
|
|
void createContact(OverlappingPair* overlappingPair, const ContactPointInfo& contactInfo);
|
2015-09-13 11:02:05 +00:00
|
|
|
|
2014-05-15 04:39:39 +00:00
|
|
|
// -------------------- Friendship -------------------- //
|
|
|
|
|
|
|
|
friend class DynamicsWorld;
|
2014-08-09 08:28:37 +00:00
|
|
|
friend class ConvexMeshShape;
|
2010-09-09 22:06:57 +00:00
|
|
|
};
|
|
|
|
|
2015-09-10 05:30:50 +00:00
|
|
|
// Return the Narrow-phase collision detection algorithm to use between two types of shapes
|
|
|
|
inline NarrowPhaseAlgorithm* CollisionDetection::getCollisionAlgorithm(CollisionShapeType shape1Type,
|
|
|
|
CollisionShapeType shape2Type) const {
|
|
|
|
return mCollisionMatrix[shape1Type][shape2Type];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the collision dispatch configuration
|
2015-08-19 16:48:08 +00:00
|
|
|
inline void CollisionDetection::setCollisionDispatch(CollisionDispatch* collisionDispatch) {
|
|
|
|
mCollisionDispatch = collisionDispatch;
|
|
|
|
|
2015-09-10 05:30:50 +00:00
|
|
|
mCollisionDispatch->init(this, &mMemoryAllocator);
|
2015-08-19 16:48:08 +00:00
|
|
|
|
|
|
|
// Fill-in the collision matrix with the new algorithms to use
|
|
|
|
fillInCollisionMatrix();
|
|
|
|
}
|
2012-07-25 21:31:57 +00:00
|
|
|
|
|
|
|
// Add a body to the collision detection
|
2014-06-10 20:46:32 +00:00
|
|
|
inline void CollisionDetection::addProxyCollisionShape(ProxyShape* proxyShape,
|
|
|
|
const AABB& aabb) {
|
2012-07-25 21:31:57 +00:00
|
|
|
|
|
|
|
// Add the body to the broad-phase
|
2014-06-10 20:46:32 +00:00
|
|
|
mBroadPhaseAlgorithm.addProxyCollisionShape(proxyShape, aabb);
|
2012-07-25 21:31:57 +00:00
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
mIsCollisionShapesAdded = true;
|
|
|
|
}
|
2013-06-26 20:28:31 +00:00
|
|
|
|
|
|
|
// Add a pair of bodies that cannot collide with each other
|
|
|
|
inline void CollisionDetection::addNoCollisionPair(CollisionBody* body1,
|
|
|
|
CollisionBody* body2) {
|
2014-04-11 21:50:00 +00:00
|
|
|
mNoCollisionPairs.insert(OverlappingPair::computeBodiesIndexPair(body1, body2));
|
2013-06-26 20:28:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove a pair of bodies that cannot collide with each other
|
|
|
|
inline void CollisionDetection::removeNoCollisionPair(CollisionBody* body1,
|
|
|
|
CollisionBody* body2) {
|
2014-04-11 21:50:00 +00:00
|
|
|
mNoCollisionPairs.erase(OverlappingPair::computeBodiesIndexPair(body1, body2));
|
|
|
|
}
|
|
|
|
|
2014-06-24 21:31:13 +00:00
|
|
|
// Ask for a collision shape to be tested again during broad-phase.
|
|
|
|
/// We simply put the shape in the list of collision shape that have moved in the
|
|
|
|
/// previous frame so that it is tested for collision again in the broad-phase.
|
|
|
|
inline void CollisionDetection::askForBroadPhaseCollisionCheck(ProxyShape* shape) {
|
|
|
|
mBroadPhaseAlgorithm.addMovedCollisionShape(shape->mBroadPhaseID);
|
|
|
|
}
|
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
// Update a proxy collision shape (that has moved for instance)
|
2014-07-02 22:13:30 +00:00
|
|
|
inline void CollisionDetection::updateProxyCollisionShape(ProxyShape* shape, const AABB& aabb,
|
2015-11-20 06:20:56 +00:00
|
|
|
const Vector3& displacement, bool forceReinsert) {
|
2014-07-02 22:13:30 +00:00
|
|
|
mBroadPhaseAlgorithm.updateProxyCollisionShape(shape, aabb, displacement);
|
2013-06-26 20:28:31 +00:00
|
|
|
}
|
2012-01-25 22:57:27 +00:00
|
|
|
|
2014-11-04 21:38:40 +00:00
|
|
|
// Ray casting method
|
|
|
|
inline void CollisionDetection::raycast(RaycastCallback* raycastCallback,
|
2014-12-31 00:19:14 +00:00
|
|
|
const Ray& ray,
|
|
|
|
unsigned short raycastWithCategoryMaskBits) const {
|
2014-11-04 21:38:40 +00:00
|
|
|
|
2015-12-07 16:32:18 +00:00
|
|
|
PROFILE("CollisionDetection::raycast()");
|
|
|
|
|
2014-11-04 21:38:40 +00:00
|
|
|
RaycastTest rayCastTest(raycastCallback);
|
|
|
|
|
|
|
|
// Ask the broad-phase algorithm to call the testRaycastAgainstShape()
|
|
|
|
// callback method for each proxy shape hit by the ray in the broad-phase
|
2014-12-31 00:19:14 +00:00
|
|
|
mBroadPhaseAlgorithm.raycast(ray, rayCastTest, raycastWithCategoryMaskBits);
|
2014-11-04 21:38:40 +00:00
|
|
|
}
|
|
|
|
|
2014-12-27 23:54:34 +00:00
|
|
|
// Test if the AABBs of two proxy shapes overlap
|
|
|
|
inline bool CollisionDetection::testAABBOverlap(const ProxyShape* shape1,
|
|
|
|
const ProxyShape* shape2) const {
|
|
|
|
|
|
|
|
// If one of the shape's body is not active, we return no overlap
|
|
|
|
if (!shape1->getBody()->isActive() || !shape2->getBody()->isActive()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2);
|
|
|
|
}
|
|
|
|
|
2015-09-13 11:02:05 +00:00
|
|
|
// Return a pointer to the world
|
|
|
|
inline CollisionWorld* CollisionDetection::getWorld() {
|
|
|
|
return mWorld;
|
|
|
|
}
|
|
|
|
|
2013-03-02 15:26:18 +00:00
|
|
|
}
|
2010-09-09 22:06:57 +00:00
|
|
|
|
|
|
|
#endif
|