Use List instead of linked lists for narrow phase infos during collision detection
This commit is contained in:
parent
23e16cf156
commit
ea523e47d3
|
@ -49,7 +49,7 @@ using namespace std;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager)
|
CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager)
|
||||||
: mMemoryManager(memoryManager), mWorld(world), mNarrowPhaseInfoList(nullptr),
|
: mMemoryManager(memoryManager), mWorld(world), mNarrowPhaseInfos(mMemoryManager.getPoolAllocator()),
|
||||||
mOverlappingPairs(mMemoryManager.getPoolAllocator()), mBroadPhaseAlgorithm(*this),
|
mOverlappingPairs(mMemoryManager.getPoolAllocator()), mBroadPhaseAlgorithm(*this),
|
||||||
mNoCollisionPairs(mMemoryManager.getPoolAllocator()), mIsCollisionShapesAdded(false) {
|
mNoCollisionPairs(mMemoryManager.getPoolAllocator()), mIsCollisionShapesAdded(false) {
|
||||||
|
|
||||||
|
@ -80,9 +80,6 @@ void CollisionDetection::computeCollisionDetection() {
|
||||||
|
|
||||||
// Compute the narrow-phase collision detection
|
// Compute the narrow-phase collision detection
|
||||||
computeNarrowPhase();
|
computeNarrowPhase();
|
||||||
|
|
||||||
// Reset the linked list of narrow-phase info
|
|
||||||
mNarrowPhaseInfoList = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the broad-phase collision detection
|
// Compute the broad-phase collision detection
|
||||||
|
@ -162,29 +159,17 @@ void CollisionDetection::computeMiddlePhase() {
|
||||||
|
|
||||||
// No middle-phase is necessary, simply create a narrow phase info
|
// No middle-phase is necessary, simply create a narrow phase info
|
||||||
// for the narrow-phase collision detection
|
// for the narrow-phase collision detection
|
||||||
NarrowPhaseInfo* firstNarrowPhaseInfo = mNarrowPhaseInfoList;
|
NarrowPhaseInfo* narrowPhaseInfo = new (mMemoryManager.allocate(MemoryManager::AllocationType::Frame, sizeof(NarrowPhaseInfo)))
|
||||||
mNarrowPhaseInfoList = new (mMemoryManager.allocate(MemoryManager::AllocationType::Frame, sizeof(NarrowPhaseInfo)))
|
|
||||||
NarrowPhaseInfo(pair, shape1->getCollisionShape(),
|
NarrowPhaseInfo(pair, shape1->getCollisionShape(),
|
||||||
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
|
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
|
||||||
shape2->getLocalToWorldTransform(), mMemoryManager.getSingleFrameAllocator());
|
shape2->getLocalToWorldTransform(), mMemoryManager.getSingleFrameAllocator());
|
||||||
mNarrowPhaseInfoList->next = firstNarrowPhaseInfo;
|
mNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Concave vs Convex algorithm
|
// Concave vs Convex algorithm
|
||||||
else if ((!isShape1Convex && isShape2Convex) || (!isShape2Convex && isShape1Convex)) {
|
else if ((!isShape1Convex && isShape2Convex) || (!isShape2Convex && isShape1Convex)) {
|
||||||
|
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = nullptr;
|
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getSingleFrameAllocator(), mNarrowPhaseInfos);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Concave vs Concave shape
|
// Concave vs Concave shape
|
||||||
else {
|
else {
|
||||||
|
@ -200,7 +185,7 @@ void CollisionDetection::computeMiddlePhase() {
|
||||||
|
|
||||||
// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
|
// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
|
||||||
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
||||||
NarrowPhaseInfo** firstNarrowPhaseInfo) {
|
List<NarrowPhaseInfo*>& narrowPhaseInfos) {
|
||||||
|
|
||||||
ProxyShape* shape1 = pair->getShape1();
|
ProxyShape* shape1 = pair->getShape1();
|
||||||
ProxyShape* shape2 = pair->getShape2();
|
ProxyShape* shape2 = pair->getShape2();
|
||||||
|
@ -226,7 +211,7 @@ void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair
|
||||||
|
|
||||||
// Set the parameters of the callback object
|
// Set the parameters of the callback object
|
||||||
MiddlePhaseTriangleCallback middlePhaseCallback(pair, concaveProxyShape, convexProxyShape,
|
MiddlePhaseTriangleCallback middlePhaseCallback(pair, concaveProxyShape, convexProxyShape,
|
||||||
concaveShape, allocator);
|
concaveShape, narrowPhaseInfos, allocator);
|
||||||
|
|
||||||
#ifdef IS_PROFILING_ACTIVE
|
#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
|
// Call the convex vs triangle callback for each triangle of the concave shape
|
||||||
concaveShape->testAllTriangles(middlePhaseCallback, aabb);
|
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
|
// Compute the narrow-phase collision detection
|
||||||
|
@ -254,29 +235,33 @@ void CollisionDetection::computeNarrowPhase() {
|
||||||
|
|
||||||
RP3D_PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler);
|
RP3D_PROFILE("CollisionDetection::computeNarrowPhase()", mProfiler);
|
||||||
|
|
||||||
List<NarrowPhaseInfo*> narrowPhaseInfos(mMemoryManager.getSingleFrameAllocator());
|
List<NarrowPhaseInfo*> collidingNarrowPhaseInfos(mMemoryManager.getSingleFrameAllocator());
|
||||||
|
|
||||||
NarrowPhaseInfo* currentNarrowPhaseInfo = mNarrowPhaseInfoList;
|
// For each narrow phase info to process
|
||||||
while (currentNarrowPhaseInfo != nullptr) {
|
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
|
// Select the narrow phase algorithm to use according to the two collision shapes
|
||||||
const CollisionShapeType shape1Type = currentNarrowPhaseInfo->collisionShape1->getType();
|
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
||||||
const CollisionShapeType shape2Type = currentNarrowPhaseInfo->collisionShape2->getType();
|
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
||||||
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
|
NarrowPhaseAlgorithm* narrowPhaseAlgorithm = selectNarrowPhaseAlgorithm(shape1Type, shape2Type);
|
||||||
|
|
||||||
// If there is no collision algorithm between those two kinds of shapes, skip it
|
// If there is no collision algorithm between those two kinds of shapes, skip it
|
||||||
if (narrowPhaseAlgorithm != nullptr) {
|
if (narrowPhaseAlgorithm != nullptr) {
|
||||||
|
|
||||||
LastFrameCollisionInfo* lastCollisionFrameInfo = currentNarrowPhaseInfo->getLastFrameCollisionInfo();
|
LastFrameCollisionInfo* lastCollisionFrameInfo = narrowPhaseInfo->getLastFrameCollisionInfo();
|
||||||
|
|
||||||
narrowPhaseInfos.add(currentNarrowPhaseInfo);
|
|
||||||
|
|
||||||
// Use the narrow-phase collision detection algorithm to check
|
// Use the narrow-phase collision detection algorithm to check
|
||||||
// if there really is a collision. If a collision occurs, the
|
// if there really is a collision. If a collision occurs, the
|
||||||
// notifyContact() callback method will be called.
|
// notifyContact() callback method will be called.
|
||||||
if (narrowPhaseAlgorithm->testCollision(currentNarrowPhaseInfo, true, mMemoryManager.getSingleFrameAllocator())) {
|
if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getSingleFrameAllocator())) {
|
||||||
|
|
||||||
lastCollisionFrameInfo->wasColliding = true;
|
lastCollisionFrameInfo->wasColliding = true;
|
||||||
|
|
||||||
|
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lastCollisionFrameInfo->wasColliding = false;
|
lastCollisionFrameInfo->wasColliding = false;
|
||||||
|
@ -285,12 +270,10 @@ void CollisionDetection::computeNarrowPhase() {
|
||||||
// The previous frame collision info is now valid
|
// The previous frame collision info is now valid
|
||||||
lastCollisionFrameInfo->isValid = true;
|
lastCollisionFrameInfo->isValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentNarrowPhaseInfo = currentNarrowPhaseInfo->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the potential contact into actual contacts
|
// Convert the potential contact into actual contacts
|
||||||
processAllPotentialContacts(narrowPhaseInfos, mOverlappingPairs);
|
processAllPotentialContacts(collidingNarrowPhaseInfos, mOverlappingPairs);
|
||||||
|
|
||||||
// Add all the contact manifolds (between colliding bodies) to the bodies
|
// Add all the contact manifolds (between colliding bodies) to the bodies
|
||||||
addAllContactManifoldsToBodies();
|
addAllContactManifoldsToBodies();
|
||||||
|
@ -299,9 +282,9 @@ void CollisionDetection::computeNarrowPhase() {
|
||||||
reportAllContacts();
|
reportAllContacts();
|
||||||
|
|
||||||
// Destroy the narrow phase infos
|
// 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
|
// Call the destructor
|
||||||
narrowPhaseInfo->~NarrowPhaseInfo();
|
narrowPhaseInfo->~NarrowPhaseInfo();
|
||||||
|
@ -309,6 +292,9 @@ void CollisionDetection::computeNarrowPhase() {
|
||||||
// Release the allocated memory for the narrow phase info
|
// Release the allocated memory for the narrow phase info
|
||||||
mMemoryManager.release(MemoryManager::AllocationType::Frame, narrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
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.
|
// 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
|
/// Convert the potential contact into actual contacts
|
||||||
void CollisionDetection::processAllPotentialContacts(const List<NarrowPhaseInfo*>& narrowPhaseInfos,
|
void CollisionDetection::processAllPotentialContacts(const List<NarrowPhaseInfo*>& collidingNarrowPhaseInfos,
|
||||||
const OverlappingPairMap& overlappingPairs) {
|
const OverlappingPairMap& overlappingPairs) {
|
||||||
|
|
||||||
RP3D_PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler);
|
RP3D_PROFILE("CollisionDetection::processAllPotentialContacts()", mProfiler);
|
||||||
|
|
||||||
// For each narrow phase info object
|
// 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 != nullptr);
|
||||||
|
assert(narrowPhaseInfo->contactPoints != nullptr);
|
||||||
if (narrowPhaseInfo->contactPoints != nullptr) {
|
|
||||||
|
|
||||||
// Transfer the contact points from the narrow phase info to the overlapping pair
|
// Transfer the contact points from the narrow phase info to the overlapping pair
|
||||||
narrowPhaseInfo->overlappingPair->addPotentialContactPoints(narrowPhaseInfo);
|
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
|
// 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
|
// 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* shape1 = pair->getShape1();
|
||||||
ProxyShape* shape2 = pair->getShape2();
|
ProxyShape* shape2 = pair->getShape2();
|
||||||
|
@ -501,8 +488,6 @@ NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(Overlappin
|
||||||
const bool isShape1Convex = shape1->getCollisionShape()->isConvex();
|
const bool isShape1Convex = shape1->getCollisionShape()->isConvex();
|
||||||
const bool isShape2Convex = shape2->getCollisionShape()->isConvex();
|
const bool isShape2Convex = shape2->getCollisionShape()->isConvex();
|
||||||
|
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = nullptr;
|
|
||||||
|
|
||||||
pair->makeLastFrameCollisionInfosObsolete();
|
pair->makeLastFrameCollisionInfosObsolete();
|
||||||
|
|
||||||
// If both shapes are convex
|
// If both shapes are convex
|
||||||
|
@ -510,10 +495,11 @@ NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(Overlappin
|
||||||
|
|
||||||
// No middle-phase is necessary, simply create a narrow phase info
|
// No middle-phase is necessary, simply create a narrow phase info
|
||||||
// for the narrow-phase collision detection
|
// 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(),
|
sizeof(NarrowPhaseInfo))) NarrowPhaseInfo(pair, shape1->getCollisionShape(),
|
||||||
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
|
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
|
||||||
shape2->getLocalToWorldTransform(), mMemoryManager.getPoolAllocator());
|
shape2->getLocalToWorldTransform(), mMemoryManager.getPoolAllocator());
|
||||||
|
outNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Concave vs Convex algorithm
|
// 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
|
// 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
|
// shape we need to use during the narrow-phase collision detection
|
||||||
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getPoolAllocator(), &narrowPhaseInfo);
|
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getPoolAllocator(), outNarrowPhaseInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
pair->clearObsoleteLastFrameCollisionInfos();
|
pair->clearObsoleteLastFrameCollisionInfos();
|
||||||
|
|
||||||
return narrowPhaseInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report all the bodies that overlap with the aabb in parameter
|
// 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
|
// Return true if two bodies overlap
|
||||||
bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2) {
|
bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2) {
|
||||||
|
|
||||||
|
List<NarrowPhaseInfo*> narrowPhaseInfos(mMemoryManager.getPoolAllocator());
|
||||||
|
|
||||||
// For each proxy shape proxy shape of the first body
|
// For each proxy shape proxy shape of the first body
|
||||||
ProxyShape* body1ProxyShape = body1->getProxyShapesList();
|
ProxyShape* body1ProxyShape = body1->getProxyShapesList();
|
||||||
while (body1ProxyShape != nullptr) {
|
while (body1ProxyShape != nullptr) {
|
||||||
|
@ -591,13 +577,17 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
|
||||||
OverlappingPair pair(body1ProxyShape, body2ProxyShape, mMemoryManager.getPoolAllocator(),
|
OverlappingPair pair(body1ProxyShape, body2ProxyShape, mMemoryManager.getPoolAllocator(),
|
||||||
mMemoryManager.getPoolAllocator(), mWorld->mConfig);
|
mMemoryManager.getPoolAllocator(), mWorld->mConfig);
|
||||||
|
|
||||||
|
narrowPhaseInfos.clear();
|
||||||
|
|
||||||
// Compute the middle-phase collision detection between the two shapes
|
// Compute the middle-phase collision detection between the two shapes
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
|
computeMiddlePhaseForProxyShapes(&pair, narrowPhaseInfos);
|
||||||
|
|
||||||
bool isColliding = false;
|
bool isColliding = false;
|
||||||
|
|
||||||
// For each narrow-phase info object
|
// 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 we have not found a collision yet
|
||||||
if (!isColliding) {
|
if (!isColliding) {
|
||||||
|
@ -618,14 +608,11 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NarrowPhaseInfo* currentNarrowPhaseInfo = narrowPhaseInfo;
|
|
||||||
narrowPhaseInfo = narrowPhaseInfo->next;
|
|
||||||
|
|
||||||
// Call the destructor
|
// Call the destructor
|
||||||
currentNarrowPhaseInfo->~NarrowPhaseInfo();
|
narrowPhaseInfo->~NarrowPhaseInfo();
|
||||||
|
|
||||||
// Release the allocated memory
|
// 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
|
// Return if we have found a narrow-phase collision
|
||||||
|
@ -651,6 +638,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
||||||
assert(overlapCallback != nullptr);
|
assert(overlapCallback != nullptr);
|
||||||
|
|
||||||
Set<bodyindex> reportedBodies(mMemoryManager.getPoolAllocator());
|
Set<bodyindex> reportedBodies(mMemoryManager.getPoolAllocator());
|
||||||
|
List<NarrowPhaseInfo*> narrowPhaseInfos(mMemoryManager.getPoolAllocator());
|
||||||
|
|
||||||
// For each proxy shape proxy shape of the body
|
// For each proxy shape proxy shape of the body
|
||||||
ProxyShape* bodyProxyShape = body->getProxyShapesList();
|
ProxyShape* bodyProxyShape = body->getProxyShapesList();
|
||||||
|
@ -687,13 +675,17 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
||||||
OverlappingPair pair(bodyProxyShape, proxyShape, mMemoryManager.getPoolAllocator(),
|
OverlappingPair pair(bodyProxyShape, proxyShape, mMemoryManager.getPoolAllocator(),
|
||||||
mMemoryManager.getPoolAllocator(), mWorld->mConfig);
|
mMemoryManager.getPoolAllocator(), mWorld->mConfig);
|
||||||
|
|
||||||
|
narrowPhaseInfos.clear();
|
||||||
|
|
||||||
// Compute the middle-phase collision detection between the two shapes
|
// Compute the middle-phase collision detection between the two shapes
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
|
computeMiddlePhaseForProxyShapes(&pair, narrowPhaseInfos);
|
||||||
|
|
||||||
bool isColliding = false;
|
bool isColliding = false;
|
||||||
|
|
||||||
// For each narrow-phase info object
|
// 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 we have not found a collision yet
|
||||||
if (!isColliding) {
|
if (!isColliding) {
|
||||||
|
@ -714,14 +706,11 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NarrowPhaseInfo* currentNarrowPhaseInfo = narrowPhaseInfo;
|
|
||||||
narrowPhaseInfo = narrowPhaseInfo->next;
|
|
||||||
|
|
||||||
// Call the destructor
|
// Call the destructor
|
||||||
currentNarrowPhaseInfo->~NarrowPhaseInfo();
|
narrowPhaseInfo->~NarrowPhaseInfo();
|
||||||
|
|
||||||
// Release the allocated memory
|
// 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
|
// Return if we have found a narrow-phase collision
|
||||||
|
@ -795,12 +784,21 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the middle-phase collision detection between the two shapes
|
// Compute the middle-phase collision detection between the two shapes
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(pair);
|
computeMiddlePhaseForProxyShapes(pair, allNarrowPhaseInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next proxy shape
|
||||||
|
body2ProxyShape = body2ProxyShape->getNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next proxy shape
|
||||||
|
body1ProxyShape = body1ProxyShape->getNext();
|
||||||
|
}
|
||||||
|
|
||||||
// For each narrow-phase info object
|
// For each narrow-phase info object
|
||||||
while (narrowPhaseInfo != nullptr) {
|
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
|
||||||
|
|
||||||
allNarrowPhaseInfos.add(narrowPhaseInfo);
|
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
|
||||||
|
|
||||||
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
||||||
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
||||||
|
@ -819,17 +817,6 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
||||||
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
narrowPhaseInfo = narrowPhaseInfo->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to the next proxy shape
|
|
||||||
body2ProxyShape = body2ProxyShape->getNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to the next proxy shape
|
|
||||||
body1ProxyShape = body1ProxyShape->getNext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the potential contacts
|
// Process the potential contacts
|
||||||
|
@ -853,9 +840,9 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the narrow phase infos
|
// 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
|
// Call the destructor
|
||||||
narrowPhaseInfo->~NarrowPhaseInfo();
|
narrowPhaseInfo->~NarrowPhaseInfo();
|
||||||
|
@ -926,12 +913,23 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the middle-phase collision detection between the two shapes
|
// Compute the middle-phase collision detection between the two shapes
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(pair);
|
computeMiddlePhaseForProxyShapes(pair, allNarrowPhaseInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next overlapping proxy shape
|
||||||
|
element = element->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the next proxy shape
|
||||||
|
bodyProxyShape = bodyProxyShape->getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For each narrow-phase info object
|
// For each narrow-phase info object
|
||||||
while (narrowPhaseInfo != nullptr) {
|
for (auto it = allNarrowPhaseInfos.begin(); it != allNarrowPhaseInfos.end(); ++it) {
|
||||||
|
|
||||||
allNarrowPhaseInfos.add(narrowPhaseInfo);
|
NarrowPhaseInfo* narrowPhaseInfo = *it;
|
||||||
|
|
||||||
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
||||||
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
||||||
|
@ -950,19 +948,6 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
||||||
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
narrowPhaseInfo = narrowPhaseInfo->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to the next overlapping proxy shape
|
|
||||||
element = element->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go to the next proxy shape
|
|
||||||
bodyProxyShape = bodyProxyShape->getNext();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the potential contacts
|
// Process the potential contacts
|
||||||
|
@ -986,9 +971,9 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the narrow phase infos
|
// 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
|
// Call the destructor
|
||||||
narrowPhaseInfo->~NarrowPhaseInfo();
|
narrowPhaseInfo->~NarrowPhaseInfo();
|
||||||
|
@ -1047,12 +1032,14 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
||||||
mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
|
mBroadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
|
||||||
|
|
||||||
// Compute the middle-phase collision detection between the two shapes
|
// Compute the middle-phase collision detection between the two shapes
|
||||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(pair);
|
computeMiddlePhaseForProxyShapes(pair, allNarrowPhaseInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For each narrow-phase info object
|
// For each narrow-phase info object
|
||||||
while (narrowPhaseInfo != nullptr) {
|
for (uint i=0; i < allNarrowPhaseInfos.size(); i++) {
|
||||||
|
|
||||||
allNarrowPhaseInfos.add(narrowPhaseInfo);
|
NarrowPhaseInfo* narrowPhaseInfo = allNarrowPhaseInfos[i];
|
||||||
|
|
||||||
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
const CollisionShapeType shape1Type = narrowPhaseInfo->collisionShape1->getType();
|
||||||
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
const CollisionShapeType shape2Type = narrowPhaseInfo->collisionShape2->getType();
|
||||||
|
@ -1071,10 +1058,6 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
||||||
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
collidingNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
narrowPhaseInfo = narrowPhaseInfo->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the potential contacts
|
// Process the potential contacts
|
||||||
|
@ -1098,9 +1081,9 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the narrow phase infos
|
// 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
|
// Call the destructor
|
||||||
narrowPhaseInfo->~NarrowPhaseInfo();
|
narrowPhaseInfo->~NarrowPhaseInfo();
|
||||||
|
|
|
@ -78,8 +78,8 @@ class CollisionDetection {
|
||||||
/// Pointer to the physics world
|
/// Pointer to the physics world
|
||||||
CollisionWorld* mWorld;
|
CollisionWorld* mWorld;
|
||||||
|
|
||||||
/// Pointer to the first narrow-phase info of the linked list
|
/// List of narrow phase infos
|
||||||
NarrowPhaseInfo* mNarrowPhaseInfoList;
|
List<NarrowPhaseInfo*> mNarrowPhaseInfos;
|
||||||
|
|
||||||
/// Broad-phase overlapping pairs
|
/// Broad-phase overlapping pairs
|
||||||
OverlappingPairMap mOverlappingPairs;
|
OverlappingPairMap mOverlappingPairs;
|
||||||
|
@ -127,13 +127,13 @@ class CollisionDetection {
|
||||||
|
|
||||||
/// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
|
/// Compute the concave vs convex middle-phase algorithm for a given pair of bodies
|
||||||
void computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
void computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
||||||
NarrowPhaseInfo** firstNarrowPhaseInfo);
|
List<NarrowPhaseInfo*>& narrowPhaseInfos);
|
||||||
|
|
||||||
/// Compute the middle-phase collision detection between two proxy shapes
|
/// 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
|
/// Convert the potential contact into actual contacts
|
||||||
void processAllPotentialContacts(const List<NarrowPhaseInfo*>& narrowPhaseInfos,
|
void processAllPotentialContacts(const List<NarrowPhaseInfo*>& collidingNarrowPhaseInfos,
|
||||||
const OverlappingPairMap& overlappingPairs);
|
const OverlappingPairMap& overlappingPairs);
|
||||||
|
|
||||||
/// Report contacts for all the colliding overlapping pairs
|
/// Report contacts for all the colliding overlapping pairs
|
||||||
|
|
|
@ -94,11 +94,6 @@ void ContactManifoldSet::addContactPoints(NarrowPhaseInfo* narrowPhaseInfo) {
|
||||||
|
|
||||||
contactPoint = contactPoint->next;
|
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
|
// Return the total number of contact points in the set of manifolds
|
||||||
|
|
|
@ -51,13 +51,12 @@ void MiddlePhaseTriangleCallback::testTriangle(const Vector3* trianglePoints, co
|
||||||
ProxyShape* shape2 = isShape1Convex ? mConcaveProxyShape : mConvexProxyShape;
|
ProxyShape* shape2 = isShape1Convex ? mConcaveProxyShape : mConvexProxyShape;
|
||||||
|
|
||||||
// Create a narrow phase info for the narrow-phase collision detection
|
// Create a narrow phase info for the narrow-phase collision detection
|
||||||
NarrowPhaseInfo* firstNarrowPhaseInfo = narrowPhaseInfoList;
|
NarrowPhaseInfo* narrowPhaseInfo = new (mAllocator.allocate(sizeof(NarrowPhaseInfo)))
|
||||||
narrowPhaseInfoList = new (mAllocator.allocate(sizeof(NarrowPhaseInfo)))
|
|
||||||
NarrowPhaseInfo(mOverlappingPair,
|
NarrowPhaseInfo(mOverlappingPair,
|
||||||
isShape1Convex ? mConvexProxyShape->getCollisionShape() : triangleShape,
|
isShape1Convex ? mConvexProxyShape->getCollisionShape() : triangleShape,
|
||||||
isShape1Convex ? triangleShape : mConvexProxyShape->getCollisionShape(),
|
isShape1Convex ? triangleShape : mConvexProxyShape->getCollisionShape(),
|
||||||
shape1->getLocalToWorldTransform(),
|
shape1->getLocalToWorldTransform(),
|
||||||
shape2->getLocalToWorldTransform(),
|
shape2->getLocalToWorldTransform(),
|
||||||
mAllocator);
|
mAllocator);
|
||||||
narrowPhaseInfoList->next = firstNarrowPhaseInfo;
|
mOutNarrowPhaseInfos.add(narrowPhaseInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,9 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
|
||||||
/// Pointer to the concave collision shape
|
/// Pointer to the concave collision shape
|
||||||
const ConcaveShape* mConcaveShape;
|
const ConcaveShape* mConcaveShape;
|
||||||
|
|
||||||
|
/// Reference to the list of narrow-phase infos
|
||||||
|
List<NarrowPhaseInfo*>& mOutNarrowPhaseInfos;
|
||||||
|
|
||||||
/// Reference to the single-frame memory allocator
|
/// Reference to the single-frame memory allocator
|
||||||
MemoryAllocator& mAllocator;
|
MemoryAllocator& mAllocator;
|
||||||
|
|
||||||
|
@ -78,17 +81,15 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Pointer to the first element of the linked-list of narrow-phase info
|
|
||||||
NarrowPhaseInfo* narrowPhaseInfoList;
|
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
|
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
|
||||||
ProxyShape* concaveProxyShape,
|
ProxyShape* concaveProxyShape,
|
||||||
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
|
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
|
||||||
|
List<NarrowPhaseInfo*>& outNarrowPhaseInfos,
|
||||||
MemoryAllocator& allocator)
|
MemoryAllocator& allocator)
|
||||||
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
|
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
|
||||||
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
|
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
|
||||||
mAllocator(allocator), narrowPhaseInfoList(nullptr) {
|
mOutNarrowPhaseInfos(outNarrowPhaseInfos), mAllocator(allocator) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ NarrowPhaseInfo::NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1,
|
||||||
const Transform& shape2Transform, MemoryAllocator& shapeAllocator)
|
const Transform& shape2Transform, MemoryAllocator& shapeAllocator)
|
||||||
: overlappingPair(pair), collisionShape1(shape1), collisionShape2(shape2),
|
: overlappingPair(pair), collisionShape1(shape1), collisionShape2(shape2),
|
||||||
shape1ToWorldTransform(shape1Transform), shape2ToWorldTransform(shape2Transform),
|
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)
|
// Add a collision info for the two collision shapes into the overlapping pair (if not present yet)
|
||||||
overlappingPair->addLastFrameInfoIfNecessary(shape1->getId(), shape2->getId());
|
overlappingPair->addLastFrameInfoIfNecessary(shape1->getId(), shape2->getId());
|
||||||
|
|
|
@ -65,9 +65,6 @@ struct NarrowPhaseInfo {
|
||||||
/// Linked-list of contact points created during the narrow-phase
|
/// Linked-list of contact points created during the narrow-phase
|
||||||
ContactPointInfo* contactPoints;
|
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)
|
/// Memory allocator for the collision shape (Used to release TriangleShape memory in destructor)
|
||||||
MemoryAllocator& collisionShapeAllocator;
|
MemoryAllocator& collisionShapeAllocator;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user