Refactor memory allocation

This commit is contained in:
Daniel Chappuis 2018-01-01 18:35:57 +01:00
parent 3be2970d30
commit 261ffef616
75 changed files with 449 additions and 296 deletions

View File

@ -187,7 +187,7 @@ SET (REACTPHYSICS3D_SOURCES
"src/mathematics/Vector3.h" "src/mathematics/Vector3.h"
"src/mathematics/Ray.h" "src/mathematics/Ray.h"
"src/mathematics/Vector3.cpp" "src/mathematics/Vector3.cpp"
"src/memory/Allocator.h" "src/memory/MemoryAllocator.h"
"src/memory/PoolAllocator.h" "src/memory/PoolAllocator.h"
"src/memory/PoolAllocator.cpp" "src/memory/PoolAllocator.cpp"
"src/memory/SingleFrameAllocator.h" "src/memory/SingleFrameAllocator.h"

View File

@ -70,9 +70,9 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape,
const Transform& transform) { const Transform& transform) {
// Create a new proxy collision shape to attach the collision shape to the body // Create a new proxy collision shape to attach the collision shape to the body
ProxyShape* proxyShape = new (mWorld.mPoolAllocator.allocate( ProxyShape* proxyShape = new (mWorld.mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(ProxyShape))) ProxyShape(this, collisionShape, sizeof(ProxyShape))) ProxyShape(this, collisionShape,
transform, decimal(1), mWorld.mPoolAllocator); transform, decimal(1), mWorld.mMemoryManager);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -123,7 +123,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
} }
current->~ProxyShape(); current->~ProxyShape();
mWorld.mPoolAllocator.release(current, sizeof(ProxyShape)); mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, current, sizeof(ProxyShape));
mNbCollisionShapes--; mNbCollisionShapes--;
return; return;
} }
@ -143,7 +143,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
} }
elementToRemove->~ProxyShape(); elementToRemove->~ProxyShape();
mWorld.mPoolAllocator.release(elementToRemove, sizeof(ProxyShape)); mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, elementToRemove, sizeof(ProxyShape));
mNbCollisionShapes--; mNbCollisionShapes--;
return; return;
} }
@ -169,7 +169,7 @@ void CollisionBody::removeAllCollisionShapes() {
} }
current->~ProxyShape(); current->~ProxyShape();
mWorld.mPoolAllocator.release(current, sizeof(ProxyShape)); mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, current, sizeof(ProxyShape));
// Get the next element in the list // Get the next element in the list
current = nextElement; current = nextElement;
@ -188,7 +188,7 @@ void CollisionBody::resetContactManifoldsList() {
// Delete the current element // Delete the current element
currentElement->~ContactManifoldListElement(); currentElement->~ContactManifoldListElement();
mWorld.mPoolAllocator.release(currentElement, sizeof(ContactManifoldListElement)); mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, currentElement, sizeof(ContactManifoldListElement));
currentElement = nextElement; currentElement = nextElement;
} }

View File

@ -176,7 +176,7 @@ void RigidBody::setMass(decimal mass) {
} }
// Remove a joint from the joints list // Remove a joint from the joints list
void RigidBody::removeJointFromJointsList(PoolAllocator& memoryAllocator, const Joint* joint) { void RigidBody::removeJointFromJointsList(MemoryManager& memoryManager, const Joint* joint) {
assert(joint != nullptr); assert(joint != nullptr);
assert(mJointsList != nullptr); assert(mJointsList != nullptr);
@ -186,7 +186,8 @@ void RigidBody::removeJointFromJointsList(PoolAllocator& memoryAllocator, const
JointListElement* elementToRemove = mJointsList; JointListElement* elementToRemove = mJointsList;
mJointsList = elementToRemove->next; mJointsList = elementToRemove->next;
elementToRemove->~JointListElement(); elementToRemove->~JointListElement();
memoryAllocator.release(elementToRemove, sizeof(JointListElement)); memoryManager.release(MemoryManager::AllocationType::Pool,
elementToRemove, sizeof(JointListElement));
} }
else { // If the element to remove is not the first one in the list else { // If the element to remove is not the first one in the list
JointListElement* currentElement = mJointsList; JointListElement* currentElement = mJointsList;
@ -195,7 +196,8 @@ void RigidBody::removeJointFromJointsList(PoolAllocator& memoryAllocator, const
JointListElement* elementToRemove = currentElement->next; JointListElement* elementToRemove = currentElement->next;
currentElement->next = elementToRemove->next; currentElement->next = elementToRemove->next;
elementToRemove->~JointListElement(); elementToRemove->~JointListElement();
memoryAllocator.release(elementToRemove, sizeof(JointListElement)); memoryManager.release(MemoryManager::AllocationType::Pool,
elementToRemove, sizeof(JointListElement));
break; break;
} }
currentElement = currentElement->next; currentElement = currentElement->next;
@ -224,9 +226,9 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
decimal mass) { decimal mass) {
// Create a new proxy collision shape to attach the collision shape to the body // Create a new proxy collision shape to attach the collision shape to the body
ProxyShape* proxyShape = new (mWorld.mPoolAllocator.allocate( ProxyShape* proxyShape = new (mWorld.mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(ProxyShape))) ProxyShape(this, collisionShape, sizeof(ProxyShape))) ProxyShape(this, collisionShape,
transform, mass, mWorld.mPoolAllocator); transform, mass, mWorld.mMemoryManager);
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -31,7 +31,7 @@
#include "CollisionBody.h" #include "CollisionBody.h"
#include "engine/Material.h" #include "engine/Material.h"
#include "mathematics/mathematics.h" #include "mathematics/mathematics.h"
#include "memory/PoolAllocator.h" #include "memory/MemoryManager.h"
/// Namespace reactphysics3d /// Namespace reactphysics3d
namespace reactphysics3d { namespace reactphysics3d {
@ -112,7 +112,7 @@ class RigidBody : public CollisionBody {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Remove a joint from the joints list /// Remove a joint from the joints list
void removeJointFromJointsList(PoolAllocator& memoryAllocator, const Joint* joint); void removeJointFromJointsList(reactphysics3d::MemoryManager& memoryManager, const Joint* joint);
/// Update the transform of the body after a change of the center of mass /// Update the transform of the body after a change of the center of mass
void updateTransformWithCenterOfMass(); void updateTransformWithCenterOfMass();

View File

@ -26,18 +26,18 @@
// Libraries // Libraries
#include "collision/CollisionCallback.h" #include "collision/CollisionCallback.h"
#include "engine/OverlappingPair.h" #include "engine/OverlappingPair.h"
#include "memory/Allocator.h" #include "memory/MemoryAllocator.h"
#include "collision/ContactManifold.h" #include "collision/ContactManifold.h"
// We want to use the ReactPhysics3D namespace // We want to use the ReactPhysics3D namespace
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* pair, Allocator& allocator) : CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* pair, MemoryManager& memoryManager) :
contactManifoldElements(nullptr), body1(pair->getShape1()->getBody()), contactManifoldElements(nullptr), body1(pair->getShape1()->getBody()),
body2(pair->getShape2()->getBody()), body2(pair->getShape2()->getBody()),
proxyShape1(pair->getShape1()), proxyShape2(pair->getShape2()), proxyShape1(pair->getShape1()), proxyShape2(pair->getShape2()),
mMemoryAllocator(allocator) { mMemoryManager(memoryManager) {
assert(pair != nullptr); assert(pair != nullptr);
@ -52,7 +52,8 @@ CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair*
// Add the contact manifold at the beginning of the linked // Add the contact manifold at the beginning of the linked
// list of contact manifolds of the first body // list of contact manifolds of the first body
ContactManifoldListElement* element = new (mMemoryAllocator.allocate(sizeof(ContactManifoldListElement))) ContactManifoldListElement* element = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(ContactManifoldListElement)))
ContactManifoldListElement(contactManifold, ContactManifoldListElement(contactManifold,
contactManifoldElements); contactManifoldElements);
contactManifoldElements = element; contactManifoldElements = element;
@ -72,7 +73,8 @@ CollisionCallback::CollisionCallbackInfo::~CollisionCallbackInfo() {
// Delete and release memory // Delete and release memory
element->~ContactManifoldListElement(); element->~ContactManifoldListElement();
mMemoryAllocator.release(element, sizeof(ContactManifoldListElement)); mMemoryManager.release(MemoryManager::AllocationType::Pool, element,
sizeof(ContactManifoldListElement));
element = nextElement; element = nextElement;
} }

View File

