Use List instead of linked lists for narrow phase infos during collision detection

This commit is contained in:
Daniel Chappuis 2018-09-15 10:14:26 +02:00
parent 23e16cf156
commit ea523e47d3
7 changed files with 142 additions and 167 deletions

View File

@ -49,7 +49,7 @@ using namespace std;
// Constructor
CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager)
: mMemoryManager(memoryManager), mWorld(world), mNarrowPhaseInfoList(nullptr),
: mMemoryManager(memoryManager), mWorld(world), mNarrowPhaseInfos(mMemoryManager.getPoolAllocator()),
mOverlappingPairs(mMemoryManager.getPoolAllocator()), mBroadPhaseAlgorithm(*this),
mNoCollisionPairs(mMemoryManager.getPoolAllocator()), mIsCollisionShapesAdded(false) {
@ -80,9 +80,6 @@ void CollisionDetection::computeCollisionDetection() {
// Compute the narrow-phase collision detection
computeNarrowPhase();
// Reset the linked list of narrow-phase info
mNarrowPhaseInfoList = nullptr;
}
// Compute the broad-phase collision detection
@ -162,29 +159,17 @@ void CollisionDetection::computeMiddlePhase() {
// No middle-phase is necessary, simply create a narrow phase info
// for the narrow-phase collision detection
NarrowPhaseInfo* firstNarrowPhaseInfo = mNarrowPhaseInfoList;
mNarrowPhaseInfoList = new (mMemoryManager.allocate(MemoryManager::AllocationType::Frame, sizeof(NarrowPhaseInfo)))
NarrowPhaseInfo* narrowPhaseInfo = new (mMemoryManager.allocate(MemoryManager::AllocationType::Frame, sizeof(NarrowPhaseInfo)))
NarrowPhaseInfo(pair, shape1->getCollisionShape(),
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
shape2->getLocalToWorldTransform(), mMemoryManager.getSingleFrameAllocator());
mNarrowPhaseInfoList->next = firstNarrowPhaseInfo;
mNarrowPhaseInfos.add(narrowPhaseInfo);
}
// Concave vs Convex algorithm
else if ((!isShape1Convex && isShape2Convex) || (!isShape2Convex && isShape1Convex)) {
NarrowPhaseInfo* narrowPhaseInfo = nullptr;
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getSingleFrameAllocator(), &narrowPhaseInfo);
// Add all the narrow-phase info object reported by the callback into the
// list of all the narrow-phase info object
while (narrowPhaseInfo != nullptr) {
NarrowPhaseInfo* next = narrowPhaseInfo->next;
narrowPhaseInfo->next = mNarrowPhaseInfoList;
mNarrowPhaseInfoList = narrowPhaseInfo;
narrowPhaseInfo = next;
}
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getSingleFrameAllocator(), mNarrowPhaseInfos);
}
// Concave vs Concave shape
else {
@ -200,7 +185,7 @@ void CollisionDetection::computeMiddlePhase() {
// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
NarrowPhaseInfo** firstNarrowPhaseInfo) {
List<NarrowPhaseInfo*>& narrowPhaseInfos) {
ProxyShape* shape1 = pair->getShape1();
ProxyShape* shape2 = pair->getShape2();
@ -226,7 +211,7 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
// Set the parameters of the callback object
MiddlePhaseTriangleCallback middlePhaseCallback(pair, concaveProxyShape, convexProxyShape,
concaveShape, allocator);
concaveShape, narrowPhaseInfos, allocator);
#ifdef IS_PROFILING_ACTIVE
@ -243,10 +228,6 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
// Call the convex vs triangle callback for each triangle of the concave shape
concaveShape->testAllTriangles(middlePhaseCallback, aabb);
// Add all the narrow-phase info object reported by the callback into the
// list of all the narrow-phase info object
*firstNarrowPhaseInfo = middlePhaseCallback.narrowPhaseInfoList;
}
// Compute the narrow-phase collision detection
@ -254,29 +235,33 @@ void CollisionDetection::computeNarrowPhase() {
RP3D_PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler);
List<NarrowPhaseInfo*> narrowPhaseInfos(mMemoryManager.getSingleFrameAllocator());
List<NarrowPhaseInfo*> collidingNarrowPhaseInfos(mMemoryManager.getSingleFrameAllocator());
NarrowPhaseInfo* currentNarrowPhaseInfo = mNarrowPhaseInfoList;
while (currentNarrowPhaseInfo != nullptr) {
// For each narrow phase info to process
for(uint i=0; i < mNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = mNarrowPhaseInfos[i];
assert(narrowPhaseInfo->contactPoints == nullptr);
// Select the narrow phase algorithm to use according to the two collision shapes
const CollisionShapeType shape1Type = currentNarrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = currentNarrowPhaseInfo->collisionShape2->getType();
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// If there is no collision algorithm between those two kinds of shapes, skip it
if (narrowPhaseAlgorithm != nullptr) {
LastFrameCollisionInfo* lastCollisionFrameInfo = currentNarrowPhaseInfo->getLastFrameCollisionInfo();
narrowPhaseInfos.add(currentNarrowPhaseInfo);
LastFrameCollisionInfo* lastCollisionFrameInfo = narrowPhaseInfo->getLastFrameCollisionInfo();
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(currentNarrowPhaseInfo, true, mMemoryManager.getSingleFrameAllocator())) {
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getSingleFrameAllocator())) {
lastCollisionFrameInfo->wasColliding = true;
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
else {
lastCollisionFrameInfo->wasColliding = false;
@ -285,12 +270,10 @@ void CollisionDetection::computeNarrowPhase() {
// The previous frame collision info is now valid
lastCollisionFrameInfo->isValid = true;
}
currentNarrowPhaseInfo = currentNarrowPhaseInfo->next;
}
// Convert the potential contact into actual contacts
processAllPotentialContacts(narrowPhaseInfos, mOverlappingPairs);
processAllPotentialContacts(collidingNarrowPhaseInfos, mOverlappingPairs);
// Add all the contact manifolds (between colliding bodies) to the bodies
addAllContactManifoldsToBodies();
@ -299,9 +282,9 @@ void CollisionDetection::computeNarrowPhase() {
reportAllContacts();
// Destroy the narrow phase infos
for (auto it = narrowPhaseInfos.begin(); it != narrowPhaseInfos.end(); ++it) {
for(uint i=0; i < mNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = *it;
NarrowPhaseInfo* narrowPhaseInfo = mNarrowPhaseInfos[i];
// Call the destructor
narrowPhaseInfo->~NarrowPhaseInfo();
@ -309,6 +292,9 @@ void CollisionDetection::computeNarrowPhase() {
// Release the allocated memory for the narrow phase info
mMemoryManager.release(MemoryManager::AllocationType::Frame, narrowPhaseInfo, sizeof(NarrowPhaseInfo));
}
// Clear the list of narrow-phase infos
mNarrowPhaseInfos.clear();
}
// Allow the broadphase to notify the collision detection about an overlapping pair.
@ -437,23 +423,24 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
}
/// Convert the potential contact into actual contacts
void CollisionDetection::processAllPotentialContacts(const List<NarrowPhaseInfo*>& narrowPhaseInfos,
void CollisionDetection::processAllPotentialContacts(const List<NarrowPhaseInfo*>& collidingNarrowPhaseInfos,
const OverlappingPairMap& overlappingPairs) {
RP3D_PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler);
// For each narrow phase info object
for (auto it = narrowPhaseInfos.begin(); it != narrowPhaseInfos.end(); ++it) {
for(uint i=0; i < collidingNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = *it;
NarrowPhaseInfo* narrowPhaseInfo = collidingNarrowPhaseInfos[i];
assert(narrowPhaseInfo != nullptr);
assert(narrowPhaseInfo->contactPoints != nullptr);
if (narrowPhaseInfo->contactPoints != nullptr) {
// Transfer the contact points from the narrow phase info to the overlapping pair
narrowPhaseInfo->overlappingPair->addPotentialContactPoints(narrowPhaseInfo);
// Transfer the contact points from the narrow phase info to the overlapping pair
narrowPhaseInfo->overlappingPair->addPotentialContactPoints(narrowPhaseInfo);
}
// Remove the contacts points from the narrow phase info object.
narrowPhaseInfo->resetContactPoints();
}
// For each overlapping pairs in contact during the narrow-phase
@ -491,7 +478,7 @@ void CollisionDetection::reportAllContacts() {
}
// Compute the middle-phase collision detection between two proxy shapes
NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(OverlappingPair* pair) {
void CollisionDetection::computeMiddlePhaseForProxyShapes(OverlappingPair* pair, List<NarrowPhaseInfo*>& outNarrowPhaseInfos) {
ProxyShape* shape1 = pair->getShape1();
ProxyShape* shape2 = pair->getShape2();
@ -501,8 +488,6 @@ NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(Overlappin
const bool isShape1Convex = shape1->getCollisionShape()->isConvex();
const bool isShape2Convex = shape2->getCollisionShape()->isConvex();
NarrowPhaseInfo* narrowPhaseInfo = nullptr;
pair->makeLastFrameCollisionInfosObsolete();
// If both shapes are convex
@ -510,10 +495,11 @@ NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(Overlappin
// No middle-phase is necessary, simply create a narrow phase info
// for the narrow-phase collision detection
narrowPhaseInfo = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
NarrowPhaseInfo* narrowPhaseInfo = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(NarrowPhaseInfo))) NarrowPhaseInfo(pair, shape1->getCollisionShape(),
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
shape2->getLocalToWorldTransform(), mMemoryManager.getPoolAllocator());
outNarrowPhaseInfos.add(narrowPhaseInfo);
}
// Concave vs Convex algorithm
@ -521,12 +507,10 @@ NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(Overlappin
// Run the middle-phase collision detection algorithm to find the triangles of the concave
// shape we need to use during the narrow-phase collision detection
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getPoolAllocator(), &narrowPhaseInfo);
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getPoolAllocator(), outNarrowPhaseInfos);
}
pair->clearObsoleteLastFrameCollisionInfos();
return narrowPhaseInfo;
}
// Report all the bodies that overlap with the aabb in parameter
@ -572,6 +556,8 @@ void CollisionDetection::testAABBOverlap(const AABB& aabb, OverlapCallback* over
// Return true if two bodies overlap
bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2) {
List<NarrowPhaseInfo*> narrowPhaseInfos(mMemoryManager.getPoolAllocator());
// For each proxy shape proxy shape of the first body
ProxyShape* body1ProxyShape = body1->getProxyShapesList();
while (body1ProxyShape != nullptr) {
@ -591,13 +577,17 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
OverlappingPair pair(body1ProxyShape, body2ProxyShape, mMemoryManager.getPoolAllocator(),
mMemoryManager.getPoolAllocator(), mWorld->mConfig);
narrowPhaseInfos.clear();
// Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
computeMiddlePhaseForProxyShapes(&pair, narrowPhaseInfos);
bool isColliding = false;
// For each narrow-phase info object
while (narrowPhaseInfo != nullptr) {
for(uint i=0; i < narrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = narrowPhaseInfos[i];
// If we have not found a collision yet
if (!isColliding) {
@ -618,14 +608,11 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
}
}
NarrowPhaseInfo* currentNarrowPhaseInfo = narrowPhaseInfo;
narrowPhaseInfo = narrowPhaseInfo->next;
// Call the destructor
currentNarrowPhaseInfo->~NarrowPhaseInfo();
narrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
mMemoryManager.release(MemoryManager::AllocationType::Pool, narrowPhaseInfo, sizeof(NarrowPhaseInfo));
}
// Return if we have found a narrow-phase collision
@ -651,6 +638,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
assert(overlapCallback != nullptr);
Set<bodyindex> reportedBodies(mMemoryManager.getPoolAllocator());
List<NarrowPhaseInfo*> narrowPhaseInfos(mMemoryManager.getPoolAllocator());
// For each proxy shape proxy shape of the body
ProxyShape* bodyProxyShape = body->getProxyShapesList();
@ -687,13 +675,17 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
OverlappingPair pair(bodyProxyShape, proxyShape, mMemoryManager.getPoolAllocator(),
mMemoryManager.getPoolAllocator(), mWorld->mConfig);
narrowPhaseInfos.clear();
// Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
computeMiddlePhaseForProxyShapes(&pair, narrowPhaseInfos);
bool isColliding = false;
// For each narrow-phase info object
while (narrowPhaseInfo != nullptr) {
for (uint i=0; i<narrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = narrowPhaseInfos[i];
// If we have not found a collision yet
if (!isColliding) {
@ -714,14 +706,11 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
}
}
NarrowPhaseInfo* currentNarrowPhaseInfo = narrowPhaseInfo;
narrowPhaseInfo = narrowPhaseInfo->next;
// Call the destructor
currentNarrowPhaseInfo->~NarrowPhaseInfo();
narrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
mMemoryManager.release(MemoryManager::AllocationType::Pool, narrowPhaseInfo, sizeof(NarrowPhaseInfo));
}
// Return if we have found a narrow-phase collision
@ -795,33 +784,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
}
// Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(pair);
// For each narrow-phase info object
while (narrowPhaseInfo != nullptr) {
allNarrowPhaseInfos.add(narrowPhaseInfo);
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// If there is a collision algorithm for those two kinds of shapes
if (narrowPhaseAlgorithm != nullptr) {
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
}
narrowPhaseInfo = narrowPhaseInfo->next;
}
computeMiddlePhaseForProxyShapes(pair, allNarrowPhaseInfos);
}
// Go to the next proxy shape
@ -832,6 +795,30 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
body1ProxyShape = body1ProxyShape->getNext();
}
// For each narrow-phase info object
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// If there is a collision algorithm for those two kinds of shapes
if (narrowPhaseAlgorithm != nullptr) {
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
}
}
// Process the potential contacts
processAllPotentialContacts(collidingNarrowPhaseInfos, overlappingPairs);
@ -853,9 +840,9 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
}
// Destroy the narrow phase infos
for (auto it = allNarrowPhaseInfos.begin(); it != allNarrowPhaseInfos.end(); ++it) {
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = *it;
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
// Call the destructor
narrowPhaseInfo->~NarrowPhaseInfo();
@ -926,33 +913,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
}
// Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(pair);
// For each narrow-phase info object
while (narrowPhaseInfo != nullptr) {
allNarrowPhaseInfos.add(narrowPhaseInfo);
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// If there is a collision algorithm for those two kinds of shapes
if (narrowPhaseAlgorithm != nullptr) {
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
}
narrowPhaseInfo = narrowPhaseInfo->next;
}
computeMiddlePhaseForProxyShapes(pair, allNarrowPhaseInfos);
}
}
@ -965,6 +926,30 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
}
}
// For each narrow-phase info object
for (auto it = allNarrowPhaseInfos.begin(); it != allNarrowPhaseInfos.end(); ++it) {
NarrowPhaseInfo* narrowPhaseInfo = *it;
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// If there is a collision algorithm for those two kinds of shapes
if (narrowPhaseAlgorithm != nullptr) {
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
}
}
// Process the potential contacts
processAllPotentialContacts(collidingNarrowPhaseInfos, overlappingPairs);
@ -986,9 +971,9 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
}
// Destroy the narrow phase infos
for (auto it = allNarrowPhaseInfos.begin(); it != allNarrowPhaseInfos.end(); ++it) {
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = *it;
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
// Call the destructor
narrowPhaseInfo->~NarrowPhaseInfo();
@ -1047,32 +1032,30 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
// Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(pair);
computeMiddlePhaseForProxyShapes(pair, allNarrowPhaseInfos);
}
}
// For each narrow-phase info object
while (narrowPhaseInfo != nullptr) {
// For each narrow-phase info object
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
allNarrowPhaseInfos.add(narrowPhaseInfo);
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// Select the narrow phase algorithm to use according to the two collision shapes
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
// If there is a collision algorithm for those two kinds of shapes
if (narrowPhaseAlgorithm != nullptr) {
// If there is a collision algorithm for those two kinds of shapes
if (narrowPhaseAlgorithm != nullptr) {
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
// Use the narrow-phase collision detection algorithm to check
// if there really is a collision. If a collision occurs, the
// notifyContact() callback method will be called.
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
}
narrowPhaseInfo = narrowPhaseInfo->next;
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
}
}
}
@ -1098,9 +1081,9 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
}
// Destroy the narrow phase infos
for (auto it = allNarrowPhaseInfos.begin(); it != allNarrowPhaseInfos.end(); ++it) {
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
NarrowPhaseInfo* narrowPhaseInfo = *it;
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
// Call the destructor
narrowPhaseInfo->~NarrowPhaseInfo();

View File

@ -78,8 +78,8 @@ class CollisionDetection {
/// Pointer to the physics world
CollisionWorld* mWorld;
/// Pointer to the first narrow-phase info of the linked list
NarrowPhaseInfo* mNarrowPhaseInfoList;
/// List of narrow phase infos
List<NarrowPhaseInfo*> mNarrowPhaseInfos;
/// Broad-phase overlapping pairs
OverlappingPairMap mOverlappingPairs;
@ -127,13 +127,13 @@ class CollisionDetection {
/// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
void computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
NarrowPhaseInfo** firstNarrowPhaseInfo);
List<NarrowPhaseInfo*>& narrowPhaseInfos);
/// Compute the middle-phase collision detection between two proxy shapes
NarrowPhaseInfo* computeMiddlePhaseForProxyShapes(OverlappingPair* pair);
void computeMiddlePhaseForProxyShapes(OverlappingPair* pair, List<NarrowPhaseInfo*>& outNarrowPhaseInfos);
/// Convert the potential contact into actual contacts
void processAllPotentialContacts(const List<NarrowPhaseInfo*>& narrowPhaseInfos,
void processAllPotentialContacts(const List<NarrowPhaseInfo*>& collidingNarrowPhaseInfos,
const OverlappingPairMap& overlappingPairs);
/// Report contacts for all the colliding overlapping pairs

View File

@ -94,11 +94,6 @@ void ContactManifoldSet::addContactPoints(NarrowPhaseInfo* narrowPhaseInfo) {
contactPoint = contactPoint->next;
}
// All the contact point info of the narrow-phase info have been moved
// into the potential contacts of the overlapping pair. We can now
// remove the contacts points from the narrow phase info object.
narrowPhaseInfo->resetContactPoints();
}
// Return the total number of contact points in the set of manifolds

View File

@ -51,13 +51,12 @@ void MiddlePhaseTriangleCallback::testTriangle(const Vector3* trianglePoints, co
ProxyShape* shape2 = isShape1Convex ? mConcaveProxyShape : mConvexProxyShape;
// Create a narrow phase info for the narrow-phase collision detection
NarrowPhaseInfo* firstNarrowPhaseInfo = narrowPhaseInfoList;
narrowPhaseInfoList = new (mAllocator.allocate(sizeof(NarrowPhaseInfo)))
NarrowPhaseInfo* narrowPhaseInfo = new (mAllocator.allocate(sizeof(NarrowPhaseInfo)))
NarrowPhaseInfo(mOverlappingPair,
isShape1Convex ? mConvexProxyShape->getCollisionShape() : triangleShape,
isShape1Convex ? triangleShape : mConvexProxyShape->getCollisionShape(),
shape1->getLocalToWorldTransform(),
shape2->getLocalToWorldTransform(),
mAllocator);
narrowPhaseInfoList->next = firstNarrowPhaseInfo;
mOutNarrowPhaseInfos.add(narrowPhaseInfo);
}

View File

@ -66,6 +66,9 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
/// Pointer to the concave collision shape
const ConcaveShape* mConcaveShape;
/// Reference to the list of narrow-phase infos
List<NarrowPhaseInfo*>& mOutNarrowPhaseInfos;
/// Reference to the single-frame memory allocator
MemoryAllocator& mAllocator;
@ -78,17 +81,15 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
public:
/// Pointer to the first element of the linked-list of narrow-phase info
NarrowPhaseInfo* narrowPhaseInfoList;
/// Constructor
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
ProxyShape* concaveProxyShape,
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
List<NarrowPhaseInfo*>& outNarrowPhaseInfos,
MemoryAllocator& allocator)
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
mAllocator(allocator), narrowPhaseInfoList(nullptr) {
mOutNarrowPhaseInfos(outNarrowPhaseInfos), mAllocator(allocator) {
}

View File

@ -37,7 +37,7 @@ NarrowPhaseInfo::NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1,
const Transform& shape2Transform, MemoryAllocator& shapeAllocator)
: overlappingPair(pair), collisionShape1(shape1), collisionShape2(shape2),
shape1ToWorldTransform(shape1Transform), shape2ToWorldTransform(shape2Transform),
contactPoints(nullptr), next(nullptr), collisionShapeAllocator(shapeAllocator) {
contactPoints(nullptr), collisionShapeAllocator(shapeAllocator) {
// Add a collision info for the two collision shapes into the overlapping pair (if not present yet)
overlappingPair->addLastFrameInfoIfNecessary(shape1->getId(), shape2->getId());

View File

@ -65,9 +65,6 @@ struct NarrowPhaseInfo {
/// Linked-list of contact points created during the narrow-phase
ContactPointInfo* contactPoints;
/// Pointer to the next element in the linked list
NarrowPhaseInfo* next;
/// Memory allocator for the collision shape (Used to release TriangleShape memory in destructor)
MemoryAllocator& collisionShapeAllocator;