2011-10-18 22:03:05 +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 *
|
2011-10-18 22:03:05 +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. *
|
2011-10-18 22:03:05 +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. *
|
2011-10-18 22:03:05 +00:00
|
|
|
* *
|
|
|
|
********************************************************************************/
|
|
|
|
|
2013-04-18 20:54:36 +00:00
|
|
|
#ifndef REACTPHYSICS3D_OVERLAPPING_PAIR_H
|
|
|
|
#define REACTPHYSICS3D_OVERLAPPING_PAIR_H
|
2011-10-18 22:03:05 +00:00
|
|
|
|
|
|
|
// Libraries
|
2015-10-02 05:04:05 +00:00
|
|
|
#include "collision/ContactManifoldSet.h"
|
2014-08-04 20:46:58 +00:00
|
|
|
#include "collision/ProxyShape.h"
|
2014-08-07 19:38:31 +00:00
|
|
|
#include "collision/shapes/CollisionShape.h"
|
2018-01-26 16:34:26 +00:00
|
|
|
#include "containers/Map.h"
|
|
|
|
#include "containers/containers_common.h"
|
2011-10-18 22:03:05 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// ReactPhysics3D namespace
|
2011-10-18 22:03:05 +00:00
|
|
|
namespace reactphysics3d {
|
|
|
|
|
2017-05-29 06:32:10 +00:00
|
|
|
// Structure LastFrameCollisionInfo
|
|
|
|
/**
|
|
|
|
* This structure contains collision info about the last frame.
|
|
|
|
* This is used for temporal coherence between frames.
|
|
|
|
*/
|
|
|
|
struct LastFrameCollisionInfo {
|
|
|
|
|
|
|
|
/// True if we have information about the previous frame
|
|
|
|
bool isValid;
|
|
|
|
|
2017-11-22 21:43:27 +00:00
|
|
|
/// True if the frame info is obsolete (the collision shape are not overlapping in middle phase)
|
|
|
|
bool isObsolete;
|
|
|
|
|
2017-05-29 06:32:10 +00:00
|
|
|
/// True if the two shapes were colliding in the previous frame
|
|
|
|
bool wasColliding;
|
|
|
|
|
|
|
|
/// True if we were using GJK algorithm to check for collision in the previous frame
|
|
|
|
bool wasUsingGJK;
|
|
|
|
|
|
|
|
/// True if we were using SAT algorithm to check for collision in the previous frame
|
|
|
|
bool wasUsingSAT;
|
|
|
|
|
|
|
|
// ----- GJK Algorithm -----
|
|
|
|
|
|
|
|
/// Previous separating axis
|
|
|
|
Vector3 gjkSeparatingAxis;
|
|
|
|
|
|
|
|
// SAT Algorithm
|
|
|
|
bool satIsAxisFacePolyhedron1;
|
|
|
|
bool satIsAxisFacePolyhedron2;
|
|
|
|
uint satMinAxisFaceIndex;
|
|
|
|
uint satMinEdge1Index;
|
|
|
|
uint satMinEdge2Index;
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
LastFrameCollisionInfo() {
|
|
|
|
|
|
|
|
isValid = false;
|
2017-11-22 21:43:27 +00:00
|
|
|
isObsolete = false;
|
2017-05-29 06:32:10 +00:00
|
|
|
wasColliding = false;
|
|
|
|
wasUsingSAT = false;
|
|
|
|
wasUsingGJK = false;
|
2017-09-09 13:37:55 +00:00
|
|
|
|
|
|
|
gjkSeparatingAxis = Vector3(0, 1, 0);
|
2017-05-29 06:32:10 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
// Class OverlappingPair
|
|
|
|
/**
|
2014-04-11 21:50:00 +00:00
|
|
|
* This class represents a pair of two proxy collision shapes that are overlapping
|
2013-03-05 22:09:50 +00:00
|
|
|
* during the broad-phase collision detection. It is created when
|
2014-04-11 21:50:00 +00:00
|
|
|
* the two proxy collision shapes start to overlap and is destroyed when they do not
|
2013-03-05 22:09:50 +00:00
|
|
|
* overlap anymore. This class contains a contact manifold that
|
|
|
|
* store all the contact points between the two bodies.
|
|
|
|
*/
|
2011-10-18 22:03:05 +00:00
|
|
|
class OverlappingPair {
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2018-01-26 16:34:26 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
/// Pair of shape ids
|
|
|
|
struct ShapeIdPair {
|
|
|
|
|
|
|
|
uint shapeIdBody1;
|
|
|
|
uint shapeIdBody2;
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
ShapeIdPair(uint id1, uint id2) : shapeIdBody1(id1), shapeIdBody2(id2) {}
|
|
|
|
|
|
|
|
/// Equality operator
|
|
|
|
bool operator==(const ShapeIdPair& pair) const {
|
|
|
|
return shapeIdBody1 == pair.shapeIdBody1 && shapeIdBody2 == pair.shapeIdBody2;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Pair of broad-phase ids
|
|
|
|
struct OverlappingPairId {
|
|
|
|
|
|
|
|
uint body1Id;
|
|
|
|
uint body2Id;
|
|
|
|
|
|
|
|
/// Constructor
|
|
|
|
OverlappingPairId(uint id1, uint id2) : body1Id(id1), body2Id(id2) {}
|
|
|
|
|
|
|
|
/// Equality operator
|
|
|
|
bool operator==(const OverlappingPairId& pair) const {
|
|
|
|
return body1Id == pair.body1Id && body2Id == pair.body2Id;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-10-18 22:03:05 +00:00
|
|
|
private:
|
2012-10-09 20:21:02 +00:00
|
|
|
|
|
|
|
// -------------------- Attributes -------------------- //
|
|
|
|
|
2015-10-02 05:04:05 +00:00
|
|
|
/// Set of persistent contact manifolds
|
|
|
|
ContactManifoldSet mContactManifoldSet;
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2017-07-30 20:14:46 +00:00
|
|
|
/// Linked-list of potential contact manifold
|
|
|
|
ContactManifoldInfo* mPotentialContactManifolds;
|
|
|
|
|
2017-11-22 21:43:27 +00:00
|
|
|
/// Persistent memory allocator
|
2018-01-01 17:35:57 +00:00
|
|
|
MemoryAllocator& mPersistentAllocator;
|
2017-11-22 21:43:27 +00:00
|
|
|
|
2017-07-30 20:14:46 +00:00
|
|
|
/// Memory allocator used to allocated memory for the ContactManifoldInfo and ContactPointInfo
|
2018-01-01 17:35:57 +00:00
|
|
|
MemoryAllocator& mTempMemoryAllocator;
|
2017-07-30 20:14:46 +00:00
|
|
|
|
2018-01-26 16:34:26 +00:00
|
|
|
/// Temporal coherence collision data for each overlapping collision shapes of this pair.
|
|
|
|
/// Temporal coherence data store collision information about the last frame.
|
|
|
|
/// If two convex shapes overlap, we have a single collision data but if one shape is concave,
|
|
|
|
/// we might have collision data for several overlapping triangles. The key in the map is the
|
|
|
|
/// shape Ids of the two collision shapes.
|
|
|
|
Map<ShapeIdPair, LastFrameCollisionInfo*> mLastFrameCollisionInfos;
|
|
|
|
|
2011-10-18 22:03:05 +00:00
|
|
|
public:
|
2012-10-09 20:21:02 +00:00
|
|
|
|
|
|
|
// -------------------- Methods -------------------- //
|
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Constructor
|
2018-01-01 17:35:57 +00:00
|
|
|
OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, MemoryAllocator& persistentMemoryAllocator,
|
|
|
|
MemoryAllocator& temporaryMemoryAllocator);
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Destructor
|
2017-08-31 21:11:00 +00:00
|
|
|
~OverlappingPair();
|
2016-07-08 05:25:37 +00:00
|
|
|
|
|
|
|
/// Deleted copy-constructor
|
|
|
|
OverlappingPair(const OverlappingPair& pair) = delete;
|
|
|
|
|
|
|
|
/// Deleted assignment operator
|
|
|
|
OverlappingPair& operator=(const OverlappingPair& pair) = delete;
|
2011-10-18 22:03:05 +00:00
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
/// Return the pointer to first proxy collision shape
|
2015-08-17 04:44:26 +00:00
|
|
|
ProxyShape* getShape1() const;
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2013-03-05 22:09:50 +00:00
|
|
|
/// Return the pointer to second body
|
2015-08-17 04:44:26 +00:00
|
|
|
ProxyShape* getShape2() const;
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2017-05-29 06:32:10 +00:00
|
|
|
/// Return the last frame collision info
|
2018-01-26 16:34:26 +00:00
|
|
|
LastFrameCollisionInfo* getLastFrameCollisionInfo(ShapeIdPair& shapeIds);
|
2012-10-09 20:21:02 +00:00
|
|
|
|
2015-10-15 05:48:28 +00:00
|
|
|
/// Return the a reference to the contact manifold set
|
|
|
|
const ContactManifoldSet& getContactManifoldSet();
|
2013-08-26 19:28:48 +00:00
|
|
|
|
2017-07-30 20:14:46 +00:00
|
|
|
/// Clear all the potential contact manifolds
|
|
|
|
void clearPotentialContactManifolds();
|
|
|
|
|
|
|
|
/// Add potential contact-points from narrow-phase into potential contact manifolds
|
|
|
|
void addPotentialContactPoints(NarrowPhaseInfo* narrowPhaseInfo);
|
|
|
|
|
|
|
|
/// Add a contact to the contact manifold
|
|
|
|
void addContactManifold(const ContactManifoldInfo* contactManifoldInfo);
|
|
|
|
|
|
|
|
/// Return a reference to the temporary memory allocator
|
2018-01-01 17:35:57 +00:00
|
|
|
MemoryAllocator& getTemporaryAllocator();
|
2017-07-30 20:14:46 +00:00
|
|
|
|
|
|
|
/// Return true if one of the shapes of the pair is a concave shape
|
|
|
|
bool hasConcaveShape() const;
|
|
|
|
|
2017-08-18 15:50:27 +00:00
|
|
|
/// Return true if the overlapping pair has contact manifolds with contacts
|
|
|
|
bool hasContacts() const;
|
|
|
|
|
2017-07-30 20:14:46 +00:00
|
|
|
/// Return a pointer to the first potential contact manifold in the linked-list
|
|
|
|
ContactManifoldInfo* getPotentialContactManifolds();
|
|
|
|
|
|
|
|
/// Reduce the number of contact points of all the potential contact manifolds
|
|
|
|
void reducePotentialContactManifolds();
|
|
|
|
|
2017-09-04 20:23:29 +00:00
|
|
|
/// Make the contact manifolds and contact points obsolete
|
2017-10-17 22:41:32 +00:00
|
|
|
void makeContactsObsolete();
|
2017-07-30 20:14:46 +00:00
|
|
|
|
2017-09-04 20:23:29 +00:00
|
|
|
/// Clear the obsolete contact manifold and contact points
|
|
|
|
void clearObsoleteManifoldsAndContactPoints();
|
2014-12-27 23:54:34 +00:00
|
|
|
|
2017-10-17 22:41:32 +00:00
|
|
|
/// Reduce the contact manifolds that have too many contact points
|
|
|
|
void reduceContactManifolds();
|
2017-10-12 18:07:39 +00:00
|
|
|
|
2017-11-22 21:43:27 +00:00
|
|
|
/// Add a new last frame collision info if it does not exist for the given shapes already
|
|
|
|
void addLastFrameInfoIfNecessary(uint shapeId1, uint shapeId2);
|
|
|
|
|
|
|
|
/// Return the last frame collision info for a given pair of shape ids
|
|
|
|
LastFrameCollisionInfo* getLastFrameCollisionInfo(uint shapeId1, uint shapeId2) const;
|
|
|
|
|
|
|
|
/// Delete all the obsolete last frame collision info
|
|
|
|
void clearObsoleteLastFrameCollisionInfos();
|
|
|
|
|
|
|
|
/// Make all the last frame collision infos obsolete
|
|
|
|
void makeLastFrameCollisionInfosObsolete();
|
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
/// Return the pair of bodies index
|
2018-01-26 16:34:26 +00:00
|
|
|
static OverlappingPairId computeID(ProxyShape* shape1, ProxyShape* shape2);
|
2014-04-11 21:50:00 +00:00
|
|
|
|
|
|
|
/// Return the pair of bodies index of the pair
|
|
|
|
static bodyindexpair computeBodiesIndexPair(CollisionBody* body1, CollisionBody* body2);
|
|
|
|
|
2013-08-26 19:28:48 +00:00
|
|
|
// -------------------- Friendship -------------------- //
|
|
|
|
|
|
|
|
friend class DynamicsWorld;
|
2011-10-18 22:03:05 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Return the pointer to first body
|
2015-08-17 04:44:26 +00:00
|
|
|
inline ProxyShape* OverlappingPair::getShape1() const {
|
2015-10-13 17:10:13 +00:00
|
|
|
return mContactManifoldSet.getShape1();
|
2011-10-18 22:03:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the pointer to second body
|
2015-08-17 04:44:26 +00:00
|
|
|
inline ProxyShape* OverlappingPair::getShape2() const {
|
2015-10-13 17:10:13 +00:00
|
|
|
return mContactManifoldSet.getShape2();
|
2011-10-18 22:03:05 +00:00
|
|
|
}
|
|
|
|
|
2013-02-26 21:43:45 +00:00
|
|
|
// Add a contact to the contact manifold
|
2017-07-30 20:14:46 +00:00
|
|
|
inline void OverlappingPair::addContactManifold(const ContactManifoldInfo* contactManifoldInfo) {
|
2017-02-26 11:48:50 +00:00
|
|
|
mContactManifoldSet.addContactManifold(contactManifoldInfo);
|
2013-02-28 18:50:52 +00:00
|
|
|
}
|
2011-10-18 22:03:05 +00:00
|
|
|
|
2017-11-22 21:43:27 +00:00
|
|
|
// Return the last frame collision info for a given shape id or nullptr if none is found
|
2018-01-26 16:34:26 +00:00
|
|
|
inline LastFrameCollisionInfo* OverlappingPair::getLastFrameCollisionInfo(ShapeIdPair& shapeIds) {
|
|
|
|
Map<ShapeIdPair, LastFrameCollisionInfo*>::Iterator it = mLastFrameCollisionInfos.find(shapeIds);
|
2017-11-22 21:43:27 +00:00
|
|
|
if (it != mLastFrameCollisionInfos.end()) {
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
2013-02-28 18:50:52 +00:00
|
|
|
}
|
2011-10-18 22:03:05 +00:00
|
|
|
|
2013-02-26 21:43:45 +00:00
|
|
|
// Return the contact manifold
|
2015-10-15 05:48:28 +00:00
|
|
|
inline const ContactManifoldSet& OverlappingPair::getContactManifoldSet() {
|
|
|
|
return mContactManifoldSet;
|
2011-10-18 22:03:05 +00:00
|
|
|
}
|
|
|
|
|
2017-09-04 20:23:29 +00:00
|
|
|
// Make the contact manifolds and contact points obsolete
|
2017-10-17 22:41:32 +00:00
|
|
|
inline void OverlappingPair::makeContactsObsolete() {
|
2017-07-30 20:14:46 +00:00
|
|
|
|
2017-09-04 20:23:29 +00:00
|
|
|
mContactManifoldSet.makeContactsObsolete();
|
2017-07-30 20:14:46 +00:00
|
|
|
}
|
|
|
|
|
2014-04-11 21:50:00 +00:00
|
|
|
// Return the pair of bodies index
|
2018-01-26 16:34:26 +00:00
|
|
|
inline OverlappingPair::OverlappingPairId OverlappingPair::computeID(ProxyShape* shape1, ProxyShape* shape2) {
|
2014-04-11 21:50:00 +00:00
|
|
|
assert(shape1->mBroadPhaseID >= 0 && shape2->mBroadPhaseID >= 0);
|
|
|
|
|
|
|
|
// Construct the pair of body index
|
2018-01-26 16:34:26 +00:00
|
|
|
OverlappingPairId pairID = shape1->mBroadPhaseID < shape2->mBroadPhaseID ?
|
|
|
|
OverlappingPairId(shape1->mBroadPhaseID, shape2->mBroadPhaseID) :
|
|
|
|
OverlappingPairId(shape2->mBroadPhaseID, shape1->mBroadPhaseID);
|
|
|
|
assert(pairID.body1Id != pairID.body2Id);
|
2014-04-11 21:50:00 +00:00
|
|
|
return pairID;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the pair of bodies index
|
|
|
|
inline bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* body1,
|
|
|
|
CollisionBody* body2) {
|
|
|
|
|
|
|
|
// Construct the pair of body index
|
|
|
|
bodyindexpair indexPair = body1->getID() < body2->getID() ?
|
|
|
|
std::make_pair(body1->getID(), body2->getID()) :
|
|
|
|
std::make_pair(body2->getID(), body1->getID());
|
|
|
|
assert(indexPair.first != indexPair.second);
|
|
|
|
return indexPair;
|
|
|
|
}
|
|
|
|
|
2017-07-30 20:14:46 +00:00
|
|
|
// Return a reference to the temporary memory allocator
|
2018-01-01 17:35:57 +00:00
|
|
|
inline MemoryAllocator& OverlappingPair::getTemporaryAllocator() {
|
2017-07-30 20:14:46 +00:00
|
|
|
return mTempMemoryAllocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return true if one of the shapes of the pair is a concave shape
|
|
|
|
inline bool OverlappingPair::hasConcaveShape() const {
|
|
|
|
return !getShape1()->getCollisionShape()->isConvex() ||
|
|
|
|
!getShape2()->getCollisionShape()->isConvex();
|
|
|
|
}
|
|
|
|
|
2017-08-18 15:50:27 +00:00
|
|
|
// Return true if the overlapping pair has contact manifolds with contacts
|
|
|
|
inline bool OverlappingPair::hasContacts() const {
|
|
|
|
return mContactManifoldSet.getContactManifolds() != nullptr;
|
|
|
|
}
|
|
|
|
|
2017-07-30 20:14:46 +00:00
|
|
|
// Return a pointer to the first potential contact manifold in the linked-list
|
|
|
|
inline ContactManifoldInfo* OverlappingPair::getPotentialContactManifolds() {
|
|
|
|
return mPotentialContactManifolds;
|
|
|
|
}
|
|
|
|
|
2017-09-04 20:23:29 +00:00
|
|
|
// Clear the obsolete contact manifold and contact points
|
|
|
|
inline void OverlappingPair::clearObsoleteManifoldsAndContactPoints() {
|
|
|
|
mContactManifoldSet.clearObsoleteManifoldsAndContactPoints();
|
2014-12-27 23:54:34 +00:00
|
|
|
}
|
|
|
|
|
2017-10-17 22:41:32 +00:00
|
|
|
// Reduce the contact manifolds that have too many contact points
|
|
|
|
inline void OverlappingPair::reduceContactManifolds() {
|
|
|
|
mContactManifoldSet.reduce();
|
2017-10-12 18:07:39 +00:00
|
|
|
}
|
|
|
|
|
2017-11-22 21:43:27 +00:00
|
|
|
// Return the last frame collision info for a given pair of shape ids
|
|
|
|
inline LastFrameCollisionInfo* OverlappingPair::getLastFrameCollisionInfo(uint shapeId1, uint shapeId2) const {
|
2018-01-26 16:34:26 +00:00
|
|
|
return mLastFrameCollisionInfos[ShapeIdPair(shapeId1, shapeId2)];
|
2017-11-22 21:43:27 +00:00
|
|
|
}
|
|
|
|
|
2013-03-02 15:26:18 +00:00
|
|
|
}
|
2011-10-18 22:03:05 +00:00
|
|
|
|
2018-01-26 16:34:26 +00:00
|
|
|
// Hash function for struct ShapeIdPair
|
|
|
|
namespace std {
|
|
|
|
|
|
|
|
template <> struct hash<reactphysics3d::OverlappingPair::ShapeIdPair> {
|
|
|
|
|
|
|
|
size_t operator()(const reactphysics3d::OverlappingPair::ShapeIdPair& pair) const {
|
|
|
|
|
|
|
|
std::size_t seed = 0;
|
|
|
|
reactphysics3d::hash_combine<uint>(seed, pair.shapeIdBody1);
|
|
|
|
reactphysics3d::hash_combine<uint>(seed, pair.shapeIdBody2);
|
|
|
|
|
|
|
|
return seed;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <> struct hash<reactphysics3d::OverlappingPair::OverlappingPairId> {
|
|
|
|
|
|
|
|
size_t operator()(const reactphysics3d::OverlappingPair::OverlappingPairId& pair) const {
|
|
|
|
|
|
|
|
std::size_t seed = 0;
|
|
|
|
reactphysics3d::hash_combine<uint>(seed, pair.body1Id);
|
|
|
|
reactphysics3d::hash_combine<uint>(seed, pair.body2Id);
|
|
|
|
|
|
|
|
return seed;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2011-10-18 22:03:05 +00:00
|
|
|
#endif
|
|
|
|
|