From 5e57ea896a7dcc3ffecd1f85b5556b9e189c883e Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Fri, 9 Nov 2018 17:19:28 +0100 Subject: [PATCH] Refactor NarrowPhaseAlgorithm and make possible to use single frame allocator for NarrowPhaseInput memory allocation --- src/collision/CollisionDetection.cpp | 7 ++-- src/collision/NarrowPhaseInfoBatch.cpp | 39 ++++++++++++++----- src/collision/NarrowPhaseInfoBatch.h | 6 +++ .../narrowphase/CapsuleVsCapsuleAlgorithm.h | 4 +- .../CapsuleVsConvexPolyhedronAlgorithm.h | 4 +- ...vexPolyhedronVsConvexPolyhedronAlgorithm.h | 4 +- .../narrowphase/NarrowPhaseAlgorithm.h | 8 ---- .../narrowphase/NarrowPhaseInput.cpp | 11 ++++++ src/collision/narrowphase/NarrowPhaseInput.h | 4 +- .../narrowphase/SphereVsCapsuleAlgorithm.h | 4 +- .../SphereVsConvexPolyhedronAlgorithm.h | 4 +- .../narrowphase/SphereVsSphereAlgorithm.h | 4 +- 12 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index 70e5e0ad..8d7d29b5 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -52,7 +52,7 @@ CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& mem : mMemoryManager(memoryManager), mCollisionDispatch(mMemoryManager.getPoolAllocator()), mWorld(world), mOverlappingPairs(mMemoryManager.getPoolAllocator()), mBroadPhaseAlgorithm(*this), mNoCollisionPairs(mMemoryManager.getPoolAllocator()), mIsCollisionShapesAdded(false), - mNarrowPhaseInput(mMemoryManager.getPoolAllocator()) { + mNarrowPhaseInput(mMemoryManager.getSingleFrameAllocator()) { #ifdef IS_PROFILING_ACTIVE @@ -98,6 +98,9 @@ void CollisionDetection::computeMiddlePhase() { RP3D_PROFILE("CollisionDetection::computeMiddlePhase()", mProfiler); + // Reserve memory for the narrow-phase input using cached capacity from previous frame + mNarrowPhaseInput.reserveMemory(); + // For each possible collision pair of bodies for (auto it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); ) { @@ -639,8 +642,6 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2) // Test narrow-phase collision bool isCollisionFound = testNarrowPhaseCollision(narrowPhaseInput, true, false, mMemoryManager.getPoolAllocator()); - narrowPhaseInput.clear(); - // No overlap has been found return isCollisionFound; } diff --git a/src/collision/NarrowPhaseInfoBatch.cpp b/src/collision/NarrowPhaseInfoBatch.cpp index 1e8807eb..08466945 100644 --- a/src/collision/NarrowPhaseInfoBatch.cpp +++ b/src/collision/NarrowPhaseInfoBatch.cpp @@ -102,6 +102,20 @@ void NarrowPhaseInfoBatch::resetContactPoints(uint index) { contactPoints[index].clear(); } +// Initialize the containers using cached capacity +void NarrowPhaseInfoBatch::reserveMemory() { + + overlappingPairs.reserve(mCachedCapacity); + collisionShapes1.reserve(mCachedCapacity); + collisionShapes2.reserve(mCachedCapacity); + shape1ToWorldTransforms.reserve(mCachedCapacity); + shape2ToWorldTransforms.reserve(mCachedCapacity); + collisionShapeAllocators.reserve(mCachedCapacity); + lastFrameCollisionInfos.reserve(mCachedCapacity); + isColliding.reserve(mCachedCapacity); + contactPoints.reserve(mCachedCapacity); +} + // Clear all the objects in the batch void NarrowPhaseInfoBatch::clear() { @@ -121,13 +135,20 @@ void NarrowPhaseInfoBatch::clear() { } } - overlappingPairs.clear(); - collisionShapes1.clear(); - collisionShapes2.clear(); - shape1ToWorldTransforms.clear(); - shape2ToWorldTransforms.clear(); - collisionShapeAllocators.clear(); - lastFrameCollisionInfos.clear(); - isColliding.clear(); - contactPoints.clear(); + // Note that we clear the following containers and we release their allocated memory. Therefore, + // if the memory allocator is a single frame allocator, the memory is deallocated and will be + // allocated in the next frame at a possibly different location in memory (remember that the + // location of the allocated memory of a single frame allocator might change between two frames) + + mCachedCapacity = overlappingPairs.size(); + + overlappingPairs.clear(true); + collisionShapes1.clear(true); + collisionShapes2.clear(true); + shape1ToWorldTransforms.clear(true); + shape2ToWorldTransforms.clear(true); + collisionShapeAllocators.clear(true); + lastFrameCollisionInfos.clear(true); + isColliding.clear(true); + contactPoints.clear(true); } diff --git a/src/collision/NarrowPhaseInfoBatch.h b/src/collision/NarrowPhaseInfoBatch.h index 0a9c0ae0..48c23221 100644 --- a/src/collision/NarrowPhaseInfoBatch.h +++ b/src/collision/NarrowPhaseInfoBatch.h @@ -52,6 +52,9 @@ struct NarrowPhaseInfoBatch { /// Memory allocator MemoryAllocator& mMemoryAllocator; + /// Cached capacity + uint mCachedCapacity = 0; + public: /// List of Broadphase overlapping pairs @@ -102,6 +105,9 @@ struct NarrowPhaseInfoBatch { /// Reset the remaining contact points void resetContactPoints(uint index); + // Initialize the containers using cached capacity + void reserveMemory(); + /// Clear all the objects in the batch void clear(); }; diff --git a/src/collision/narrowphase/CapsuleVsCapsuleAlgorithm.h b/src/collision/narrowphase/CapsuleVsCapsuleAlgorithm.h index 8612c9ed..8587316e 100644 --- a/src/collision/narrowphase/CapsuleVsCapsuleAlgorithm.h +++ b/src/collision/narrowphase/CapsuleVsCapsuleAlgorithm.h @@ -67,9 +67,9 @@ class CapsuleVsCapsuleAlgorithm : public NarrowPhaseAlgorithm { CapsuleVsCapsuleAlgorithm& operator=(const CapsuleVsCapsuleAlgorithm& algorithm) = delete; /// Compute the narrow-phase collision detection between two capsules - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, + bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator) override; + MemoryAllocator& memoryAllocator); }; } diff --git a/src/collision/narrowphase/CapsuleVsConvexPolyhedronAlgorithm.h b/src/collision/narrowphase/CapsuleVsConvexPolyhedronAlgorithm.h index c69225c8..70f223b5 100644 --- a/src/collision/narrowphase/CapsuleVsConvexPolyhedronAlgorithm.h +++ b/src/collision/narrowphase/CapsuleVsConvexPolyhedronAlgorithm.h @@ -70,9 +70,9 @@ class CapsuleVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm { CapsuleVsConvexPolyhedronAlgorithm& operator=(const CapsuleVsConvexPolyhedronAlgorithm& algorithm) = delete; /// Compute the narrow-phase collision detection between a capsule and a polyhedron - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, + bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator) override; + MemoryAllocator& memoryAllocator); }; } diff --git a/src/collision/narrowphase/ConvexPolyhedronVsConvexPolyhedronAlgorithm.h b/src/collision/narrowphase/ConvexPolyhedronVsConvexPolyhedronAlgorithm.h index b63fb53e..7f9fccd2 100644 --- a/src/collision/narrowphase/ConvexPolyhedronVsConvexPolyhedronAlgorithm.h +++ b/src/collision/narrowphase/ConvexPolyhedronVsConvexPolyhedronAlgorithm.h @@ -65,9 +65,9 @@ class ConvexPolyhedronVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm ConvexPolyhedronVsConvexPolyhedronAlgorithm& operator=(const ConvexPolyhedronVsConvexPolyhedronAlgorithm& algorithm) = delete; /// Compute the narrow-phase collision detection between two convex polyhedra - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, + bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator) override; + MemoryAllocator& memoryAllocator); }; } diff --git a/src/collision/narrowphase/NarrowPhaseAlgorithm.h b/src/collision/narrowphase/NarrowPhaseAlgorithm.h index 608651c9..3d61edb9 100644 --- a/src/collision/narrowphase/NarrowPhaseAlgorithm.h +++ b/src/collision/narrowphase/NarrowPhaseAlgorithm.h @@ -72,9 +72,6 @@ class NarrowPhaseAlgorithm { // -------------------- Attributes -------------------- // - // Id of the algorithm (computed by hasing the algorithm name) - size_t mId; - #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler @@ -99,11 +96,6 @@ class NarrowPhaseAlgorithm { /// Deleted assignment operator NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete; - /// Compute a contact info if the two bounding volumes collide - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, - uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator)=0; - #ifdef IS_PROFILING_ACTIVE /// Set the profiler diff --git a/src/collision/narrowphase/NarrowPhaseInput.cpp b/src/collision/narrowphase/NarrowPhaseInput.cpp index da08213c..88d6cb14 100644 --- a/src/collision/narrowphase/NarrowPhaseInput.cpp +++ b/src/collision/narrowphase/NarrowPhaseInput.cpp @@ -68,6 +68,17 @@ void NarrowPhaseInput::addNarrowPhaseTest(OverlappingPair* pair, CollisionShape* } } +/// Reserve memory for the containers with cached capacity +void NarrowPhaseInput::reserveMemory() { + + mSphereVsSphereBatch.reserveMemory(); + mSphereVsCapsuleBatch.reserveMemory(); + mCapsuleVsCapsuleBatch.reserveMemory(); + mSphereVsConvexPolyhedronBatch.reserveMemory(); + mCapsuleVsConvexPolyhedronBatch.reserveMemory(); + mConvexPolyhedronVsConvexPolyhedronBatch.reserveMemory(); +} + // Clear void NarrowPhaseInput::clear() { diff --git a/src/collision/narrowphase/NarrowPhaseInput.h b/src/collision/narrowphase/NarrowPhaseInput.h index 32200f11..e71e327e 100644 --- a/src/collision/narrowphase/NarrowPhaseInput.h +++ b/src/collision/narrowphase/NarrowPhaseInput.h @@ -58,7 +58,6 @@ class NarrowPhaseInput { NarrowPhaseInfoBatch mSphereVsConvexPolyhedronBatch; NarrowPhaseInfoBatch mCapsuleVsConvexPolyhedronBatch; NarrowPhaseInfoBatch mConvexPolyhedronVsConvexPolyhedronBatch; - public: /// Constructor @@ -88,6 +87,9 @@ class NarrowPhaseInput { /// Get a reference to the convex polyhedron vs convex polyhedron batch NarrowPhaseInfoBatch& getConvexPolyhedronVsConvexPolyhedronBatch(); + /// Reserve memory for the containers with cached capacity + void reserveMemory(); + /// Clear void clear(); }; diff --git a/src/collision/narrowphase/SphereVsCapsuleAlgorithm.h b/src/collision/narrowphase/SphereVsCapsuleAlgorithm.h index eab8153a..573e5756 100644 --- a/src/collision/narrowphase/SphereVsCapsuleAlgorithm.h +++ b/src/collision/narrowphase/SphereVsCapsuleAlgorithm.h @@ -66,9 +66,9 @@ class SphereVsCapsuleAlgorithm : public NarrowPhaseAlgorithm { SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete; /// Compute the narrow-phase collision detection between a sphere and a capsule - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, + bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator) override; + MemoryAllocator& memoryAllocator); }; } diff --git a/src/collision/narrowphase/SphereVsConvexPolyhedronAlgorithm.h b/src/collision/narrowphase/SphereVsConvexPolyhedronAlgorithm.h index 73251daa..040caec6 100644 --- a/src/collision/narrowphase/SphereVsConvexPolyhedronAlgorithm.h +++ b/src/collision/narrowphase/SphereVsConvexPolyhedronAlgorithm.h @@ -71,9 +71,9 @@ class SphereVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm { SphereVsConvexPolyhedronAlgorithm& operator=(const SphereVsConvexPolyhedronAlgorithm& algorithm) = delete; /// Compute the narrow-phase collision detection between a sphere and a convex polyhedron - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, + bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator) override; + MemoryAllocator& memoryAllocator); }; } diff --git a/src/collision/narrowphase/SphereVsSphereAlgorithm.h b/src/collision/narrowphase/SphereVsSphereAlgorithm.h index ab68f5eb..8099b608 100644 --- a/src/collision/narrowphase/SphereVsSphereAlgorithm.h +++ b/src/collision/narrowphase/SphereVsSphereAlgorithm.h @@ -65,9 +65,9 @@ class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm { SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm) = delete; /// Compute a contact info if the two bounding volume collide - virtual bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, + bool testCollision(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchStartIndex, uint batchNbItems, bool reportContacts, bool stopFirstContactFound, - MemoryAllocator& memoryAllocator) override; + MemoryAllocator& memoryAllocator); }; }