Replace malloc/free calls by use of the MemoryManager of ReactPhysics3D

This commit is contained in:
Daniel Chappuis 2018-02-04 19:43:17 +01:00
parent b3e771838d
commit e0fda18446
7 changed files with 76 additions and 32 deletions

View File

@ -228,6 +228,9 @@ class CollisionDetection {
/// Allow the broadphase to notify the collision detection about an overlapping pair. /// Allow the broadphase to notify the collision detection about an overlapping pair.
void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2); void broadPhaseNotifyOverlappingPair(ProxyShape* shape1, ProxyShape* shape2);
/// Return a reference to the memory manager
MemoryManager& getMemoryManager() const;
/// Return a pointer to the world /// Return a pointer to the world
CollisionWorld* getWorld(); CollisionWorld* getWorld();
@ -342,6 +345,11 @@ inline CollisionWorld* CollisionDetection::getWorld() {
return mWorld; return mWorld;
} }
// Return a reference to the memory manager
inline MemoryManager& CollisionDetection::getMemoryManager() const {
return mMemoryManager;
}
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
// Set the profiler // Set the profiler

View File

@ -33,16 +33,19 @@ using namespace reactphysics3d;
// Constructor // Constructor
BroadPhaseAlgorithm::BroadPhaseAlgorithm(CollisionDetection& collisionDetection) 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), mNbNonUsedMovedShapes(0), mNbPotentialPairs(0), mNbAllocatedPotentialPairs(8),
mCollisionDetection(collisionDetection) { mCollisionDetection(collisionDetection) {
PoolAllocator& poolAllocator = collisionDetection.getMemoryManager().getPoolAllocator();
// Allocate memory for the array of non-static proxy shapes IDs // Allocate memory for the array of non-static proxy shapes IDs
mMovedShapes = (int*) malloc(mNbAllocatedMovedShapes * sizeof(int)); mMovedShapes = static_cast<int*>(poolAllocator.allocate(mNbAllocatedMovedShapes * sizeof(int)));
assert(mMovedShapes != nullptr); assert(mMovedShapes != nullptr);
// Allocate memory for the array of potential overlapping pairs // Allocate memory for the array of potential overlapping pairs
mPotentialPairs = (BroadPhasePair*) malloc(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); mPotentialPairs = static_cast<BroadPhasePair*>(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)));
assert(mPotentialPairs != nullptr); assert(mPotentialPairs != nullptr);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -56,25 +59,34 @@ BroadPhaseAlgorithm::BroadPhaseAlgorithm(CollisionDetection& collisionDetection)
// Destructor // Destructor
BroadPhaseAlgorithm::~BroadPhaseAlgorithm() { BroadPhaseAlgorithm::~BroadPhaseAlgorithm() {
// Get the memory pool allocatory
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
// Release the memory for the array of non-static proxy shapes IDs // 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 // 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 // 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. // and that need to be tested again for broad-phase overlapping.
void BroadPhaseAlgorithm::addMovedCollisionShape(int broadPhaseID) { void BroadPhaseAlgorithm::addMovedCollisionShape(int broadPhaseID) {
// Allocate more elements in the array of shapes that have moved if necessary // Allocate more elements in the array of shapes that have moved if necessary
if (mNbAllocatedMovedShapes == mNbMovedShapes) { if (mNbAllocatedMovedShapes == mNbMovedShapes) {
// Get the memory pool allocatory
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
uint oldNbAllocatedMovedShapes = mNbAllocatedMovedShapes;
mNbAllocatedMovedShapes *= 2; mNbAllocatedMovedShapes *= 2;
int* oldArray = mMovedShapes; int* oldArray = mMovedShapes;
mMovedShapes = (int*) malloc(mNbAllocatedMovedShapes * sizeof(int)); mMovedShapes = static_cast<int*>(poolAllocator.allocate(mNbAllocatedMovedShapes * sizeof(int)));
assert(mMovedShapes != nullptr); assert(mMovedShapes != nullptr);
memcpy(mMovedShapes, oldArray, mNbMovedShapes * sizeof(int)); std::memcpy(mMovedShapes, oldArray, mNbMovedShapes * sizeof(int));
free(oldArray); poolAllocator.release(oldArray, oldNbAllocatedMovedShapes * sizeof(int));
} }
// Store the broad-phase ID into the array of shapes that have moved // 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 && if ((mNbMovedShapes - mNbNonUsedMovedShapes) < mNbAllocatedMovedShapes / 4 &&
mNbAllocatedMovedShapes > 8) { mNbAllocatedMovedShapes > 8) {
// Get the memory pool allocatory
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
uint oldNbAllocatedMovedShapes = mNbAllocatedMovedShapes;
mNbAllocatedMovedShapes /= 2; mNbAllocatedMovedShapes /= 2;
int* oldArray = mMovedShapes; int* oldArray = mMovedShapes;
mMovedShapes = (int*) malloc(mNbAllocatedMovedShapes * sizeof(int)); mMovedShapes = static_cast<int*>(poolAllocator.allocate(mNbAllocatedMovedShapes * sizeof(int)));
assert(mMovedShapes != nullptr); assert(mMovedShapes != nullptr);
uint nbElements = 0; uint nbElements = 0;
for (uint i=0; i<mNbMovedShapes; i++) { for (uint i=0; i<mNbMovedShapes; i++) {
@ -108,7 +124,7 @@ void BroadPhaseAlgorithm::removeMovedCollisionShape(int broadPhaseID) {
} }
mNbMovedShapes = nbElements; mNbMovedShapes = nbElements;
mNbNonUsedMovedShapes = 0; mNbNonUsedMovedShapes = 0;
free(oldArray); poolAllocator.release(oldArray, oldNbAllocatedMovedShapes * sizeof(int));
} }
// Remove the broad-phase ID from the array // Remove the broad-phase ID from the array
@ -266,13 +282,16 @@ void BroadPhaseAlgorithm::computeOverlappingPairs(MemoryManager& memoryManager)
// number of overlapping pairs // number of overlapping pairs
if (mNbPotentialPairs < mNbAllocatedPotentialPairs / 4 && mNbPotentialPairs > 8) { if (mNbPotentialPairs < mNbAllocatedPotentialPairs / 4 && mNbPotentialPairs > 8) {
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
// Reduce the number of allocated potential overlapping pairs // Reduce the number of allocated potential overlapping pairs
BroadPhasePair* oldPairs = mPotentialPairs; BroadPhasePair* oldPairs = mPotentialPairs;
uint oldNbAllocatedPotentialPairs = mNbAllocatedPotentialPairs;
mNbAllocatedPotentialPairs /= 2; mNbAllocatedPotentialPairs /= 2;
mPotentialPairs = (BroadPhasePair*) malloc(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); mPotentialPairs = static_cast<BroadPhasePair*>(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)));
assert(mPotentialPairs); assert(mPotentialPairs);
memcpy(mPotentialPairs, oldPairs, mNbPotentialPairs * sizeof(BroadPhasePair)); 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 we need to allocate more memory for the array of potential overlapping pairs
if (mNbPotentialPairs == mNbAllocatedPotentialPairs) { if (mNbPotentialPairs == mNbAllocatedPotentialPairs) {
PoolAllocator& poolAllocator = mCollisionDetection.getMemoryManager().getPoolAllocator();
// Allocate more memory for the array of potential pairs // Allocate more memory for the array of potential pairs
BroadPhasePair* oldPairs = mPotentialPairs; BroadPhasePair* oldPairs = mPotentialPairs;
uint oldNbAllocatedPotentialPairs = mNbAllocatedPotentialPairs;
mNbAllocatedPotentialPairs *= 2; mNbAllocatedPotentialPairs *= 2;
mPotentialPairs = (BroadPhasePair*) malloc(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)); mPotentialPairs = static_cast<BroadPhasePair*>(poolAllocator.allocate(mNbAllocatedPotentialPairs * sizeof(BroadPhasePair)));
assert(mPotentialPairs); assert(mPotentialPairs);
memcpy(mPotentialPairs, oldPairs, mNbPotentialPairs * sizeof(BroadPhasePair)); 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 // Add the new potential pair into the array of potential overlapping pairs

View File

@ -35,7 +35,8 @@ using namespace reactphysics3d;
const int TreeNode::NULL_TREE_NODE = -1; const int TreeNode::NULL_TREE_NODE = -1;
// Constructor // Constructor
DynamicAABBTree::DynamicAABBTree(decimal extraAABBGap) : mExtraAABBGap(extraAABBGap) { DynamicAABBTree::DynamicAABBTree(MemoryAllocator& allocator, decimal extraAABBGap)
: mAllocator(allocator), mExtraAABBGap(extraAABBGap) {
init(); init();
} }
@ -44,7 +45,7 @@ DynamicAABBTree::DynamicAABBTree(decimal extraAABBGap) : mExtraAABBGap(extraAABB
DynamicAABBTree::~DynamicAABBTree() { DynamicAABBTree::~DynamicAABBTree() {
// Free the allocated memory for the nodes // Free the allocated memory for the nodes
free(mNodes); mAllocator.release(mNodes, mNbAllocatedNodes * sizeof(TreeNode));
} }
// Initialize the tree // Initialize the tree
@ -55,9 +56,9 @@ void DynamicAABBTree::init() {
mNbAllocatedNodes = 8; mNbAllocatedNodes = 8;
// Allocate memory for the nodes of the tree // Allocate memory for the nodes of the tree
mNodes = (TreeNode*) malloc(mNbAllocatedNodes * sizeof(TreeNode)); mNodes = static_cast<TreeNode*>(mAllocator.allocate(mNbAllocatedNodes * sizeof(TreeNode)));
assert(mNodes); assert(mNodes);
memset(mNodes, 0, mNbAllocatedNodes * sizeof(TreeNode)); std::memset(mNodes, 0, mNbAllocatedNodes * sizeof(TreeNode));
// Initialize the allocated nodes // Initialize the allocated nodes
for (int i=0; i<mNbAllocatedNodes - 1; i++) { for (int i=0; i<mNbAllocatedNodes - 1; i++) {
@ -73,7 +74,7 @@ void DynamicAABBTree::init() {
void DynamicAABBTree::reset() { void DynamicAABBTree::reset() {
// Free the allocated memory for the nodes // Free the allocated memory for the nodes
free(mNodes); mAllocator.release(mNodes, mNbAllocatedNodes * sizeof(TreeNode));
// Initialize the tree // Initialize the tree
init(); init();
@ -88,12 +89,13 @@ int DynamicAABBTree::allocateNode() {
assert(mNbNodes == mNbAllocatedNodes); assert(mNbNodes == mNbAllocatedNodes);
// Allocate more nodes in the tree // Allocate more nodes in the tree
uint oldNbAllocatedNodes = mNbAllocatedNodes;
mNbAllocatedNodes *= 2; mNbAllocatedNodes *= 2;
TreeNode* oldNodes = mNodes; TreeNode* oldNodes = mNodes;
mNodes = (TreeNode*) malloc(mNbAllocatedNodes * sizeof(TreeNode)); mNodes = static_cast<TreeNode*>(mAllocator.allocate(mNbAllocatedNodes * sizeof(TreeNode)));
assert(mNodes); assert(mNodes);
memcpy(mNodes, oldNodes, mNbNodes * sizeof(TreeNode)); memcpy(mNodes, oldNodes, mNbNodes * sizeof(TreeNode));
free(oldNodes); mAllocator.release(oldNodes, oldNbAllocatedNodes * sizeof(TreeNode));
// Initialize the allocated nodes // Initialize the allocated nodes
for (int i=mNbNodes; i<mNbAllocatedNodes - 1; i++) { for (int i=mNbNodes; i<mNbAllocatedNodes - 1; i++) {
@ -596,7 +598,7 @@ void DynamicAABBTree::reportAllShapesOverlappingWithAABB(const AABB& aabb,
DynamicAABBTreeOverlapCallback& callback) const { DynamicAABBTreeOverlapCallback& callback) const {
// Create a stack with the nodes to visit // Create a stack with the nodes to visit
Stack<int, 64> stack; Stack<int, 64> stack(mAllocator);
stack.push(mRootNodeID); stack.push(mRootNodeID);
// While there are still nodes to visit // While there are still nodes to visit
@ -637,7 +639,7 @@ void DynamicAABBTree::raycast(const Ray& ray, DynamicAABBTreeRaycastCallback &ca
decimal maxFraction = ray.maxFraction; decimal maxFraction = ray.maxFraction;
Stack<int, 128> stack; Stack<int, 128> stack(mAllocator);
stack.push(mRootNodeID); stack.push(mRootNodeID);
// Walk through the tree from the root looking for proxy shapes // Walk through the tree from the root looking for proxy shapes

View File

@ -30,6 +30,7 @@
#include "configuration.h" #include "configuration.h"
#include "collision/shapes/AABB.h" #include "collision/shapes/AABB.h"
#include "body/CollisionBody.h" #include "body/CollisionBody.h"
#include "memory/MemoryAllocator.h"
/// Namespace ReactPhysics3D /// Namespace ReactPhysics3D
namespace reactphysics3d { namespace reactphysics3d {
@ -136,6 +137,9 @@ class DynamicAABBTree {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Memory allocator
MemoryAllocator& mAllocator;
/// Pointer to the memory location of the nodes of the tree /// Pointer to the memory location of the nodes of the tree
TreeNode* mNodes; TreeNode* mNodes;
@ -203,7 +207,7 @@ class DynamicAABBTree {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
DynamicAABBTree(decimal extraAABBGap = decimal(0.0)); DynamicAABBTree(MemoryAllocator& allocator, decimal extraAABBGap = decimal(0.0));
/// Destructor /// Destructor
~DynamicAABBTree(); ~DynamicAABBTree();

View File

@ -25,12 +25,13 @@
// Libraries // Libraries
#include "ConcaveMeshShape.h" #include "ConcaveMeshShape.h"
#include "memory/MemoryManager.h"
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh) ConcaveMeshShape::ConcaveMeshShape(TriangleMesh* triangleMesh)
: ConcaveShape(CollisionShapeName::TRIANGLE_MESH) { : ConcaveShape(CollisionShapeName::TRIANGLE_MESH), mDynamicAABBTree(MemoryManager::getBaseAllocator()) {
mTriangleMesh = triangleMesh; mTriangleMesh = triangleMesh;
mRaycastTestType = TriangleRaycastSide::FRONT; mRaycastTestType = TriangleRaycastSide::FRONT;

View File

@ -28,6 +28,7 @@
// Libraries // Libraries
#include "configuration.h" #include "configuration.h"
#include "memory/MemoryAllocator.h"
namespace reactphysics3d { namespace reactphysics3d {
@ -43,6 +44,9 @@ class Stack {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Reference to the memory allocator
MemoryAllocator& mAllocator;
/// Initial array that contains the elements of the stack /// Initial array that contains the elements of the stack
T mInitArray[capacity]; T mInitArray[capacity];
@ -60,7 +64,8 @@ class Stack {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// 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) { if (mInitArray != mElements) {
// Release the memory allocated on the heap // Release the memory allocated on the heap
free(mElements); mAllocator.release(mElements, mNbAllocatedElements * sizeof(T));
} }
} }
@ -93,12 +98,13 @@ inline void Stack<T, capacity>::push(const T& element) {
// If we need to allocate more elements // If we need to allocate more elements
if (mNbElements == mNbAllocatedElements) { if (mNbElements == mNbAllocatedElements) {
T* oldElements = mElements; T* oldElements = mElements;
uint oldNbAllocatedElements = mNbAllocatedElements;
mNbAllocatedElements *= 2; mNbAllocatedElements *= 2;
mElements = (T*) malloc(mNbAllocatedElements * sizeof(T)); mElements = static_cast<T*>(mAllocator.allocate(mNbAllocatedElements * sizeof(T)));
assert(mElements); assert(mElements);
memcpy(mElements, oldElements, mNbElements * sizeof(T)); memcpy(mElements, oldElements, mNbElements * sizeof(T));
if (oldElements != mInitArray) { if (oldElements != mInitArray) {
free(oldElements); mAllocator.release(oldElements, oldNbAllocatedElements * sizeof(T));
} }
} }

View File

@ -29,6 +29,7 @@
// Libraries // Libraries
#include "Test.h" #include "Test.h"
#include "collision/broadphase/DynamicAABBTree.h" #include "collision/broadphase/DynamicAABBTree.h"
#include "memory/MemoryManager.h"
/// Reactphysics3D namespace /// Reactphysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -112,7 +113,7 @@ class TestDynamicAABBTree : public Test {
// ------------ Create tree ---------- // // ------------ Create tree ---------- //
// Dynamic AABB Tree // Dynamic AABB Tree
DynamicAABBTree tree; DynamicAABBTree tree(MemoryManager::getBaseAllocator());
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler /// Pointer to the profiler
@ -168,7 +169,7 @@ class TestDynamicAABBTree : public Test {
// ------------- Create tree ----------- // // ------------- Create tree ----------- //
// Dynamic AABB Tree // Dynamic AABB Tree
DynamicAABBTree tree; DynamicAABBTree tree(MemoryManager::getBaseAllocator());
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler /// Pointer to the profiler
@ -367,7 +368,7 @@ class TestDynamicAABBTree : public Test {
// ------------- Create tree ----------- // // ------------- Create tree ----------- //
// Dynamic AABB Tree // Dynamic AABB Tree
DynamicAABBTree tree; DynamicAABBTree tree(MemoryManager::getBaseAllocator());
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler /// Pointer to the profiler