From e0fda1844626c4599d47e556bd8a6a3352f4d246 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Sun, 4 Feb 2018 19:43:17 +0100 Subject: [PATCH] Replace malloc/free calls by use of the MemoryManager of ReactPhysics3D --- src/collision/CollisionDetection.h | 8 +++ .../broadphase/BroadPhaseAlgorithm.cpp | 50 +++++++++++++------ src/collision/broadphase/DynamicAABBTree.cpp | 20 ++++---- src/collision/broadphase/DynamicAABBTree.h | 6 ++- src/collision/shapes/ConcaveMeshShape.cpp | 3 +- src/containers/Stack.h | 14 ++++-- test/tests/collision/TestDynamicAABBTree.h | 7 +-- 7 files changed, 76 insertions(+), 32 deletions(-) diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index 36bede7e..f06d52f0 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -228,6 +228,9 @@ class CollisionDetection { /// Allow the broadphase to notify the collision detection about an overlapping pair. void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2); + /// Return a reference to the memory manager + MemoryManager& getMemoryManager() const; + /// Return a pointer to the world CollisionWorld* getWorld(); @@ -342,6 +345,11 @@ inline CollisionWorld* CollisionDetection::getWorld() { return mWorld; } +// Return a reference to the memory manager +inline MemoryManager& CollisionDetection::getMemoryManager() const { + return mMemoryManager; +} + #ifdef IS_PROFILING_ACTIVE // Set the profiler diff --git a/src/collision/broadphase/BroadPhaseAlgorithm.cpp b/src/collision/broadphase/BroadPhaseAlgorithm.cpp index 8998859e..5f76e2c2 100644 --- a/src/collision/broadphase/BroadPhaseAlgorithm.cpp +++ b/src/collision/broadphase/BroadPhaseAlgorithm.cpp @@ -33,16 +33,19 @@ using namespace reactphysics3d; // Constructor BroadPhaseAlgorithm::BroadPhaseAlgorithm(CollisionDetection& collisionDetection) - :mDynamicAABBTree(DYNAMIC_TREE_AABB_GAP), mNbMovedShapes(0), mNbAllocatedMovedShapes(8), + :mDynamicAABBTree(collisionDetection.getMemoryManager().getPoolAllocator(), DYNAMIC_TREE_AABB_GAP), + mNbMovedShapes(0), mNbAllocatedMovedShapes(8), mNbNonUsedMovedShapes(0), mNbPotentialPairs(0), mNbAllocatedPotentialPairs(8), mCollisionDetection(collisionDetection) { + PoolAllocator& poolAllocator = collisionDetection.getMemoryManager().getPoolAllocator(); + // Allocate memory for the array of non-static proxy shapes IDs - mMovedShapes = (int*) malloc(mNbAllocatedMovedShapes * sizeof(int)); + mMovedShapes = static_cast(poolAllocator.allocate(mNbAllocatedMovedShapes * sizeof(int))); assert(mMovedShapes != nullptr); // Allocate memory for the array of potential overlapping pairs - mPotentialPairs = (BroadPhasePair*) malloc(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); + mPotentialPairs = static_cast(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair))); assert(mPotentialPairs != nullptr); #ifdef IS_PROFILING_ACTIVE @@ -56,25 +59,34 @@ BroadPhaseAlgorithm::BroadPhaseAlgorithm(CollisionDetection& collisionDetection) // Destructor BroadPhaseAlgorithm::~BroadPhaseAlgorithm() { + // Get the memory pool allocatory + PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); + // Release the memory for the array of non-static proxy shapes IDs - free(mMovedShapes); + poolAllocator.release(mMovedShapes, mNbAllocatedMovedShapes * sizeof (int)); // Release the memory for the array of potential overlapping pairs - free(mPotentialPairs); + poolAllocator.release(mPotentialPairs, mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); } // Add a collision shape in the array of shapes that have moved in the last simulation step // and that need to be tested again for broad-phase overlapping. void BroadPhaseAlgorithm::addMovedCollisionShape(int broadPhaseID) { + // Allocate more elements in the array of shapes that have moved if necessary if (mNbAllocatedMovedShapes == mNbMovedShapes) { + + // Get the memory pool allocatory + PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); + + uint oldNbAllocatedMovedShapes = mNbAllocatedMovedShapes; mNbAllocatedMovedShapes *= 2; int* oldArray = mMovedShapes; - mMovedShapes = (int*) malloc(mNbAllocatedMovedShapes * sizeof(int)); + mMovedShapes = static_cast(poolAllocator.allocate(mNbAllocatedMovedShapes * sizeof(int))); assert(mMovedShapes != nullptr); - memcpy(mMovedShapes, oldArray, mNbMovedShapes * sizeof(int)); - free(oldArray); + std::memcpy(mMovedShapes, oldArray, mNbMovedShapes * sizeof(int)); + poolAllocator.release(oldArray, oldNbAllocatedMovedShapes * sizeof(int)); } // Store the broad-phase ID into the array of shapes that have moved @@ -95,9 +107,13 @@ void BroadPhaseAlgorithm::removeMovedCollisionShape(int broadPhaseID) { if ((mNbMovedShapes - mNbNonUsedMovedShapes) < mNbAllocatedMovedShapes / 4 && mNbAllocatedMovedShapes > 8) { + // Get the memory pool allocatory + PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); + + uint oldNbAllocatedMovedShapes = mNbAllocatedMovedShapes; mNbAllocatedMovedShapes /= 2; int* oldArray = mMovedShapes; - mMovedShapes = (int*) malloc(mNbAllocatedMovedShapes * sizeof(int)); + mMovedShapes = static_cast(poolAllocator.allocate(mNbAllocatedMovedShapes * sizeof(int))); assert(mMovedShapes != nullptr); uint nbElements = 0; for (uint i=0; i 8) { + PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); + // Reduce the number of allocated potential overlapping pairs BroadPhasePair* oldPairs = mPotentialPairs; + uint oldNbAllocatedPotentialPairs = mNbAllocatedPotentialPairs; mNbAllocatedPotentialPairs /= 2; - mPotentialPairs = (BroadPhasePair*) malloc(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); + mPotentialPairs = static_cast(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair))); assert(mPotentialPairs); memcpy(mPotentialPairs, oldPairs, mNbPotentialPairs * sizeof(BroadPhasePair)); - free(oldPairs); + poolAllocator.release(oldPairs, oldNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); } } @@ -289,13 +308,16 @@ void BroadPhaseAlgorithm::addOverlappingNodes(int referenceNodeId, const LinkedL // If we need to allocate more memory for the array of potential overlapping pairs if (mNbPotentialPairs == mNbAllocatedPotentialPairs) { + PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator(); + // Allocate more memory for the array of potential pairs BroadPhasePair* oldPairs = mPotentialPairs; + uint oldNbAllocatedPotentialPairs = mNbAllocatedPotentialPairs; mNbAllocatedPotentialPairs *= 2; - mPotentialPairs = (BroadPhasePair*) malloc(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); + mPotentialPairs = static_cast(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair))); assert(mPotentialPairs); memcpy(mPotentialPairs, oldPairs, mNbPotentialPairs * sizeof(BroadPhasePair)); - free(oldPairs); + poolAllocator.release(oldPairs, oldNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); } // Add the new potential pair into the array of potential overlapping pairs diff --git a/src/collision/broadphase/DynamicAABBTree.cpp b/src/collision/broadphase/DynamicAABBTree.cpp index 5fa33d9d..bbc4b109 100644 --- a/src/collision/broadphase/DynamicAABBTree.cpp +++ b/src/collision/broadphase/DynamicAABBTree.cpp @@ -35,7 +35,8 @@ using namespace reactphysics3d; const int TreeNode::NULL_TREE_NODE = -1; // Constructor -DynamicAABBTree::DynamicAABBTree(decimal extraAABBGap) : mExtraAABBGap(extraAABBGap) { +DynamicAABBTree::DynamicAABBTree(MemoryAllocator& allocator, decimal extraAABBGap) + : mAllocator(allocator), mExtraAABBGap(extraAABBGap) { init(); } @@ -44,7 +45,7 @@ DynamicAABBTree::DynamicAABBTree(decimal extraAABBGap) : mExtraAABBGap(extraAABB DynamicAABBTree::~DynamicAABBTree() { // Free the allocated memory for the nodes - free(mNodes); + mAllocator.release(mNodes, mNbAllocatedNodes * sizeof(TreeNode)); } // Initialize the tree @@ -55,9 +56,9 @@ void DynamicAABBTree::init() { mNbAllocatedNodes = 8; // Allocate memory for the nodes of the tree - mNodes = (TreeNode*) malloc(mNbAllocatedNodes * sizeof(TreeNode)); + mNodes = static_cast(mAllocator.allocate(mNbAllocatedNodes * sizeof(TreeNode))); assert(mNodes); - memset(mNodes, 0, mNbAllocatedNodes * sizeof(TreeNode)); + std::memset(mNodes, 0, mNbAllocatedNodes * sizeof(TreeNode)); // Initialize the allocated nodes for (int i=0; i(mAllocator.allocate(mNbAllocatedNodes * sizeof(TreeNode))); assert(mNodes); memcpy(mNodes, oldNodes, mNbNodes * sizeof(TreeNode)); - free(oldNodes); + mAllocator.release(oldNodes, oldNbAllocatedNodes * sizeof(TreeNode)); // Initialize the allocated nodes for (int i=mNbNodes; i stack; + Stack stack(mAllocator); stack.push(mRootNodeID); // While there are still nodes to visit @@ -637,7 +639,7 @@ void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback &ca decimal maxFraction = ray.maxFraction; - Stack stack; + Stack stack(mAllocator); stack.push(mRootNodeID); // Walk through the tree from the root looking for proxy shapes diff --git a/src/collision/broadphase/DynamicAABBTree.h b/src/collision/broadphase/DynamicAABBTree.h index 54751138..936595a5 100644 --- a/src/collision/broadphase/DynamicAABBTree.h +++ b/src/collision/broadphase/DynamicAABBTree.h @@ -30,6 +30,7 @@ #include "configuration.h" #include "collision/shapes/AABB.h" #include "body/CollisionBody.h" +#include "memory/MemoryAllocator.h" /// Namespace ReactPhysics3D namespace reactphysics3d { @@ -136,6 +137,9 @@ class DynamicAABBTree { // -------------------- Attributes -------------------- // + /// Memory allocator + MemoryAllocator& mAllocator; + /// Pointer to the memory location of the nodes of the tree TreeNode* mNodes; @@ -203,7 +207,7 @@ class DynamicAABBTree { // -------------------- Methods -------------------- // /// Constructor - DynamicAABBTree(decimal extraAABBGap = decimal(0.0)); + DynamicAABBTree(MemoryAllocator& allocator, decimal extraAABBGap = decimal(0.0)); /// Destructor ~DynamicAABBTree(); diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index ec5fa913..d2046adc 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -25,12 +25,13 @@ // Libraries #include "ConcaveMeshShape.h" +#include "memory/MemoryManager.h" using namespace reactphysics3d; // Constructor ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh) - : ConcaveShape(CollisionShapeName::TRIANGLE_MESH) { + : ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()) { mTriangleMesh = triangleMesh; mRaycastTestType = TriangleRaycastSide::FRONT; diff --git a/src/containers/Stack.h b/src/containers/Stack.h index 904486f1..84e470ba 100644 --- a/src/containers/Stack.h +++ b/src/containers/Stack.h @@ -28,6 +28,7 @@ // Libraries #include "configuration.h" +#include "memory/MemoryAllocator.h" namespace reactphysics3d { @@ -43,6 +44,9 @@ class Stack { // -------------------- Attributes -------------------- // + /// Reference to the memory allocator + MemoryAllocator& mAllocator; + /// Initial array that contains the elements of the stack T mInitArray[capacity]; @@ -60,7 +64,8 @@ class Stack { // -------------------- Methods -------------------- // /// Constructor - Stack() : mElements(mInitArray), mNbElements(0), mNbAllocatedElements(capacity) { + Stack(MemoryAllocator& allocator) + :mAllocator(allocator), mElements(mInitArray), mNbElements(0), mNbAllocatedElements(capacity) { } @@ -71,7 +76,7 @@ class Stack { if (mInitArray != mElements) { // Release the memory allocated on the heap - free(mElements); + mAllocator.release(mElements, mNbAllocatedElements * sizeof(T)); } } @@ -93,12 +98,13 @@ inline void Stack::push(const T& element) { // If we need to allocate more elements if (mNbElements == mNbAllocatedElements) { T* oldElements = mElements; + uint oldNbAllocatedElements = mNbAllocatedElements; mNbAllocatedElements *= 2; - mElements = (T*) malloc(mNbAllocatedElements * sizeof(T)); + mElements = static_cast(mAllocator.allocate(mNbAllocatedElements * sizeof(T))); assert(mElements); memcpy(mElements, oldElements, mNbElements * sizeof(T)); if (oldElements != mInitArray) { - free(oldElements); + mAllocator.release(oldElements, oldNbAllocatedElements * sizeof(T)); } } diff --git a/test/tests/collision/TestDynamicAABBTree.h b/test/tests/collision/TestDynamicAABBTree.h index e43c63e7..a117df57 100755 --- a/test/tests/collision/TestDynamicAABBTree.h +++ b/test/tests/collision/TestDynamicAABBTree.h @@ -29,6 +29,7 @@ // Libraries #include "Test.h" #include "collision/broadphase/DynamicAABBTree.h" +#include "memory/MemoryManager.h" /// Reactphysics3D namespace namespace reactphysics3d { @@ -112,7 +113,7 @@ class TestDynamicAABBTree : public Test { // ------------ Create tree ---------- // // Dynamic AABB Tree - DynamicAABBTree tree; + DynamicAABBTree tree(MemoryManager::getBaseAllocator()); #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler @@ -168,7 +169,7 @@ class TestDynamicAABBTree : public Test { // ------------- Create tree ----------- // // Dynamic AABB Tree - DynamicAABBTree tree; + DynamicAABBTree tree(MemoryManager::getBaseAllocator()); #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler @@ -367,7 +368,7 @@ class TestDynamicAABBTree : public Test { // ------------- Create tree ----------- // // Dynamic AABB Tree - DynamicAABBTree tree; + DynamicAABBTree tree(MemoryManager::getBaseAllocator()); #ifdef IS_PROFILING_ACTIVE /// Pointer to the profiler