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),
mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr),
mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr),
mConstrainedOrientations(nullptr), mNbIslands(0),
mNbIslandsCapacity(0), mIslands(nullptr), mNbBodiesCapacity(0),
mConstrainedOrientations(nullptr), mNbIslands(0), mIslands(nullptr),
mSleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
mSleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
mTimeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
@ -76,29 +75,6 @@ DynamicsWorld::~DynamicsWorld() {
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(mRigidBodies.size() == 0);
@ -245,31 +221,26 @@ void DynamicsWorld::updateBodiesState() {
// Initialize the bodies velocities arrays for the next simulation step.
void DynamicsWorld::initVelocityArrays() {
PROFILE("DynamicsWorld::initVelocityArrays()");
// Allocate memory for the bodies velocity arrays
uint nbBodies = mRigidBodies.size();
if (mNbBodiesCapacity != nbBodies && nbBodies > 0) {
if (mNbBodiesCapacity > 0) {
delete[] mSplitLinearVelocities;
delete[] mSplitAngularVelocities;
}
mNbBodiesCapacity = nbBodies;
// TODO : Use better memory allocation here
mSplitLinearVelocities = new Vector3[mNbBodiesCapacity];
mSplitAngularVelocities = new Vector3[mNbBodiesCapacity];
mConstrainedLinearVelocities = new Vector3[mNbBodiesCapacity];
mConstrainedAngularVelocities = new Vector3[mNbBodiesCapacity];
mConstrainedPositions = new Vector3[mNbBodiesCapacity];
mConstrainedOrientations = new Quaternion[mNbBodiesCapacity];
assert(mSplitLinearVelocities != nullptr);
assert(mSplitAngularVelocities != nullptr);
assert(mConstrainedLinearVelocities != nullptr);
assert(mConstrainedAngularVelocities != nullptr);
assert(mConstrainedPositions != nullptr);
assert(mConstrainedOrientations != nullptr);
}
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)));
assert(mSplitLinearVelocities != nullptr);
assert(mSplitAngularVelocities != nullptr);
assert(mConstrainedLinearVelocities != nullptr);
assert(mConstrainedAngularVelocities != nullptr);
assert(mConstrainedPositions != nullptr);
assert(mConstrainedOrientations != nullptr);
// Reset the velocities arrays
for (uint i=0; i<mNbBodiesCapacity; i++) {
for (uint i=0; i<nbBodies; i++) {
mSplitLinearVelocities[i].setToZero();
mSplitAngularVelocities[i].setToZero();
}
@ -652,24 +623,9 @@ void DynamicsWorld::computeIslands() {
uint nbBodies = mRigidBodies.size();
// Clear all 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));
}
// 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);
}
// 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));
mNbIslands = 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
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 (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) {
@ -708,10 +664,9 @@ void DynamicsWorld::computeIslands() {
body->mIsAlreadyInIsland = true;
// Create the new island
void* allocatedMemoryIsland = mPoolAllocator.allocate(sizeof(Island));
mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies,
nbContactManifolds,
mJoints.size(), mPoolAllocator);
void* allocatedMemoryIsland = mSingleFrameAllocator.allocate(sizeof(Island));
mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies, nbContactManifolds, mJoints.size(),
mSingleFrameAllocator);
// While there are still some bodies to visit in the stack
while (stackIndex > 0) {
@ -801,9 +756,6 @@ void DynamicsWorld::computeIslands() {
mNbIslands++;
}
// Release the allocated memory for the stack of bodies to visit
mPoolAllocator.release(stackBodiesToVisit, nbBytesStack);
}
// Put bodies to sleep if needed.

View File

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

View File

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

View File

@ -27,7 +27,7 @@
#define REACTPHYSICS3D_ISLAND_H
// Libraries
#include "memory/PoolAllocator.h"
#include "memory/SingleFrameAllocator.h"
#include "body/RigidBody.h"
#include "constraint/Joint.h"
#include "collision/ContactManifold.h"
@ -63,25 +63,13 @@ class Island {
/// Current number of joints in the island
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:
// -------------------- Methods -------------------- //
/// Constructor
Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
PoolAllocator& memoryAllocator);
SingleFrameAllocator& allocator);
/// Destructor
~Island();