@ -69,11 +69,11 @@ class CollisionCallback {
/// Pointer to the proxy shape of second body /// Pointer to the proxy shape of second body
const ProxyShape* proxyShape2; const ProxyShape* proxyShape2;
/// Memory allocator /// Memory manager
Allocator& mMemoryAllocator; MemoryManager& mMemoryManager;
// Constructor // Constructor
CollisionCallbackInfo(OverlappingPair* pair, Allocator& allocator); CollisionCallbackInfo(OverlappingPair* pair, MemoryManager& memoryManager);
// Destructor // Destructor
~CollisionCallbackInfo(); ~CollisionCallbackInfo();

View File

@ -47,9 +47,8 @@ using namespace reactphysics3d;
using namespace std; using namespace std;
// Constructor // Constructor
CollisionDetection::CollisionDetection(CollisionWorld* world, PoolAllocator& memoryAllocator, SingleFrameAllocator& singleFrameAllocator) CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager)
: mPoolAllocator(memoryAllocator), mSingleFrameAllocator(singleFrameAllocator), : mMemoryManager(memoryManager), mWorld(world), mNarrowPhaseInfoList(nullptr), mBroadPhaseAlgorithm(*this),
mWorld(world), mNarrowPhaseInfoList(nullptr), mBroadPhaseAlgorithm(*this),
mIsCollisionShapesAdded(false) { mIsCollisionShapesAdded(false) {
// Set the default collision dispatch configuration // Set the default collision dispatch configuration
@ -95,7 +94,7 @@ void CollisionDetection::computeBroadPhase() {
// Ask the broad-phase to recompute the overlapping pairs of collision // Ask the broad-phase to recompute the overlapping pairs of collision
// shapes. This call can only add new overlapping pairs in the collision // shapes. This call can only add new overlapping pairs in the collision
// detection. // detection.
mBroadPhaseAlgorithm.computeOverlappingPairs(mPoolAllocator); mBroadPhaseAlgorithm.computeOverlappingPairs(mMemoryManager);
} }
} }
@ -133,7 +132,7 @@ void CollisionDetection::computeMiddlePhase() {
// Destroy the overlapping pair // Destroy the overlapping pair
itToRemove->second->~OverlappingPair(); itToRemove->second->~OverlappingPair();
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair)); mWorld->mMemoryManager.release(MemoryManager::AllocationType::Pool, itToRemove->second, sizeof(OverlappingPair));
mOverlappingPairs.erase(itToRemove); mOverlappingPairs.erase(itToRemove);
continue; continue;
} }
@ -166,10 +165,10 @@ 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* firstNarrowPhaseInfo = mNarrowPhaseInfoList;
mNarrowPhaseInfoList = new (mSingleFrameAllocator.allocate(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(), mSingleFrameAllocator); shape2->getLocalToWorldTransform(), mMemoryManager.getSingleFrameAllocator());
mNarrowPhaseInfoList->next = firstNarrowPhaseInfo; mNarrowPhaseInfoList->next = firstNarrowPhaseInfo;
} }
@ -177,7 +176,7 @@ void CollisionDetection::computeMiddlePhase() {
else if ((!isShape1Convex && isShape2Convex) || (!isShape2Convex && isShape1Convex)) { else if ((!isShape1Convex && isShape2Convex) || (!isShape2Convex && isShape1Convex)) {
NarrowPhaseInfo* narrowPhaseInfo = nullptr; NarrowPhaseInfo* narrowPhaseInfo = nullptr;
computeConvexVsConcaveMiddlePhase(pair, mSingleFrameAllocator, &narrowPhaseInfo); computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getSingleFrameAllocator(), &narrowPhaseInfo);
// Add all the narrow-phase info object reported by the callback into the // Add all the narrow-phase info object reported by the callback into the
// list of all the narrow-phase info object // list of all the narrow-phase info object
@ -202,7 +201,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, Allocator& allocator, void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
NarrowPhaseInfo** firstNarrowPhaseInfo) { NarrowPhaseInfo** firstNarrowPhaseInfo) {
ProxyShape* shape1 = pair->getShape1(); ProxyShape* shape1 = pair->getShape1();
@ -273,7 +272,7 @@ void CollisionDetection::computeNarrowPhase() {
// 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, mSingleFrameAllocator)) { if (narrowPhaseAlgorithm->testCollision(currentNarrowPhaseInfo, true, mMemoryManager.getSingleFrameAllocator())) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
currentNarrowPhaseInfo->addContactPointsAsPotentialContactManifold(); currentNarrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -295,7 +294,7 @@ void CollisionDetection::computeNarrowPhase() {
narrowPhaseInfoToDelete->~NarrowPhaseInfo(); narrowPhaseInfoToDelete->~NarrowPhaseInfo();
// Release the allocated memory for the narrow phase info // Release the allocated memory for the narrow phase info
mSingleFrameAllocator.release(narrowPhaseInfoToDelete, sizeof(NarrowPhaseInfo)); mMemoryManager.release(MemoryManager::AllocationType::Frame, narrowPhaseInfoToDelete, sizeof(NarrowPhaseInfo));
} }
// Convert the potential contact into actual contacts // Convert the potential contact into actual contacts
@ -327,8 +326,9 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
if (mOverlappingPairs.find(pairID) != mOverlappingPairs.end()) return; if (mOverlappingPairs.find(pairID) != mOverlappingPairs.end()) return;
// Create the overlapping pair and add it into the set of overlapping pairs // Create the overlapping pair and add it into the set of overlapping pairs
OverlappingPair* newPair = new (mPoolAllocator.allocate(sizeof(OverlappingPair))) OverlappingPair* newPair = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(OverlappingPair)))
OverlappingPair(shape1, shape2, mPoolAllocator, mSingleFrameAllocator); OverlappingPair(shape1, shape2, mMemoryManager.getPoolAllocator(),
mMemoryManager.getSingleFrameAllocator());
assert(newPair != nullptr); assert(newPair != nullptr);
#ifndef NDEBUG #ifndef NDEBUG
@ -359,7 +359,7 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) {
// Destroy the overlapping pair // Destroy the overlapping pair
itToRemove->second->~OverlappingPair(); itToRemove->second->~OverlappingPair();
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair)); mWorld->mMemoryManager.release(MemoryManager::AllocationType::Pool, itToRemove->second, sizeof(OverlappingPair));
mOverlappingPairs.erase(itToRemove); mOverlappingPairs.erase(itToRemove);
} }
else { else {
@ -403,14 +403,16 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
// Add the contact manifold at the beginning of the linked // Add the contact manifold at the beginning of the linked
// list of contact manifolds of the first body // list of contact manifolds of the first body
ContactManifoldListElement* listElement1 = new (mPoolAllocator.allocate(sizeof(ContactManifoldListElement))) ContactManifoldListElement* listElement1 = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(ContactManifoldListElement)))
ContactManifoldListElement(contactManifold, ContactManifoldListElement(contactManifold,
body1->mContactManifoldsList); body1->mContactManifoldsList);
body1->mContactManifoldsList = listElement1; body1->mContactManifoldsList = listElement1;
// Add the contact manifold at the beginning of the linked // Add the contact manifold at the beginning of the linked
// list of the contact manifolds of the second body // list of the contact manifolds of the second body
ContactManifoldListElement* listElement2 = new (mPoolAllocator.allocate(sizeof(ContactManifoldListElement))) ContactManifoldListElement* listElement2 = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(ContactManifoldListElement)))
ContactManifoldListElement(contactManifold, ContactManifoldListElement(contactManifold,
body2->mContactManifoldsList); body2->mContactManifoldsList);
body2->mContactManifoldsList = listElement2; body2->mContactManifoldsList = listElement2;
@ -470,7 +472,7 @@ void CollisionDetection::reportAllContacts() {
// If there is a user callback // If there is a user callback
if (mWorld->mEventListener != nullptr && it->second->hasContacts()) { if (mWorld->mEventListener != nullptr && it->second->hasContacts()) {
CollisionCallback::CollisionCallbackInfo collisionInfo(it->second, mPoolAllocator); CollisionCallback::CollisionCallbackInfo collisionInfo(it->second, mMemoryManager);
// Trigger a callback event to report the new contact to the user // Trigger a callback event to report the new contact to the user
mWorld->mEventListener->newContact(collisionInfo); mWorld->mEventListener->newContact(collisionInfo);
@ -498,9 +500,10 @@ 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 (mPoolAllocator.allocate(sizeof(NarrowPhaseInfo))) NarrowPhaseInfo(pair, shape1->getCollisionShape(), narrowPhaseInfo = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(NarrowPhaseInfo))) NarrowPhaseInfo(pair, shape1->getCollisionShape(),
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(), shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
shape2->getLocalToWorldTransform(), mPoolAllocator); shape2->getLocalToWorldTransform(), mMemoryManager.getPoolAllocator());
} }
// Concave vs Convex algorithm // Concave vs Convex algorithm
@ -508,7 +511,7 @@ 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, mPoolAllocator, &narrowPhaseInfo); computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getPoolAllocator(), &narrowPhaseInfo);
} }
pair->clearObsoleteLastFrameCollisionInfos(); pair->clearObsoleteLastFrameCollisionInfos();
@ -524,7 +527,7 @@ void CollisionDetection::testAABBOverlap(const AABB& aabb, OverlapCallback* over
std::unordered_set<bodyindex> reportedBodies; std::unordered_set<bodyindex> reportedBodies;
// Ask the broad-phase to get all the overlapping shapes // Ask the broad-phase to get all the overlapping shapes
LinkedList<int> overlappingNodes(mPoolAllocator); LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes); mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes);
// For each overlaping proxy shape // For each overlaping proxy shape
@ -575,7 +578,8 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
if (aabb1.testCollision(aabb2)) { if (aabb1.testCollision(aabb2)) {
// Create a temporary overlapping pair // Create a temporary overlapping pair
OverlappingPair pair(body1ProxyShape, body2ProxyShape, mPoolAllocator, mPoolAllocator); OverlappingPair pair(body1ProxyShape, body2ProxyShape, mMemoryManager.getPoolAllocator(),
mMemoryManager.getPoolAllocator());
// Compute the middle-phase collision detection between the two shapes // Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair); NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
@ -600,7 +604,7 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
// 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.
isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false, mPoolAllocator); isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false, mMemoryManager.getPoolAllocator());
} }
} }
@ -611,7 +615,7 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
currentNarrowPhaseInfo->~NarrowPhaseInfo(); currentNarrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory // Release the allocated memory
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo)); mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
} }
// Return if we have found a narrow-phase collision // Return if we have found a narrow-phase collision
@ -648,7 +652,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID); const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID);
// Ask the broad-phase to get all the overlapping shapes // Ask the broad-phase to get all the overlapping shapes
LinkedList<int> overlappingNodes(mPoolAllocator); LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes); mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes);
const bodyindex bodyId = body->getID(); const bodyindex bodyId = body->getID();
@ -670,7 +674,8 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) { if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
// Create a temporary overlapping pair // Create a temporary overlapping pair
OverlappingPair pair(bodyProxyShape, proxyShape, mPoolAllocator, mPoolAllocator); OverlappingPair pair(bodyProxyShape, proxyShape, mMemoryManager.getPoolAllocator(),
mMemoryManager.getPoolAllocator());
// Compute the middle-phase collision detection between the two shapes // Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair); NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
@ -695,7 +700,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
// 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.
isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false, mPoolAllocator); isColliding |= narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, false, mMemoryManager.getPoolAllocator());
} }
} }
@ -706,7 +711,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
currentNarrowPhaseInfo->~NarrowPhaseInfo(); currentNarrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory // Release the allocated memory
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo)); mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
} }
// Return if we have found a narrow-phase collision // Return if we have found a narrow-phase collision
@ -754,7 +759,8 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
if (aabb1.testCollision(aabb2)) { if (aabb1.testCollision(aabb2)) {
// Create a temporary overlapping pair // Create a temporary overlapping pair
OverlappingPair pair(body1ProxyShape, body2ProxyShape, mPoolAllocator, mPoolAllocator); OverlappingPair pair(body1ProxyShape, body2ProxyShape, mMemoryManager.getPoolAllocator(),
mMemoryManager.getPoolAllocator());
// Compute the middle-phase collision detection between the two shapes // Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair); NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
@ -774,7 +780,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
// 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(narrowPhaseInfo, true, mPoolAllocator)) { if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
narrowPhaseInfo->addContactPointsAsPotentialContactManifold(); narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -788,7 +794,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
currentNarrowPhaseInfo->~NarrowPhaseInfo(); currentNarrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory // Release the allocated memory
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo)); mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
} }
// Process the potential contacts // Process the potential contacts
@ -797,7 +803,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
if (pair.hasContacts()) { if (pair.hasContacts()) {
// Report the contacts to the user // Report the contacts to the user
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mPoolAllocator); CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mMemoryManager);
collisionCallback->notifyContact(collisionInfo); collisionCallback->notifyContact(collisionInfo);
} }
} }
@ -826,7 +832,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID); const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID);
// Ask the broad-phase to get all the overlapping shapes // Ask the broad-phase to get all the overlapping shapes
LinkedList<int> overlappingNodes(mPoolAllocator); LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes); mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes);
const bodyindex bodyId = body->getID(); const bodyindex bodyId = body->getID();
@ -846,7 +852,8 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) { if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
// Create a temporary overlapping pair // Create a temporary overlapping pair
OverlappingPair pair(bodyProxyShape, proxyShape, mPoolAllocator, mPoolAllocator); OverlappingPair pair(bodyProxyShape, proxyShape, mMemoryManager.getPoolAllocator(),
mMemoryManager.getPoolAllocator());
// Compute the middle-phase collision detection between the two shapes // Compute the middle-phase collision detection between the two shapes
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair); NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
@ -866,7 +873,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
// 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(narrowPhaseInfo, true, mPoolAllocator)) { if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
narrowPhaseInfo->addContactPointsAsPotentialContactManifold(); narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -880,7 +887,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
currentNarrowPhaseInfo->~NarrowPhaseInfo(); currentNarrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory // Release the allocated memory
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo)); mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
} }
// Process the potential contacts // Process the potential contacts
@ -889,7 +896,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
if (pair.hasContacts()) { if (pair.hasContacts()) {
// Report the contacts to the user // Report the contacts to the user
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mPoolAllocator); CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mMemoryManager);
callback->notifyContact(collisionInfo); callback->notifyContact(collisionInfo);
} }
} }
@ -920,8 +927,8 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
OverlappingPair* originalPair = it->second; OverlappingPair* originalPair = it->second;
// Create a new overlapping pair so that we do not work on the original one // Create a new overlapping pair so that we do not work on the original one
OverlappingPair pair(originalPair->getShape1(), originalPair->getShape2(), mPoolAllocator, OverlappingPair pair(originalPair->getShape1(), originalPair->getShape2(), mMemoryManager.getPoolAllocator(),
mPoolAllocator); mMemoryManager.getPoolAllocator());
ProxyShape* shape1 = pair.getShape1(); ProxyShape* shape1 = pair.getShape1();
ProxyShape* shape2 = pair.getShape2(); ProxyShape* shape2 = pair.getShape2();
@ -950,7 +957,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
// 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(narrowPhaseInfo, true, mPoolAllocator)) { if (narrowPhaseAlgorithm->testCollision(narrowPhaseInfo, true, mMemoryManager.getPoolAllocator())) {
// Add the contact points as a potential contact manifold into the pair // Add the contact points as a potential contact manifold into the pair
narrowPhaseInfo->addContactPointsAsPotentialContactManifold(); narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
@ -964,7 +971,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
currentNarrowPhaseInfo->~NarrowPhaseInfo(); currentNarrowPhaseInfo->~NarrowPhaseInfo();
// Release the allocated memory // Release the allocated memory
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo)); mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
} }
// Process the potential contacts // Process the potential contacts
@ -973,7 +980,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
if (pair.hasContacts()) { if (pair.hasContacts()) {
// Report the contacts to the user // Report the contacts to the user
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mPoolAllocator); CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mMemoryManager);
callback->notifyContact(collisionInfo); callback->notifyContact(collisionInfo);
} }
} }
@ -996,12 +1003,6 @@ EventListener* CollisionDetection::getWorldEventListener() {
return mWorld->mEventListener; return mWorld->mEventListener;
} }
// Return a reference to the world memory allocator
PoolAllocator& CollisionDetection::getWorldMemoryAllocator() {
return mWorld->mPoolAllocator;
}
// Return the world-space AABB of a given proxy shape // Return the world-space AABB of a given proxy shape
const AABB CollisionDetection::getWorldAABB(const ProxyShape* proxyShape) const { const AABB CollisionDetection::getWorldAABB(const ProxyShape* proxyShape) const {
assert(proxyShape->mBroadPhaseID > -1); assert(proxyShape->mBroadPhaseID > -1);

View File

@ -32,8 +32,7 @@
#include "engine/OverlappingPair.h" #include "engine/OverlappingPair.h"
#include "engine/EventListener.h" #include "engine/EventListener.h"
#include "narrowphase/DefaultCollisionDispatch.h" #include "narrowphase/DefaultCollisionDispatch.h"
#include "memory/PoolAllocator.h" #include "memory/MemoryManager.h"
#include "memory/SingleFrameAllocator.h"
#include "constraint/ContactPoint.h" #include "constraint/ContactPoint.h"
#include <vector> #include <vector>
#include <set> #include <set>
@ -62,6 +61,9 @@ class CollisionDetection {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Memory manager
MemoryManager& mMemoryManager;
/// Collision Detection Dispatch configuration /// Collision Detection Dispatch configuration
CollisionDispatch* mCollisionDispatch; CollisionDispatch* mCollisionDispatch;
@ -71,12 +73,6 @@ class CollisionDetection {
/// Collision detection matrix (algorithms to use) /// Collision detection matrix (algorithms to use)
NarrowPhaseAlgorithm* mCollisionMatrix[NB_COLLISION_SHAPE_TYPES][NB_COLLISION_SHAPE_TYPES]; NarrowPhaseAlgorithm* mCollisionMatrix[NB_COLLISION_SHAPE_TYPES][NB_COLLISION_SHAPE_TYPES];
/// Reference to the memory allocator
PoolAllocator& mPoolAllocator;
/// Reference to the single frame memory allocator
SingleFrameAllocator& mSingleFrameAllocator;
/// Pointer to the physics world /// Pointer to the physics world
CollisionWorld* mWorld; CollisionWorld* mWorld;
@ -133,7 +129,7 @@ class CollisionDetection {
void addAllContactManifoldsToBodies(); void addAllContactManifoldsToBodies();
/// 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, Allocator& allocator, void computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
NarrowPhaseInfo** firstNarrowPhaseInfo); NarrowPhaseInfo** firstNarrowPhaseInfo);
/// Compute the middle-phase collision detection between two proxy shapes /// Compute the middle-phase collision detection between two proxy shapes
@ -156,7 +152,7 @@ class CollisionDetection {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
CollisionDetection(CollisionWorld* world, PoolAllocator& memoryAllocator, SingleFrameAllocator& singleFrameAllocator); CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager);
/// Destructor /// Destructor
~CollisionDetection() = default; ~CollisionDetection() = default;
@ -223,9 +219,6 @@ class CollisionDetection {
/// Return the world event listener /// Return the world event listener
EventListener* getWorldEventListener(); EventListener* getWorldEventListener();
/// Return a reference to the world memory allocator
PoolAllocator& getWorldMemoryAllocator();
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Set the profiler /// Set the profiler

View File

@ -30,7 +30,7 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
ContactManifold::ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2, Allocator& memoryAllocator) ContactManifold::ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2, MemoryAllocator& memoryAllocator)
: mShape1(shape1), mShape2(shape2), mContactPoints(nullptr), : mShape1(shape1), mShape2(shape2), mContactPoints(nullptr),
mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0), mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false), mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),

