Allocate memory in the SingleFrameAllocator in the update() method

This commit is contained in:
Daniel Chappuis 2016-09-22 23:24:03 +02:00
parent e014f00afc
commit 8f4979f4a2
4 changed files with 34 additions and 108 deletions

View File

@ -49,8 +49,7 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr), mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr),
mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr), mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr),
mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr), mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr),
mConstrainedOrientations(nullptr), mNbIslands(0), mConstrainedOrientations(nullptr), mNbIslands(0), mIslands(nullptr),
mNbIslandsCapacity(0), mIslands(nullptr), mNbBodiesCapacity(0),
mSleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY), mSleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
mSleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY), mSleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
mTimeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) { mTimeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
@ -76,29 +75,6 @@ DynamicsWorld::~DynamicsWorld() {
destroyRigidBody(*itToRemove); destroyRigidBody(*itToRemove);
} }
// Release the memory allocated for the islands
for (uint i=0; i<mNbIslands; i++) {
// Call the island destructor
mIslands[i]->~Island();
// Release the allocated memory for the island
mPoolAllocator.release(mIslands[i], sizeof(Island));
}
if (mNbIslandsCapacity > 0) {
mPoolAllocator.release(mIslands, sizeof(Island*) * mNbIslandsCapacity);
}
// Release the memory allocated for the bodies velocity arrays
if (mNbBodiesCapacity > 0) {
delete[] mSplitLinearVelocities;
delete[] mSplitAngularVelocities;
delete[] mConstrainedLinearVelocities;
delete[] mConstrainedAngularVelocities;
delete[] mConstrainedPositions;
delete[] mConstrainedOrientations;
}
assert(mJoints.size() == 0); assert(mJoints.size() == 0);
assert(mRigidBodies.size() == 0); assert(mRigidBodies.size() == 0);
@ -245,31 +221,26 @@ void DynamicsWorld::updateBodiesState() {
// Initialize the bodies velocities arrays for the next simulation step. // Initialize the bodies velocities arrays for the next simulation step.
void DynamicsWorld::initVelocityArrays() { void DynamicsWorld::initVelocityArrays() {
PROFILE("DynamicsWorld::initVelocityArrays()");
// Allocate memory for the bodies velocity arrays // Allocate memory for the bodies velocity arrays
uint nbBodies = mRigidBodies.size(); uint nbBodies = mRigidBodies.size();
if (mNbBodiesCapacity != nbBodies && nbBodies > 0) {
if (mNbBodiesCapacity > 0) { mSplitLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
delete[] mSplitLinearVelocities; mSplitAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
delete[] mSplitAngularVelocities; mConstrainedLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
} mConstrainedAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
mNbBodiesCapacity = nbBodies; mConstrainedPositions = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
// TODO : Use better memory allocation here mConstrainedOrientations = static_cast<Quaternion*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Quaternion)));
mSplitLinearVelocities = new Vector3[mNbBodiesCapacity]; assert(mSplitLinearVelocities != nullptr);
mSplitAngularVelocities = new Vector3[mNbBodiesCapacity]; assert(mSplitAngularVelocities != nullptr);
mConstrainedLinearVelocities = new Vector3[mNbBodiesCapacity]; assert(mConstrainedLinearVelocities != nullptr);
mConstrainedAngularVelocities = new Vector3[mNbBodiesCapacity]; assert(mConstrainedAngularVelocities != nullptr);
mConstrainedPositions = new Vector3[mNbBodiesCapacity]; assert(mConstrainedPositions != nullptr);
mConstrainedOrientations = new Quaternion[mNbBodiesCapacity]; assert(mConstrainedOrientations != nullptr);
assert(mSplitLinearVelocities != nullptr);
assert(mSplitAngularVelocities != nullptr);
assert(mConstrainedLinearVelocities != nullptr);
assert(mConstrainedAngularVelocities != nullptr);
assert(mConstrainedPositions != nullptr);
assert(mConstrainedOrientations != nullptr);
}
// Reset the velocities arrays // Reset the velocities arrays
for (uint i=0; i<mNbBodiesCapacity; i++) { for (uint i=0; i<nbBodies; i++) {
mSplitLinearVelocities[i].setToZero(); mSplitLinearVelocities[i].setToZero();
mSplitAngularVelocities[i].setToZero(); mSplitAngularVelocities[i].setToZero();
} }
@ -652,24 +623,9 @@ void DynamicsWorld::computeIslands() {
uint nbBodies = mRigidBodies.size(); uint nbBodies = mRigidBodies.size();
// Clear all the islands // Allocate and create the array of islands pointer. This memory is allocated
for (uint i=0; i<mNbIslands; i++) { // in the single frame allocator
mIslands = static_cast<Island**>(mSingleFrameAllocator.allocate(sizeof(Island*) * nbBodies));
// Call the island destructor
mIslands[i]->~Island();
// Release the allocated memory for the island
mPoolAllocator.release(mIslands[i], sizeof(Island));
}
// Allocate and create the array of islands
if (mNbIslandsCapacity != nbBodies && nbBodies > 0) {
if (mNbIslandsCapacity > 0) {
mPoolAllocator.release(mIslands, sizeof(Island*) * mNbIslandsCapacity);
}
mNbIslandsCapacity = nbBodies;
mIslands = (Island**)mPoolAllocator.allocate(sizeof(Island*) * mNbIslandsCapacity);
}
mNbIslands = 0; mNbIslands = 0;
int nbContactManifolds = 0; int nbContactManifolds = 0;
@ -685,7 +641,7 @@ void DynamicsWorld::computeIslands() {
// Create a stack (using an array) for the rigid bodies to visit during the Depth First Search // Create a stack (using an array) for the rigid bodies to visit during the Depth First Search
size_t nbBytesStack = sizeof(RigidBody*) * nbBodies; size_t nbBytesStack = sizeof(RigidBody*) * nbBodies;
RigidBody** stackBodiesToVisit = (RigidBody**)mPoolAllocator.allocate(nbBytesStack); RigidBody** stackBodiesToVisit = static_cast<RigidBody**>(mSingleFrameAllocator.allocate(nbBytesStack));
// For each rigid body of the world // For each rigid body of the world
for (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) { for (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) {
@ -708,10 +664,9 @@ void DynamicsWorld::computeIslands() {
body->mIsAlreadyInIsland = true; body->mIsAlreadyInIsland = true;
// Create the new island // Create the new island
void* allocatedMemoryIsland = mPoolAllocator.allocate(sizeof(Island)); void* allocatedMemoryIsland = mSingleFrameAllocator.allocate(sizeof(Island));
mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies, mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies, nbContactManifolds, mJoints.size(),
nbContactManifolds, mSingleFrameAllocator);
mJoints.size(), mPoolAllocator);
// While there are still some bodies to visit in the stack // While there are still some bodies to visit in the stack
while (stackIndex > 0) { while (stackIndex > 0) {
@ -801,9 +756,6 @@ void DynamicsWorld::computeIslands() {
mNbIslands++; mNbIslands++;
} }
// Release the allocated memory for the stack of bodies to visit
mPoolAllocator.release(stackBodiesToVisit, nbBytesStack);
} }
// Put bodies to sleep if needed. // Put bodies to sleep if needed.

View File

@ -109,15 +109,9 @@ class DynamicsWorld : public CollisionWorld {
/// Number of islands in the world /// Number of islands in the world
uint mNbIslands; uint mNbIslands;
/// Current allocated capacity for the islands
uint mNbIslandsCapacity;
/// Array with all the islands of awaken bodies /// Array with all the islands of awaken bodies
Island** mIslands; Island** mIslands;
/// Current allocated capacity for the bodies
uint mNbBodiesCapacity;
/// Sleep linear velocity threshold /// Sleep linear velocity threshold
decimal mSleepLinearVelocity; decimal mSleepLinearVelocity;

View File

@ -29,26 +29,18 @@
using namespace reactphysics3d; using namespace reactphysics3d;
// Constructor // Constructor
Island::Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, Island::Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, SingleFrameAllocator& allocator)
PoolAllocator& memoryAllocator)
: mBodies(nullptr), mContactManifolds(nullptr), mJoints(nullptr), mNbBodies(0), : mBodies(nullptr), mContactManifolds(nullptr), mJoints(nullptr), mNbBodies(0),
mNbContactManifolds(0), mNbJoints(0), mMemoryAllocator(memoryAllocator) { mNbContactManifolds(0), mNbJoints(0) {
// Allocate memory for the arrays // Allocate memory for the arrays on the single frame allocator
mNbAllocatedBytesBodies = sizeof(RigidBody*) * nbMaxBodies; mBodies = static_cast<RigidBody**>(allocator.allocate(sizeof(RigidBody*) * nbMaxBodies));
mBodies = (RigidBody**) mMemoryAllocator.allocate(mNbAllocatedBytesBodies); mContactManifolds = static_cast<ContactManifold**>(allocator.allocate(sizeof(ContactManifold*) * nbMaxContactManifolds));
mNbAllocatedBytesContactManifolds = sizeof(ContactManifold*) * nbMaxContactManifolds; mJoints = static_cast<Joint**>(allocator.allocate(sizeof(Joint*) * nbMaxJoints));
mContactManifolds = (ContactManifold**) mMemoryAllocator.allocate(
mNbAllocatedBytesContactManifolds);
mNbAllocatedBytesJoints = sizeof(Joint*) * nbMaxJoints;
mJoints = (Joint**) mMemoryAllocator.allocate(mNbAllocatedBytesJoints);
} }
// Destructor // Destructor
Island::~Island() { Island::~Island() {
// This destructor is never called because memory is allocated on the
// Release the memory of the arrays // single frame allocator
mMemoryAllocator.release(mBodies, mNbAllocatedBytesBodies);
mMemoryAllocator.release(mContactManifolds, mNbAllocatedBytesContactManifolds);
mMemoryAllocator.release(mJoints, mNbAllocatedBytesJoints);
} }

View File

@ -27,7 +27,7 @@
#define REACTPHYSICS3D_ISLAND_H #define REACTPHYSICS3D_ISLAND_H
// Libraries // Libraries
#include "memory/PoolAllocator.h" #include "memory/SingleFrameAllocator.h"
#include "body/RigidBody.h" #include "body/RigidBody.h"
#include "constraint/Joint.h" #include "constraint/Joint.h"
#include "collision/ContactManifold.h" #include "collision/ContactManifold.h"
@ -63,25 +63,13 @@ class Island {
/// Current number of joints in the island /// Current number of joints in the island
uint mNbJoints; uint mNbJoints;
/// Reference to the memory allocator
PoolAllocator& mMemoryAllocator;
/// Number of bytes allocated for the bodies array
size_t mNbAllocatedBytesBodies;
/// Number of bytes allocated for the contact manifolds array
size_t mNbAllocatedBytesContactManifolds;
/// Number of bytes allocated for the joints array
size_t mNbAllocatedBytesJoints;
public: public:
// -------------------- Methods -------------------- // // -------------------- Methods -------------------- //
/// Constructor /// Constructor
Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
PoolAllocator& memoryAllocator); SingleFrameAllocator& allocator);
/// Destructor /// Destructor
~Island(); ~Island();