Refactor memory allocation
This commit is contained in:
parent
3be2970d30
commit
261ffef616
|
@ -187,7 +187,7 @@ SET (REACTPHYSICS3D_SOURCES
|
|||
"src/mathematics/Vector3.h"
|
||||
"src/mathematics/Ray.h"
|
||||
"src/mathematics/Vector3.cpp"
|
||||
"src/memory/Allocator.h"
|
||||
"src/memory/MemoryAllocator.h"
|
||||
"src/memory/PoolAllocator.h"
|
||||
"src/memory/PoolAllocator.cpp"
|
||||
"src/memory/SingleFrameAllocator.h"
|
||||
|
|
|
@ -70,9 +70,9 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape,
|
|||
const Transform& transform) {
|
||||
|
||||
// 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,
|
||||
transform, decimal(1), mWorld.mPoolAllocator);
|
||||
transform, decimal(1), mWorld.mMemoryManager);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -123,7 +123,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
|||
}
|
||||
|
||||
current->~ProxyShape();
|
||||
mWorld.mPoolAllocator.release(current, sizeof(ProxyShape));
|
||||
mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, current, sizeof(ProxyShape));
|
||||
mNbCollisionShapes--;
|
||||
return;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
|||
}
|
||||
|
||||
elementToRemove->~ProxyShape();
|
||||
mWorld.mPoolAllocator.release(elementToRemove, sizeof(ProxyShape));
|
||||
mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, elementToRemove, sizeof(ProxyShape));
|
||||
mNbCollisionShapes--;
|
||||
return;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ void CollisionBody::removeAllCollisionShapes() {
|
|||
}
|
||||
|
||||
current->~ProxyShape();
|
||||
mWorld.mPoolAllocator.release(current, sizeof(ProxyShape));
|
||||
mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, current, sizeof(ProxyShape));
|
||||
|
||||
// Get the next element in the list
|
||||
current = nextElement;
|
||||
|
@ -188,7 +188,7 @@ void CollisionBody::resetContactManifoldsList() {
|
|||
|
||||
// Delete the current element
|
||||
currentElement->~ContactManifoldListElement();
|
||||
mWorld.mPoolAllocator.release(currentElement, sizeof(ContactManifoldListElement));
|
||||
mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, currentElement, sizeof(ContactManifoldListElement));
|
||||
|
||||
currentElement = nextElement;
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ void RigidBody::setMass(decimal mass) {
|
|||
}
|
||||
|
||||
// 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(mJointsList != nullptr);
|
||||
|
@ -186,7 +186,8 @@ void RigidBody::removeJointFromJointsList(PoolAllocator& memoryAllocator, const
|
|||
JointListElement* elementToRemove = mJointsList;
|
||||
mJointsList = elementToRemove->next;
|
||||
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
|
||||
JointListElement* currentElement = mJointsList;
|
||||
|
@ -195,7 +196,8 @@ void RigidBody::removeJointFromJointsList(PoolAllocator& memoryAllocator, const
|
|||
JointListElement* elementToRemove = currentElement->next;
|
||||
currentElement->next = elementToRemove->next;
|
||||
elementToRemove->~JointListElement();
|
||||
memoryAllocator.release(elementToRemove, sizeof(JointListElement));
|
||||
memoryManager.release(MemoryManager::AllocationType::Pool,
|
||||
elementToRemove, sizeof(JointListElement));
|
||||
break;
|
||||
}
|
||||
currentElement = currentElement->next;
|
||||
|
@ -224,9 +226,9 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
|
|||
decimal mass) {
|
||||
|
||||
// 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,
|
||||
transform, mass, mWorld.mPoolAllocator);
|
||||
transform, mass, mWorld.mMemoryManager);
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "CollisionBody.h"
|
||||
#include "engine/Material.h"
|
||||
#include "mathematics/mathematics.h"
|
||||
#include "memory/PoolAllocator.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
namespace reactphysics3d {
|
||||
|
@ -112,7 +112,7 @@ class RigidBody : public CollisionBody {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// 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
|
||||
void updateTransformWithCenterOfMass();
|
||||
|
|
|
@ -26,18 +26,18 @@
|
|||
// Libraries
|
||||
#include "collision/CollisionCallback.h"
|
||||
#include "engine/OverlappingPair.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
#include "collision/ContactManifold.h"
|
||||
|
||||
// We want to use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* pair, Allocator& allocator) :
|
||||
CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* pair, MemoryManager& memoryManager) :
|
||||
contactManifoldElements(nullptr), body1(pair->getShape1()->getBody()),
|
||||
body2(pair->getShape2()->getBody()),
|
||||
proxyShape1(pair->getShape1()), proxyShape2(pair->getShape2()),
|
||||
mMemoryAllocator(allocator) {
|
||||
mMemoryManager(memoryManager) {
|
||||
|
||||
assert(pair != nullptr);
|
||||
|
||||
|
@ -52,7 +52,8 @@ CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair*
|
|||
|
||||
// Add the contact manifold at the beginning of the linked
|
||||
// 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,
|
||||
contactManifoldElements);
|
||||
contactManifoldElements = element;
|
||||
|
@ -72,7 +73,8 @@ CollisionCallback::CollisionCallbackInfo::~CollisionCallbackInfo() {
|
|||
|
||||
// Delete and release memory
|
||||
element->~ContactManifoldListElement();
|
||||
mMemoryAllocator.release(element, sizeof(ContactManifoldListElement));
|
||||
mMemoryManager.release(MemoryManager::AllocationType::Pool, element,
|
||||
sizeof(ContactManifoldListElement));
|
||||
|
||||
element = nextElement;
|
||||
}
|
||||
|
|
|
@ -69,11 +69,11 @@ class CollisionCallback {
|
|||
/// Pointer to the proxy shape of second body
|
||||
const ProxyShape* proxyShape2;
|
||||
|
||||
/// Memory allocator
|
||||
Allocator& mMemoryAllocator;
|
||||
/// Memory manager
|
||||
MemoryManager& mMemoryManager;
|
||||
|
||||
// Constructor
|
||||
CollisionCallbackInfo(OverlappingPair* pair, Allocator& allocator);
|
||||
CollisionCallbackInfo(OverlappingPair* pair, MemoryManager& memoryManager);
|
||||
|
||||
// Destructor
|
||||
~CollisionCallbackInfo();
|
||||
|
|
|
@ -47,9 +47,8 @@ using namespace reactphysics3d;
|
|||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
CollisionDetection::CollisionDetection(CollisionWorld* world, PoolAllocator& memoryAllocator, SingleFrameAllocator& singleFrameAllocator)
|
||||
: mPoolAllocator(memoryAllocator), mSingleFrameAllocator(singleFrameAllocator),
|
||||
mWorld(world), mNarrowPhaseInfoList(nullptr), mBroadPhaseAlgorithm(*this),
|
||||
CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager)
|
||||
: mMemoryManager(memoryManager), mWorld(world), mNarrowPhaseInfoList(nullptr), mBroadPhaseAlgorithm(*this),
|
||||
mIsCollisionShapesAdded(false) {
|
||||
|
||||
// Set the default collision dispatch configuration
|
||||
|
@ -95,7 +94,7 @@ void CollisionDetection::computeBroadPhase() {
|
|||
// Ask the broad-phase to recompute the overlapping pairs of collision
|
||||
// shapes. This call can only add new overlapping pairs in the collision
|
||||
// detection.
|
||||
mBroadPhaseAlgorithm.computeOverlappingPairs(mPoolAllocator);
|
||||
mBroadPhaseAlgorithm.computeOverlappingPairs(mMemoryManager);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +132,7 @@ void CollisionDetection::computeMiddlePhase() {
|
|||
// Destroy the overlapping pair
|
||||
itToRemove->second->~OverlappingPair();
|
||||
|
||||
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
||||
mWorld->mMemoryManager.release(MemoryManager::AllocationType::Pool, itToRemove->second, sizeof(OverlappingPair));
|
||||
mOverlappingPairs.erase(itToRemove);
|
||||
continue;
|
||||
}
|
||||
|
@ -166,10 +165,10 @@ void CollisionDetection::computeMiddlePhase() {
|
|||
// No middle-phase is necessary, simply create a narrow phase info
|
||||
// for the narrow-phase collision detection
|
||||
NarrowPhaseInfo* firstNarrowPhaseInfo = mNarrowPhaseInfoList;
|
||||
mNarrowPhaseInfoList = new (mSingleFrameAllocator.allocate(sizeof(NarrowPhaseInfo)))
|
||||
mNarrowPhaseInfoList = new (mMemoryManager.allocate(MemoryManager::AllocationType::Frame, sizeof(NarrowPhaseInfo)))
|
||||
NarrowPhaseInfo(pair, shape1->getCollisionShape(),
|
||||
shape2->getCollisionShape(), shape1->getLocalToWorldTransform(),
|
||||
shape2->getLocalToWorldTransform(), mSingleFrameAllocator);
|
||||
shape2->getLocalToWorldTransform(), mMemoryManager.getSingleFrameAllocator());
|
||||
mNarrowPhaseInfoList->next = firstNarrowPhaseInfo;
|
||||
|
||||
}
|
||||
|
@ -177,7 +176,7 @@ void CollisionDetection::computeMiddlePhase() {
|
|||
else if ((!isShape1Convex && isShape2Convex) || (!isShape2Convex && isShape1Convex)) {
|
||||
|
||||
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
|
||||
// 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
|
||||
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, Allocator& allocator,
|
||||
void CollisionDetection::computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator,
|
||||
NarrowPhaseInfo** firstNarrowPhaseInfo) {
|
||||
|
||||
ProxyShape* shape1 = pair->getShape1();
|
||||
|
@ -273,7 +272,7 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
// Use the narrow-phase collision detection algorithm to check
|
||||
// if there really is a collision. If a collision occurs, the
|
||||
// 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
|
||||
currentNarrowPhaseInfo->addContactPointsAsPotentialContactManifold();
|
||||
|
@ -295,7 +294,7 @@ void CollisionDetection::computeNarrowPhase() {
|
|||
narrowPhaseInfoToDelete->~NarrowPhaseInfo();
|
||||
|
||||
// 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
|
||||
|
@ -327,8 +326,9 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
|
|||
if (mOverlappingPairs.find(pairID) != mOverlappingPairs.end()) return;
|
||||
|
||||
// Create the overlapping pair and add it into the set of overlapping pairs
|
||||
OverlappingPair* newPair = new (mPoolAllocator.allocate(sizeof(OverlappingPair)))
|
||||
OverlappingPair(shape1, shape2, mPoolAllocator, mSingleFrameAllocator);
|
||||
OverlappingPair* newPair = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(OverlappingPair)))
|
||||
OverlappingPair(shape1, shape2, mMemoryManager.getPoolAllocator(),
|
||||
mMemoryManager.getSingleFrameAllocator());
|
||||
assert(newPair != nullptr);
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -359,7 +359,7 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
|||
|
||||
// Destroy the overlapping pair
|
||||
itToRemove->second->~OverlappingPair();
|
||||
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
||||
mWorld->mMemoryManager.release(MemoryManager::AllocationType::Pool, itToRemove->second, sizeof(OverlappingPair));
|
||||
mOverlappingPairs.erase(itToRemove);
|
||||
}
|
||||
else {
|
||||
|
@ -403,14 +403,16 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
|
|||
|
||||
// Add the contact manifold at the beginning of the linked
|
||||
// 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,
|
||||
body1->mContactManifoldsList);
|
||||
body1->mContactManifoldsList = listElement1;
|
||||
|
||||
// Add the contact manifold at the beginning of the linked
|
||||
// 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,
|
||||
body2->mContactManifoldsList);
|
||||
body2->mContactManifoldsList = listElement2;
|
||||
|
@ -470,7 +472,7 @@ void CollisionDetection::reportAllContacts() {
|
|||
// If there is a user callback
|
||||
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
|
||||
mWorld->mEventListener->newContact(collisionInfo);
|
||||
|
@ -498,9 +500,10 @@ NarrowPhaseInfo* CollisionDetection::computeMiddlePhaseForProxyShapes(Overlappin
|
|||
|
||||
// No middle-phase is necessary, simply create a narrow phase info
|
||||
// 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->getLocalToWorldTransform(), mPoolAllocator);
|
||||
shape2->getLocalToWorldTransform(), mMemoryManager.getPoolAllocator());
|
||||
|
||||
}
|
||||
// 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
|
||||
// shape we need to use during the narrow-phase collision detection
|
||||
computeConvexVsConcaveMiddlePhase(pair, mPoolAllocator, &narrowPhaseInfo);
|
||||
computeConvexVsConcaveMiddlePhase(pair, mMemoryManager.getPoolAllocator(), &narrowPhaseInfo);
|
||||
}
|
||||
|
||||
pair->clearObsoleteLastFrameCollisionInfos();
|
||||
|
@ -524,7 +527,7 @@ void CollisionDetection::testAABBOverlap(const AABB& aabb, OverlapCallback* over
|
|||
std::unordered_set<bodyindex> reportedBodies;
|
||||
|
||||
// Ask the broad-phase to get all the overlapping shapes
|
||||
LinkedList<int> overlappingNodes(mPoolAllocator);
|
||||
LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
|
||||
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes);
|
||||
|
||||
// For each overlaping proxy shape
|
||||
|
@ -575,7 +578,8 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
|
|||
if (aabb1.testCollision(aabb2)) {
|
||||
|
||||
// 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
|
||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
|
||||
|
@ -600,7 +604,7 @@ bool CollisionDetection::testOverlap(CollisionBody* body1, CollisionBody* body2)
|
|||
// Use the narrow-phase collision detection algorithm to check
|
||||
// if there really is a collision. If a collision occurs, the
|
||||
// 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();
|
||||
|
||||
// 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
|
||||
|
@ -648,7 +652,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
|||
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID);
|
||||
|
||||
// Ask the broad-phase to get all the overlapping shapes
|
||||
LinkedList<int> overlappingNodes(mPoolAllocator);
|
||||
LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
|
||||
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes);
|
||||
|
||||
const bodyindex bodyId = body->getID();
|
||||
|
@ -670,7 +674,8 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
|||
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
|
||||
|
||||
// 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
|
||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
|
||||
|
@ -695,7 +700,7 @@ void CollisionDetection::testOverlap(CollisionBody* body, OverlapCallback* overl
|
|||
// Use the narrow-phase collision detection algorithm to check
|
||||
// if there really is a collision. If a collision occurs, the
|
||||
// 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();
|
||||
|
||||
// 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
|
||||
|
@ -754,7 +759,8 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
|||
if (aabb1.testCollision(aabb2)) {
|
||||
|
||||
// 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
|
||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
|
||||
|
@ -774,7 +780,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
|||
// Use the narrow-phase collision detection algorithm to check
|
||||
// if there really is a collision. If a collision occurs, the
|
||||
// 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
|
||||
narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
|
||||
|
@ -788,7 +794,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
|||
currentNarrowPhaseInfo->~NarrowPhaseInfo();
|
||||
|
||||
// Release the allocated memory
|
||||
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
||||
mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
||||
}
|
||||
|
||||
// Process the potential contacts
|
||||
|
@ -797,7 +803,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body
|
|||
if (pair.hasContacts()) {
|
||||
|
||||
// Report the contacts to the user
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mPoolAllocator);
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mMemoryManager);
|
||||
collisionCallback->notifyContact(collisionInfo);
|
||||
}
|
||||
}
|
||||
|
@ -826,7 +832,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
const AABB& shapeAABB = mBroadPhaseAlgorithm.getFatAABB(bodyProxyShape->mBroadPhaseID);
|
||||
|
||||
// Ask the broad-phase to get all the overlapping shapes
|
||||
LinkedList<int> overlappingNodes(mPoolAllocator);
|
||||
LinkedList<int> overlappingNodes(mMemoryManager.getPoolAllocator());
|
||||
mBroadPhaseAlgorithm.reportAllShapesOverlappingWithAABB(shapeAABB, overlappingNodes);
|
||||
|
||||
const bodyindex bodyId = body->getID();
|
||||
|
@ -846,7 +852,8 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
if ((proxyShape->getCollisionCategoryBits() & categoryMaskBits) != 0) {
|
||||
|
||||
// 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
|
||||
NarrowPhaseInfo* narrowPhaseInfo = computeMiddlePhaseForProxyShapes(&pair);
|
||||
|
@ -866,7 +873,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
// Use the narrow-phase collision detection algorithm to check
|
||||
// if there really is a collision. If a collision occurs, the
|
||||
// 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
|
||||
narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
|
||||
|
@ -880,7 +887,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
currentNarrowPhaseInfo->~NarrowPhaseInfo();
|
||||
|
||||
// Release the allocated memory
|
||||
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
||||
mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
||||
}
|
||||
|
||||
// Process the potential contacts
|
||||
|
@ -889,7 +896,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c
|
|||
if (pair.hasContacts()) {
|
||||
|
||||
// Report the contacts to the user
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mPoolAllocator);
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mMemoryManager);
|
||||
callback->notifyContact(collisionInfo);
|
||||
}
|
||||
}
|
||||
|
@ -920,8 +927,8 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
|||
OverlappingPair* originalPair = it->second;
|
||||
|
||||
// Create a new overlapping pair so that we do not work on the original one
|
||||
OverlappingPair pair(originalPair->getShape1(), originalPair->getShape2(), mPoolAllocator,
|
||||
mPoolAllocator);
|
||||
OverlappingPair pair(originalPair->getShape1(), originalPair->getShape2(), mMemoryManager.getPoolAllocator(),
|
||||
mMemoryManager.getPoolAllocator());
|
||||
|
||||
ProxyShape* shape1 = pair.getShape1();
|
||||
ProxyShape* shape2 = pair.getShape2();
|
||||
|
@ -950,7 +957,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
|||
// Use the narrow-phase collision detection algorithm to check
|
||||
// if there really is a collision. If a collision occurs, the
|
||||
// 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
|
||||
narrowPhaseInfo->addContactPointsAsPotentialContactManifold();
|
||||
|
@ -964,7 +971,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
|||
currentNarrowPhaseInfo->~NarrowPhaseInfo();
|
||||
|
||||
// Release the allocated memory
|
||||
mPoolAllocator.release(currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
||||
mMemoryManager.release(MemoryManager::AllocationType::Pool, currentNarrowPhaseInfo, sizeof(NarrowPhaseInfo));
|
||||
}
|
||||
|
||||
// Process the potential contacts
|
||||
|
@ -973,7 +980,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) {
|
|||
if (pair.hasContacts()) {
|
||||
|
||||
// Report the contacts to the user
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mPoolAllocator);
|
||||
CollisionCallback::CollisionCallbackInfo collisionInfo(&pair, mMemoryManager);
|
||||
callback->notifyContact(collisionInfo);
|
||||
}
|
||||
}
|
||||
|
@ -996,12 +1003,6 @@ EventListener* CollisionDetection::getWorldEventListener() {
|
|||
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
|
||||
const AABB CollisionDetection::getWorldAABB(const ProxyShape* proxyShape) const {
|
||||
assert(proxyShape->mBroadPhaseID > -1);
|
||||
|
|
|
@ -32,8 +32,7 @@
|
|||
#include "engine/OverlappingPair.h"
|
||||
#include "engine/EventListener.h"
|
||||
#include "narrowphase/DefaultCollisionDispatch.h"
|
||||
#include "memory/PoolAllocator.h"
|
||||
#include "memory/SingleFrameAllocator.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "constraint/ContactPoint.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
@ -62,6 +61,9 @@ class CollisionDetection {
|
|||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Memory manager
|
||||
MemoryManager& mMemoryManager;
|
||||
|
||||
/// Collision Detection Dispatch configuration
|
||||
CollisionDispatch* mCollisionDispatch;
|
||||
|
||||
|
@ -71,12 +73,6 @@ class CollisionDetection {
|
|||
/// Collision detection matrix (algorithms to use)
|
||||
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
|
||||
CollisionWorld* mWorld;
|
||||
|
||||
|
@ -133,7 +129,7 @@ class CollisionDetection {
|
|||
void addAllContactManifoldsToBodies();
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Compute the middle-phase collision detection between two proxy shapes
|
||||
|
@ -156,7 +152,7 @@ class CollisionDetection {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
CollisionDetection(CollisionWorld* world, PoolAllocator& memoryAllocator, SingleFrameAllocator& singleFrameAllocator);
|
||||
CollisionDetection(CollisionWorld* world, MemoryManager& memoryManager);
|
||||
|
||||
/// Destructor
|
||||
~CollisionDetection() = default;
|
||||
|
@ -223,9 +219,6 @@ class CollisionDetection {
|
|||
/// Return the world event listener
|
||||
EventListener* getWorldEventListener();
|
||||
|
||||
/// Return a reference to the world memory allocator
|
||||
PoolAllocator& getWorldMemoryAllocator();
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Set the profiler
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// 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),
|
||||
mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
|
||||
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),
|
||||
|
|
|
@ -129,7 +129,7 @@ class ContactManifold {
|
|||
bool mIsAlreadyInIsland;
|
||||
|
||||
/// Reference to the memory allocator
|
||||
Allocator& mMemoryAllocator;
|
||||
MemoryAllocator& mMemoryAllocator;
|
||||
|
||||
/// Pointer to the next contact manifold in the linked-list
|
||||
ContactManifold* mNext;
|
||||
|
@ -217,7 +217,7 @@ class ContactManifold {
|
|||
|
||||
/// Constructor
|
||||
ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyShape* shape1, ProxyShape* shape2,
|
||||
Allocator& memoryAllocator);
|
||||
MemoryAllocator& memoryAllocator);
|
||||
|
||||
/// Destructor
|
||||
~ContactManifold();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
ContactManifoldInfo::ContactManifoldInfo(Allocator& allocator)
|
||||
ContactManifoldInfo::ContactManifoldInfo(MemoryAllocator& allocator)
|
||||
: mContactPointsList(nullptr), mNbContactPoints(0), mNext(nullptr), mAllocator(allocator) {
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "collision/ContactPointInfo.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -57,14 +57,14 @@ class ContactManifoldInfo {
|
|||
ContactManifoldInfo* mNext;
|
||||
|
||||
/// Reference the the memory allocator where the contact point infos have been allocated
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ContactManifoldInfo(Allocator& allocator);
|
||||
ContactManifoldInfo(MemoryAllocator& allocator);
|
||||
|
||||
/// Destructor
|
||||
~ContactManifoldInfo();
|
||||
|
|
|
@ -30,7 +30,7 @@ using namespace reactphysics3d;
|
|||
|
||||
// Constructor
|
||||
ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
|
||||
Allocator& memoryAllocator)
|
||||
MemoryAllocator& memoryAllocator)
|
||||
: mNbManifolds(0), mShape1(shape1),
|
||||
mShape2(shape2), mMemoryAllocator(memoryAllocator), mManifolds(nullptr) {
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class ContactManifoldSet {
|
|||
ProxyShape* mShape2;
|
||||
|
||||
/// Reference to the memory allocator for the contact manifolds
|
||||
Allocator& mMemoryAllocator;
|
||||
MemoryAllocator& mMemoryAllocator;
|
||||
|
||||
/// Contact manifolds of the set
|
||||
ContactManifold* mManifolds;
|
||||
|
@ -95,7 +95,7 @@ class ContactManifoldSet {
|
|||
|
||||
/// Constructor
|
||||
ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
|
||||
Allocator& memoryAllocator);
|
||||
MemoryAllocator& memoryAllocator);
|
||||
|
||||
/// Destructor
|
||||
~ContactManifoldSet();
|
||||
|
|
|
@ -54,7 +54,7 @@ class HalfEdgeStructure {
|
|||
List<uint> faceVertices; // Index of the vertices of the face
|
||||
|
||||
/// Constructor
|
||||
Face(Allocator& allocator) : faceVertices(allocator) {}
|
||||
Face(MemoryAllocator& allocator) : faceVertices(allocator) {}
|
||||
|
||||
/// Constructor
|
||||
Face(List<uint> vertices) : faceVertices(vertices) {}
|
||||
|
@ -71,7 +71,7 @@ class HalfEdgeStructure {
|
|||
private:
|
||||
|
||||
/// Reference to a memory allocator
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
/// All the faces
|
||||
List<Face> mFaces;
|
||||
|
@ -85,7 +85,7 @@ class HalfEdgeStructure {
|
|||
public:
|
||||
|
||||
/// Constructor
|
||||
HalfEdgeStructure(Allocator& allocator, uint facesCapacity, uint verticesCapacity,
|
||||
HalfEdgeStructure(MemoryAllocator& allocator, uint facesCapacity, uint verticesCapacity,
|
||||
uint edgesCapacity) :mAllocator(allocator), mFaces(allocator, facesCapacity),
|
||||
mVertices(allocator, verticesCapacity), mEdges(allocator, edgesCapacity) {}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
|
|||
const ConcaveShape* mConcaveShape;
|
||||
|
||||
/// Reference to the single-frame memory allocator
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -74,7 +74,7 @@ class MiddlePhaseTriangleCallback : public TriangleCallback {
|
|||
MiddlePhaseTriangleCallback(OverlappingPair* overlappingPair,
|
||||
ProxyShape* concaveProxyShape,
|
||||
ProxyShape* convexProxyShape, const ConcaveShape* concaveShape,
|
||||
Allocator& allocator)
|
||||
MemoryAllocator& allocator)
|
||||
:mOverlappingPair(overlappingPair), mConcaveProxyShape(concaveProxyShape),
|
||||
mConvexProxyShape(convexProxyShape), mConcaveShape(concaveShape),
|
||||
mAllocator(allocator), narrowPhaseInfoList(nullptr) {
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace reactphysics3d;
|
|||
// Constructor
|
||||
NarrowPhaseInfo::NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform, Allocator& shapeAllocator)
|
||||
const Transform& shape2Transform, MemoryAllocator& shapeAllocator)
|
||||
: overlappingPair(pair), collisionShape1(shape1), collisionShape2(shape2),
|
||||
shape1ToWorldTransform(shape1Transform), shape2ToWorldTransform(shape2Transform),
|
||||
contactPoints(nullptr), next(nullptr), collisionShapeAllocator(shapeAllocator) {
|
||||
|
@ -68,7 +68,7 @@ void NarrowPhaseInfo::addContactPoint(const Vector3& contactNormal, decimal penD
|
|||
assert(penDepth > decimal(0.0));
|
||||
|
||||
// Get the memory allocator
|
||||
Allocator& allocator = overlappingPair->getTemporaryAllocator();
|
||||
MemoryAllocator& allocator = overlappingPair->getTemporaryAllocator();
|
||||
|
||||
// Create the contact point info
|
||||
ContactPointInfo* contactPointInfo = new (allocator.allocate(sizeof(ContactPointInfo)))
|
||||
|
@ -89,7 +89,7 @@ void NarrowPhaseInfo::addContactPointsAsPotentialContactManifold() {
|
|||
void NarrowPhaseInfo::resetContactPoints() {
|
||||
|
||||
// Get the memory allocator
|
||||
Allocator& allocator = overlappingPair->getTemporaryAllocator();
|
||||
MemoryAllocator& allocator = overlappingPair->getTemporaryAllocator();
|
||||
|
||||
// For each remaining contact point info
|
||||
ContactPointInfo* element = contactPoints;
|
||||
|
|
|
@ -67,12 +67,12 @@ struct NarrowPhaseInfo {
|
|||
NarrowPhaseInfo* next;
|
||||
|
||||
/// Memory allocator for the collision shape (Used to release TriangleShape memory in destructor)
|
||||
Allocator& collisionShapeAllocator;
|
||||
MemoryAllocator& collisionShapeAllocator;
|
||||
|
||||
/// Constructor
|
||||
NarrowPhaseInfo(OverlappingPair* pair, CollisionShape* shape1,
|
||||
CollisionShape* shape2, const Transform& shape1Transform,
|
||||
const Transform& shape2Transform, Allocator& shapeAllocator);
|
||||
const Transform& shape2Transform, MemoryAllocator& shapeAllocator);
|
||||
|
||||
/// Destructor
|
||||
~NarrowPhaseInfo();
|
||||
|
|
|
@ -36,7 +36,7 @@ using namespace reactphysics3d;
|
|||
* @param polygonVertexArray Pointer to the array of polygons and their vertices
|
||||
*/
|
||||
PolyhedronMesh::PolyhedronMesh(PolygonVertexArray* polygonVertexArray)
|
||||
: mHalfEdgeStructure(MemoryManager::getDefaultAllocator(),
|
||||
: mHalfEdgeStructure(MemoryManager::getBaseAllocator(),
|
||||
polygonVertexArray->getNbFaces(),
|
||||
polygonVertexArray->getNbVertices(),
|
||||
(polygonVertexArray->getNbFaces() + polygonVertexArray->getNbVertices() - 2) * 2) {
|
||||
|
@ -75,7 +75,7 @@ void PolyhedronMesh::createHalfEdgeStructure() {
|
|||
// Get the polygon face
|
||||
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 (uint v=0; v < face->nbVertices; v++) {
|
||||
|
|
|
@ -35,9 +35,9 @@ using namespace reactphysics3d;
|
|||
* @param transform Transformation from collision shape local-space to body local-space
|
||||
* @param mass Mass of the collision shape (in kilograms)
|
||||
*/
|
||||
ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, decimal mass, Allocator& allocator)
|
||||
:mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass),
|
||||
mNext(nullptr), mBroadPhaseID(-1), mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF), mAllocator(allocator) {
|
||||
ProxyShape::ProxyShape(CollisionBody* body, CollisionShape* shape, const Transform& transform, decimal mass, MemoryManager& memoryManager)
|
||||
:mMemoryManager(memoryManager), mBody(body), mCollisionShape(shape), mLocalToBodyTransform(transform), mMass(mass),
|
||||
mNext(nullptr), mBroadPhaseID(-1), mCollisionCategoryBits(0x0001), mCollideWithMaskBits(0xFFFF) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo) {
|
|||
worldToLocalTransform * ray.point2,
|
||||
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
|
||||
raycastInfo.worldPoint = localToWorldTransform * raycastInfo.worldPoint;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
// Libraries
|
||||
#include "body/CollisionBody.h"
|
||||
#include "shapes/CollisionShape.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -48,6 +49,9 @@ class ProxyShape {
|
|||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Reference to the memory manager
|
||||
MemoryManager& mMemoryManager;
|
||||
|
||||
/// Pointer to the parent body
|
||||
CollisionBody* mBody;
|
||||
|
||||
|
@ -82,9 +86,6 @@ class ProxyShape {
|
|||
/// proxy shape will collide with every collision categories by default.
|
||||
unsigned short mCollideWithMaskBits;
|
||||
|
||||
/// Memory allocator
|
||||
Allocator& mAllocator;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
/// Pointer to the profiler
|
||||
|
@ -103,7 +104,7 @@ class ProxyShape {
|
|||
|
||||
/// Constructor
|
||||
ProxyShape(CollisionBody* body, CollisionShape* shape,
|
||||
const Transform& transform, decimal mass, Allocator& allocator);
|
||||
const Transform& transform, decimal mass, MemoryManager& memoryManager);
|
||||
|
||||
/// Destructor
|
||||
virtual ~ProxyShape();
|
||||
|
|
|
@ -185,14 +185,14 @@ void BroadPhaseAlgorithm::reportAllShapesOverlappingWithAABB(const AABB& aabb,
|
|||
}
|
||||
|
||||
// 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
|
||||
|
||||
// Reset the potential overlapping pairs
|
||||
mNbPotentialPairs = 0;
|
||||
|
||||
LinkedList<int> overlappingNodes(allocator);
|
||||
LinkedList<int> overlappingNodes(memoryManager.getPoolAllocator());
|
||||
|
||||
// For all collision shapes that have moved (or have been created) during the
|
||||
// last simulation step
|
||||
|
|
|
@ -210,7 +210,7 @@ class BroadPhaseAlgorithm {
|
|||
void reportAllShapesOverlappingWithAABB(const AABB& aabb, LinkedList<int>& overlappingNodes) const;
|
||||
|
||||
/// 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
|
||||
ProxyShape* getProxyShapeForBroadPhaseId(int broadPhaseId) const;
|
||||
|
|
|
@ -34,7 +34,7 @@ using namespace reactphysics3d;
|
|||
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
|
||||
// by Dirk Gregorius.
|
||||
bool CapsuleVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator) {
|
||||
MemoryAllocator& memoryAllocator) {
|
||||
|
||||
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CAPSULE);
|
||||
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CAPSULE);
|
||||
|
|
|
@ -61,7 +61,7 @@ class CapsuleVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
|
|||
CapsuleVsCapsuleAlgorithm& operator=(const CapsuleVsCapsuleAlgorithm& algorithm) = delete;
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ using namespace reactphysics3d;
|
|||
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
|
||||
// by Dirk Gregorius.
|
||||
bool CapsuleVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator) {
|
||||
MemoryAllocator& memoryAllocator) {
|
||||
|
||||
// First, we run the GJK algorithm
|
||||
GJKAlgorithm gjkAlgorithm;
|
||||
|
|
|
@ -61,7 +61,7 @@ class CapsuleVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm {
|
|||
CapsuleVsConvexPolyhedronAlgorithm& operator=(const CapsuleVsConvexPolyhedronAlgorithm& algorithm) = delete;
|
||||
|
||||
/// Compute the narrow-phase collision detection between a capsule and a polyhedron
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace reactphysics3d;
|
|||
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
|
||||
// by Dirk Gregorius.
|
||||
bool ConvexPolyhedronVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator) {
|
||||
MemoryAllocator& memoryAllocator) {
|
||||
|
||||
// Run the SAT algorithm to find the separating axis and compute contact point
|
||||
SATAlgorithm satAlgorithm(memoryAllocator);
|
||||
|
|
|
@ -61,7 +61,7 @@ class ConvexPolyhedronVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm
|
|||
ConvexPolyhedronVsConvexPolyhedronAlgorithm& operator=(const ConvexPolyhedronVsConvexPolyhedronAlgorithm& algorithm) = delete;
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ class NarrowPhaseAlgorithm {
|
|||
|
||||
/// Compute a contact info if the two bounding volumes collide
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator)=0;
|
||||
MemoryAllocator& memoryAllocator)=0;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ using namespace reactphysics3d;
|
|||
const decimal SATAlgorithm::SAME_SEPARATING_AXIS_BIAS = decimal(0.001);
|
||||
|
||||
// Constructor
|
||||
SATAlgorithm::SATAlgorithm(Allocator& memoryAllocator) : mMemoryAllocator(memoryAllocator) {
|
||||
SATAlgorithm::SATAlgorithm(MemoryAllocator& memoryAllocator) : mMemoryAllocator(memoryAllocator) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class SATAlgorithm {
|
|||
static const decimal SAME_SEPARATING_AXIS_BIAS;
|
||||
|
||||
/// Memory allocator
|
||||
Allocator& mMemoryAllocator;
|
||||
MemoryAllocator& mMemoryAllocator;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -115,7 +115,7 @@ class SATAlgorithm {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
SATAlgorithm(Allocator& memoryAllocator);
|
||||
SATAlgorithm(MemoryAllocator& memoryAllocator);
|
||||
|
||||
/// Destructor
|
||||
~SATAlgorithm() = default;
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace reactphysics3d;
|
|||
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
|
||||
// by Dirk Gregorius.
|
||||
bool SphereVsCapsuleAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator) {
|
||||
MemoryAllocator& memoryAllocator) {
|
||||
|
||||
bool isSphereShape1 = narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class SphereVsCapsuleAlgorithm : public NarrowPhaseAlgorithm {
|
|||
SphereVsCapsuleAlgorithm& operator=(const SphereVsCapsuleAlgorithm& algorithm) = delete;
|
||||
|
||||
/// Compute the narrow-phase collision detection between a sphere and a capsule
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ using namespace reactphysics3d;
|
|||
// This technique is based on the "Robust Contact Creation for Physics Simulations" presentation
|
||||
// by Dirk Gregorius.
|
||||
bool SphereVsConvexPolyhedronAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator) {
|
||||
MemoryAllocator& memoryAllocator) {
|
||||
|
||||
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::CONVEX_POLYHEDRON ||
|
||||
narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::CONVEX_POLYHEDRON);
|
||||
|
|
|
@ -61,7 +61,7 @@ class SphereVsConvexPolyhedronAlgorithm : public NarrowPhaseAlgorithm {
|
|||
SphereVsConvexPolyhedronAlgorithm& operator=(const SphereVsConvexPolyhedronAlgorithm& algorithm) = delete;
|
||||
|
||||
/// Compute the narrow-phase collision detection between a sphere and a convex polyhedron
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, Allocator& memoryAllocator) override;
|
||||
virtual bool testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts, MemoryAllocator& memoryAllocator) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
bool SphereVsSphereAlgorithm::testCollision(NarrowPhaseInfo* narrowPhaseInfo, bool reportContacts,
|
||||
Allocator& memoryAllocator) {
|
||||
MemoryAllocator& memoryAllocator) {
|
||||
|
||||
assert(narrowPhaseInfo->collisionShape1->getType() == CollisionShapeType::SPHERE);
|
||||
assert(narrowPhaseInfo->collisionShape2->getType() == CollisionShapeType::SPHERE);
|
||||
|
|
|
@ -61,7 +61,7 @@ class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm {
|
|||
SphereVsSphereAlgorithm& operator=(const SphereVsSphereAlgorithm& algorithm) = delete;
|
||||
|
||||
/// 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ using namespace reactphysics3d;
|
|||
*/
|
||||
BoxShape::BoxShape(const Vector3& 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.y > decimal(0.0));
|
||||
|
@ -55,7 +55,7 @@ BoxShape::BoxShape(const Vector3& extent)
|
|||
mHalfEdgeStructure.addVertex(6);
|
||||
mHalfEdgeStructure.addVertex(7);
|
||||
|
||||
DefaultAllocator& allocator = MemoryManager::getDefaultAllocator();
|
||||
MemoryAllocator& allocator = MemoryManager::getBaseAllocator();
|
||||
|
||||
// Faces
|
||||
List<uint> face0(allocator, 4);
|
||||
|
@ -98,7 +98,7 @@ void BoxShape::computeLocalInertiaTensor(Matrix3x3& tensor, decimal mass) const
|
|||
}
|
||||
|
||||
// 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;
|
||||
decimal tMin = DECIMAL_SMALLEST;
|
||||
|
|
|
@ -64,7 +64,7 @@ class BoxShape : public ConvexPolyhedronShape {
|
|||
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
|
||||
|
||||
/// 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
|
||||
virtual size_t getSizeInBytes() const override;
|
||||
|
|
|
@ -85,7 +85,7 @@ bool CapsuleShape::testPointInside(const Vector3& localPoint, ProxyShape* proxyS
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ class CapsuleShape : public ConvexShape {
|
|||
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
|
||||
|
||||
/// 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
|
||||
bool raycastWithSphereEndCap(const Vector3& point1, const Vector3& point2,
|
||||
|
|
|
@ -87,7 +87,7 @@ class CollisionShape {
|
|||
virtual bool testPointInside(const Vector3& worldPoint, ProxyShape* proxyShape) const=0;
|
||||
|
||||
/// 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
|
||||
virtual size_t getSizeInBytes() const = 0;
|
||||
|
|
|
@ -111,7 +111,7 @@ void ConcaveMeshShape::testAllTriangles(TriangleCallback& callback, const AABB&
|
|||
// Raycast method with feedback information
|
||||
/// Note that only the first triangle hit by the ray in the mesh will be returned, even if
|
||||
/// 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);
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
|||
RaycastInfo& mRaycastInfo;
|
||||
const Ray& mRay;
|
||||
bool mIsHit;
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -90,7 +90,7 @@ class ConcaveMeshRaycastCallback : public DynamicAABBTreeRaycastCallback {
|
|||
|
||||
// Constructor
|
||||
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),
|
||||
mRaycastInfo(raycastInfo), mRay(ray), mIsHit(false), mAllocator(allocator) {
|
||||
|
||||
|
@ -142,7 +142,7 @@ class ConcaveMeshShape : public ConcaveShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// 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
|
||||
virtual size_t getSizeInBytes() const override;
|
||||
|
|
|
@ -112,7 +112,7 @@ void ConvexMeshShape::recalculateBounds() {
|
|||
}
|
||||
|
||||
// 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(
|
||||
ray, proxyShape, raycastInfo);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ class ConvexMeshShape : public ConvexPolyhedronShape {
|
|||
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
|
||||
|
||||
/// 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
|
||||
virtual size_t getSizeInBytes() const override;
|
||||
|
|
|
@ -212,7 +212,7 @@ void HeightFieldShape::computeMinMaxGridCoordinates(int* minCoords, int* maxCoor
|
|||
// Raycast method with feedback information
|
||||
/// Note that only the first triangle hit by the ray in the mesh will be returned, even if
|
||||
/// 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
|
||||
// but using a dynamic AABB tree or octree instead
|
||||
|
|
|
@ -49,7 +49,7 @@ class TriangleOverlapCallback : public TriangleCallback {
|
|||
bool mIsHit;
|
||||
decimal mSmallestHitFraction;
|
||||
const HeightFieldShape& mHeightFieldShape;
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
||||
|
@ -62,7 +62,7 @@ class TriangleOverlapCallback : public TriangleCallback {
|
|||
|
||||
// Constructor
|
||||
TriangleOverlapCallback(const Ray& ray, ProxyShape* proxyShape, RaycastInfo& raycastInfo,
|
||||
const HeightFieldShape& heightFieldShape, Allocator& allocator)
|
||||
const HeightFieldShape& heightFieldShape, MemoryAllocator& allocator)
|
||||
: mRay(ray), mProxyShape(proxyShape), mRaycastInfo(raycastInfo),
|
||||
mHeightFieldShape (heightFieldShape), mAllocator(allocator) {
|
||||
mIsHit = false;
|
||||
|
@ -144,7 +144,7 @@ class HeightFieldShape : public ConcaveShape {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// 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
|
||||
virtual size_t getSizeInBytes() const override;
|
||||
|
|
|
@ -41,7 +41,7 @@ SphereShape::SphereShape(decimal radius)
|
|||
}
|
||||
|
||||
// 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;
|
||||
decimal c = m.dot(m) - mMargin * mMargin;
|
||||
|
|
|
@ -55,7 +55,7 @@ class SphereShape : public ConvexShape {
|
|||
virtual bool testPointInside(const Vector3& localPoint, ProxyShape* proxyShape) const override;
|
||||
|
||||
/// 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
|
||||
virtual size_t getSizeInBytes() const override;
|
||||
|
|
|
@ -45,7 +45,7 @@ using namespace reactphysics3d;
|
|||
* @param margin The collision margin (in meters) around the collision shape
|
||||
*/
|
||||
TriangleShape::TriangleShape(const Vector3* vertices, const Vector3* verticesNormals, uint shapeId,
|
||||
Allocator& allocator)
|
||||
MemoryAllocator& allocator)
|
||||
: ConvexPolyhedronShape(CollisionShapeName::TRIANGLE), mFaces{HalfEdgeStructure::Face(allocator), HalfEdgeStructure::Face(allocator)} {
|
||||
|
||||
mPoints[0] = vertices[0];
|
||||
|
@ -211,7 +211,7 @@ Vector3 TriangleShape::computeSmoothLocalContactNormalForTriangle(const Vector3&
|
|||
// Raycast method with feedback information
|
||||
/// This method use the line vs triangle raycasting technique described in
|
||||
/// 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);
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ class TriangleShape : public ConvexPolyhedronShape {
|
|||
|
||||
/// Raycast method with feedback information
|
||||
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
|
||||
virtual size_t getSizeInBytes() const override;
|
||||
|
@ -113,7 +113,7 @@ class TriangleShape : public ConvexPolyhedronShape {
|
|||
|
||||
/// Constructor
|
||||
TriangleShape(const Vector3* vertices, const Vector3* verticesNormals,
|
||||
uint shapeId, Allocator& allocator);
|
||||
uint shapeId, MemoryAllocator& allocator);
|
||||
|
||||
/// Destructor
|
||||
virtual ~TriangleShape() override = default;
|
||||
|
|
|
@ -152,7 +152,7 @@ constexpr int NB_MAX_CONTACT_MANIFOLDS_CONCAVE_SHAPE = 3;
|
|||
constexpr decimal COS_ANGLE_SIMILAR_CONTACT_MANIFOLD = decimal(0.95);
|
||||
|
||||
/// 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
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define REACTPHYSICS3D_LINKED_LIST_H
|
||||
|
||||
// Libraries
|
||||
#include "memory/Allocator.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
||||
|
@ -64,14 +64,14 @@ class LinkedList {
|
|||
ListElement* mListHead;
|
||||
|
||||
/// Memory allocator used to allocate the list elements
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
LinkedList(Allocator& allocator) : mListHead(nullptr), mAllocator(allocator) {
|
||||
LinkedList(MemoryAllocator& allocator) : mListHead(nullptr), mAllocator(allocator) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "configuration.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace reactphysics3d {
|
||||
|
@ -54,7 +54,7 @@ class List {
|
|||
size_t mCapacity;
|
||||
|
||||
/// Memory allocator
|
||||
Allocator& mAllocator;
|
||||
MemoryAllocator& mAllocator;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
|
@ -64,7 +64,7 @@ class List {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
List(Allocator& allocator, size_t capacity = 0)
|
||||
List(MemoryAllocator& allocator, size_t capacity = 0)
|
||||
: mBuffer(nullptr), mSize(0), mCapacity(0), mAllocator(allocator) {
|
||||
|
||||
if (capacity > 0) {
|
||||
|
|
|
@ -33,8 +33,7 @@ using namespace std;
|
|||
|
||||
// Constructor
|
||||
CollisionWorld::CollisionWorld()
|
||||
: mSingleFrameAllocator(SIZE_SINGLE_FRAME_ALLOCATOR_BYTES),
|
||||
mCollisionDetection(this, mPoolAllocator, mSingleFrameAllocator), mCurrentBodyID(0),
|
||||
: mCollisionDetection(this, mMemoryManager), mCurrentBodyID(0),
|
||||
mEventListener(nullptr) {
|
||||
|
||||
#ifdef IS_PROFILING_ACTIVE
|
||||
|
@ -74,7 +73,8 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
|
|||
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
||||
|
||||
// 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);
|
||||
|
||||
assert(collisionBody != nullptr);
|
||||
|
@ -111,7 +111,7 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
|
|||
mBodies.erase(collisionBody);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
#include "collision/CollisionDetection.h"
|
||||
#include "constraint/Joint.h"
|
||||
#include "constraint/ContactPoint.h"
|
||||
#include "memory/DefaultAllocator.h"
|
||||
#include "memory/PoolAllocator.h"
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "EventListener.h"
|
||||
|
||||
/// Namespace reactphysics3d
|
||||
|
@ -62,11 +61,8 @@ class CollisionWorld {
|
|||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Pool Memory allocator
|
||||
PoolAllocator mPoolAllocator;
|
||||
|
||||
/// Single frame Memory allocator
|
||||
SingleFrameAllocator mSingleFrameAllocator;
|
||||
/// Memory manager
|
||||
MemoryManager mMemoryManager;
|
||||
|
||||
/// Reference to the collision detection
|
||||
CollisionDetection mCollisionDetection;
|
||||
|
|
|
@ -39,9 +39,9 @@ const decimal ContactSolver::BETA_SPLIT_IMPULSE = decimal(0.2);
|
|||
const decimal ContactSolver::SLOP = decimal(0.01);
|
||||
|
||||
// Constructor
|
||||
ContactSolver::ContactSolver(SingleFrameAllocator& allocator)
|
||||
:mSplitLinearVelocities(nullptr), mSplitAngularVelocities(nullptr),
|
||||
mContactConstraints(nullptr), mSingleFrameAllocator(allocator),
|
||||
ContactSolver::ContactSolver(MemoryManager& memoryManager)
|
||||
:mMemoryManager(memoryManager), mSplitLinearVelocities(nullptr),
|
||||
mSplitAngularVelocities(nullptr), mContactConstraints(nullptr),
|
||||
mLinearVelocities(nullptr), mAngularVelocities(nullptr),
|
||||
mIsSplitImpulseActive(true) {
|
||||
|
||||
|
@ -75,10 +75,12 @@ void ContactSolver::init(Island** islands, uint nbIslands, decimal timeStep) {
|
|||
if (nbContactManifolds == 0 || nbContactPoints == 0) return;
|
||||
|
||||
// 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);
|
||||
|
||||
mContactConstraints = static_cast<ContactManifoldSolver*>(mSingleFrameAllocator.allocate(sizeof(ContactManifoldSolver) * nbContactManifolds));
|
||||
mContactConstraints = static_cast<ContactManifoldSolver*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
|
||||
sizeof(ContactManifoldSolver) * nbContactManifolds));
|
||||
assert(mContactConstraints != nullptr);
|
||||
|
||||
// For each island of the world
|
||||
|
|
|
@ -272,6 +272,10 @@ class ContactSolver {
|
|||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Memory manager
|
||||
MemoryManager& mMemoryManager;
|
||||
|
||||
|
||||
/// Split linear velocities for the position contact solver (split impulse)
|
||||
Vector3* mSplitLinearVelocities;
|
||||
|
||||
|
@ -293,9 +297,6 @@ class ContactSolver {
|
|||
/// Number of contact constraints
|
||||
uint mNbContactManifolds;
|
||||
|
||||
/// Single frame memory allocator
|
||||
SingleFrameAllocator& mSingleFrameAllocator;
|
||||
|
||||
/// Array of linear velocities
|
||||
Vector3* mLinearVelocities;
|
||||
|
||||
|
@ -339,7 +340,7 @@ class ContactSolver {
|
|||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
ContactSolver(SingleFrameAllocator& allocator);
|
||||
ContactSolver(MemoryManager& memoryManager);
|
||||
|
||||
/// Destructor
|
||||
~ContactSolver() = default;
|
||||
|
|
|
@ -41,7 +41,7 @@ using namespace std;
|
|||
*/
|
||||
DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
|
||||
: CollisionWorld(),
|
||||
mContactSolver(mSingleFrameAllocator),
|
||||
mContactSolver(mMemoryManager),
|
||||
mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
|
||||
mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
|
||||
mIsSleepingEnabled(SLEEPING_ENABLED), mGravity(gravity), mTimeStep(decimal(1.0f / 60.0f)),
|
||||
|
@ -147,7 +147,7 @@ void DynamicsWorld::update(decimal timeStep) {
|
|||
resetBodiesForceAndTorque();
|
||||
|
||||
// Reset the single frame memory allocator
|
||||
mSingleFrameAllocator.reset();
|
||||
mMemoryManager.resetFrameAllocator();
|
||||
}
|
||||
|
||||
// Integrate position and orientation of the rigid bodies.
|
||||
|
@ -236,12 +236,18 @@ void DynamicsWorld::initVelocityArrays() {
|
|||
// Allocate memory for the bodies velocity arrays
|
||||
uint nbBodies = mRigidBodies.size();
|
||||
|
||||
mSplitLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||
mSplitAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||
mConstrainedLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||
mConstrainedAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||
mConstrainedPositions = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||
mConstrainedOrientations = static_cast<Quaternion*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Quaternion)));
|
||||
mSplitLinearVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
|
||||
nbBodies * sizeof(Vector3)));
|
||||
mSplitAngularVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
|
||||
nbBodies * sizeof(Vector3)));
|
||||
mConstrainedLinearVelocities = static_cast<Vector3*>(mMemoryManager.allocate(MemoryManager::AllocationType::Frame,
|
||||
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(mSplitAngularVelocities != nullptr);
|
||||
assert(mConstrainedLinearVelocities != nullptr);
|
||||
|
@ -412,8 +418,8 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
|
|||
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
||||
|
||||
// Create the rigid body
|
||||
RigidBody* rigidBody = new (mPoolAllocator.allocate(sizeof(RigidBody))) RigidBody(transform,
|
||||
*this, bodyID);
|
||||
RigidBody* rigidBody = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool,
|
||||
sizeof(RigidBody))) RigidBody(transform, *this, bodyID);
|
||||
assert(rigidBody != nullptr);
|
||||
|
||||
// Add the rigid body to the physics world
|
||||
|
@ -459,7 +465,7 @@ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
|
|||
mRigidBodies.erase(rigidBody);
|
||||
|
||||
// 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
|
||||
|
@ -477,7 +483,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
// Ball-and-Socket joint
|
||||
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&>(
|
||||
jointInfo);
|
||||
newJoint = new (allocatedMemory) BallAndSocketJoint(info);
|
||||
|
@ -487,7 +494,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
// Slider joint
|
||||
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);
|
||||
newJoint = new (allocatedMemory) SliderJoint(info);
|
||||
break;
|
||||
|
@ -496,7 +504,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
// Hinge joint
|
||||
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);
|
||||
newJoint = new (allocatedMemory) HingeJoint(info);
|
||||
break;
|
||||
|
@ -505,7 +514,8 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
|||
// Fixed joint
|
||||
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);
|
||||
newJoint = new (allocatedMemory) FixedJoint(info);
|
||||
break;
|
||||
|
@ -558,8 +568,8 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
|||
mJoints.erase(joint);
|
||||
|
||||
// Remove the joint from the joint list of the bodies involved in the joint
|
||||
joint->mBody1->removeJointFromJointsList(mPoolAllocator, joint);
|
||||
joint->mBody2->removeJointFromJointsList(mPoolAllocator, joint);
|
||||
joint->mBody1->removeJointFromJointsList(mMemoryManager, joint);
|
||||
joint->mBody2->removeJointFromJointsList(mMemoryManager, joint);
|
||||
|
||||
size_t nbBytes = joint->getSizeInBytes();
|
||||
|
||||
|
@ -567,7 +577,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
|||
joint->~Joint();
|
||||
|
||||
// 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
|
||||
|
@ -576,13 +586,15 @@ void DynamicsWorld::addJointToBody(Joint* joint) {
|
|||
assert(joint != nullptr);
|
||||
|
||||
// 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,
|
||||
joint->mBody1->mJointsList);
|
||||
joint->mBody1->mJointsList = jointListElement1;
|
||||
|
||||
// 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,
|
||||
joint->mBody2->mJointsList);
|
||||
joint->mBody2->mJointsList = jointListElement2;
|
||||
|
@ -603,7 +615,8 @@ void DynamicsWorld::computeIslands() {
|
|||
|
||||
// Allocate and create the array of islands pointer. This memory is allocated
|
||||
// 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;
|
||||
|
||||
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
|
||||
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 (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) {
|
||||
|
@ -642,9 +656,10 @@ void DynamicsWorld::computeIslands() {
|
|||
body->mIsAlreadyInIsland = true;
|
||||
|
||||
// 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(),
|
||||
mSingleFrameAllocator);
|
||||
mMemoryManager);
|
||||
|
||||
// While there are still some bodies to visit in the stack
|
||||
while (stackIndex > 0) {
|
||||
|
|
|
@ -29,14 +29,17 @@
|
|||
using namespace reactphysics3d;
|
||||
|
||||
// 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),
|
||||
mNbContactManifolds(0), mNbJoints(0) {
|
||||
|
||||
// Allocate memory for the arrays on the single frame allocator
|
||||
mBodies = static_cast<RigidBody**>(allocator.allocate(sizeof(RigidBody*) * nbMaxBodies));
|
||||
mContactManifolds = static_cast<ContactManifold**>(allocator.allocate(sizeof(ContactManifold*) * nbMaxContactManifolds));
|
||||
mJoints = static_cast<Joint**>(allocator.allocate(sizeof(Joint*) * nbMaxJoints));
|
||||
mBodies = static_cast<RigidBody**>(memoryManager.allocate(MemoryManager::AllocationType::Frame,
|
||||
sizeof(RigidBody*) * nbMaxBodies));
|
||||
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
|
||||
|
|
|
@ -69,7 +69,7 @@ class Island {
|
|||
|
||||
/// Constructor
|
||||
Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
|
||||
SingleFrameAllocator& allocator);
|
||||
MemoryManager& memoryManager);
|
||||
|
||||
/// Destructor
|
||||
~Island();
|
||||
|
|
|
@ -33,7 +33,7 @@ using namespace reactphysics3d;
|
|||
|
||||
// Constructor
|
||||
OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
|
||||
Allocator& persistentMemoryAllocator, Allocator& temporaryMemoryAllocator)
|
||||
MemoryAllocator& persistentMemoryAllocator, MemoryAllocator& temporaryMemoryAllocator)
|
||||
: mContactManifoldSet(shape1, shape2, persistentMemoryAllocator), mPotentialContactManifolds(nullptr),
|
||||
mPersistentAllocator(persistentMemoryAllocator), mTempMemoryAllocator(temporaryMemoryAllocator) {
|
||||
|
||||
|
|
|
@ -113,18 +113,18 @@ class OverlappingPair {
|
|||
ContactManifoldInfo* mPotentialContactManifolds;
|
||||
|
||||
/// Persistent memory allocator
|
||||
Allocator& mPersistentAllocator;
|
||||
MemoryAllocator& mPersistentAllocator;
|
||||
|
||||
/// Memory allocator used to allocated memory for the ContactManifoldInfo and ContactPointInfo
|
||||
Allocator& mTempMemoryAllocator;
|
||||
MemoryAllocator& mTempMemoryAllocator;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, Allocator& persistentMemoryAllocator,
|
||||
Allocator& temporaryMemoryAllocator);
|
||||
OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, MemoryAllocator& persistentMemoryAllocator,
|
||||
MemoryAllocator& temporaryMemoryAllocator);
|
||||
|
||||
/// Destructor
|
||||
~OverlappingPair();
|
||||
|
@ -157,7 +157,7 @@ class OverlappingPair {
|
|||
void addContactManifold(const ContactManifoldInfo* contactManifoldInfo);
|
||||
|
||||
/// 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
|
||||
bool hasConcaveShape() const;
|
||||
|
@ -264,7 +264,7 @@ inline bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* body
|
|||
}
|
||||
|
||||
// Return a reference to the temporary memory allocator
|
||||
inline Allocator& OverlappingPair::getTemporaryAllocator() {
|
||||
inline MemoryAllocator& OverlappingPair::getTemporaryAllocator() {
|
||||
return mTempMemoryAllocator;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ decimal reactphysics3d::computePointToLineDistance(const Vector3& linePointA, co
|
|||
List<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB,
|
||||
const List<Vector3>& planesPoints,
|
||||
const List<Vector3>& planesNormals,
|
||||
Allocator& allocator) {
|
||||
MemoryAllocator& allocator) {
|
||||
|
||||
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
|
||||
// This method implements the Sutherland–Hodgman clipping algorithm
|
||||
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());
|
||||
|
||||
|
|
|
@ -115,11 +115,11 @@ decimal computePointToLineDistance(const Vector3& linePointA, const Vector3& lin
|
|||
List<Vector3> clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB,
|
||||
const List<Vector3>& planesPoints,
|
||||
const List<Vector3>& planesNormals,
|
||||
Allocator& allocator);
|
||||
MemoryAllocator& allocator);
|
||||
|
||||
/// Clip a polygon against multiple planes and return the clipped polygon vertices
|
||||
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
|
||||
Vector3 projectPointOntoPlane(const Vector3& point, const Vector3& planeNormal, const Vector3& planePoint);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define REACTPHYSICS3D_DEFAULT_ALLOCATOR_H
|
||||
|
||||
// Libraries
|
||||
#include "memory/Allocator.h"
|
||||
#include "memory/MemoryAllocator.h"
|
||||
#include <cstdlib>
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
|
@ -37,13 +37,16 @@ namespace reactphysics3d {
|
|||
/**
|
||||
* This class represents a default memory allocator that uses default malloc/free methods
|
||||
*/
|
||||
class DefaultAllocator : public Allocator {
|
||||
class DefaultAllocator : public MemoryAllocator {
|
||||
|
||||
public:
|
||||
|
||||
/// Destructor
|
||||
virtual ~DefaultAllocator() = default;
|
||||
|
||||
/// Assignment operator
|
||||
DefaultAllocator& operator=(DefaultAllocator& allocator) = default;
|
||||
|
||||
/// Allocate memory of a given size (in bytes) and return a pointer to the
|
||||
/// allocated memory.
|
||||
virtual void* allocate(size_t size) override {
|
||||
|
@ -54,11 +57,6 @@ class DefaultAllocator : public Allocator {
|
|||
virtual void release(void* pointer, size_t size) override {
|
||||
free(pointer);
|
||||
}
|
||||
|
||||
/// Return true if memory needs to be release with this allocator
|
||||
virtual bool isReleaseNeeded() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef REACTPHYSICS3D_ALLOCATOR_H
|
||||
#define REACTPHYSICS3D_ALLOCATOR_H
|
||||
#ifndef REACTPHYSICS3D_MEMORY_ALLOCATOR_H
|
||||
#define REACTPHYSICS3D_MEMORY_ALLOCATOR_H
|
||||
|
||||
// Libraries
|
||||
#include <cstring>
|
||||
|
@ -32,16 +32,22 @@
|
|||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
||||
// Class Allocator
|
||||
// Class MemoryAllocator
|
||||
/**
|
||||
* Abstract class with the basic interface of all the derived memory allocators
|
||||
*/
|
||||
class Allocator {
|
||||
class MemoryAllocator {
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
MemoryAllocator() = default;
|
||||
|
||||
/// 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
|
||||
/// allocated memory.
|
||||
|
@ -49,9 +55,6 @@ class Allocator {
|
|||
|
||||
/// Release previously allocated memory.
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
|
@ -30,3 +30,5 @@ using namespace reactphysics3d;
|
|||
|
||||
// Static variables
|
||||
DefaultAllocator MemoryManager::mDefaultAllocator;
|
||||
MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator;
|
||||
|
||||
|
|
|
@ -27,7 +27,10 @@
|
|||
#define REACTPHYSICS3D_MEMORY_MANAGER_H
|
||||
|
||||
// Libraries
|
||||
#include "memory/MemoryAllocator.h"
|
||||
#include "memory/DefaultAllocator.h"
|
||||
#include "memory/PoolAllocator.h"
|
||||
#include "memory/SingleFrameAllocator.h"
|
||||
|
||||
/// Namespace ReactPhysics3D
|
||||
namespace reactphysics3d {
|
||||
|
@ -41,31 +44,98 @@ class MemoryManager {
|
|||
|
||||
private:
|
||||
|
||||
/// Default memory allocator
|
||||
/// Default malloc/free memory allocator
|
||||
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:
|
||||
|
||||
/// Memory allocation types
|
||||
enum class AllocationType {
|
||||
Default, // Default memory allocator
|
||||
Base, // Base memory allocator
|
||||
Pool, // Memory pool allocator
|
||||
Frame, // Single frame memory allocator
|
||||
};
|
||||
|
||||
/// Constructor
|
||||
MemoryManager();
|
||||
/// Constructor
|
||||
MemoryManager() = default;
|
||||
|
||||
/// Destructor
|
||||
~MemoryManager();
|
||||
/// Destructor
|
||||
~MemoryManager() = default;
|
||||
|
||||
/// Return the default memory allocator
|
||||
static DefaultAllocator& getDefaultAllocator();
|
||||
/// Allocate memory of a given type
|
||||
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
|
||||
inline DefaultAllocator& MemoryManager::getDefaultAllocator() {
|
||||
return mDefaultAllocator;
|
||||
// Allocate memory of a given type
|
||||
inline void* MemoryManager::allocate(AllocationType allocationType, size_t size) {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "PoolAllocator.h"
|
||||
#include "MemoryManager.h"
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
|
@ -42,7 +43,7 @@ PoolAllocator::PoolAllocator() {
|
|||
mNbAllocatedMemoryBlocks = 64;
|
||||
mNbCurrentMemoryBlocks = 0;
|
||||
const size_t sizeToAllocate = mNbAllocatedMemoryBlocks * sizeof(MemoryBlock);
|
||||
mMemoryBlocks = (MemoryBlock*) malloc(sizeToAllocate);
|
||||
mMemoryBlocks = static_cast<MemoryBlock*>(MemoryManager::getBaseAllocator().allocate(sizeToAllocate));
|
||||
memset(mMemoryBlocks, 0, sizeToAllocate);
|
||||
memset(mFreeMemoryUnits, 0, sizeof(mFreeMemoryUnits));
|
||||
|
||||
|
@ -55,7 +56,7 @@ PoolAllocator::PoolAllocator() {
|
|||
|
||||
// Initialize the array that contains the sizes the memory units that will
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -82,16 +83,17 @@ PoolAllocator::~PoolAllocator() {
|
|||
|
||||
// Release the memory allocated for each block
|
||||
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
|
||||
// Check that the allocate() and release() methods have been called the same
|
||||
// number of times to avoid memory leaks.
|
||||
assert(mNbTimesAllocateMethodCalled == 0);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// 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 (size > MAX_UNIT_SIZE) {
|
||||
|
||||
// Allocate memory using standard malloc() function
|
||||
return malloc(size);
|
||||
// Allocate memory using default allocation
|
||||
return MemoryManager::getBaseAllocator().allocate(size);
|
||||
}
|
||||
|
||||
// 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
|
||||
MemoryBlock* currentMemoryBlocks = mMemoryBlocks;
|
||||
mNbAllocatedMemoryBlocks += 64;
|
||||
mMemoryBlocks = (MemoryBlock*) malloc(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock));
|
||||
mMemoryBlocks = static_cast<MemoryBlock*>(MemoryManager::getBaseAllocator().allocate(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock)));
|
||||
memcpy(mMemoryBlocks, currentMemoryBlocks,mNbCurrentMemoryBlocks * sizeof(MemoryBlock));
|
||||
memset(mMemoryBlocks + mNbCurrentMemoryBlocks, 0, 64 * sizeof(MemoryBlock));
|
||||
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
|
||||
// memory units
|
||||
MemoryBlock* newBlock = mMemoryBlocks + mNbCurrentMemoryBlocks;
|
||||
newBlock->memoryUnits = (MemoryUnit*) malloc(BLOCK_SIZE);
|
||||
newBlock->memoryUnits = static_cast<MemoryUnit*>(MemoryManager::getBaseAllocator().allocate(BLOCK_SIZE));
|
||||
assert(newBlock->memoryUnits != nullptr);
|
||||
size_t unitSize = mUnitSizes[indexHeap];
|
||||
uint nbUnits = BLOCK_SIZE / unitSize;
|
||||
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++) {
|
||||
MemoryUnit* unit = (MemoryUnit*) ((size_t)newBlock->memoryUnits + unitSize * i);
|
||||
MemoryUnit* nextUnit = (MemoryUnit*) ((size_t)newBlock->memoryUnits + unitSize * (i+1));
|
||||
void* unitPointer = static_cast<void*>(memoryUnitsStartChar + unitSize * i);
|
||||
void* nextUnitPointer = static_cast<void*>(memoryUnitsStartChar + unitSize * (i+1));
|
||||
MemoryUnit* unit = static_cast<MemoryUnit*>(unitPointer);
|
||||
MemoryUnit* nextUnit = static_cast<MemoryUnit*>(nextUnitPointer);
|
||||
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;
|
||||
|
||||
// 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 (size > MAX_UNIT_SIZE) {
|
||||
|
||||
// Release the memory using the standard free() function
|
||||
free(pointer);
|
||||
// Release the memory using the default deallocation
|
||||
MemoryManager::getBaseAllocator().release(pointer, size);
|
||||
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
|
||||
// corresponding heap
|
||||
MemoryUnit* releasedUnit = (MemoryUnit*) pointer;
|
||||
MemoryUnit* releasedUnit = static_cast<MemoryUnit*>(pointer);
|
||||
releasedUnit->nextUnit = mFreeMemoryUnits[indexHeap];
|
||||
mFreeMemoryUnits[indexHeap] = releasedUnit;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
// Libraries
|
||||
#include "configuration.h"
|
||||
#include "Allocator.h"
|
||||
#include "MemoryAllocator.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
namespace reactphysics3d {
|
||||
|
@ -40,7 +40,7 @@ namespace reactphysics3d {
|
|||
* efficiently. This implementation is inspired by the small block allocator
|
||||
* described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp
|
||||
*/
|
||||
class PoolAllocator : public Allocator {
|
||||
class PoolAllocator : public MemoryAllocator {
|
||||
|
||||
private :
|
||||
|
||||
|
@ -131,23 +131,17 @@ class PoolAllocator : public Allocator {
|
|||
/// Destructor
|
||||
virtual ~PoolAllocator() override;
|
||||
|
||||
/// Assignment operator
|
||||
PoolAllocator& operator=(PoolAllocator& allocator) = default;
|
||||
|
||||
/// Allocate memory of a given size (in bytes) and return a pointer to the
|
||||
/// allocated memory.
|
||||
virtual void* allocate(size_t size) override;
|
||||
|
||||
/// Release previously allocated memory.
|
||||
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
|
||||
|
|
|
@ -25,17 +25,19 @@
|
|||
|
||||
// Libraries
|
||||
#include "SingleFrameAllocator.h"
|
||||
#include "MemoryManager.h"
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constructor
|
||||
SingleFrameAllocator::SingleFrameAllocator(size_t totalSizeBytes)
|
||||
: mTotalSizeBytes(totalSizeBytes), mCurrentOffset(0) {
|
||||
SingleFrameAllocator::SingleFrameAllocator()
|
||||
: mTotalSizeBytes(INIT_SINGLE_FRAME_ALLOCATOR_BYTES),
|
||||
mCurrentOffset(0), mNbFramesTooMuchAllocated(0), mNeedToAllocatedMore(false) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -43,7 +45,7 @@ SingleFrameAllocator::SingleFrameAllocator(size_t totalSizeBytes)
|
|||
SingleFrameAllocator::~SingleFrameAllocator() {
|
||||
|
||||
// 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) {
|
||||
|
||||
// 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
|
||||
// size of memory of this allocator
|
||||
assert(false);
|
||||
// We need to allocate more memory next time reset() is called
|
||||
mNeedToAllocatedMore = true;
|
||||
|
||||
// Return null
|
||||
return nullptr;
|
||||
// Return default memory allocation
|
||||
return MemoryManager::getBaseAllocator().allocate(size);
|
||||
}
|
||||
|
||||
// Next available memory location
|
||||
|
@ -72,9 +73,63 @@ void* SingleFrameAllocator::allocate(size_t size) {
|
|||
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
|
||||
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
|
||||
mCurrentOffset = 0;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define REACTPHYSICS3D_SINGLE_FRAME_ALLOCATOR_H
|
||||
|
||||
// Libraries
|
||||
#include "Allocator.h"
|
||||
#include "MemoryAllocator.h"
|
||||
#include "configuration.h"
|
||||
|
||||
/// ReactPhysics3D namespace
|
||||
|
@ -38,10 +38,16 @@ namespace reactphysics3d {
|
|||
* This class represent a memory allocator used to efficiently allocate
|
||||
* memory on the heap that is used during a single frame.
|
||||
*/
|
||||
class SingleFrameAllocator : public Allocator {
|
||||
class SingleFrameAllocator : public MemoryAllocator {
|
||||
|
||||
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 -------------------- //
|
||||
|
||||
/// Total size (in bytes) of memory of the allocator
|
||||
|
@ -51,36 +57,38 @@ class SingleFrameAllocator : public Allocator {
|
|||
char* mMemoryBufferStart;
|
||||
|
||||
/// 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 :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
SingleFrameAllocator(size_t totalSizeBytes);
|
||||
SingleFrameAllocator();
|
||||
|
||||
/// Destructor
|
||||
virtual ~SingleFrameAllocator() override;
|
||||
|
||||
/// Assignment operator
|
||||
SingleFrameAllocator& operator=(SingleFrameAllocator& allocator) = default;
|
||||
|
||||
/// Allocate memory of a given size (in bytes)
|
||||
virtual void* allocate(size_t size) override;
|
||||
|
||||
/// 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
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue
Block a user