View File

@ -129,7 +129,7 @@ class ContactManifold {
bool mIsAlreadyInIsland; bool mIsAlreadyInIsland;
/// Reference to the memory allocator /// Reference to the memory allocator
Allocator& mMemoryAllocator; MemoryAllocator& mMemoryAllocator;
/// Pointer to the next contact manifold in the linked-list /// Pointer to the next contact manifold in the linked-list
ContactManifold* mNext; ContactManifold* mNext;
@ -217,7 +217,7 @@ class ContactManifold {
/// Constructor /// Constructor
ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2, ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2,
Allocator& memoryAllocator); MemoryAllocator& memoryAllocator);
/// Destructor /// Destructor
~ContactManifold(); ~ContactManifold();

View File

@ -29,7 +29,7 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
ContactManifoldInfo::ContactManifoldInfo(Allocator& allocator) ContactManifoldInfo::ContactManifoldInfo(MemoryAllocator& allocator)
: mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator) { : mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator) {
} }

View File

@ -28,7 +28,7 @@
// Libraries // Libraries
#include "collision/ContactPointInfo.h" #include "collision/ContactPointInfo.h"
#include "memory/Allocator.h" #include "memory/MemoryAllocator.h"
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -57,14 +57,14 @@ class ContactManifoldInfo {
ContactManifoldInfo* mNext; ContactManifoldInfo* mNext;
/// Reference the the memory allocator where the contact point infos have been allocated /// Reference the the memory allocator where the contact point infos have been allocated
Allocator& mAllocator; MemoryAllocator& mAllocator;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ContactManifoldInfo(Allocator& allocator); ContactManifoldInfo(MemoryAllocator& allocator);
/// Destructor /// Destructor
~ContactManifoldInfo(); ~ContactManifoldInfo();

View File

@ -30,7 +30,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2, ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
Allocator& memoryAllocator) MemoryAllocator& memoryAllocator)
: mNbManifolds(0), mShape1(shape1), : mNbManifolds(0), mShape1(shape1),
mShape2(shape2), mMemoryAllocator(memoryAllocator), mManifolds(nullptr) { mShape2(shape2), mMemoryAllocator(memoryAllocator), mManifolds(nullptr) {

View File

@ -61,7 +61,7 @@ class ContactManifoldSet {
ProxyShape* mShape2; ProxyShape* mShape2;
/// Reference to the memory allocator for the contact manifolds /// Reference to the memory allocator for the contact manifolds
Allocator& mMemoryAllocator; MemoryAllocator& mMemoryAllocator;
/// Contact manifolds of the set /// Contact manifolds of the set
ContactManifold* mManifolds; ContactManifold* mManifolds;
@ -95,7 +95,7 @@ class ContactManifoldSet {
/// Constructor /// Constructor
ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2, ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
Allocator& memoryAllocator); MemoryAllocator& memoryAllocator);
/// Destructor /// Destructor
~ContactManifoldSet(); ~ContactManifoldSet();

View File

@ -54,7 +54,7 @@ class HalfEdgeStructure {
List<uint> faceVertices; // Index of the vertices of the face List<uint> faceVertices; // Index of the vertices of the face
/// Constructor /// Constructor
Face(Allocator& allocator) : faceVertices(allocator) {} Face(MemoryAllocator& allocator) : faceVertices(allocator) {}
/// Constructor /// Constructor
Face(List<uint> vertices) : faceVertices(vertices) {} Face(List<uint> vertices) : faceVertices(vertices) {}
@ -71,7 +71,7 @@ class HalfEdgeStructure {
private: private:
/// Reference to a memory allocator /// Reference to a memory allocator
Allocator& mAllocator; MemoryAllocator& mAllocator;
/// All the faces /// All the faces
List<Face> mFaces; List<Face> mFaces;
@ -85,7 +85,7 @@ class HalfEdgeStructure {
public: public:
/// Constructor /// Constructor
HalfEdgeStructure(Allocator& allocator, uint facesCapacity, uint verticesCapacity, HalfEdgeStructure(MemoryAllocator& allocator, uint facesCapacity, uint verticesCapacity,
uint edgesCapacity) :mAllocator(allocator), mFaces(allocator, facesCapacity), uint edgesCapacity) :mAllocator(allocator), mFaces(allocator, facesCapacity),
mVertices(allocator, verticesCapacity), mEdges(allocator, edgesCapacity) {} mVertices(allocator, verticesCapacity), mEdges(allocator, edgesCapacity) {}

View File

@ -56,7 +56,7 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
const ConcaveShape* mConcaveShape; const ConcaveShape* mConcaveShape;
/// Reference to the single-frame memory allocator /// Reference to the single-frame memory allocator
Allocator& mAllocator; MemoryAllocator& mAllocator;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -74,7 +74,7 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair, MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
ProxyShape* concaveProxyShape, ProxyShape* concaveProxyShape,
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape, ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
Allocator& allocator) MemoryAllocator& allocator)
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape), :mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape), mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
mAllocator(allocator), narrowPhaseInfoList(nullptr) { mAllocator(allocator), narrowPhaseInfoList(nullptr) {

View File

@ -35,7 +35,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
NarrowPhaseInfo::NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1, NarrowPhaseInfo::NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1,
CollisionShape* shape2, const Transform& shape1Transform, CollisionShape* shape2, const Transform& shape1Transform,
const Transform& shape2Transform, Allocator& 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), next(nullptr), collisionShapeAllocator(shapeAllocator) {
@ -68,7 +68,7 @@ void NarrowPhaseInfo::addContactPoint(const Vector3& contactNormal, decimal penD
assert(penDepth > decimal(0.0)); assert(penDepth > decimal(0.0));
// Get the memory allocator // Get the memory allocator
Allocator& allocator = overlappingPair->getTemporaryAllocator(); MemoryAllocator& allocator = overlappingPair->getTemporaryAllocator();
// Create the contact point info // Create the contact point info
ContactPointInfo* contactPointInfo = new (allocator.allocate(sizeof(ContactPointInfo))) ContactPointInfo* contactPointInfo = new (allocator.allocate(sizeof(ContactPointInfo)))
@ -89,7 +89,7 @@ void NarrowPhaseInfo::addContactPointsAsPotentialContactManifold() {
void NarrowPhaseInfo::resetContactPoints() { void NarrowPhaseInfo::resetContactPoints() {
// Get the memory allocator // Get the memory allocator
Allocator& allocator = overlappingPair->getTemporaryAllocator(); MemoryAllocator& allocator = overlappingPair->getTemporaryAllocator();
// For each remaining contact point info // For each remaining contact point info
ContactPointInfo* element = contactPoints; ContactPointInfo* element = contactPoints;

View File

@ -67,12 +67,12 @@ struct NarrowPhaseInfo {
NarrowPhaseInfo* next; 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)
Allocator& collisionShapeAllocator; MemoryAllocator& collisionShapeAllocator;
/// Constructor /// Constructor
NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1, NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1,
CollisionShape* shape2, const Transform& shape1Transform, CollisionShape* shape2, const Transform& shape1Transform,
const Transform& shape2Transform, Allocator& shapeAllocator); const Transform& shape2Transform, MemoryAllocator& shapeAllocator);
/// Destructor /// Destructor
~NarrowPhaseInfo(); ~NarrowPhaseInfo();

View File

@ -36,7 +36,7 @@ using namespace reactphysics3d;
* @param polygonVertexArray Pointer to the array of polygons and their vertices * @param polygonVertexArray Pointer to the array of polygons and their vertices
*/ */
PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray) PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray)
: mHalfEdgeStructure(MemoryManager::getDefaultAllocator(), : mHalfEdgeStructure(MemoryManager::getBaseAllocator(),
polygonVertexArray->getNbFaces(), polygonVertexArray->getNbFaces(),
polygonVertexArray->getNbVertices(), polygonVertexArray->getNbVertices(),
(polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2) { (polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2) {
@ -75,7 +75,7 @@ void PolyhedronMesh::createHalfEdgeStructure() {
// Get the polygon face // Get the polygon face
PolygonVertexArray::PolygonFace* face = mPolygonVertexArray->getPolygonFace(f); PolygonVertexArray::PolygonFace* face = mPolygonVertexArray->getPolygonFace(f);
List<uint> faceVertices(MemoryManager::getDefaultAllocator(), face->nbVertices); List<uint> faceVertices(MemoryManager::getBaseAllocator(), face->nbVertices);
// For each vertex of the face // For each vertex of the face
for (uint v=0; v < face->nbVertices; v++) { for (uint v=0; v < face->nbVertices; v++) {

View File

@ -35,9 +35,9 @@ using namespace reactphysics3d;
* @param transform Transformation from collision shape local-space to body local-space * @param transform Transformation from collision shape local-space to body local-space
* @param mass Mass of the collision shape (in kilograms) * @param mass Mass of the collision shape (in kilograms)
*/ */
ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, decimal mass, Allocator& allocator) ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, decimal mass, MemoryManager& memoryManager)
:mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass), :mMemoryManager(memoryManager), mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass),
mNext(nullptr), mBroadPhaseID(-1), mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF), mAllocator(allocator) { mNext(nullptr), mBroadPhaseID(-1), mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF) {
} }
@ -76,7 +76,7 @@ bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo) {
worldToLocalTransform * ray.point2, worldToLocalTransform * ray.point2,
ray.maxFraction); ray.maxFraction);
bool isHit = mCollisionShape->raycast(rayLocal, raycastInfo, this, mAllocator); bool isHit = mCollisionShape->raycast(rayLocal, raycastInfo, this, mMemoryManager.getPoolAllocator());
// Convert the raycast info into world-space // Convert the raycast info into world-space
raycastInfo.worldPoint = localToWorldTransform * raycastInfo.worldPoint; raycastInfo.worldPoint = localToWorldTransform * raycastInfo.worldPoint;

View File

@ -29,6 +29,7 @@
// Libraries // Libraries
#include "body/CollisionBody.h" #include "body/CollisionBody.h"
#include "shapes/CollisionShape.h" #include "shapes/CollisionShape.h"
#include "memory/MemoryManager.h"
namespace reactphysics3d { namespace reactphysics3d {
@ -48,6 +49,9 @@ class ProxyShape {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Reference to the memory manager
MemoryManager& mMemoryManager;
/// Pointer to the parent body /// Pointer to the parent body
CollisionBody* mBody; CollisionBody* mBody;
@ -82,9 +86,6 @@ class ProxyShape {
/// proxy shape will collide with every collision categories by default. /// proxy shape will collide with every collision categories by default.
unsigned short mCollideWithMaskBits; unsigned short mCollideWithMaskBits;
/// Memory allocator
Allocator& mAllocator;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
/// Pointer to the profiler /// Pointer to the profiler
@ -103,7 +104,7 @@ class ProxyShape {
/// Constructor /// Constructor
ProxyShape(CollisionBody* body, CollisionShape* shape, ProxyShape(CollisionBody* body, CollisionShape* shape,
const Transform& transform, decimal mass, Allocator& allocator); const Transform& transform, decimal mass, MemoryManager& memoryManager);
/// Destructor /// Destructor
virtual ~ProxyShape(); virtual ~ProxyShape();

View File

@ -185,14 +185,14 @@ void BroadPhaseAlgorithm::reportAllShapesOverlappingWithAABB(const AABB& aabb,
} }
// Compute all the overlapping pairs of collision shapes // Compute all the overlapping pairs of collision shapes
void BroadPhaseAlgorithm::computeOverlappingPairs(Allocator& allocator) { void BroadPhaseAlgorithm::computeOverlappingPairs(MemoryManager& memoryManager) {
// TODO : Try to see if we can allocate potential pairs in single frame allocator // TODO : Try to see if we can allocate potential pairs in single frame allocator
// Reset the potential overlapping pairs // Reset the potential overlapping pairs
mNbPotentialPairs = 0; mNbPotentialPairs = 0;
LinkedList<int> overlappingNodes(allocator); LinkedList<int> overlappingNodes(memoryManager.getPoolAllocator());
// For all collision shapes that have moved (or have been created) during the // For all collision shapes that have moved (or have been created) during the
// last simulation step // last simulation step

View File

@ -210,7 +210,7 @@ class BroadPhaseAlgorithm {
void reportAllShapesOverlappingWithAABB(const AABB& aabb, LinkedList<int>& overlappingNodes) const; void reportAllShapesOverlappingWithAABB(const AABB& aabb, LinkedList<int>& overlappingNodes) const;
/// Compute all the overlapping pairs of collision shapes /// Compute all the overlapping pairs of collision shapes
void computeOverlappingPairs(Allocator& allocator); void computeOverlappingPairs(MemoryManager& memoryManager);
/// Return the proxy shape corresponding to the broad-phase node id in parameter /// Return the proxy shape corresponding to the broad-phase node id in parameter
ProxyShape* getProxyShapeForBroadPhaseId(int broadPhaseId) const; ProxyShape* getProxyShapeForBroadPhaseId(int broadPhaseId) const;

View File

@ -34,7 +34,7 @@ using namespace reactphysics3d;
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) { MemoryAllocator& memoryAllocator) {
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE); assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE);
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CAPSULE); assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CAPSULE);

View File

@ -61,7 +61,7 @@ class CapsuleVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
CapsuleVsCapsuleAlgorithm& operator=(const CapsuleVsCapsuleAlgorithm& algorithm) = delete; CapsuleVsCapsuleAlgorithm& operator=(const CapsuleVsCapsuleAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between two capsules /// Compute the narrow-phase collision detection between two capsules
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
}; };
} }

View File

@ -38,7 +38,7 @@ using namespace reactphysics3d;
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) { MemoryAllocator& memoryAllocator) {
// First, we run the GJK algorithm // First, we run the GJK algorithm
GJKAlgorithm gjkAlgorithm; GJKAlgorithm gjkAlgorithm;

View File

@ -61,7 +61,7 @@ class CapsuleVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm {
CapsuleVsConvexPolyhedronAlgorithm& operator=(const CapsuleVsConvexPolyhedronAlgorithm& algorithm) = delete; CapsuleVsConvexPolyhedronAlgorithm& operator=(const CapsuleVsConvexPolyhedronAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between a capsule and a polyhedron /// Compute the narrow-phase collision detection between a capsule and a polyhedron
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
}; };
} }

