Refactoring

This commit is contained in:
Daniel Chappuis 2019-10-18 07:13:45 +02:00
parent 2c2b75def7
commit 130eb00136
10 changed files with 96 additions and 123 deletions

View File

@ -130,8 +130,7 @@ class DynamicAABBTreeRaycastCallback {
// Class DynamicAABBTree
/**
* This class implements a dynamic AABB tree that is used for broad-phase
* collision detection. This data structure is inspired by Nathanael Presson's
* dynamic tree implementation in BulletPhysics. The following implementation is
* collision detection. The following implementation is
* based on the one from Erin Catto in Box2D as described in the book
* "Introduction to Game Physics with Box2D" by Ian Parberry.
*/

View File

@ -536,7 +536,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
// Compute the contact points between two faces of two convex polyhedra.
if(computePolyhedronVsPolyhedronFaceContactPoints(isMinPenetrationFaceNormalPolyhedron1, polyhedron1, polyhedron2,
polyhedron1ToPolyhedron2, polyhedron2ToPolyhedron1, minFaceIndex,
narrowPhaseInfoBatch, batchIndex, minPenetrationDepth)) {
narrowPhaseInfoBatch, batchIndex)) {
lastFrameCollisionInfo->satIsAxisFacePolyhedron1 = isMinPenetrationFaceNormalPolyhedron1;
lastFrameCollisionInfo->satIsAxisFacePolyhedron2 = !isMinPenetrationFaceNormalPolyhedron1;
@ -576,7 +576,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
// Compute the contact points between two faces of two convex polyhedra.
if(computePolyhedronVsPolyhedronFaceContactPoints(isMinPenetrationFaceNormalPolyhedron1, polyhedron1, polyhedron2,
polyhedron1ToPolyhedron2, polyhedron2ToPolyhedron1, minFaceIndex,
narrowPhaseInfoBatch, batchIndex, minPenetrationDepth)) {
narrowPhaseInfoBatch, batchIndex)) {
lastFrameCollisionInfo->satIsAxisFacePolyhedron1 = isMinPenetrationFaceNormalPolyhedron1;
lastFrameCollisionInfo->satIsAxisFacePolyhedron2 = !isMinPenetrationFaceNormalPolyhedron1;
@ -804,7 +804,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
// Compute the contact points between two faces of two convex polyhedra.
bool contactsFound = computePolyhedronVsPolyhedronFaceContactPoints(isMinPenetrationFaceNormalPolyhedron1, polyhedron1,
polyhedron2, polyhedron1ToPolyhedron2, polyhedron2ToPolyhedron1,
minFaceIndex, narrowPhaseInfoBatch, batchIndex, minPenetrationDepth);
minFaceIndex, narrowPhaseInfoBatch, batchIndex);
// There should be clipping points here. If it is not the case, it might be
// because of a numerical issue
@ -877,8 +877,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn
bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPenetrationFaceNormalPolyhedron1,
const ConvexPolyhedronShape* polyhedron1, const ConvexPolyhedronShape* polyhedron2,
const Transform& polyhedron1ToPolyhedron2, const Transform& polyhedron2ToPolyhedron1,
uint minFaceIndex, NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex,
decimal minPenetrationDepth) const {
uint minFaceIndex, NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex) const {
RP3D_PROFILE("SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints", mProfiler);
@ -887,8 +886,6 @@ bool SATAlgorithm::computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPene
const Transform& referenceToIncidentTransform = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron1ToPolyhedron2 : polyhedron2ToPolyhedron1;
const Transform& incidentToReferenceTransform = isMinPenetrationFaceNormalPolyhedron1 ? polyhedron2ToPolyhedron1 : polyhedron1ToPolyhedron2;
assert(minPenetrationDepth > decimal(0.0));
const Vector3 axisReferenceSpace = referencePolyhedron->getFaceNormal(minFaceIndex);
const Vector3 axisIncidentSpace = referenceToIncidentTransform.getOrientation() * axisReferenceSpace;

View File

@ -132,7 +132,7 @@ class SATAlgorithm {
bool computePolyhedronVsPolyhedronFaceContactPoints(bool isMinPenetrationFaceNormalPolyhedron1, const ConvexPolyhedronShape* polyhedron1,
const ConvexPolyhedronShape* polyhedron2, const Transform& polyhedron1ToPolyhedron2,
const Transform& polyhedron2ToPolyhedron1, uint minFaceIndex,
NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex, decimal minPenetrationDepth) const;
NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex) const;
public :

View File

@ -405,7 +405,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
if (!jointInfo.isCollisionEnabled) {
// Add the pair of bodies in the set of body pairs that cannot collide with each other
mCollisionDetection.addNoCollisionPair(jointInfo.body1, jointInfo.body2);
mCollisionDetection.addNoCollisionPair(jointInfo.body1->getEntity(), jointInfo.body2->getEntity());
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
@ -435,7 +435,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
if (!joint->isCollisionEnabled()) {
// Remove the pair of bodies from the set of body pairs that cannot collide with each other
mCollisionDetection.removeNoCollisionPair(joint->getBody1(), joint->getBody2());
mCollisionDetection.removeNoCollisionPair(joint->getBody1()->getEntity(), joint->getBody2()->getEntity());
}
RigidBody* body1 = joint->getBody1();

View File

@ -35,7 +35,7 @@ using namespace reactphysics3d;
OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
MemoryAllocator& persistentMemoryAllocator, MemoryAllocator& temporaryMemoryAllocator,
const WorldSettings& worldSettings)
: mPairID(computeID(shape1->getBroadPhaseId(), shape2->getBroadPhaseId())), mProxyShape1(shape1), mProxyShape2(shape2),
: mPairID(computeID(shape1->getBroadPhaseId(), shape2->getBroadPhaseId())), mProxyShape1(shape1->getEntity()), mProxyShape2(shape2->getEntity()),
mPersistentAllocator(persistentMemoryAllocator), mTempMemoryAllocator(temporaryMemoryAllocator),
mLastFrameCollisionInfos(mPersistentAllocator), mWorldSettings(worldSettings) {
@ -99,16 +99,12 @@ void OverlappingPair::clearObsoleteLastFrameCollisionInfos() {
it = mLastFrameCollisionInfos.remove(it);
}
else {
else { // If the collision info is not obsolete
// Do not delete it but mark it as obsolete
it->second->isObsolete = true;
++it;
}
}
}
// Make all the last frame collision infos obsolete
void OverlappingPair::makeLastFrameCollisionInfosObsolete() {
for (auto it = mLastFrameCollisionInfos.begin(); it != mLastFrameCollisionInfos.end(); ++it) {
it->second->isObsolete = true;
}
}

View File

@ -109,9 +109,11 @@ class OverlappingPair {
/// Pair ID
OverlappingPairId mPairID;
// TODO : Replace this by entities
ProxyShape* mProxyShape1;
ProxyShape* mProxyShape2;
/// Entity of the first proxy-shape of the overlapping pair
Entity mProxyShape1;
/// Entity of the second proxy-shape of the overlapping pair
Entity mProxyShape2;
/// Persistent memory allocator
MemoryAllocator& mPersistentAllocator;
@ -149,11 +151,11 @@ class OverlappingPair {
/// Return the Id of the pair
OverlappingPairId getId() const;
/// Return the pointer to first proxy collision shape
ProxyShape* getShape1() const;
/// Return the entity of the first proxy-shape
Entity getProxyShape1() const;
/// Return the pointer to second body
ProxyShape* getShape2() const;
/// Return the entity of the second proxy-shape
Entity getProxyShape2() const;
/// Return the last frame collision info
LastFrameCollisionInfo* getLastFrameCollisionInfo(ShapeIdPair& shapeIds);
@ -161,9 +163,6 @@ class OverlappingPair {
/// Return a reference to the temporary memory allocator
MemoryAllocator& getTemporaryAllocator();
/// Return true if one of the shapes of the pair is a concave shape
bool hasConcaveShape() const;
/// Add a new last frame collision info if it does not exist for the given shapes already
LastFrameCollisionInfo* addLastFrameInfoIfNecessary(uint shapeId1, uint shapeId2);
@ -173,14 +172,11 @@ class OverlappingPair {
/// Delete all the obsolete last frame collision info
void clearObsoleteLastFrameCollisionInfos();
/// Make all the last frame collision infos obsolete
void makeLastFrameCollisionInfosObsolete();
/// Return the pair of bodies index
static OverlappingPairId computeID(int shape1BroadPhaseId, int shape2BroadPhaseId);
/// Return the pair of bodies index of the pair
static bodypair computeBodiesIndexPair(CollisionBody* body1, CollisionBody* body2);
static bodypair computeBodiesIndexPair(Entity body1Entity, Entity body2Entity);
// -------------------- Friendship -------------------- //
@ -192,13 +188,13 @@ inline OverlappingPair::OverlappingPairId OverlappingPair::getId() const {
return mPairID;
}
// Return the pointer to first body
inline ProxyShape* OverlappingPair::getShape1() const {
// Return the entity of the first proxy-shape
inline Entity OverlappingPair::getProxyShape1() const {
return mProxyShape1;
}
// Return the pointer to second body
inline ProxyShape* OverlappingPair::getShape2() const {
// Return the entity of the second proxy-shape
inline Entity OverlappingPair::getProxyShape2() const {
return mProxyShape2;
}
@ -225,13 +221,12 @@ inline OverlappingPair::OverlappingPairId OverlappingPair::computeID(int shape1B
}
// Return the pair of bodies index
inline bodypair OverlappingPair::computeBodiesIndexPair(CollisionBody* body1,
CollisionBody* body2) {
inline bodypair OverlappingPair::computeBodiesIndexPair(Entity body1Entity, Entity body2Entity) {
// Construct the pair of body index
bodypair indexPair = body1->getEntity().id < body2->getEntity().id ?
bodypair(body1->getEntity(), body2->getEntity()) :
bodypair(body2->getEntity(), body1->getEntity());
bodypair indexPair = body1Entity.id < body2Entity.id ?
bodypair(body1Entity, body2Entity) :
bodypair(body2Entity, body1Entity);
assert(indexPair.first != indexPair.second);
return indexPair;
}
@ -241,12 +236,6 @@ inline MemoryAllocator& OverlappingPair::getTemporaryAllocator() {
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();
}
// Return the last frame collision info for a given pair of shape ids
inline LastFrameCollisionInfo* OverlappingPair::getLastFrameCollisionInfo(uint shapeId1, uint shapeId2) const {
return mLastFrameCollisionInfos[ShapeIdPair(shapeId1, shapeId2)];

View File

@ -51,14 +51,16 @@ BroadPhaseSystem::BroadPhaseSystem(CollisionDetectionSystem& collisionDetection,
}
// Return true if the two broad-phase collision shapes are overlapping
// TODO : Use proxy-shape entities in parameters
bool BroadPhaseSystem::testOverlappingShapes(const ProxyShape* shape1, const ProxyShape* shape2) const {
bool BroadPhaseSystem::testOverlappingShapes(Entity proxyShape1Entity, Entity proxyShape2Entity) const {
if (shape1->getBroadPhaseId() == -1 || shape2->getBroadPhaseId() == -1) return false;
const int32 shape1BroadPhaseId = mProxyShapesComponents.getBroadPhaseId(proxyShape1Entity);
const int32 shape2BroadPhaseId = mProxyShapesComponents.getBroadPhaseId(proxyShape2Entity);
if (shape1BroadPhaseId == -1 || shape2BroadPhaseId == -1) return false;
// Get the two AABBs of the collision shapes
const AABB& aabb1 = mDynamicAABBTree.getFatAABB(shape1->getBroadPhaseId());
const AABB& aabb2 = mDynamicAABBTree.getFatAABB(shape2->getBroadPhaseId());
const AABB& aabb1 = mDynamicAABBTree.getFatAABB(shape1BroadPhaseId);
const AABB& aabb2 = mDynamicAABBTree.getFatAABB(shape2BroadPhaseId);
// Check if the two AABBs are overlapping
return aabb1.testCollision(aabb2);

View File

@ -189,7 +189,7 @@ class BroadPhaseSystem {
ProxyShape* getProxyShapeForBroadPhaseId(int broadPhaseId) const;
/// Return true if the two broad-phase collision shapes are overlapping
bool testOverlappingShapes(const ProxyShape* shape1, const ProxyShape* shape2) const;
bool testOverlappingShapes(Entity proxyShape1Entity, Entity proxyShape2Entity) const;
/// Return the fat AABB of a given broad-phase shape
const AABB& getFatAABB(int broadPhaseId) const;

View File

@ -82,7 +82,7 @@ CollisionDetectionSystem::CollisionDetectionSystem(CollisionWorld* world, ProxyS
// Compute the collision detection
void CollisionDetectionSystem::computeCollisionDetection() {
RP3D_PROFILE("CollisionDetection::computeCollisionDetection()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeCollisionDetection()", mProfiler);
// Compute the broad-phase collision detection
computeBroadPhase();
@ -97,7 +97,7 @@ void CollisionDetectionSystem::computeCollisionDetection() {
// Compute the broad-phase collision detection
void CollisionDetectionSystem::computeBroadPhase() {
RP3D_PROFILE("CollisionDetection::computeBroadPhase()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeBroadPhase()", mProfiler);
// Ask the broad-phase to compute all the shapes overlapping the shapes that
// have moved or have been added in the last frame. This call can only add new
@ -120,11 +120,8 @@ void CollisionDetectionSystem::removeNonOverlappingPairs() {
OverlappingPair* pair = it->second;
ProxyShape* shape1 = pair->getShape1();
ProxyShape* shape2 = pair->getShape2();
// Check if the two shapes are still overlapping. Otherwise, we destroy the overlapping pair
if (!mBroadPhaseSystem.testOverlappingShapes(shape1, shape2)) {
if (!mBroadPhaseSystem.testOverlappingShapes(pair->getProxyShape1(), pair->getProxyShape2())) {
// Destroy the overlapping pair
pair->~OverlappingPair();
@ -154,12 +151,12 @@ void CollisionDetectionSystem::updateOverlappingPairs(const List<Pair<int, int>>
if (nodePair.first != nodePair.second) {
// Get the two proxy-shapes
Entity proxyShape1Entity = mMapBroadPhaseIdToProxyShapeEntity[nodePair.first];
Entity proxyShape2Entity = mMapBroadPhaseIdToProxyShapeEntity[nodePair.second];
const Entity proxyShape1Entity = mMapBroadPhaseIdToProxyShapeEntity[nodePair.first];
const Entity proxyShape2Entity = mMapBroadPhaseIdToProxyShapeEntity[nodePair.second];
// Get the two bodies
Entity body1Entity = mProxyShapesComponents.getBody(proxyShape1Entity);
Entity body2Entity = mProxyShapesComponents.getBody(proxyShape2Entity);
const Entity body1Entity = mProxyShapesComponents.getBody(proxyShape1Entity);
const Entity body2Entity = mProxyShapesComponents.getBody(proxyShape2Entity);
// If the two proxy collision shapes are from the same body, skip it
if (body1Entity != body2Entity) {
@ -212,14 +209,11 @@ void CollisionDetectionSystem::computeMiddlePhase(OverlappingPairMap& overlappin
OverlappingPair* pair = it->second;
// Make all the last frame collision info obsolete
pair->makeLastFrameCollisionInfosObsolete();
// Remove the obsolete last frame collision infos and mark all the others as obsolete
pair->clearObsoleteLastFrameCollisionInfos();
const Entity proxyShape1Entity = pair->getShape1()->getEntity();
const Entity proxyShape2Entity = pair->getShape2()->getEntity();
ProxyShape* shape1 = pair->getShape1();
ProxyShape* shape2 = pair->getShape2();
const Entity proxyShape1Entity = pair->getProxyShape1();
const Entity proxyShape2Entity = pair->getProxyShape2();
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape1Entity) != -1);
assert(mProxyShapesComponents.getBroadPhaseId(proxyShape2Entity) != -1);
@ -229,11 +223,8 @@ void CollisionDetectionSystem::computeMiddlePhase(OverlappingPairMap& overlappin
if ((mProxyShapesComponents.getCollideWithMaskBits(proxyShape1Entity) & mProxyShapesComponents.getCollisionCategoryBits(proxyShape2Entity)) != 0 &&
(mProxyShapesComponents.getCollisionCategoryBits(proxyShape1Entity) & mProxyShapesComponents.getCollideWithMaskBits(proxyShape2Entity)) != 0) {
CollisionBody* const body1 = shape1->getBody();
CollisionBody* const body2 = shape2->getBody();
const Entity body1Entity = body1->getEntity();
const Entity body2Entity = body2->getEntity();
const Entity body1Entity = mProxyShapesComponents.getBody(proxyShape1Entity);
const Entity body2Entity = mProxyShapesComponents.getBody(proxyShape2Entity);
const bool isStaticRigidBody1 = mWorld->mRigidBodyComponents.hasComponent(body1Entity) &&
mWorld->mRigidBodyComponents.getBodyType(body1Entity) == BodyType::STATIC;
@ -246,22 +237,25 @@ void CollisionDetectionSystem::computeMiddlePhase(OverlappingPairMap& overlappin
if (!isBody1Active && !isBody2Active) continue;
// Check if the bodies are in the set of bodies that cannot collide between each other
bodypair bodiesIndex = OverlappingPair::computeBodiesIndexPair(body1, body2);
bodypair bodiesIndex = OverlappingPair::computeBodiesIndexPair(body1Entity, body2Entity);
if (mNoCollisionPairs.contains(bodiesIndex) > 0) continue;
bool isShape1Convex = shape1->getCollisionShape()->isConvex();
bool isShape2Convex = shape2->getCollisionShape()->isConvex();
CollisionShape* collisionShape1 = mProxyShapesComponents.getCollisionShape(proxyShape1Entity);
CollisionShape* collisionShape2 = mProxyShapesComponents.getCollisionShape(proxyShape2Entity);
const bool isShape1Convex = collisionShape1->isConvex();
const bool isShape2Convex = collisionShape2->isConvex();
// If both shapes are convex
if (isShape1Convex && isShape2Convex) {
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithmType algorithmType = mCollisionDispatch.selectNarrowPhaseAlgorithm(shape1->getCollisionShape()->getType(),
shape2->getCollisionShape()->getType());
NarrowPhaseAlgorithmType algorithmType = mCollisionDispatch.selectNarrowPhaseAlgorithm(collisionShape1->getType(),
collisionShape2->getType());
// No middle-phase is necessary, simply create a narrow phase info
// for the narrow-phase collision detection
narrowPhaseInput.addNarrowPhaseTest(pair, shape1->getCollisionShape(), shape2->getCollisionShape(),
narrowPhaseInput.addNarrowPhaseTest(pair, collisionShape1, collisionShape2,
mProxyShapesComponents.getLocalToWorldTransform(proxyShape1Entity),
mProxyShapesComponents.getLocalToWorldTransform(proxyShape2Entity),
algorithmType, mMemoryManager.getSingleFrameAllocator());
@ -277,9 +271,6 @@ void CollisionDetectionSystem::computeMiddlePhase(OverlappingPairMap& overlappin
// Not handled
continue;
}
// Remove the obsolete last frame collision infos
pair->clearObsoleteLastFrameCollisionInfos();
}
}
}
@ -288,10 +279,10 @@ void CollisionDetectionSystem::computeMiddlePhase(OverlappingPairMap& overlappin
void CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
NarrowPhaseInput& narrowPhaseInput) {
RP3D_PROFILE("CollisionDetection::computeConvexVsConcaveMiddlePhase()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase()", mProfiler);
ProxyShape* shape1 = pair->getShape1();
ProxyShape* shape2 = pair->getShape2();
ProxyShape* shape1 = mProxyShapesComponents.getProxyShape(pair->getProxyShape1());
ProxyShape* shape2 = mProxyShapesComponents.getProxyShape(pair->getProxyShape2());
ProxyShape* convexProxyShape;
ProxyShape* concaveProxyShape;
@ -350,7 +341,7 @@ void CollisionDetectionSystem::computeConvexVsConcaveMiddlePhase(OverlappingPair
#endif
bool isShape1Convex = pair->getShape1()->getCollisionShape()->isConvex();
bool isShape1Convex = mProxyShapesComponents.getCollisionShape(pair->getProxyShape1())->isConvex();
ProxyShape* shape1 = isShape1Convex ? convexProxyShape : concaveProxyShape;
ProxyShape* shape2 = isShape1Convex ? concaveProxyShape : convexProxyShape;
@ -445,7 +436,7 @@ void CollisionDetectionSystem::processAllPotentialContacts(NarrowPhaseInput& nar
// Compute the narrow-phase collision detection
void CollisionDetectionSystem::computeNarrowPhase() {
RP3D_PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeNarrowPhase()", mProfiler);
MemoryAllocator& allocator = mMemoryManager.getSingleFrameAllocator();
@ -475,7 +466,7 @@ void CollisionDetectionSystem::computeNarrowPhase() {
/// This method returns true if contacts are found.
bool CollisionDetectionSystem::computeNarrowPhaseOverlapSnapshot(NarrowPhaseInput& narrowPhaseInput, OverlapCallback* callback) {
RP3D_PROFILE("CollisionDetection::computeNarrowPhaseOverlapSnapshot()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeNarrowPhaseOverlapSnapshot()", mProfiler);
MemoryAllocator& allocator = mMemoryManager.getPoolAllocator();
@ -518,7 +509,7 @@ void CollisionDetectionSystem::computeSnapshotContactPairs(NarrowPhaseInput& nar
// Convert the potential overlapping bodies for the testOverlap() methods
void CollisionDetectionSystem::computeSnapshotContactPairs(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, List<Pair<Entity, Entity>>& overlapPairs) const {
RP3D_PROFILE("CollisionDetection::computeSnapshotContactPairs()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeSnapshotContactPairs()", mProfiler);
// For each narrow phase info object
for(uint i=0; i < narrowPhaseInfoBatch.getNbObjects(); i++) {
@ -527,8 +518,8 @@ void CollisionDetectionSystem::computeSnapshotContactPairs(NarrowPhaseInfoBatch&
if (narrowPhaseInfoBatch.isColliding[i]) {
// Add the pair of bodies in contact into the list
overlapPairs.add(Pair<Entity, Entity>(narrowPhaseInfoBatch.overlappingPairs[i]->getShape1()->getBody()->getEntity(),
narrowPhaseInfoBatch.overlappingPairs[i]->getShape2()->getBody()->getEntity()));
overlapPairs.add(Pair<Entity, Entity>(mProxyShapesComponents.getBody(narrowPhaseInfoBatch.overlappingPairs[i]->getProxyShape1()),
mProxyShapesComponents.getBody(narrowPhaseInfoBatch.overlappingPairs[i]->getProxyShape2())));
}
narrowPhaseInfoBatch.resetContactPoints(i);
@ -539,7 +530,7 @@ void CollisionDetectionSystem::computeSnapshotContactPairs(NarrowPhaseInfoBatch&
// This method returns true if contacts are found.
bool CollisionDetectionSystem::computeNarrowPhaseCollisionSnapshot(NarrowPhaseInput& narrowPhaseInput, CollisionCallback& callback) {
RP3D_PROFILE("CollisionDetection::computeNarrowPhaseCollisionSnapshot()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::computeNarrowPhaseCollisionSnapshot()", mProfiler);
MemoryAllocator& allocator = mMemoryManager.getPoolAllocator();
@ -675,7 +666,7 @@ void CollisionDetectionSystem::createSnapshotContacts(List<ContactPair>& contact
List<ContactManifoldInfo>& potentialContactManifolds,
List<ContactPointInfo>& potentialContactPoints) {
RP3D_PROFILE("CollisionDetection::createSnapshotContacts()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::createSnapshotContacts()", mProfiler);
contactManifolds.reserve(contactPairs.size());
contactPoints.reserve(contactManifolds.size());
@ -830,8 +821,8 @@ void CollisionDetectionSystem::removeProxyCollisionShape(ProxyShape* proxyShape)
OverlappingPair* pair = it->second;
if (pair->getShape1()->getBroadPhaseId() == proxyShape->getBroadPhaseId()||
pair->getShape2()->getBroadPhaseId() == proxyShape->getBroadPhaseId()) {
if (mProxyShapesComponents.getBroadPhaseId(pair->getProxyShape1()) == proxyShape->getBroadPhaseId() ||
mProxyShapesComponents.getBroadPhaseId(pair->getProxyShape2()) == proxyShape->getBroadPhaseId()) {
// TODO : Remove all the contact manifold of the overlapping pair from the contact manifolds list of the two bodies involved
@ -856,7 +847,7 @@ void CollisionDetectionSystem::raycast(RaycastCallback* raycastCallback,
const Ray& ray,
unsigned short raycastWithCategoryMaskBits) const {
RP3D_PROFILE("CollisionDetection::raycast()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::raycast()", mProfiler);
RaycastTest rayCastTest(raycastCallback);
@ -873,7 +864,7 @@ void CollisionDetectionSystem::processPotentialContacts(NarrowPhaseInfoBatch& na
List<ContactPair>* contactPairs,
Map<Entity, List<uint>>& mapBodyToContactPairs) {
RP3D_PROFILE("CollisionDetection::processPotentialContacts()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::processPotentialContacts()", mProfiler);
// For each narrow phase info object
for(uint i=0; i < narrowPhaseInfoBatch.getNbObjects(); i++) {
@ -952,16 +943,18 @@ void CollisionDetectionSystem::processPotentialContacts(NarrowPhaseInfoBatch& na
// If the overlapping pair contact does not exists yet
if (pairContact == nullptr) {
Entity body1Entity = narrowPhaseInfoBatch.overlappingPairs[i]->getShape1()->getBody()->getEntity();
Entity body2Entity = narrowPhaseInfoBatch.overlappingPairs[i]->getShape2()->getBody()->getEntity();
const Entity proxyShape1Entity = narrowPhaseInfoBatch.overlappingPairs[i]->getProxyShape1();
const Entity proxyShape2Entity = narrowPhaseInfoBatch.overlappingPairs[i]->getProxyShape2();
const Entity body1Entity = mProxyShapesComponents.getBody(proxyShape1Entity);
const Entity body2Entity = mProxyShapesComponents.getBody(proxyShape2Entity);
assert(!mWorld->mCollisionBodyComponents.getIsEntityDisabled(body1Entity) || !mWorld->mCollisionBodyComponents.getIsEntityDisabled(body2Entity));
// TODO : We should probably use a single frame allocator here
const uint newContactPairIndex = contactPairs->size();
ContactPair overlappingPairContact(pairId, body1Entity, body2Entity,
narrowPhaseInfoBatch.overlappingPairs[i]->getShape1()->getEntity(),
narrowPhaseInfoBatch.overlappingPairs[i]->getShape2()->getEntity(),
proxyShape1Entity, proxyShape2Entity,
newContactPairIndex, mMemoryManager.getPoolAllocator());
contactPairs->add(overlappingPairContact);
pairContact = &((*contactPairs)[newContactPairIndex]);
@ -1010,7 +1003,7 @@ void CollisionDetectionSystem::reducePotentialContactManifolds(List<ContactPair>
List<ContactManifoldInfo>& potentialContactManifolds,
const List<ContactPointInfo>& potentialContactPoints) const {
RP3D_PROFILE("CollisionDetection::reducePotentialContactManifolds()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::reducePotentialContactManifolds()", mProfiler);
// Reduce the number of potential contact manifolds in a contact pair
for (uint i=0; i < contactPairs->size(); i++) {
@ -1057,7 +1050,7 @@ void CollisionDetectionSystem::reducePotentialContactManifolds(List<ContactPair>
// If there are two many contact points in the manifold
if (manifold.potentialContactPointsIndices.size() > MAX_CONTACT_POINTS_IN_MANIFOLD) {
Transform shape1LocalToWorldTransoform = mOverlappingPairs[manifold.pairId]->getShape1()->getLocalToWorldTransform();
Transform shape1LocalToWorldTransoform = mProxyShapesComponents.getLocalToWorldTransform(mOverlappingPairs[manifold.pairId]->getProxyShape1());
// Reduce the number of contact points in the manifold
reduceContactPoints(manifold, shape1LocalToWorldTransoform, potentialContactPoints);
@ -1280,7 +1273,7 @@ void CollisionDetectionSystem::reportContacts() {
void CollisionDetectionSystem::reportContacts(CollisionCallback& callback, List<ContactPair>* contactPairs,
List<ContactManifold>* manifolds, List<ContactPoint>* contactPoints) {
RP3D_PROFILE("CollisionDetection::reportContacts()", mProfiler);
RP3D_PROFILE("CollisionDetectionSystem::reportContacts()", mProfiler);
// If there are contacts
if (contactPairs->size() > 0) {
@ -1420,12 +1413,12 @@ void CollisionDetectionSystem::filterOverlappingPairs(Entity bodyEntity, Overlap
OverlappingPair* pair = it->second;
if (pair->getShape1()->getBody()->getEntity() == bodyEntity || pair->getShape2()->getBody()->getEntity() == bodyEntity) {
if (mProxyShapesComponents.getBody(pair->getProxyShape1()) == bodyEntity ||
mProxyShapesComponents.getBody(pair->getProxyShape2()) == bodyEntity) {
outFilteredPairs.add(Pair<Pair<uint, uint>, OverlappingPair*>(it->first, pair));
}
}
}
// Filter the overlapping pairs to keep only the pairs where two given bodies are involved
@ -1436,13 +1429,12 @@ void CollisionDetectionSystem::filterOverlappingPairs(Entity body1Entity, Entity
OverlappingPair* pair = it->second;
if ((pair->getShape1()->getBody()->getEntity() == body1Entity && pair->getShape2()->getBody()->getEntity() == body2Entity) ||
(pair->getShape1()->getBody()->getEntity() == body2Entity && pair->getShape2()->getBody()->getEntity() == body1Entity)) {
if ((mProxyShapesComponents.getBody(pair->getProxyShape1()) == body1Entity && mProxyShapesComponents.getBody(pair->getProxyShape2()) == body2Entity) ||
(mProxyShapesComponents.getBody(pair->getProxyShape1()) == body2Entity && mProxyShapesComponents.getBody(pair->getProxyShape2()) == body1Entity)) {
outFilteredPairs.add(Pair<Pair<uint, uint>, OverlappingPair*>(it->first, pair));
}
}
}
// Return the world event listener

View File

@ -292,10 +292,10 @@ class CollisionDetectionSystem {
void updateProxyShapes(decimal timeStep);
/// Add a pair of bodies that cannot collide with each other
void addNoCollisionPair(CollisionBody* body1, CollisionBody* body2);
void addNoCollisionPair(Entity body1Entity, Entity body2Entity);
/// Remove a pair of bodies that cannot collide with each other
void removeNoCollisionPair(CollisionBody* body1, CollisionBody* body2);
void removeNoCollisionPair(Entity body1Entity, Entity body2Entity);
/// Ask for a collision shape to be tested again during broad-phase.
void askForBroadPhaseCollisionCheck(ProxyShape* shape);
@ -373,15 +373,13 @@ inline void CollisionDetectionSystem::addProxyCollisionShape(ProxyShape* proxySh
}
// Add a pair of bodies that cannot collide with each other
inline void CollisionDetectionSystem::addNoCollisionPair(CollisionBody* body1,
CollisionBody* body2) {
mNoCollisionPairs.add(OverlappingPair::computeBodiesIndexPair(body1, body2));
inline void CollisionDetectionSystem::addNoCollisionPair(Entity body1Entity, Entity body2Entity) {
mNoCollisionPairs.add(OverlappingPair::computeBodiesIndexPair(body1Entity, body2Entity));
}
// Remove a pair of bodies that cannot collide with each other
inline void CollisionDetectionSystem::removeNoCollisionPair(CollisionBody* body1,
CollisionBody* body2) {
mNoCollisionPairs.remove(OverlappingPair::computeBodiesIndexPair(body1, body2));
inline void CollisionDetectionSystem::removeNoCollisionPair(Entity body1Entity, Entity body2Entity) {
mNoCollisionPairs.remove(OverlappingPair::computeBodiesIndexPair(body1Entity, body2Entity));
}
// Ask for a collision shape to be tested again during broad-phase.