diff --git a/CHANGELOG.md b/CHANGELOG.md index ff7b1ba9..6a79e1cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,9 @@ - Bug [#37](https://github.com/DanielChappuis/reactphysics3d/issues/37) has been fixed. - Bug [#62](https://github.com/DanielChappuis/reactphysics3d/issues/62) has been fixed. - Bug [#63](https://github.com/DanielChappuis/reactphysics3d/issues/63) has been fixed. + - Bug [#82](https://github.com/DanielChappuis/reactphysics3d/issues/82) has been fixed. + - Bug [#85](https://github.com/DanielChappuis/reactphysics3d/issues/85) has been fixed. + - Bug: the free() method was called in PoolAllocator instead of release() method of base allocator. ## Version 0.7.0 (May 1, 2018) diff --git a/GenerateNewVersion.py b/GenerateNewVersion.py index ec0c9e91..57c89194 100644 --- a/GenerateNewVersion.py +++ b/GenerateNewVersion.py @@ -19,7 +19,7 @@ def findReplaceText(directory, findRegex, substituteExpr, filePattern): # ----- Code ----- # -# Read new version number from user +# Read old version number from user oldVersion = raw_input("Enter the old version string: ") # Read new version number from user @@ -32,10 +32,14 @@ file.write(newVersion + "\n") file.close() print("Version number has been updated in VERSION file") -# Update the RP3D version number in the documentation/API/Doxyfile +# Update the RP3D version number in the documentation/API/Doxyfile file findReplaceText("documentation/API/", r'(PROJECT_NUMBER[ \t]+=[ \t]+)"[\d\.]+"', r'\g<1>"' + newVersion + '"', "Doxyfile") print("Version number has been updated in documentation/API/Doxyfile file") +# Update the RP3D version number in the documentation/UserManual/title.tex file +findReplaceText("documentation/UserManual/", r'(Version:[\s]+)[\d\.]+', r'\g<1>' + newVersion, "title.tex") +print("Version number has been updated in documentation/API/Doxyfile file") + # Update the RP3D version number in the src/configuration.h file findReplaceText("src/", r'(RP3D_VERSION[ \t]+=[ \t]+std::string\()"[\d\.]+"', r'\g<1>"' + newVersion + '"', "configuration.h") print("Version number has been updated in src/configuration.h file") @@ -48,4 +52,3 @@ print("Copyright date has been updated in LICENSE file") findReplaceText("src/", '(Copyright ' + re.escape("(c)") + r' 2010-)[\d]+', r'\g<1>' + str(date.today().year), "*.h") findReplaceText("src/", '(Copyright ' + re.escape("(c)") + r' 2010-)[\d]+', r'\g<1>' + str(date.today().year), "*.cpp") print("Copyright date in license has been updated in all source code files") - diff --git a/README.md b/README.md index 479ac037..1ee78d6f 100644 --- a/README.md +++ b/README.md @@ -52,3 +52,9 @@ your application, it is recommended to checkout the "master" branch. ## Issues If you find any issue with the library, you can report it on the issue tracker [here](https://github.com/DanielChappuis/reactphysics3d/issues). + +## Credits + +Thanks a lot to Erin Catto, Dirk Gregorius, Erwin Coumans, Pierre Terdiman and Christer Ericson for their amazing GDC presentations, +their physics engines, their books or articles and their contributions on many physics engine forums. + diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 27fd75d5..6322c237 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -547,17 +547,21 @@ void RigidBody::updateBroadPhaseState() const { RP3D_PROFILE("RigidBody::updateBroadPhaseState()", mProfiler); DynamicsWorld& world = static_cast(mWorld); - const Vector3 displacement = world.mTimeStep * mLinearVelocity; + const Vector3 displacement = world.mTimeStep * mLinearVelocity; // For all the proxy collision shapes of the body for (ProxyShape* shape = mProxyCollisionShapes; shape != nullptr; shape = shape->mNext) { - // Recompute the world-space AABB of the collision shape - AABB aabb; - shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform()); + // If the proxy-shape shape is still part of the broad-phase + if (shape->getBroadPhaseId() != -1) { - // Update the broad-phase state for the proxy collision shape - mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb, displacement); + // Recompute the world-space AABB of the collision shape + AABB aabb; + shape->getCollisionShape()->computeAABB(aabb, mTransform * shape->getLocalToBodyTransform()); + + // Update the broad-phase state for the proxy collision shape + mWorld.mCollisionDetection.updateProxyCollisionShape(shape, aabb, displacement); + } } } diff --git a/src/collision/NarrowPhaseInfo.cpp b/src/collision/NarrowPhaseInfo.cpp index 10a29332..52fc60a5 100644 --- a/src/collision/NarrowPhaseInfo.cpp +++ b/src/collision/NarrowPhaseInfo.cpp @@ -65,6 +65,7 @@ void NarrowPhaseInfo::addContactPoint(const Vector3& contactNormal, decimal penD const Vector3& localPt1, const Vector3& localPt2) { assert(penDepth > decimal(0.0)); + assert(contactNormal.length() > decimal(0.8)); // Get the memory allocator MemoryAllocator& allocator = overlappingPair->getTemporaryAllocator(); diff --git a/src/collision/narrowphase/SAT/SATAlgorithm.cpp b/src/collision/narrowphase/SAT/SATAlgorithm.cpp index 374a812a..49c657c5 100644 --- a/src/collision/narrowphase/SAT/SATAlgorithm.cpp +++ b/src/collision/narrowphase/SAT/SATAlgorithm.cpp @@ -40,7 +40,8 @@ using namespace reactphysics3d; // Static variables initialization -const decimal SATAlgorithm::SAME_SEPARATING_AXIS_BIAS = decimal(0.001); +const decimal SATAlgorithm::SEPARATING_AXIS_RELATIVE_TOLERANCE = decimal(1.002); +const decimal SATAlgorithm::SEPARATING_AXIS_ABSOLUTE_TOLERANCE = decimal(0.0005); // Constructor SATAlgorithm::SATAlgorithm(MemoryAllocator& memoryAllocator) : mMemoryAllocator(memoryAllocator) { @@ -478,8 +479,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn uint minSeparatingEdge2Index = 0; Vector3 separatingEdge1A, separatingEdge1B; Vector3 separatingEdge2A, separatingEdge2B; - Vector3 minEdgeVsEdgeSeparatingAxisPolyhedron2Space; - bool isShape1Triangle = polyhedron1->getName() == CollisionShapeName::TRIANGLE; + const bool isShape1Triangle = polyhedron1->getName() == CollisionShapeName::TRIANGLE; LastFrameCollisionInfo* lastFrameCollisionInfo = narrowPhaseInfo->getLastFrameCollisionInfo(); @@ -633,7 +633,6 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn normal = polyhedron1ToPolyhedron2.getOrientation() * ((polyhedron2ToPolyhedron1 * closestPointPolyhedron1Edge) - polyhedron1->getCentroid()); } - //Vector3 normalWorld = narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * minEdgeVsEdgeSeparatingAxisPolyhedron2Space; Vector3 normalWorld = narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * normal.getUnit(); // Compute smooth triangle mesh contact if one of the two collision shapes is a triangle @@ -657,40 +656,58 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn } } + minPenetrationDepth = DECIMAL_LARGEST; + isMinPenetrationFaceNormal = false; + // Test all the face normals of the polyhedron 1 for separating axis - uint faceIndex; - decimal penetrationDepth = testFacesDirectionPolyhedronVsPolyhedron(polyhedron1, polyhedron2, polyhedron1ToPolyhedron2, faceIndex); - if (penetrationDepth <= decimal(0.0)) { + uint faceIndex1; + decimal penetrationDepth1 = testFacesDirectionPolyhedronVsPolyhedron(polyhedron1, polyhedron2, polyhedron1ToPolyhedron2, faceIndex1); + if (penetrationDepth1 <= decimal(0.0)) { lastFrameCollisionInfo->satIsAxisFacePolyhedron1 = true; lastFrameCollisionInfo->satIsAxisFacePolyhedron2 = false; - lastFrameCollisionInfo->satMinAxisFaceIndex = faceIndex; + lastFrameCollisionInfo->satMinAxisFaceIndex = faceIndex1; // We have found a separating axis return false; } - if (penetrationDepth < minPenetrationDepth - SAME_SEPARATING_AXIS_BIAS) { - isMinPenetrationFaceNormal = true; - minPenetrationDepth = penetrationDepth; - minFaceIndex = faceIndex; - isMinPenetrationFaceNormalPolyhedron1 = true; - } // Test all the face normals of the polyhedron 2 for separating axis - penetrationDepth = testFacesDirectionPolyhedronVsPolyhedron(polyhedron2, polyhedron1, polyhedron2ToPolyhedron1, faceIndex); - if (penetrationDepth <= decimal(0.0)) { + uint faceIndex2; + decimal penetrationDepth2 = testFacesDirectionPolyhedronVsPolyhedron(polyhedron2, polyhedron1, polyhedron2ToPolyhedron1, faceIndex2); + if (penetrationDepth2 <= decimal(0.0)) { lastFrameCollisionInfo->satIsAxisFacePolyhedron1 = false; lastFrameCollisionInfo->satIsAxisFacePolyhedron2 = true; - lastFrameCollisionInfo->satMinAxisFaceIndex = faceIndex; + lastFrameCollisionInfo->satMinAxisFaceIndex = faceIndex2; // We have found a separating axis return false; } - if (penetrationDepth < minPenetrationDepth - SAME_SEPARATING_AXIS_BIAS) { + + // Here we know that we have found penetration along both axis of a face of polyhedron1 and a face of + // polyhedron2. If the two penetration depths are almost the same, we need to make sure we always prefer + // one axis to the other for consistency between frames. This is to prevent the contact manifolds to switch + // from one reference axis to the other for a face to face resting contact for instance. This is better for + // stability. To do this, we use a relative and absolute bias to move penetrationDepth2 a little bit to the right. + // Now if: + // penetrationDepth1 < penetrationDepth2: Nothing happens and we use axis of polygon 1 + // penetrationDepth1 ~ penetrationDepth2: Until penetrationDepth1 becomes significantly less than penetrationDepth2 we still use axis of polygon 1 + // penetrationDepth1 >> penetrationDepth2: penetrationDepth2 is now significantly less than penetrationDepth1 and we use polygon 2 axis + if (penetrationDepth1 < penetrationDepth2 * SEPARATING_AXIS_RELATIVE_TOLERANCE + SEPARATING_AXIS_ABSOLUTE_TOLERANCE) { + + // We use penetration axis of polygon 1 isMinPenetrationFaceNormal = true; - minPenetrationDepth = penetrationDepth; - minFaceIndex = faceIndex; + minPenetrationDepth = std::min(penetrationDepth1, penetrationDepth2); + minFaceIndex = faceIndex1; + isMinPenetrationFaceNormalPolyhedron1 = true; + } + else { + + // We use penetration axis of polygon 2 + isMinPenetrationFaceNormal = true; + minPenetrationDepth = std::min(penetrationDepth1, penetrationDepth2); + minFaceIndex = faceIndex2; isMinPenetrationFaceNormalPolyhedron1 = false; } @@ -735,7 +752,7 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn return false; } - if (penetrationDepth < minPenetrationDepth - SAME_SEPARATING_AXIS_BIAS) { + if (penetrationDepth < minPenetrationDepth) { minPenetrationDepth = penetrationDepth; isMinPenetrationFaceNormalPolyhedron1 = false; @@ -746,7 +763,6 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn separatingEdge1B = edge1B; separatingEdge2A = edge2A; separatingEdge2B = edge2B; - minEdgeVsEdgeSeparatingAxisPolyhedron2Space = separatingAxisPolyhedron2Space; } } } @@ -807,8 +823,10 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn else { normal = polyhedron1ToPolyhedron2.getOrientation() * ((polyhedron2ToPolyhedron1 * closestPointPolyhedron1Edge) - polyhedron1->getCentroid()); } - //Vector3 normalWorld = narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * minEdgeVsEdgeSeparatingAxisPolyhedron2Space; - Vector3 normalWorld = narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * normal.getUnit(); + const Vector3 unitNormal = normal.getUnit(); + assert(unitNormal.length() > decimal(0.7)); + Vector3 normalWorld = narrowPhaseInfo->shape2ToWorldTransform.getOrientation() * unitNormal; + assert(normalWorld.length() > decimal(0.7)); // Compute smooth triangle mesh contact if one of the two collision shapes is a triangle TriangleShape::computeSmoothTriangleMeshContact(narrowPhaseInfo->collisionShape1, narrowPhaseInfo->collisionShape2, @@ -816,6 +834,8 @@ bool SATAlgorithm::testCollisionConvexPolyhedronVsConvexPolyhedron(NarrowPhaseIn narrowPhaseInfo->shape1ToWorldTransform, narrowPhaseInfo->shape2ToWorldTransform, minPenetrationDepth, normalWorld); + assert(normalWorld.length() > decimal(0.7)); + // Create the contact point narrowPhaseInfo->addContactPoint(normalWorld, minPenetrationDepth, closestPointPolyhedron1EdgeLocalSpace, closestPointPolyhedron2Edge); diff --git a/src/collision/narrowphase/SAT/SATAlgorithm.h b/src/collision/narrowphase/SAT/SATAlgorithm.h index 5be84220..c7eb2695 100644 --- a/src/collision/narrowphase/SAT/SATAlgorithm.h +++ b/src/collision/narrowphase/SAT/SATAlgorithm.h @@ -55,10 +55,11 @@ class SATAlgorithm { // -------------------- Attributes -------------------- // - /// Bias used to make sure the SAT algorithm returns the same penetration axis between frames - /// when there are multiple separating axis with the same penetration depth. The goal is to - /// make sure the contact manifold does not change too much between frames. - static const decimal SAME_SEPARATING_AXIS_BIAS; + /// Relative and absolute bias used to make sure the SAT algorithm returns the same penetration axis between frames + /// when there are multiple separating axis with almost the same penetration depth. The goal is to + /// make sure the contact manifold does not change too much between frames for better stability. + static const decimal SEPARATING_AXIS_RELATIVE_TOLERANCE; + static const decimal SEPARATING_AXIS_ABSOLUTE_TOLERANCE; /// Memory allocator MemoryAllocator& mMemoryAllocator; diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index 1d359a9c..d292c728 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -165,6 +165,9 @@ class CollisionWorld { /// Test and report collisions between all shapes of the world void testCollision(CollisionCallback* callback); + /// Return a reference to the memory manager of the world + MemoryManager& getMemoryManager(); + #ifdef IS_PROFILING_ACTIVE /// Return a reference to the profiler @@ -255,6 +258,11 @@ inline void CollisionWorld::testOverlap(CollisionBody* body, OverlapCallback* ov mCollisionDetection.testOverlap(body, overlapCallback, categoryMaskBits); } +// Return a reference to the memory manager of the world +inline MemoryManager& CollisionWorld::getMemoryManager() { + return mMemoryManager; +} + // Return the name of the world /** * @return Name of the world diff --git a/src/engine/ContactSolver.cpp b/src/engine/ContactSolver.cpp index 385cbe5e..6b67bba5 100644 --- a/src/engine/ContactSolver.cpp +++ b/src/engine/ContactSolver.cpp @@ -615,14 +615,16 @@ void ContactSolver::solve() { contactPointIndex++; } - // ------ First friction constraint at the center of the contact manifol ------ // + // ------ First friction constraint at the center of the contact manifold ------ // // Compute J*v // deltaV = v2 + w2.cross(mContactConstraints[c].r2Friction) - v1 - w1.cross(mContactConstraints[c].r1Friction); Vector3 deltaV(v2.x + w2.y * mContactConstraints[c].r2Friction.z - w2.z * mContactConstraints[c].r2Friction.y - v1.x - w1.y * mContactConstraints[c].r1Friction.z + w1.z * mContactConstraints[c].r1Friction.y, + v2.y + w2.z * mContactConstraints[c].r2Friction.x - w2.x * mContactConstraints[c].r2Friction.z - v1.y - w1.z * mContactConstraints[c].r1Friction.x + w1.x * mContactConstraints[c].r1Friction.z, + v2.z + w2.x * mContactConstraints[c].r2Friction.y - w2.y * mContactConstraints[c].r2Friction.x - v1.z - w1.x * mContactConstraints[c].r1Friction.y + w1.y * mContactConstraints[c].r1Friction.x); decimal Jv = deltaV.x * mContactConstraints[c].frictionVector1.x + @@ -649,6 +651,7 @@ void ContactSolver::solve() { mContactConstraints[c].r2CrossT1.y * deltaLambda, mContactConstraints[c].r2CrossT1.z * deltaLambda); + // Update the velocities of the body 1 by applying the impulse P mLinearVelocities[mContactConstraints[c].indexBody1].x -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.x; mLinearVelocities[mContactConstraints[c].indexBody1].y -= mContactConstraints[c].massInverseBody1 * linearImpulseBody2.y; @@ -663,15 +666,15 @@ void ContactSolver::solve() { mAngularVelocities[mContactConstraints[c].indexBody2] += mContactConstraints[c].inverseInertiaTensorBody2 * angularImpulseBody2; - // ------ Second friction constraint at the center of the contact manifol ----- // + // ------ Second friction constraint at the center of the contact manifold ----- // // Compute J*v //deltaV = v2 + w2.cross(mContactConstraints[c].r2Friction) - v1 - w1.cross(mContactConstraints[c].r1Friction); - deltaV.x = v2.x + w2.y * mContactConstraints[c].r2Friction.z - v2.z * mContactConstraints[c].r2Friction.y - v1.x - + deltaV.x = v2.x + w2.y * mContactConstraints[c].r2Friction.z - w2.z * mContactConstraints[c].r2Friction.y - v1.x - w1.y * mContactConstraints[c].r1Friction.z + w1.z * mContactConstraints[c].r1Friction.y; - deltaV.y = v2.y + w2.z * mContactConstraints[c].r2Friction.x - v2.x * mContactConstraints[c].r2Friction.z - v1.y - + deltaV.y = v2.y + w2.z * mContactConstraints[c].r2Friction.x - w2.x * mContactConstraints[c].r2Friction.z - v1.y - w1.z * mContactConstraints[c].r1Friction.x + w1.x * mContactConstraints[c].r1Friction.z; - deltaV.z = v2.z + w2.x * mContactConstraints[c].r2Friction.y - v2.y * mContactConstraints[c].r2Friction.x - v1.z - + deltaV.z = v2.z + w2.x * mContactConstraints[c].r2Friction.y - w2.y * mContactConstraints[c].r2Friction.x - v1.z - w1.x * mContactConstraints[c].r1Friction.y + w1.y * mContactConstraints[c].r1Friction.x; Jv = deltaV.x * mContactConstraints[c].frictionVector2.x + deltaV.y * mContactConstraints[c].frictionVector2.y + deltaV.z * mContactConstraints[c].frictionVector2.z; @@ -841,7 +844,7 @@ void ContactSolver::computeFrictionVectors(const Vector3& deltaVelocity, contact.frictionVector1 = contact.normal.getOneUnitOrthogonalVector(); } - // The second friction vector is computed by the cross product of the firs + // The second friction vector is computed by the cross product of the first // friction vector and the contact normal contact.frictionVector2 = contact.normal.cross(contact.frictionVector1).getUnit(); } diff --git a/src/mathematics/Matrix3x3.cpp b/src/mathematics/Matrix3x3.cpp index 74ffd9bf..5fb97376 100644 --- a/src/mathematics/Matrix3x3.cpp +++ b/src/mathematics/Matrix3x3.cpp @@ -48,7 +48,7 @@ Matrix3x3 Matrix3x3::getInverse() const { decimal determinant = getDeterminant(); // Check if the determinant is equal to zero - assert(std::abs(determinant) > MACHINE_EPSILON); + assert(determinant != decimal(0.0)); decimal invDeterminant = decimal(1.0) / determinant; diff --git a/src/memory/DefaultAllocator.h b/src/memory/DefaultAllocator.h index 5ff94895..fcfb8e15 100644 --- a/src/memory/DefaultAllocator.h +++ b/src/memory/DefaultAllocator.h @@ -39,6 +39,8 @@ namespace reactphysics3d { */ class DefaultAllocator : public MemoryAllocator { + protected: + public: /// Destructor @@ -50,11 +52,13 @@ class DefaultAllocator : public MemoryAllocator { /// Allocate memory of a given size (in bytes) and return a pointer to the /// allocated memory. virtual void* allocate(size_t size) override { + return malloc(size); } /// Release previously allocated memory. virtual void release(void* pointer, size_t size) override { + free(pointer); } }; diff --git a/src/memory/DefaultPoolAllocator.cpp b/src/memory/DefaultPoolAllocator.cpp index 5d4f4ff0..39f84eee 100644 --- a/src/memory/DefaultPoolAllocator.cpp +++ b/src/memory/DefaultPoolAllocator.cpp @@ -135,9 +135,9 @@ void* DefaultPoolAllocator::allocate(size_t size) { MemoryBlock* currentMemoryBlocks = mMemoryBlocks; mNbAllocatedMemoryBlocks += 64; mMemoryBlocks = static_cast(MemoryManager::getBaseAllocator().allocate(mNbAllocatedMemoryBlocks * sizeof(MemoryBlock))); - memcpy(mMemoryBlocks, currentMemoryBlocks,mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); + memcpy(mMemoryBlocks, currentMemoryBlocks, mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); memset(mMemoryBlocks + mNbCurrentMemoryBlocks, 0, 64 * sizeof(MemoryBlock)); - free(currentMemoryBlocks); + MemoryManager::getBaseAllocator().release(currentMemoryBlocks, mNbCurrentMemoryBlocks * sizeof(MemoryBlock)); } // Allocate a new memory blocks for the corresponding heap and divide it in many diff --git a/src/memory/DefaultSingleFrameAllocator.h b/src/memory/DefaultSingleFrameAllocator.h index 65641129..5e4c736a 100644 --- a/src/memory/DefaultSingleFrameAllocator.h +++ b/src/memory/DefaultSingleFrameAllocator.h @@ -52,7 +52,8 @@ class DefaultSingleFrameAllocator : public SingleFrameAllocator { static const size_t INIT_SINGLE_FRAME_ALLOCATOR_NB_BYTES = 1048576; // 1Mb // -------------------- Attributes -------------------- // - /// Cached memory allocator used on construction + + /// Cached memory allocator used on construction MemoryAllocator* mBaseMemoryAllocator; /// Total size (in bytes) of memory of the allocator diff --git a/src/memory/MemoryManager.cpp b/src/memory/MemoryManager.cpp index 7427bcdd..e9954f55 100644 --- a/src/memory/MemoryManager.cpp +++ b/src/memory/MemoryManager.cpp @@ -30,9 +30,11 @@ using namespace reactphysics3d; // Static variables DefaultAllocator MemoryManager::mDefaultAllocator; -DefaultSingleFrameAllocator MemoryManager::mDefaultSingleFrameAllocator; -DefaultPoolAllocator MemoryManager::mDefaultPoolAllocator; MemoryAllocator* MemoryManager::mBaseAllocator = &mDefaultAllocator; -MemoryAllocator* MemoryManager::mPoolAllocator = &mDefaultPoolAllocator; -SingleFrameAllocator* MemoryManager::mSingleFrameAllocator = &mDefaultSingleFrameAllocator; +// Constructor +MemoryManager::MemoryManager() { + + mSingleFrameAllocator = &mDefaultSingleFrameAllocator; + mPoolAllocator = &mDefaultPoolAllocator; +} diff --git a/src/memory/MemoryManager.h b/src/memory/MemoryManager.h index b4269cbb..d0495543 100644 --- a/src/memory/MemoryManager.h +++ b/src/memory/MemoryManager.h @@ -51,19 +51,19 @@ class MemoryManager { static DefaultAllocator mDefaultAllocator; /// Default single frame memory allocator - static DefaultSingleFrameAllocator mDefaultSingleFrameAllocator; + DefaultSingleFrameAllocator mDefaultSingleFrameAllocator; /// Default pool memory allocator - static DefaultPoolAllocator mDefaultPoolAllocator; + DefaultPoolAllocator mDefaultPoolAllocator; /// Pointer to the base memory allocator to use static MemoryAllocator* mBaseAllocator; /// Single frame stack allocator - static SingleFrameAllocator* mSingleFrameAllocator; + SingleFrameAllocator* mSingleFrameAllocator; /// Memory pool allocator - static MemoryAllocator* mPoolAllocator; + MemoryAllocator* mPoolAllocator; public: @@ -75,7 +75,7 @@ class MemoryManager { }; /// Constructor - MemoryManager() = default; + MemoryManager(); /// Destructor ~MemoryManager() = default; @@ -99,10 +99,10 @@ class MemoryManager { static void setBaseAllocator(MemoryAllocator* memoryAllocator); /// Set the single frame memory allocator - static void setSingleFrameAllocator(SingleFrameAllocator* singleFrameAllocator); + void setSingleFrameAllocator(SingleFrameAllocator* singleFrameAllocator); /// Set the pool memory allocator - static void setPoolAllocator(MemoryAllocator* poolAllocator); + void setPoolAllocator(MemoryAllocator* poolAllocator); /// Reset the single frame allocator void resetFrameAllocator();