View File

@ -35,7 +35,7 @@ using namespace reactphysics3d;
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool ConvexPolyhedronVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, bool ConvexPolyhedronVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) { MemoryAllocator& memoryAllocator) {
// Run the SAT algorithm to find the separating axis and compute contact point // Run the SAT algorithm to find the separating axis and compute contact point
SATAlgorithm satAlgorithm(memoryAllocator); SATAlgorithm satAlgorithm(memoryAllocator);

View File

@ -61,7 +61,7 @@ class ConvexPolyhedronVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm
ConvexPolyhedronVsConvexPolyhedronAlgorithm& operator=(const ConvexPolyhedronVsConvexPolyhedronAlgorithm& algorithm) = delete; ConvexPolyhedronVsConvexPolyhedronAlgorithm& operator=(const ConvexPolyhedronVsConvexPolyhedronAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between two convex polyhedra /// Compute the narrow-phase collision detection between two convex polyhedra
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
}; };
} }

View File

@ -92,7 +92,7 @@ class NarrowPhaseAlgorithm {
/// Compute a contact info if the two bounding volumes collide /// Compute a contact info if the two bounding volumes collide
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator)=0; MemoryAllocator& memoryAllocator)=0;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE

View File

@ -45,7 +45,7 @@ using namespace reactphysics3d;
const decimal SATAlgorithm::SAME_SEPARATING_AXIS_BIAS = decimal(0.001); const decimal SATAlgorithm::SAME_SEPARATING_AXIS_BIAS = decimal(0.001);
// Constructor // Constructor
SATAlgorithm::SATAlgorithm(Allocator& memoryAllocator) : mMemoryAllocator(memoryAllocator) { SATAlgorithm::SATAlgorithm(MemoryAllocator& memoryAllocator) : mMemoryAllocator(memoryAllocator) {
} }

View File

@ -51,7 +51,7 @@ class SATAlgorithm {
static const decimal SAME_SEPARATING_AXIS_BIAS; static const decimal SAME_SEPARATING_AXIS_BIAS;
/// Memory allocator /// Memory allocator
Allocator& mMemoryAllocator; MemoryAllocator& mMemoryAllocator;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -115,7 +115,7 @@ class SATAlgorithm {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
SATAlgorithm(Allocator& memoryAllocator); SATAlgorithm(MemoryAllocator& memoryAllocator);
/// Destructor /// Destructor
~SATAlgorithm() = default; ~SATAlgorithm() = default;

View File

@ -35,7 +35,7 @@ using namespace reactphysics3d;
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) { MemoryAllocator& memoryAllocator) {
bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE; bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE;

View File

@ -61,7 +61,7 @@ class SphereVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete; SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between a sphere and a capsule /// Compute the narrow-phase collision detection between a sphere and a capsule
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
}; };
} }

View File

@ -35,7 +35,7 @@ using namespace reactphysics3d;
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation // This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
// by Dirk Gregorius. // by Dirk Gregorius.
bool SphereVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, bool SphereVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) { MemoryAllocator& memoryAllocator) {
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON || assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON ||
narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON); narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON);

View File

@ -61,7 +61,7 @@ class SphereVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm {
SphereVsConvexPolyhedronAlgorithm& operator=(const SphereVsConvexPolyhedronAlgorithm& algorithm) = delete; SphereVsConvexPolyhedronAlgorithm& operator=(const SphereVsConvexPolyhedronAlgorithm& algorithm) = delete;
/// Compute the narrow-phase collision detection between a sphere and a convex polyhedron /// Compute the narrow-phase collision detection between a sphere and a convex polyhedron
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
}; };
} }

View File

@ -31,7 +31,7 @@
using namespace reactphysics3d; using namespace reactphysics3d;
bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
Allocator& memoryAllocator) { MemoryAllocator& memoryAllocator) {
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE); assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE);
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::SPHERE); assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::SPHERE);

View File

@ -61,7 +61,7 @@ class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm {
SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm) = delete; SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm) = delete;
/// Compute a contact info if the two bounding volume collide /// Compute a contact info if the two bounding volume collide
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override; virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
}; };
} }

View File

@ -39,7 +39,7 @@ using namespace reactphysics3d;
*/ */
BoxShape::BoxShape(const Vector3& extent) BoxShape::BoxShape(const Vector3& extent)
: ConvexPolyhedronShape(CollisionShapeName::BOX), mExtent(extent), : ConvexPolyhedronShape(CollisionShapeName::BOX), mExtent(extent),
mHalfEdgeStructure(MemoryManager::getDefaultAllocator(), 6, 8, 24) { mHalfEdgeStructure(MemoryManager::getBaseAllocator(), 6, 8, 24) {
assert(extent.x > decimal(0.0)); assert(extent.x > decimal(0.0));
assert(extent.y > decimal(0.0)); assert(extent.y > decimal(0.0));
@ -55,7 +55,7 @@ BoxShape::BoxShape(const Vector3& extent)
mHalfEdgeStructure.addVertex(6); mHalfEdgeStructure.addVertex(6);
mHalfEdgeStructure.addVertex(7); mHalfEdgeStructure.addVertex(7);
DefaultAllocator& allocator = MemoryManager::getDefaultAllocator(); MemoryAllocator& allocator = MemoryManager::getBaseAllocator();
// Faces // Faces
List<uint> face0(allocator, 4); List<uint> face0(allocator, 4);
@ -98,7 +98,7 @@ void BoxShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const
} }
// Raycast method with feedback information // Raycast method with feedback information
bool BoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool BoxShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
Vector3 rayDirection = ray.point2 - ray.point1; Vector3 rayDirection = ray.point2 - ray.point1;
decimal tMin = DECIMAL_SMALLEST; decimal tMin = DECIMAL_SMALLEST;

View File

@ -64,7 +64,7 @@ class BoxShape : public ConvexPolyhedronShape {
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override; virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const override; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const override; virtual size_t getSizeInBytes() const override;

View File

@ -85,7 +85,7 @@ bool CapsuleShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyS
} }
// Raycast method with feedback information // Raycast method with feedback information
bool CapsuleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool CapsuleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
const Vector3 n = ray.point2 - ray.point1; const Vector3 n = ray.point2 - ray.point1;

View File

@ -62,7 +62,7 @@ class CapsuleShape : public ConvexShape {
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override; virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const override; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override;
/// Raycasting method between a ray one of the two spheres end cap of the capsule /// Raycasting method between a ray one of the two spheres end cap of the capsule
bool raycastWithSphereEndCap(const Vector3& point1, const Vector3& point2, bool raycastWithSphereEndCap(const Vector3& point1, const Vector3& point2,

View File

@ -87,7 +87,7 @@ class CollisionShape {
virtual bool testPointInside(const Vector3& worldPoint, ProxyShape* proxyShape) const=0; virtual bool testPointInside(const Vector3& worldPoint, ProxyShape* proxyShape) const=0;
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const=0; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const=0;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const = 0; virtual size_t getSizeInBytes() const = 0;

View File

@ -111,7 +111,7 @@ void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB&
// Raycast method with feedback information // Raycast method with feedback information
/// Note that only the first triangle hit by the ray in the mesh will be returned, even if /// Note that only the first triangle hit by the ray in the mesh will be returned, even if
/// the ray hits many triangles. /// the ray hits many triangles.
bool ConcaveMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool ConcaveMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
PROFILE("ConcaveMeshShape::raycast()", mProfiler); PROFILE("ConcaveMeshShape::raycast()", mProfiler);

View File

@ -77,7 +77,7 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
RaycastInfo& mRaycastInfo; RaycastInfo& mRaycastInfo;
const Ray& mRay; const Ray& mRay;
bool mIsHit; bool mIsHit;
Allocator& mAllocator; MemoryAllocator& mAllocator;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -90,7 +90,7 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
// Constructor // Constructor
ConcaveMeshRaycastCallback(const DynamicAABBTree& dynamicAABBTree, const ConcaveMeshShape& concaveMeshShape, ConcaveMeshRaycastCallback(const DynamicAABBTree& dynamicAABBTree, const ConcaveMeshShape& concaveMeshShape,
ProxyShape* proxyShape, RaycastInfo& raycastInfo, const Ray& ray, Allocator& allocator) ProxyShape* proxyShape, RaycastInfo& raycastInfo, const Ray& ray, MemoryAllocator& allocator)
: mDynamicAABBTree(dynamicAABBTree), mConcaveMeshShape(concaveMeshShape), mProxyShape(proxyShape), : mDynamicAABBTree(dynamicAABBTree), mConcaveMeshShape(concaveMeshShape), mProxyShape(proxyShape),
mRaycastInfo(raycastInfo), mRay(ray), mIsHit(false), mAllocator(allocator) { mRaycastInfo(raycastInfo), mRay(ray), mIsHit(false), mAllocator(allocator) {
@ -142,7 +142,7 @@ class ConcaveMeshShape : public ConcaveShape {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const override; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const override; virtual size_t getSizeInBytes() const override;

View File

@ -112,7 +112,7 @@ void ConvexMeshShape::recalculateBounds() {
} }
// Raycast method with feedback information // Raycast method with feedback information
bool ConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool ConvexMeshShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
return proxyShape->mBody->mWorld.mCollisionDetection.mNarrowPhaseGJKAlgorithm.raycast( return proxyShape->mBody->mWorld.mCollisionDetection.mNarrowPhaseGJKAlgorithm.raycast(
ray, proxyShape, raycastInfo); ray, proxyShape, raycastInfo);
} }

View File

@ -77,7 +77,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override; virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const override; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const override; virtual size_t getSizeInBytes() const override;

View File

@ -212,7 +212,7 @@ void HeightFieldShape::computeMinMaxGridCoordinates(int* minCoords, int* maxCoor
// Raycast method with feedback information // Raycast method with feedback information
/// Note that only the first triangle hit by the ray in the mesh will be returned, even if /// Note that only the first triangle hit by the ray in the mesh will be returned, even if
/// the ray hits many triangles. /// the ray hits many triangles.
bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool HeightFieldShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
// TODO : Implement raycasting without using an AABB for the ray // TODO : Implement raycasting without using an AABB for the ray
// but using a dynamic AABB tree or octree instead // but using a dynamic AABB tree or octree instead

View File

@ -49,7 +49,7 @@ class TriangleOverlapCallback : public TriangleCallback {
bool mIsHit; bool mIsHit;
decimal mSmallestHitFraction; decimal mSmallestHitFraction;
const HeightFieldShape& mHeightFieldShape; const HeightFieldShape& mHeightFieldShape;
Allocator& mAllocator; MemoryAllocator& mAllocator;
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -62,7 +62,7 @@ class TriangleOverlapCallback : public TriangleCallback {
// Constructor // Constructor
TriangleOverlapCallback(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo, TriangleOverlapCallback(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo,
const HeightFieldShape& heightFieldShape, Allocator& allocator) const HeightFieldShape& heightFieldShape, MemoryAllocator& allocator)
: mRay(ray), mProxyShape(proxyShape), mRaycastInfo(raycastInfo), : mRay(ray), mProxyShape(proxyShape), mRaycastInfo(raycastInfo),
mHeightFieldShape (heightFieldShape), mAllocator(allocator) { mHeightFieldShape (heightFieldShape), mAllocator(allocator) {
mIsHit = false; mIsHit = false;
@ -144,7 +144,7 @@ class HeightFieldShape : public ConcaveShape {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const override; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const override; virtual size_t getSizeInBytes() const override;

View File

@ -41,7 +41,7 @@ SphereShape::SphereShape(decimal radius)
} }
// Raycast method with feedback information // Raycast method with feedback information
bool SphereShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool SphereShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
const Vector3 m = ray.point1; const Vector3 m = ray.point1;
decimal c = m.dot(m) - mMargin * mMargin; decimal c = m.dot(m) - mMargin * mMargin;

View File

@ -55,7 +55,7 @@ class SphereShape : public ConvexShape {
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override; virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const override; virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const override;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const override; virtual size_t getSizeInBytes() const override;

View File

@ -45,7 +45,7 @@ using namespace reactphysics3d;
* @param margin The collision margin (in meters) around the collision shape * @param margin The collision margin (in meters) around the collision shape
*/ */
TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId, TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId,
Allocator& allocator) MemoryAllocator& allocator)
: ConvexPolyhedronShape(CollisionShapeName::TRIANGLE), mFaces{HalfEdgeStructure::Face(allocator), HalfEdgeStructure::Face(allocator)} { : ConvexPolyhedronShape(CollisionShapeName::TRIANGLE), mFaces{HalfEdgeStructure::Face(allocator), HalfEdgeStructure::Face(allocator)} {
mPoints[0] = vertices[0]; mPoints[0] = vertices[0];
@ -211,7 +211,7 @@ Vector3 TriangleShape::computeSmoothLocalContactNormalForTriangle(const Vector3&
// Raycast method with feedback information // Raycast method with feedback information
/// This method use the line vs triangle raycasting technique described in /// This method use the line vs triangle raycasting technique described in
/// Real-time Collision Detection by Christer Ericson. /// Real-time Collision Detection by Christer Ericson.
bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, Allocator& allocator) const { bool TriangleShape::raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, MemoryAllocator& allocator) const {
PROFILE("TriangleShape::raycast()", mProfiler); PROFILE("TriangleShape::raycast()", mProfiler);

View File

@ -92,7 +92,7 @@ class TriangleShape : public ConvexPolyhedronShape {
/// Raycast method with feedback information /// Raycast method with feedback information
virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape, virtual bool raycast(const Ray& ray, RaycastInfo& raycastInfo, ProxyShape* proxyShape,
Allocator& allocator) const override; MemoryAllocator& allocator) const override;
/// Return the number of bytes used by the collision shape /// Return the number of bytes used by the collision shape
virtual size_t getSizeInBytes() const override; virtual size_t getSizeInBytes() const override;
@ -113,7 +113,7 @@ class TriangleShape : public ConvexPolyhedronShape {
/// Constructor /// Constructor
TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, TriangleShape(const Vector3* vertices, const Vector3* verticesNormals,
uint shapeId, Allocator& allocator); uint shapeId, MemoryAllocator& allocator);
/// Destructor /// Destructor
virtual ~TriangleShape() override = default; virtual ~TriangleShape() override = default;

View File

@ -152,7 +152,7 @@ constexpr int NB_MAX_CONTACT_MANIFOLDS_CONCAVE_SHAPE = 3;
constexpr decimal COS_ANGLE_SIMILAR_CONTACT_MANIFOLD = decimal(0.95); constexpr decimal COS_ANGLE_SIMILAR_CONTACT_MANIFOLD = decimal(0.95);
/// Size (in bytes) of the single frame allocator /// Size (in bytes) of the single frame allocator
constexpr size_t SIZE_SINGLE_FRAME_ALLOCATOR_BYTES = 15728640; // 15 Mb constexpr size_t INIT_SINGLE_FRAME_ALLOCATOR_BYTES = 1048576; // 1Mb
} }

View File

@ -27,7 +27,7 @@
#define REACTPHYSICS3D_LINKED_LIST_H #define REACTPHYSICS3D_LINKED_LIST_H
// Libraries // Libraries
#include "memory/Allocator.h" #include "memory/MemoryAllocator.h"
namespace reactphysics3d { namespace reactphysics3d {
@ -64,14 +64,14 @@ class LinkedList {
ListElement* mListHead; ListElement* mListHead;
/// Memory allocator used to allocate the list elements /// Memory allocator used to allocate the list elements
Allocator& mAllocator; MemoryAllocator& mAllocator;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
LinkedList(Allocator& allocator) : mListHead(nullptr), mAllocator(allocator) { LinkedList(MemoryAllocator& allocator) : mListHead(nullptr), mAllocator(allocator) {
} }

View File

@ -28,7 +28,7 @@
// Libraries // Libraries
#include "configuration.h" #include "configuration.h"
#include "memory/Allocator.h" #include "memory/MemoryAllocator.h"
#include <cstring> #include <cstring>
namespace reactphysics3d { namespace reactphysics3d {
@ -54,7 +54,7 @@ class List {
size_t mCapacity; size_t mCapacity;
/// Memory allocator /// Memory allocator
Allocator& mAllocator; MemoryAllocator& mAllocator;
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
@ -64,7 +64,7 @@ class List {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
List(Allocator& allocator, size_t capacity = 0) List(MemoryAllocator& allocator, size_t capacity = 0)
: mBuffer(nullptr), mSize(0), mCapacity(0), mAllocator(allocator) { : mBuffer(nullptr), mSize(0), mCapacity(0), mAllocator(allocator) {
if (capacity > 0) { if (capacity > 0) {

View File

@ -33,8 +33,7 @@ using namespace std;
// Constructor // Constructor
CollisionWorld::CollisionWorld() CollisionWorld::CollisionWorld()
: mSingleFrameAllocator(SIZE_SINGLE_FRAME_ALLOCATOR_BYTES), : mCollisionDetection(this, mMemoryManager), mCurrentBodyID(0),
mCollisionDetection(this, mPoolAllocator, mSingleFrameAllocator), mCurrentBodyID(0),
mEventListener(nullptr) { mEventListener(nullptr) {
#ifdef IS_PROFILING_ACTIVE #ifdef IS_PROFILING_ACTIVE
@ -74,7 +73,8 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max()); assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
// Create the collision body // Create the collision body
CollisionBody* collisionBody = new (mPoolAllocator.allocate(sizeof(CollisionBody))) CollisionBody* collisionBody = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(CollisionBody)))
CollisionBody(transform, *this, bodyID); CollisionBody(transform, *this, bodyID);
assert(collisionBody != nullptr); assert(collisionBody != nullptr);
@ -111,7 +111,7 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
mBodies.erase(collisionBody); mBodies.erase(collisionBody);
// Free the object from the memory allocator // Free the object from the memory allocator
mPoolAllocator.release(collisionBody, sizeof(CollisionBody)); mMemoryManager.release(MemoryManager::AllocationType::Pool, collisionBody, sizeof(CollisionBody));
} }
// Return the next available body ID // Return the next available body ID

View File

@ -39,8 +39,7 @@
#include "collision/CollisionDetection.h" #include "collision/CollisionDetection.h"
#include "constraint/Joint.h" #include "constraint/Joint.h"
#include "constraint/ContactPoint.h" #include "constraint/ContactPoint.h"
#include "memory/DefaultAllocator.h" #include "memory/MemoryManager.h"
#include "memory/PoolAllocator.h"
#include "EventListener.h" #include "EventListener.h"
/// Namespace reactphysics3d /// Namespace reactphysics3d
@ -62,11 +61,8 @@ class CollisionWorld {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Pool Memory allocator /// Memory manager
PoolAllocator mPoolAllocator; MemoryManager mMemoryManager;
/// Single frame Memory allocator
SingleFrameAllocator mSingleFrameAllocator;
/// Reference to the collision detection /// Reference to the collision detection
CollisionDetection mCollisionDetection; CollisionDetection mCollisionDetection;

View File

@ -39,9 +39,9 @@ const decimal ContactSolver::BETA_SPLIT_IMPULSE = decimal(0.2);
const decimal ContactSolver::SLOP = decimal(0.01); const decimal ContactSolver::SLOP = decimal(0.01);
// Constructor // Constructor
ContactSolver::ContactSolver(SingleFrameAllocator& allocator) ContactSolver::ContactSolver(MemoryManager& memoryManager)
:mSplitLinearVelocities(nullptr), mSplitAngularVelocities(nullptr), :mMemoryManager(memoryManager), mSplitLinearVelocities(nullptr),
mContactConstraints(nullptr), mSingleFrameAllocator(allocator), mSplitAngularVelocities(nullptr), mContactConstraints(nullptr),
mLinearVelocities(nullptr), mAngularVelocities(nullptr), mLinearVelocities(nullptr), mAngularVelocities(nullptr),
mIsSplitImpulseActive(true) { mIsSplitImpulseActive(true) {
@ -75,10 +75,12 @@ void ContactSolver::init(Island** islands, uint nbIslands, decimal timeStep) {
if (nbContactManifolds == 0 || nbContactPoints == 0) return; if (nbContactManifolds == 0 || nbContactPoints == 0) return;
// TODO : Count exactly the number of constraints to allocate here // TODO : Count exactly the number of constraints to allocate here
mContactPoints = static_cast<ContactPointSolver*>(mSingleFrameAllocator.allocate(sizeof(ContactPointSolver) * nbContactPoints)); mContactPoints = static_cast<ContactPointSolver*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
sizeof(ContactPointSolver) * nbContactPoints));
assert(mContactPoints != nullptr); assert(mContactPoints != nullptr);
mContactConstraints = static_cast<ContactManifoldSolver*>(mSingleFrameAllocator.allocate(sizeof(ContactManifoldSolver) * nbContactManifolds)); mContactConstraints = static_cast<ContactManifoldSolver*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
sizeof(ContactManifoldSolver) * nbContactManifolds));
assert(mContactConstraints != nullptr); assert(mContactConstraints != nullptr);
// For each island of the world // For each island of the world

View File

@ -272,6 +272,10 @@ class ContactSolver {
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Memory manager
MemoryManager& mMemoryManager;
/// Split linear velocities for the position contact solver (split impulse) /// Split linear velocities for the position contact solver (split impulse)
Vector3* mSplitLinearVelocities; Vector3* mSplitLinearVelocities;
@ -293,9 +297,6 @@ class ContactSolver {
/// Number of contact constraints /// Number of contact constraints
uint mNbContactManifolds; uint mNbContactManifolds;
/// Single frame memory allocator
SingleFrameAllocator& mSingleFrameAllocator;
/// Array of linear velocities /// Array of linear velocities
Vector3* mLinearVelocities; Vector3* mLinearVelocities;
@ -339,7 +340,7 @@ class ContactSolver {
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
ContactSolver(SingleFrameAllocator& allocator); ContactSolver(MemoryManager& memoryManager);
/// Destructor /// Destructor
~ContactSolver() = default; ~ContactSolver() = default;

View File

@ -41,7 +41,7 @@ using namespace std;
*/ */
DynamicsWorld::DynamicsWorld(const Vector3 &gravity) DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
: CollisionWorld(), : CollisionWorld(),
mContactSolver(mSingleFrameAllocator), mContactSolver(mMemoryManager),
mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS), mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS), mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
mIsSleepingEnabled(SLEEPING_ENABLED), mGravity(gravity), mTimeStep(decimal(1.0f / 60.0f)), mIsSleepingEnabled(SLEEPING_ENABLED), mGravity(gravity), mTimeStep(decimal(1.0f / 60.0f)),
@ -147,7 +147,7 @@ void DynamicsWorld::update(decimal timeStep) {
resetBodiesForceAndTorque(); resetBodiesForceAndTorque();
// Reset the single frame memory allocator // Reset the single frame memory allocator
mSingleFrameAllocator.reset(); mMemoryManager.resetFrameAllocator();
} }
// Integrate position and orientation of the rigid bodies. // Integrate position and orientation of the rigid bodies.
@ -236,12 +236,18 @@ void DynamicsWorld::initVelocityArrays() {
// Allocate memory for the bodies velocity arrays // Allocate memory for the bodies velocity arrays
uint nbBodies = mRigidBodies.size(); uint nbBodies = mRigidBodies.size();
mSplitLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3))); mSplitLinearVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
mSplitAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3))); nbBodies * sizeof(Vector3)));
mConstrainedLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3))); mSplitAngularVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
mConstrainedAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3))); nbBodies * sizeof(Vector3)));
mConstrainedPositions = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3))); mConstrainedLinearVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
mConstrainedOrientations = static_cast<Quaternion*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Quaternion))); nbBodies * sizeof(Vector3)));
mConstrainedAngularVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
nbBodies * sizeof(Vector3)));
mConstrainedPositions = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
nbBodies * sizeof(Vector3)));
mConstrainedOrientations = static_cast<Quaternion*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
nbBodies * sizeof(Quaternion)));
assert(mSplitLinearVelocities != nullptr); assert(mSplitLinearVelocities != nullptr);
assert(mSplitAngularVelocities != nullptr); assert(mSplitAngularVelocities != nullptr);
assert(mConstrainedLinearVelocities != nullptr); assert(mConstrainedLinearVelocities != nullptr);
@ -412,8 +418,8 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max()); assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
// Create the rigid body // Create the rigid body
RigidBody* rigidBody = new (mPoolAllocator.allocate(sizeof(RigidBody))) RigidBody(transform, RigidBody* rigidBody = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
*this, bodyID); sizeof(RigidBody))) RigidBody(transform, *this, bodyID);
assert(rigidBody != nullptr); assert(rigidBody != nullptr);
// Add the rigid body to the physics world // Add the rigid body to the physics world
@ -459,7 +465,7 @@ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
mRigidBodies.erase(rigidBody); mRigidBodies.erase(rigidBody);
// Free the object from the memory allocator // Free the object from the memory allocator
mPoolAllocator.release(rigidBody, sizeof(RigidBody)); mMemoryManager.release(MemoryManager::AllocationType::Pool, rigidBody, sizeof(RigidBody));
} }
// Create a joint between two bodies in the world and return a pointer to the new joint // Create a joint between two bodies in the world and return a pointer to the new joint
@ -477,7 +483,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
// Ball-and-Socket joint // Ball-and-Socket joint
case JointType::BALLSOCKETJOINT: case JointType::BALLSOCKETJOINT:
{ {
void* allocatedMemory = mPoolAllocator.allocate(sizeof(BallAndSocketJoint)); void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(BallAndSocketJoint));
const BallAndSocketJointInfo& info = static_cast<const BallAndSocketJointInfo&>( const BallAndSocketJointInfo& info = static_cast<const BallAndSocketJointInfo&>(
jointInfo); jointInfo);
newJoint = new (allocatedMemory) BallAndSocketJoint(info); newJoint = new (allocatedMemory) BallAndSocketJoint(info);
@ -487,7 +494,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
// Slider joint // Slider joint
case JointType::SLIDERJOINT: case JointType::SLIDERJOINT:
{ {
void* allocatedMemory = mPoolAllocator.allocate(sizeof(SliderJoint)); void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(SliderJoint));
const SliderJointInfo& info = static_cast<const SliderJointInfo&>(jointInfo); const SliderJointInfo& info = static_cast<const SliderJointInfo&>(jointInfo);
newJoint = new (allocatedMemory) SliderJoint(info); newJoint = new (allocatedMemory) SliderJoint(info);
break; break;
@ -496,7 +504,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
// Hinge joint // Hinge joint
case JointType::HINGEJOINT: case JointType::HINGEJOINT:
{ {
void* allocatedMemory = mPoolAllocator.allocate(sizeof(HingeJoint)); void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(HingeJoint));
const HingeJointInfo& info = static_cast<const HingeJointInfo&>(jointInfo); const HingeJointInfo& info = static_cast<const HingeJointInfo&>(jointInfo);
newJoint = new (allocatedMemory) HingeJoint(info); newJoint = new (allocatedMemory) HingeJoint(info);
break; break;
@ -505,7 +514,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
// Fixed joint // Fixed joint
case JointType::FIXEDJOINT: case JointType::FIXEDJOINT:
{ {
void* allocatedMemory = mPoolAllocator.allocate(sizeof(FixedJoint)); void* allocatedMemory = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(FixedJoint));
const FixedJointInfo& info = static_cast<const FixedJointInfo&>(jointInfo); const FixedJointInfo& info = static_cast<const FixedJointInfo&>(jointInfo);
newJoint = new (allocatedMemory) FixedJoint(info); newJoint = new (allocatedMemory) FixedJoint(info);
break; break;
@ -558,8 +568,8 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
mJoints.erase(joint); mJoints.erase(joint);
// Remove the joint from the joint list of the bodies involved in the joint // Remove the joint from the joint list of the bodies involved in the joint
joint->mBody1->removeJointFromJointsList(mPoolAllocator, joint); joint->mBody1->removeJointFromJointsList(mMemoryManager, joint);
joint->mBody2->removeJointFromJointsList(mPoolAllocator, joint); joint->mBody2->removeJointFromJointsList(mMemoryManager, joint);
size_t nbBytes = joint->getSizeInBytes(); size_t nbBytes = joint->getSizeInBytes();
@ -567,7 +577,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
joint->~Joint(); joint->~Joint();
// Release the allocated memory // Release the allocated memory
mPoolAllocator.release(joint, nbBytes); mMemoryManager.release(MemoryManager::AllocationType::Pool, joint, nbBytes);
} }
// Add the joint to the list of joints of the two bodies involved in the joint // Add the joint to the list of joints of the two bodies involved in the joint
@ -576,13 +586,15 @@ void DynamicsWorld::addJointToBody(Joint* joint) {
assert(joint != nullptr); assert(joint != nullptr);
// Add the joint at the beginning of the linked list of joints of the first body // Add the joint at the beginning of the linked list of joints of the first body
void* allocatedMemory1 = mPoolAllocator.allocate(sizeof(JointListElement)); void* allocatedMemory1 = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(JointListElement));
JointListElement* jointListElement1 = new (allocatedMemory1) JointListElement(joint, JointListElement* jointListElement1 = new (allocatedMemory1) JointListElement(joint,
joint->mBody1->mJointsList); joint->mBody1->mJointsList);
joint->mBody1->mJointsList = jointListElement1; joint->mBody1->mJointsList = jointListElement1;
// Add the joint at the beginning of the linked list of joints of the second body // Add the joint at the beginning of the linked list of joints of the second body
void* allocatedMemory2 = mPoolAllocator.allocate(sizeof(JointListElement)); void* allocatedMemory2 = mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
sizeof(JointListElement));
JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint, JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint,
joint->mBody2->mJointsList); joint->mBody2->mJointsList);
joint->mBody2->mJointsList = jointListElement2; joint->mBody2->mJointsList = jointListElement2;
@ -603,7 +615,8 @@ void DynamicsWorld::computeIslands() {
// Allocate and create the array of islands pointer. This memory is allocated // Allocate and create the array of islands pointer. This memory is allocated
// in the single frame allocator // in the single frame allocator
mIslands = static_cast<Island**>(mSingleFrameAllocator.allocate(sizeof(Island*) * nbBodies)); mIslands = static_cast<Island**>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
sizeof(Island*) * nbBodies));
mNbIslands = 0; mNbIslands = 0;
int nbContactManifolds = 0; int nbContactManifolds = 0;
@ -619,7 +632,8 @@ void DynamicsWorld::computeIslands() {
// Create a stack (using an array) for the rigid bodies to visit during the Depth First Search // Create a stack (using an array) for the rigid bodies to visit during the Depth First Search
size_t nbBytesStack = sizeof(RigidBody*) * nbBodies; size_t nbBytesStack = sizeof(RigidBody*) * nbBodies;
RigidBody** stackBodiesToVisit = static_cast<RigidBody**>(mSingleFrameAllocator.allocate(nbBytesStack)); RigidBody** stackBodiesToVisit = static_cast<RigidBody**>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
nbBytesStack));
// For each rigid body of the world // For each rigid body of the world
for (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) { for (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) {
@ -642,9 +656,10 @@ void DynamicsWorld::computeIslands() {
body->mIsAlreadyInIsland = true; body->mIsAlreadyInIsland = true;
// Create the new island // Create the new island
void* allocatedMemoryIsland = mSingleFrameAllocator.allocate(sizeof(Island)); void* allocatedMemoryIsland = mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
sizeof(Island));
mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies, nbContactManifolds, mJoints.size(), mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies, nbContactManifolds, mJoints.size(),
mSingleFrameAllocator); mMemoryManager);
// While there are still some bodies to visit in the stack // While there are still some bodies to visit in the stack
while (stackIndex > 0) { while (stackIndex > 0) {

View File

@ -29,14 +29,17 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
Island::Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, SingleFrameAllocator& allocator) Island::Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, MemoryManager& memoryManager)
: mBodies(nullptr), mContactManifolds(nullptr), mJoints(nullptr), mNbBodies(0), : mBodies(nullptr), mContactManifolds(nullptr), mJoints(nullptr), mNbBodies(0),
mNbContactManifolds(0), mNbJoints(0) { mNbContactManifolds(0), mNbJoints(0) {
// Allocate memory for the arrays on the single frame allocator // Allocate memory for the arrays on the single frame allocator
mBodies = static_cast<RigidBody**>(allocator.allocate(sizeof(RigidBody*) * nbMaxBodies)); mBodies = static_cast<RigidBody**>(memoryManager.allocate(MemoryManager::AllocationType::Frame,
mContactManifolds = static_cast<ContactManifold**>(allocator.allocate(sizeof(ContactManifold*) * nbMaxContactManifolds)); sizeof(RigidBody*) * nbMaxBodies));
mJoints = static_cast<Joint**>(allocator.allocate(sizeof(Joint*) * nbMaxJoints)); mContactManifolds = static_cast<ContactManifold**>(memoryManager.allocate(MemoryManager::AllocationType::Frame,
sizeof(ContactManifold*) * nbMaxContactManifolds));
mJoints = static_cast<Joint**>(memoryManager.allocate(MemoryManager::AllocationType::Frame,
sizeof(Joint*) * nbMaxJoints));
} }
// Destructor // Destructor

View File

@ -69,7 +69,7 @@ class Island {
/// Constructor /// Constructor
Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
SingleFrameAllocator& allocator); MemoryManager& memoryManager);
/// Destructor /// Destructor
~Island(); ~Island();

View File

@ -33,7 +33,7 @@ using namespace reactphysics3d;
// Constructor // Constructor
OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
Allocator& persistentMemoryAllocator, Allocator& temporaryMemoryAllocator) MemoryAllocator& persistentMemoryAllocator, MemoryAllocator& temporaryMemoryAllocator)
: mContactManifoldSet(shape1, shape2, persistentMemoryAllocator), mPotentialContactManifolds(nullptr), : mContactManifoldSet(shape1, shape2, persistentMemoryAllocator), mPotentialContactManifolds(nullptr),
mPersistentAllocator(persistentMemoryAllocator), mTempMemoryAllocator(temporaryMemoryAllocator) { mPersistentAllocator(persistentMemoryAllocator), mTempMemoryAllocator(temporaryMemoryAllocator) {

View File

@ -113,18 +113,18 @@ class OverlappingPair {
ContactManifoldInfo* mPotentialContactManifolds; ContactManifoldInfo* mPotentialContactManifolds;
/// Persistent memory allocator /// Persistent memory allocator
Allocator& mPersistentAllocator; MemoryAllocator& mPersistentAllocator;
/// Memory allocator used to allocated memory for the ContactManifoldInfo and ContactPointInfo /// Memory allocator used to allocated memory for the ContactManifoldInfo and ContactPointInfo
Allocator& mTempMemoryAllocator; MemoryAllocator& mTempMemoryAllocator;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, Allocator& persistentMemoryAllocator, OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, MemoryAllocator& persistentMemoryAllocator,
Allocator& temporaryMemoryAllocator); MemoryAllocator& temporaryMemoryAllocator);
/// Destructor /// Destructor
~OverlappingPair(); ~OverlappingPair();
@ -157,7 +157,7 @@ class OverlappingPair {
void addContactManifold(const ContactManifoldInfo* contactManifoldInfo); void addContactManifold(const ContactManifoldInfo* contactManifoldInfo);
/// Return a reference to the temporary memory allocator /// Return a reference to the temporary memory allocator
Allocator& getTemporaryAllocator(); MemoryAllocator& getTemporaryAllocator();
/// Return true if one of the shapes of the pair is a concave shape /// Return true if one of the shapes of the pair is a concave shape
bool hasConcaveShape() const; bool hasConcaveShape() const;
@ -264,7 +264,7 @@ inline bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* body
} }
// Return a reference to the temporary memory allocator // Return a reference to the temporary memory allocator
inline Allocator& OverlappingPair::getTemporaryAllocator() { inline MemoryAllocator& OverlappingPair::getTemporaryAllocator() {
return mTempMemoryAllocator; return mTempMemoryAllocator;
} }

View File

@ -225,7 +225,7 @@ decimal reactphysics3d::computePointToLineDistance(const Vector3& linePointA, co
List<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB, List<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB,
const List<Vector3>& planesPoints, const List<Vector3>& planesPoints,
const List<Vector3>& planesNormals, const List<Vector3>& planesNormals,
Allocator& allocator) { MemoryAllocator& allocator) {
assert(planesPoints.size() == planesNormals.size()); assert(planesPoints.size() == planesNormals.size());
@ -303,7 +303,7 @@ List<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA, const V
// Clip a polygon against multiple planes and return the clipped polygon vertices // Clip a polygon against multiple planes and return the clipped polygon vertices
// This method implements the SutherlandHodgman clipping algorithm // This method implements the SutherlandHodgman clipping algorithm
List<Vector3> reactphysics3d::clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints, List<Vector3> reactphysics3d::clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints,
const List<Vector3>& planesNormals, Allocator& allocator) { const List<Vector3>& planesNormals, MemoryAllocator& allocator) {
assert(planesPoints.size() == planesNormals.size()); assert(planesPoints.size() == planesNormals.size());

View File

@ -115,11 +115,11 @@ decimal computePointToLineDistance(const Vector3& linePointA, const Vector3& lin
List<Vector3> clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB, List<Vector3> clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB,
const List<Vector3>& planesPoints, const List<Vector3>& planesPoints,
const List<Vector3>& planesNormals, const List<Vector3>& planesNormals,
Allocator& allocator); MemoryAllocator& allocator);
/// Clip a polygon against multiple planes and return the clipped polygon vertices /// Clip a polygon against multiple planes and return the clipped polygon vertices
List<Vector3> clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints, List<Vector3> clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints,
const List<Vector3>& planesNormals, Allocator& allocator); const List<Vector3>& planesNormals, MemoryAllocator& allocator);
/// Project a point onto a plane that is given by a point and its unit length normal /// Project a point onto a plane that is given by a point and its unit length normal
Vector3 projectPointOntoPlane(const Vector3& point, const Vector3& planeNormal, const Vector3& planePoint); Vector3 projectPointOntoPlane(const Vector3& point, const Vector3& planeNormal, const Vector3& planePoint);

View File

@ -27,7 +27,7 @@
#define REACTPHYSICS3D_DEFAULT_ALLOCATOR_H #define REACTPHYSICS3D_DEFAULT_ALLOCATOR_H
// Libraries // Libraries
#include "memory/Allocator.h" #include "memory/MemoryAllocator.h"
#include <cstdlib> #include <cstdlib>
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
@ -37,13 +37,16 @@ namespace reactphysics3d {
/** /**
* This class represents a default memory allocator that uses default malloc/free methods * This class represents a default memory allocator that uses default malloc/free methods
*/ */
class DefaultAllocator : public Allocator { class DefaultAllocator : public MemoryAllocator {
public: public:
/// Destructor /// Destructor
virtual ~DefaultAllocator() = default; virtual ~DefaultAllocator() = default;
/// Assignment operator
DefaultAllocator& operator=(DefaultAllocator& allocator) = default;
/// Allocate memory of a given size (in bytes) and return a pointer to the /// Allocate memory of a given size (in bytes) and return a pointer to the
/// allocated memory. /// allocated memory.
virtual void* allocate(size_t size) override { virtual void* allocate(size_t size) override {
@ -54,11 +57,6 @@ class DefaultAllocator : public Allocator {
virtual void release(void* pointer, size_t size) override { virtual void release(void* pointer, size_t size) override {
free(pointer); free(pointer);
} }
/// Return true if memory needs to be release with this allocator
virtual bool isReleaseNeeded() const override {
return true;
}
}; };
} }

View File

@ -23,8 +23,8 @@
* * * *
********************************************************************************/ ********************************************************************************/
#ifndef REACTPHYSICS3D_ALLOCATOR_H #ifndef REACTPHYSICS3D_MEMORY_ALLOCATOR_H
#define REACTPHYSICS3D_ALLOCATOR_H #define REACTPHYSICS3D_MEMORY_ALLOCATOR_H
// Libraries // Libraries
#include <cstring> #include <cstring>
@ -32,16 +32,22 @@
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
// Class Allocator // Class MemoryAllocator
/** /**
* Abstract class with the basic interface of all the derived memory allocators * Abstract class with the basic interface of all the derived memory allocators
*/ */
class Allocator { class MemoryAllocator {
public: public:
/// Constructor
MemoryAllocator() = default;
/// Destructor /// Destructor
virtual ~Allocator() = default; virtual ~MemoryAllocator() = default;
/// Assignment operator
MemoryAllocator& operator=(MemoryAllocator& allocator) = default;
/// Allocate memory of a given size (in bytes) and return a pointer to the /// Allocate memory of a given size (in bytes) and return a pointer to the
/// allocated memory. /// allocated memory.
@ -49,9 +55,6 @@ class Allocator {
/// Release previously allocated memory. /// Release previously allocated memory.
virtual void release(void* pointer, size_t size)=0; virtual void release(void* pointer, size_t size)=0;
/// Return true if memory needs to be release with this allocator
virtual bool isReleaseNeeded() const=0;
}; };
} }

View File

@ -30,3 +30,5 @@ using namespace reactphysics3d;
// Static variables // Static variables
DefaultAllocator MemoryManager::mDefaultAllocator; DefaultAllocator MemoryManager::mDefaultAllocator;
MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator;

View File

@ -27,7 +27,10 @@
#define REACTPHYSICS3D_MEMORY_MANAGER_H #define REACTPHYSICS3D_MEMORY_MANAGER_H
// Libraries // Libraries
#include "memory/MemoryAllocator.h"
#include "memory/DefaultAllocator.h" #include "memory/DefaultAllocator.h"
#include "memory/PoolAllocator.h"
#include "memory/SingleFrameAllocator.h"
/// Namespace ReactPhysics3D /// Namespace ReactPhysics3D
namespace reactphysics3d { namespace reactphysics3d {
@ -41,31 +44,98 @@ class MemoryManager {
private: private:
/// Default memory allocator /// Default malloc/free memory allocator
static DefaultAllocator mDefaultAllocator; static DefaultAllocator mDefaultAllocator;
/// Pointer to the base memory allocator to use
static MemoryAllocator* mBaseAllocator;
/// Memory pool allocator
PoolAllocator mPoolAllocator;
/// Single frame stack allocator
SingleFrameAllocator mSingleFrameAllocator;
public: public:
/// Memory allocation types /// Memory allocation types
enum class AllocationType { enum class AllocationType {
Default, // Default memory allocator Base, // Base memory allocator
Pool, // Memory pool allocator Pool, // Memory pool allocator
Frame, // Single frame memory allocator Frame, // Single frame memory allocator
}; };
/// Constructor /// Constructor
MemoryManager(); MemoryManager() = default;
/// Destructor /// Destructor
~MemoryManager(); ~MemoryManager() = default;
/// Return the default memory allocator /// Allocate memory of a given type
static DefaultAllocator& getDefaultAllocator(); void* allocate(AllocationType allocationType, size_t size);
/// Release previously allocated memory.
void release(AllocationType allocationType, void* pointer, size_t size);
/// Return the pool allocator
PoolAllocator& getPoolAllocator();
/// Return the single frame stack allocator
SingleFrameAllocator& getSingleFrameAllocator();
/// Return the base memory allocator
static MemoryAllocator& getBaseAllocator();
/// Set the base memory allocator
static void setBaseAllocator(MemoryAllocator* memoryAllocator);
/// Reset the single frame allocator
void resetFrameAllocator();
}; };
// Return the default memory allocator // Allocate memory of a given type
inline DefaultAllocator& MemoryManager::getDefaultAllocator() { inline void* MemoryManager::allocate(AllocationType allocationType, size_t size) {
return mDefaultAllocator;
switch (allocationType) {
case AllocationType::Base: return mBaseAllocator->allocate(size); break;
case AllocationType::Pool: return mPoolAllocator.allocate(size); break;
case AllocationType::Frame: return mSingleFrameAllocator.allocate(size); break;
}
}
// Release previously allocated memory.
inline void MemoryManager::release(AllocationType allocationType, void* pointer, size_t size) {
switch (allocationType) {
case AllocationType::Base: mBaseAllocator->release(pointer, size); break;
case AllocationType::Pool: mPoolAllocator.release(pointer, size); break;
case AllocationType::Frame: mSingleFrameAllocator.release(pointer, size); break;
}
}
// Return the pool allocator
inline PoolAllocator& MemoryManager::getPoolAllocator() {
return mPoolAllocator;
}
// Return the single frame stack allocator
inline SingleFrameAllocator& MemoryManager::getSingleFrameAllocator() {
return mSingleFrameAllocator;
}
// Return the base memory allocator
inline MemoryAllocator& MemoryManager::getBaseAllocator() {
return *mBaseAllocator;
}
// Set the base memory allocator
inline void MemoryManager::setBaseAllocator(MemoryAllocator* baseAllocator) {
mBaseAllocator = baseAllocator;
}
// Reset the single frame allocator
inline void MemoryManager::resetFrameAllocator() {
mSingleFrameAllocator.reset();
} }
} }

View File

@ -25,6 +25,7 @@
// Libraries // Libraries
#include "PoolAllocator.h" #include "PoolAllocator.h"
#include "MemoryManager.h"
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <cassert>
@ -42,7 +43,7 @@ PoolAllocator::PoolAllocator() {
mNbAllocatedMemoryBlocks = 64; mNbAllocatedMemoryBlocks = 64;
mNbCurrentMemoryBlocks = 0; mNbCurrentMemoryBlocks = 0;
const size_t sizeToAllocate = mNbAllocatedMemoryBlocks * sizeof(MemoryBlock); const size_t sizeToAllocate = mNbAllocatedMemoryBlocks * sizeof(MemoryBlock);
mMemoryBlocks = (MemoryBlock*) malloc(sizeToAllocate); mMemoryBlocks = static_cast<MemoryBlock*>(MemoryManager::getBaseAllocator().allocate(sizeToAllocate));
memset(mMemoryBlocks, 0, sizeToAllocate); memset(mMemoryBlocks, 0, sizeToAllocate);
memset(mFreeMemoryUnits, 0, sizeof(mFreeMemoryUnits)); memset(mFreeMemoryUnits, 0, sizeof(mFreeMemoryUnits));
@ -55,7 +56,7 @@ PoolAllocator::PoolAllocator() {
// Initialize the array that contains the sizes the memory units that will // Initialize the array that contains the sizes the memory units that will
// be allocated in each different heap // be allocated in each different heap
for (int i=0; i < NB_HEAPS; i++) { for (uint i=0; i < NB_HEAPS; i++) {
mUnitSizes[i] = (i+1) * 8; mUnitSizes[i] = (i+1) * 8;
} }
@ -82,16 +83,17 @@ PoolAllocator::~PoolAllocator() {
// Release the memory allocated for each block // Release the memory allocated for each block
for (uint i=0; i<mNbCurrentMemoryBlocks; i++) { for (uint i=0; i<mNbCurrentMemoryBlocks; i++) {
free(mMemoryBlocks[i].memoryUnits); MemoryManager::getBaseAllocator().release(mMemoryBlocks[i].memoryUnits, BLOCK_SIZE);
} }
free(mMemoryBlocks); MemoryManager::getBaseAllocator().release(mMemoryBlocks, mNbAllocatedMemoryBlocks * sizeof(MemoryBlock));
#ifndef NDEBUG #ifndef NDEBUG
// Check that the allocate() and release() methods have been called the same // Check that the allocate() and release() methods have been called the same
// number of times to avoid memory leaks. // number of times to avoid memory leaks.
assert(mNbTimesAllocateMethodCalled == 0); assert(mNbTimesAllocateMethodCalled == 0);
#endif #endif
} }
// Allocate memory of a given size (in bytes) and return a pointer to the // Allocate memory of a given size (in bytes) and return a pointer to the
@ -108,8 +110,8 @@ void* PoolAllocator::allocate(size_t size) {
// If we need to allocate more than the maximum memory unit size // If we need to allocate more than the maximum memory unit size
if (size > MAX_UNIT_SIZE) { if (size > MAX_UNIT_SIZE) {
// Allocate memory using standard malloc() function // Allocate memory using default allocation
return malloc(size); return MemoryManager::getBaseAllocator().allocate(size);
} }
// Get the index of the heap that will take care of the allocation request // Get the index of the heap that will take care of the allocation request
@ -132,7 +134,7 @@ void* PoolAllocator::allocate(size_t size) {
// Allocate more memory to contain the blocks // Allocate more memory to contain the blocks
MemoryBlock* currentMemoryBlocks = mMemoryBlocks; MemoryBlock* currentMemoryBlocks = mMemoryBlocks;
mNbAllocatedMemoryBlocks += 64; mNbAllocatedMemoryBlocks += 64;
mMemoryBlocks = (MemoryBlock*) malloc(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock)); mMemoryBlocks = static_cast<MemoryBlock*>(MemoryManager::getBaseAllocator().allocate(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock)));
memcpy(mMemoryBlocks, currentMemoryBlocks,mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); memcpy(mMemoryBlocks, currentMemoryBlocks,mNbCurrentMemoryBlocks * sizeof(MemoryBlock));
memset(mMemoryBlocks + mNbCurrentMemoryBlocks, 0, 64 * sizeof(MemoryBlock)); memset(mMemoryBlocks + mNbCurrentMemoryBlocks, 0, 64 * sizeof(MemoryBlock));
free(currentMemoryBlocks); free(currentMemoryBlocks);
@ -141,17 +143,22 @@ void* PoolAllocator::allocate(size_t size) {
// Allocate a new memory blocks for the corresponding heap and divide it in many // Allocate a new memory blocks for the corresponding heap and divide it in many
// memory units // memory units
MemoryBlock* newBlock = mMemoryBlocks + mNbCurrentMemoryBlocks; MemoryBlock* newBlock = mMemoryBlocks + mNbCurrentMemoryBlocks;
newBlock->memoryUnits = (MemoryUnit*) malloc(BLOCK_SIZE); newBlock->memoryUnits = static_cast<MemoryUnit*>(MemoryManager::getBaseAllocator().allocate(BLOCK_SIZE));
assert(newBlock->memoryUnits != nullptr); assert(newBlock->memoryUnits != nullptr);
size_t unitSize = mUnitSizes[indexHeap]; size_t unitSize = mUnitSizes[indexHeap];
uint nbUnits = BLOCK_SIZE / unitSize; uint nbUnits = BLOCK_SIZE / unitSize;
assert(nbUnits * unitSize <= BLOCK_SIZE); assert(nbUnits * unitSize <= BLOCK_SIZE);
void* memoryUnitsStart = static_cast<void*>(newBlock->memoryUnits);
char* memoryUnitsStartChar = static_cast<char*>(memoryUnitsStart);
for (size_t i=0; i < nbUnits - 1; i++) { for (size_t i=0; i < nbUnits - 1; i++) {
MemoryUnit* unit = (MemoryUnit*) ((size_t)newBlock->memoryUnits + unitSize * i); void* unitPointer = static_cast<void*>(memoryUnitsStartChar + unitSize * i);
MemoryUnit* nextUnit = (MemoryUnit*) ((size_t)newBlock->memoryUnits + unitSize * (i+1)); void* nextUnitPointer = static_cast<void*>(memoryUnitsStartChar + unitSize * (i+1));
MemoryUnit* unit = static_cast<MemoryUnit*>(unitPointer);
MemoryUnit* nextUnit = static_cast<MemoryUnit*>(nextUnitPointer);
unit->nextUnit = nextUnit; unit->nextUnit = nextUnit;
} }
MemoryUnit* lastUnit = (MemoryUnit*) ((size_t)newBlock->memoryUnits + unitSize*(nbUnits-1)); void* lastUnitPointer = static_cast<void*>(memoryUnitsStartChar + unitSize*(nbUnits-1));
MemoryUnit* lastUnit = static_cast<MemoryUnit*>(lastUnitPointer);
lastUnit->nextUnit = nullptr; lastUnit->nextUnit = nullptr;
// Add the new allocated block into the list of free memory units in the heap // Add the new allocated block into the list of free memory units in the heap
@ -176,8 +183,8 @@ void PoolAllocator::release(void* pointer, size_t size) {
// If the size is larger than the maximum memory unit size // If the size is larger than the maximum memory unit size
if (size > MAX_UNIT_SIZE) { if (size > MAX_UNIT_SIZE) {
// Release the memory using the standard free() function // Release the memory using the default deallocation
free(pointer); MemoryManager::getBaseAllocator().release(pointer, size);
return; return;
} }
@ -187,7 +194,7 @@ void PoolAllocator::release(void* pointer, size_t size) {
// Insert the released memory unit into the list of free memory units of the // Insert the released memory unit into the list of free memory units of the
// corresponding heap // corresponding heap
MemoryUnit* releasedUnit = (MemoryUnit*) pointer; MemoryUnit* releasedUnit = static_cast<MemoryUnit*>(pointer);
releasedUnit->nextUnit = mFreeMemoryUnits[indexHeap]; releasedUnit->nextUnit = mFreeMemoryUnits[indexHeap];
mFreeMemoryUnits[indexHeap] = releasedUnit; mFreeMemoryUnits[indexHeap] = releasedUnit;
} }

View File

@ -28,7 +28,7 @@
// Libraries // Libraries
#include "configuration.h" #include "configuration.h"
#include "Allocator.h" #include "MemoryAllocator.h"
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
namespace reactphysics3d { namespace reactphysics3d {
@ -40,7 +40,7 @@ namespace reactphysics3d {
* efficiently. This implementation is inspired by the small block allocator * efficiently. This implementation is inspired by the small block allocator
* described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp * described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp
*/ */
class PoolAllocator : public Allocator { class PoolAllocator : public MemoryAllocator {
private : private :
@ -131,23 +131,17 @@ class PoolAllocator : public Allocator {
/// Destructor /// Destructor
virtual ~PoolAllocator() override; virtual ~PoolAllocator() override;
/// Assignment operator
PoolAllocator& operator=(PoolAllocator& allocator) = default;
/// Allocate memory of a given size (in bytes) and return a pointer to the /// Allocate memory of a given size (in bytes) and return a pointer to the
/// allocated memory. /// allocated memory.
virtual void* allocate(size_t size) override; virtual void* allocate(size_t size) override;
/// Release previously allocated memory. /// Release previously allocated memory.
virtual void release(void* pointer, size_t size) override; virtual void release(void* pointer, size_t size) override;
/// Return true if memory needs to be release with this allocator
virtual bool isReleaseNeeded() const override;
}; };
// Return true if memory needs to be release with this allocator
inline bool PoolAllocator::isReleaseNeeded() const {
return true;
}
} }
#endif #endif

View File

@ -25,17 +25,19 @@
// Libraries // Libraries
#include "SingleFrameAllocator.h" #include "SingleFrameAllocator.h"
#include "MemoryManager.h"
#include <cstdlib> #include <cstdlib>
#include <cassert> #include <cassert>
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
SingleFrameAllocator::SingleFrameAllocator(size_t totalSizeBytes) SingleFrameAllocator::SingleFrameAllocator()
: mTotalSizeBytes(totalSizeBytes), mCurrentOffset(0) { : mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_BYTES),
mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) {
// Allocate a whole block of memory at the beginning // Allocate a whole block of memory at the beginning
mMemoryBufferStart = static_cast<char*>(malloc(mTotalSizeBytes)); mMemoryBufferStart = static_cast<char*>(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes));
assert(mMemoryBufferStart != nullptr); assert(mMemoryBufferStart != nullptr);
} }
@ -43,7 +45,7 @@ SingleFrameAllocator::SingleFrameAllocator(size_t totalSizeBytes)
SingleFrameAllocator::~SingleFrameAllocator() { SingleFrameAllocator::~SingleFrameAllocator() {
// Release the memory allocated at the beginning // Release the memory allocated at the beginning
free(mMemoryBufferStart); MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes);
} }
@ -52,14 +54,13 @@ SingleFrameAllocator::~SingleFrameAllocator() {
void* SingleFrameAllocator::allocate(size_t size) { void* SingleFrameAllocator::allocate(size_t size) {
// Check that there is enough remaining memory in the buffer // Check that there is enough remaining memory in the buffer
if (static_cast<size_t>(mCurrentOffset) + size > mTotalSizeBytes) { if (mCurrentOffset + size > mTotalSizeBytes) {
// This should never occur. If it does, you must increase the initial // We need to allocate more memory next time reset() is called
// size of memory of this allocator mNeedToAllocatedMore = true;
assert(false);
// Return null // Return default memory allocation
return nullptr; return MemoryManager::getBaseAllocator().allocate(size);
} }
// Next available memory location // Next available memory location
@ -72,9 +73,63 @@ void* SingleFrameAllocator::allocate(size_t size) {
return nextAvailableMemory; return nextAvailableMemory;
} }
// Release previously allocated memory.
void SingleFrameAllocator::release(void* pointer, size_t size) {
// If allocated memory is not within the single frame allocation range
char* p = static_cast<char*>(pointer);
if (p < mMemoryBufferStart || p > mMemoryBufferStart + mTotalSizeBytes) {
// Use default deallocation
MemoryManager::getBaseAllocator().release(pointer, size);
}
}
// Reset the marker of the current allocated memory // Reset the marker of the current allocated memory
void SingleFrameAllocator::reset() { void SingleFrameAllocator::reset() {
// If too much memory is allocated
if (mCurrentOffset < mTotalSizeBytes / 2) {
mNbFramesTooMuchAllocated++;
if (mNbFramesTooMuchAllocated > NB_FRAMES_UNTIL_SHRINK) {
// Release the memory allocated at the beginning
MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes);
// Divide the total memory to allocate by two
mTotalSizeBytes /= 2;
if (mTotalSizeBytes <= 0) mTotalSizeBytes = 1;
// Allocate a whole block of memory at the beginning
mMemoryBufferStart = static_cast<char*>(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes));
assert(mMemoryBufferStart != nullptr);
mNbFramesTooMuchAllocated = 0;
}
}
else {
mNbFramesTooMuchAllocated = 0;
}
// If we need to allocate more memory
if (mNeedToAllocatedMore) {
// Release the memory allocated at the beginning
MemoryManager::getBaseAllocator().release(mMemoryBufferStart, mTotalSizeBytes);
// Multiply the total memory to allocate by two
mTotalSizeBytes *= 2;
// Allocate a whole block of memory at the beginning
mMemoryBufferStart = static_cast<char*>(MemoryManager::getBaseAllocator().allocate(mTotalSizeBytes));
assert(mMemoryBufferStart != nullptr);
mNeedToAllocatedMore = false;
mNbFramesTooMuchAllocated = 0;
}
// Reset the current offset at the beginning of the block // Reset the current offset at the beginning of the block
mCurrentOffset = 0; mCurrentOffset = 0;
} }

View File

@ -27,7 +27,7 @@
#define REACTPHYSICS3D_SINGLE_FRAME_ALLOCATOR_H #define REACTPHYSICS3D_SINGLE_FRAME_ALLOCATOR_H
// Libraries // Libraries
#include "Allocator.h" #include "MemoryAllocator.h"
#include "configuration.h" #include "configuration.h"
/// ReactPhysics3D namespace /// ReactPhysics3D namespace
@ -38,10 +38,16 @@ namespace reactphysics3d {
* This class represent a memory allocator used to efficiently allocate * This class represent a memory allocator used to efficiently allocate
* memory on the heap that is used during a single frame. * memory on the heap that is used during a single frame.
*/ */
class SingleFrameAllocator : public Allocator { class SingleFrameAllocator : public MemoryAllocator {
private : private :
// -------------------- Constants -------------------- //
/// Number of frames to wait before shrinking the allocated
/// memory if too much is allocated
static const int NB_FRAMES_UNTIL_SHRINK = 120;
// -------------------- Attributes -------------------- // // -------------------- Attributes -------------------- //
/// Total size (in bytes) of memory of the allocator /// Total size (in bytes) of memory of the allocator
@ -51,36 +57,38 @@ class SingleFrameAllocator : public Allocator {
char* mMemoryBufferStart; char* mMemoryBufferStart;
/// Pointer to the next available memory location in the buffer /// Pointer to the next available memory location in the buffer
int mCurrentOffset; size_t mCurrentOffset;
/// Current number of frames since we detected too much memory
/// is allocated
size_t mNbFramesTooMuchAllocated;
/// True if we need to allocate more memory in the next reset() call
bool mNeedToAllocatedMore;
public : public :
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
SingleFrameAllocator(size_t totalSizeBytes); SingleFrameAllocator();
/// Destructor /// Destructor
virtual ~SingleFrameAllocator() override; virtual ~SingleFrameAllocator() override;
/// Assignment operator
SingleFrameAllocator& operator=(SingleFrameAllocator& allocator) = default;
/// Allocate memory of a given size (in bytes) /// Allocate memory of a given size (in bytes)
virtual void* allocate(size_t size) override; virtual void* allocate(size_t size) override;
/// Release previously allocated memory. /// Release previously allocated memory.
virtual void release(void* pointer, size_t size) override { } virtual void release(void* pointer, size_t size) override;
/// Reset the marker of the current allocated memory /// Reset the marker of the current allocated memory
virtual void reset(); virtual void reset();
/// Return true if memory needs to be release with this allocator
virtual bool isReleaseNeeded() const override;
}; };
// Return true if memory needs to be release with this allocator
inline bool SingleFrameAllocator::isReleaseNeeded() const {
return false;
}
} }
#endif #endif