[DEV] remove allocator (not full implemented and offuscation of code ==> bettre way to do it

This commit is contained in:
Edouard DUPIN 2017-09-29 11:42:46 +02:00
parent fc1a41f768
commit 7ead46281c
33 changed files with 259 additions and 696 deletions

View File

@ -43,7 +43,7 @@ inline void CollisionBody::setType(BodyType _type) {
ProxyShape* CollisionBody::addCollisionShape(CollisionShape* _collisionShape,
const etk::Transform3D& _transform) {
// Create a new proxy collision shape to attach the collision shape to the body
ProxyShape* proxyShape = new (m_world.m_memoryAllocator.allocate(sizeof(ProxyShape))) ProxyShape(this, _collisionShape,_transform, float(1));
ProxyShape* proxyShape = new ProxyShape(this, _collisionShape,_transform, float(1));
// Add it to the list of proxy collision shapes of the body
if (m_proxyCollisionShapes == nullptr) {
m_proxyCollisionShapes = proxyShape;
@ -66,8 +66,8 @@ void CollisionBody::removeCollisionShape(const ProxyShape* _proxyShape) {
if (m_isActive) {
m_world.m_collisionDetection.removeProxyCollisionShape(current);
}
current->~ProxyShape();
m_world.m_memoryAllocator.release(current, sizeof(ProxyShape));
delete current;
current = nullptr;
m_numberCollisionShapes--;
return;
}
@ -81,8 +81,8 @@ void CollisionBody::removeCollisionShape(const ProxyShape* _proxyShape) {
if (m_isActive) {
m_world.m_collisionDetection.removeProxyCollisionShape(elementToRemove);
}
elementToRemove->~ProxyShape();
m_world.m_memoryAllocator.release(elementToRemove, sizeof(ProxyShape));
delete elementToRemove;
elementToRemove = nullptr;
m_numberCollisionShapes--;
return;
}
@ -101,8 +101,7 @@ void CollisionBody::removeAllCollisionShapes() {
if (m_isActive) {
m_world.m_collisionDetection.removeProxyCollisionShape(current);
}
current->~ProxyShape();
m_world.m_memoryAllocator.release(current, sizeof(ProxyShape));
delete current;
// Get the next element in the list
current = nextElement;
}
@ -116,8 +115,7 @@ void CollisionBody::resetContactManifoldsList() {
while (currentElement != nullptr) {
ContactManifoldListElement* nextElement = currentElement->next;
// Delete the current element
currentElement->~ContactManifoldListElement();
m_world.m_memoryAllocator.release(currentElement, sizeof(ContactManifoldListElement));
delete currentElement;
currentElement = nextElement;
}
m_contactManifoldsList = nullptr;

View File

@ -11,7 +11,6 @@
#include <ephysics/collision/shapes/AABB.hpp>
#include <ephysics/collision/shapes/CollisionShape.hpp>
#include <ephysics/collision/RaycastInfo.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/configuration.hpp>
namespace ephysics {

View File

@ -95,15 +95,15 @@ void RigidBody::setMass(float _mass) {
}
}
void RigidBody::removeJointFrom_jointsList(MemoryAllocator& _memoryAllocator, const Joint* _joint) {
void RigidBody::removeJointFrom_jointsList(const Joint* _joint) {
assert(_joint != nullptr);
assert(m_jointsList != nullptr);
// Remove the joint from the linked list of the joints of the first body
if (m_jointsList->joint == _joint) { // If the first element is the one to remove
JointListElement* elementToRemove = m_jointsList;
m_jointsList = elementToRemove->next;
elementToRemove->~JointListElement();
_memoryAllocator.release(elementToRemove, sizeof(JointListElement));
delete elementToRemove;
elementToRemove = nullptr;
}
else { // If the element to remove is not the first one in the list
JointListElement* currentElement = m_jointsList;
@ -111,8 +111,8 @@ void RigidBody::removeJointFrom_jointsList(MemoryAllocator& _memoryAllocator, co
if (currentElement->next->joint == _joint) {
JointListElement* elementToRemove = currentElement->next;
currentElement->next = elementToRemove->next;
elementToRemove->~JointListElement();
_memoryAllocator.release(elementToRemove, sizeof(JointListElement));
delete elementToRemove;
elementToRemove = nullptr;
break;
}
currentElement = currentElement->next;
@ -126,7 +126,7 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* _collisionShape,
float _mass) {
assert(_mass > 0.0f);
// Create a new proxy collision shape to attach the collision shape to the body
ProxyShape* proxyShape = new (m_world.m_memoryAllocator.allocate(sizeof(ProxyShape))) ProxyShape(this, _collisionShape, _transform, _mass);
ProxyShape* proxyShape = new ProxyShape(this, _collisionShape, _transform, _mass);
// Add it to the list of proxy collision shapes of the body
if (m_proxyCollisionShapes == nullptr) {
m_proxyCollisionShapes = proxyShape;

View File

@ -8,7 +8,6 @@
#include <ephysics/body/CollisionBody.hpp>
#include <ephysics/engine/Material.hpp>
#include <ephysics/mathematics/mathematics.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
namespace ephysics {
@ -47,7 +46,7 @@ namespace ephysics {
/**
* @brief Remove a joint from the joints list
*/
void removeJointFrom_jointsList(MemoryAllocator& _memoryAllocator, const Joint* _joint);
void removeJointFrom_jointsList(const Joint* _joint);
/**
* @brief Update the transform of the body after a change of the center of mass
*/

View File

@ -17,8 +17,7 @@ using namespace ephysics;
using namespace std;
// Constructor
CollisionDetection::CollisionDetection(CollisionWorld* _world, MemoryAllocator& _memoryAllocator):
m_memoryAllocator(_memoryAllocator),
CollisionDetection::CollisionDetection(CollisionWorld* _world):
m_world(_world),
m_broadPhaseAlgorithm(*this),
m_isCollisionShapesAdded(false) {
@ -135,13 +134,11 @@ void CollisionDetection::computeNarrowPhase() {
if (((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 ||
(shape1->getCollisionCategoryBits() & shape2->getCollideWithMaskBits()) == 0) ||
!m_broadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
etk::Map<overlappingpairid, OverlappingPair*>::Iterator itToRemove = it;
++it;
// TODO : Remove all the contact manifold of the overlapping pair from the contact manifolds list of the two bodies involved
// Destroy the overlapping pair
itToRemove->second->~OverlappingPair();
m_world->m_memoryAllocator.release(itToRemove->second, sizeof(OverlappingPair));
m_overlappingPairs.erase(itToRemove);
delete it->second;
it->second = nullptr;
it = m_overlappingPairs.erase(it);
continue;
} else {
++it;
@ -228,13 +225,11 @@ void CollisionDetection::computeNarrowPhaseBetweenShapes(CollisionCallback* call
if (((shape1->getCollideWithMaskBits() & shape2->getCollisionCategoryBits()) == 0 ||
(shape1->getCollisionCategoryBits() & shape2->getCollideWithMaskBits()) == 0) ||
!m_broadPhaseAlgorithm.testOverlappingShapes(shape1, shape2)) {
etk::Map<overlappingpairid, OverlappingPair*>::Iterator itToRemove = it;
++it;
// TODO : Remove all the contact manifold of the overlapping pair from the contact manifolds list of the two bodies involved
// Destroy the overlapping pair
itToRemove->second->~OverlappingPair();
m_world->m_memoryAllocator.release(itToRemove->second, sizeof(OverlappingPair));
m_overlappingPairs.erase(itToRemove);
delete it->second;
it->second = nullptr;
it = m_overlappingPairs.erase(it);
continue;
} else {
++it;
@ -298,8 +293,7 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
int32_t nbMaxManifolds = CollisionShape::computeNbMaxContactManifolds(shape1->getCollisionShape()->getType(),
shape2->getCollisionShape()->getType());
// Create the overlapping pair and add it int32_to the set of overlapping pairs
OverlappingPair* newPair = new (m_world->m_memoryAllocator.allocate(sizeof(OverlappingPair)))
OverlappingPair(shape1, shape2, nbMaxManifolds, m_world->m_memoryAllocator);
OverlappingPair* newPair = new OverlappingPair(shape1, shape2, nbMaxManifolds);
assert(newPair != nullptr);
m_overlappingPairs.set(pairID, newPair);
// Wake up the two bodies
@ -313,15 +307,12 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) {
for (it = m_overlappingPairs.begin(); it != m_overlappingPairs.end(); ) {
if (it->second->getShape1()->m_broadPhaseID == proxyShape->m_broadPhaseID||
it->second->getShape2()->m_broadPhaseID == proxyShape->m_broadPhaseID) {
etk::Map<overlappingpairid, OverlappingPair*>::Iterator itToRemove = it;
++it;
// TODO : Remove all the contact manifold of the overlapping pair from the contact manifolds list of the two bodies involved
// Destroy the overlapping pair
itToRemove->second->~OverlappingPair();
m_world->m_memoryAllocator.release(itToRemove->second, sizeof(OverlappingPair));
m_overlappingPairs.erase(itToRemove);
}
else {
delete it->second;
it->second = nullptr;
it = m_overlappingPairs.erase(it);
} else {
++it;
}
}
@ -343,8 +334,7 @@ void CollisionDetection::notifyContact(OverlappingPair* overlappingPair, const C
void CollisionDetection::createContact(OverlappingPair* overlappingPair, const ContactPointInfo& contactInfo) {
// Create a new contact
ContactPoint* contact = new (m_world->m_memoryAllocator.allocate(sizeof(ContactPoint)))
ContactPoint(contactInfo);
ContactPoint* contact = new ContactPoint(contactInfo);
// Add the contact to the contact manifold set of the corresponding overlapping pair
overlappingPair->addContact(contact);
// Add the overlapping pair int32_to the set of pairs in contact during narrow-phase
@ -374,18 +364,10 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
assert(contactManifold->getNbContactPoints() > 0);
// Add the contact manifold at the beginning of the linked
// list of contact manifolds of the first body
void* allocatedMemory1 = m_world->m_memoryAllocator.allocate(sizeof(ContactManifoldListElement));
ContactManifoldListElement* listElement1 = new (allocatedMemory1)
ContactManifoldListElement(contactManifold,
body1->m_contactManifoldsList);
body1->m_contactManifoldsList = listElement1;
body1->m_contactManifoldsList = new ContactManifoldListElement(contactManifold, body1->m_contactManifoldsList);;
// Add the contact manifold at the beginning of the linked
// list of the contact manifolds of the second body
void* allocatedMemory2 = m_world->m_memoryAllocator.allocate(sizeof(ContactManifoldListElement));
ContactManifoldListElement* listElement2 = new (allocatedMemory2)
ContactManifoldListElement(contactManifold,
body2->m_contactManifoldsList);
body2->m_contactManifoldsList = listElement2;
body2->m_contactManifoldsList = new ContactManifoldListElement(contactManifold, body2->m_contactManifoldsList);;
}
}
@ -411,10 +393,6 @@ EventListener* CollisionDetection::getWorldEventListener() {
return m_world->m_eventListener;
}
MemoryAllocator& CollisionDetection::getWorldMemoryAllocator() {
return m_world->m_memoryAllocator;
}
void TestCollisionBetweenShapesCallback::notifyContact(OverlappingPair* _overlappingPair,
const ContactPointInfo& _contactInfo) {
m_collisionCallback->notifyContact(_contactInfo);
@ -426,7 +404,7 @@ NarrowPhaseAlgorithm* CollisionDetection::getCollisionAlgorithm(CollisionShapeTy
void CollisionDetection::setCollisionDispatch(CollisionDispatch* _collisionDispatch) {
m_collisionDispatch = _collisionDispatch;
m_collisionDispatch->init(this, &m_memoryAllocator);
m_collisionDispatch->init(this);
// Fill-in the collision matrix with the new algorithms to use
fillInCollisionMatrix();
}

View File

@ -10,7 +10,6 @@
#include <ephysics/engine/OverlappingPair.hpp>
#include <ephysics/engine/EventListener.hpp>
#include <ephysics/collision/narrowphase/DefaultCollisionDispatch.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/constraint/ContactPoint.hpp>
#include <etk/Vector.hpp>
#include <etk/Map.hpp>
@ -31,7 +30,6 @@ namespace ephysics {
m_collisionCallback(_callback) {
}
// Called by a narrow-phase collision algorithm when a new contact has been found
virtual void notifyContact(OverlappingPair* _overlappingPair,
const ContactPointInfo& _contactInfo);
@ -48,7 +46,6 @@ namespace ephysics {
CollisionDispatch* m_collisionDispatch; //!< Collision Detection Dispatch configuration
DefaultCollisionDispatch m_defaultCollisionDispatch; //!< Default collision dispatch configuration
NarrowPhaseAlgorithm* m_collisionMatrix[NB_COLLISION_SHAPE_TYPES][NB_COLLISION_SHAPE_TYPES]; //!< Collision detection matrix (algorithms to use)
MemoryAllocator& m_memoryAllocator; //!< Reference to the memory allocator
CollisionWorld* m_world; //!< Pointer to the physics world
etk::Map<overlappingpairid, OverlappingPair*> m_overlappingPairs; //!< Broad-phase overlapping pairs
etk::Map<overlappingpairid, OverlappingPair*> m_contactOverlappingPairs; //!< Overlapping pairs in contact (during the current Narrow-phase collision detection)
@ -76,7 +73,7 @@ namespace ephysics {
void addAllContactManifoldsToBodies();
public :
/// Constructor
CollisionDetection(CollisionWorld* _world, MemoryAllocator& _memoryAllocator);
CollisionDetection(CollisionWorld* _world);
/// Destructor
~CollisionDetection();
/// Set the collision dispatch configuration
@ -132,8 +129,6 @@ namespace ephysics {
CollisionWorld* getWorld();
/// Return the world event listener
EventListener* getWorldEventListener();
/// Return a reference to the world memory allocator
MemoryAllocator& getWorldMemoryAllocator();
/// Called by a narrow-phase collision algorithm when a new contact has been found
virtual void notifyContact(OverlappingPair* _overlappingPair, const ContactPointInfo& _contactInfo) override;
/// Create a new contact

View File

@ -11,12 +11,17 @@
using namespace ephysics;
// Constructor
ContactManifold::ContactManifold(ProxyShape* shape1, ProxyShape* shape2,
MemoryAllocator& memoryAllocator, short normalDirectionId)
: m_shape1(shape1), m_shape2(shape2), m_normalDirectionId(normalDirectionId),
m_nbContactPoints(0), m_frictionImpulse1(0.0), m_frictionImpulse2(0.0),
m_frictionTwistImpulse(0.0), m_isAlreadyInIsland(false),
m_memoryAllocator(memoryAllocator) {
ContactManifold::ContactManifold(ProxyShape* _shape1,
ProxyShape* _shape2,
short _normalDirectionId):
m_shape1(_shape1),
m_shape2(_shape2),
m_normalDirectionId(_normalDirectionId),
m_nbContactPoints(0),
m_frictionImpulse1(0.0),
m_frictionImpulse2(0.0),
m_frictionTwistImpulse(0.0),
m_isAlreadyInIsland(false) {
}
@ -36,13 +41,9 @@ void ContactManifold::addContactPoint(ContactPoint* contact) {
float distance = (m_contactPoints[i]->getWorldPointOnBody1() -
contact->getWorldPointOnBody1()).length2();
if (distance <= PERSISTENT_CONTACT_DIST_THRESHOLD*PERSISTENT_CONTACT_DIST_THRESHOLD) {
// Delete the new contact
contact->~ContactPoint();
m_memoryAllocator.release(contact, sizeof(ContactPoint));
delete contact;
assert(m_nbContactPoints > 0);
return;
}
}
@ -68,9 +69,8 @@ void ContactManifold::removeContactPoint(uint32_t index) {
// Call the destructor explicitly and tell the memory allocator that
// the corresponding memory block is now free
m_contactPoints[index]->~ContactPoint();
m_memoryAllocator.release(m_contactPoints[index], sizeof(ContactPoint));
delete m_contactPoints[index];
m_contactPoints[index] = nullptr;
// If we don't remove the last index
if (index < m_nbContactPoints - 1) {
m_contactPoints[index] = m_contactPoints[m_nbContactPoints - 1];
@ -233,12 +233,12 @@ int32_t ContactManifold::getMaxArea(float area0, float area1, float area2, float
// Clear the contact manifold
void ContactManifold::clear() {
for (uint32_t i=0; i<m_nbContactPoints; i++) {
for (uint32_t iii=0; iii<m_nbContactPoints; ++iii) {
// Call the destructor explicitly and tell the memory allocator that
// the corresponding memory block is now free
m_contactPoints[i]->~ContactPoint();
m_memoryAllocator.release(m_contactPoints[i], sizeof(ContactPoint));
delete m_contactPoints[iii];
m_contactPoints[iii] = nullptr;
}
m_nbContactPoints = 0;
}

View File

@ -9,7 +9,6 @@
#include <ephysics/body/CollisionBody.hpp>
#include <ephysics/collision/ProxyShape.hpp>
#include <ephysics/constraint/ContactPoint.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
namespace ephysics {
@ -60,7 +59,6 @@ namespace ephysics {
float m_frictionTwistImpulse; //!< Twist friction constraint accumulated impulse
vec3 m_rollingResistanceImpulse; //!< Accumulated rolling resistance impulse
bool m_isAlreadyInIsland; //!< True if the contact manifold has already been added int32_to an island
MemoryAllocator& m_memoryAllocator; //!< Reference to the memory allocator
/// Private copy-constructor
ContactManifold(const ContactManifold& _contactManifold) = delete;
/// Private assignment operator
@ -79,7 +77,6 @@ namespace ephysics {
/// Constructor
ContactManifold(ProxyShape* _shape1,
ProxyShape* _shape2,
MemoryAllocator& _memoryAllocator,
int16_t _normalDirectionId);
/// Destructor
~ContactManifold();

View File

@ -8,11 +8,14 @@
using namespace ephysics;
ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
MemoryAllocator& memoryAllocator, int32_t nbMaxManifolds)
: m_nbMaxManifolds(nbMaxManifolds), m_nbManifolds(0), m_shape1(shape1),
m_shape2(shape2), m_memoryAllocator(memoryAllocator) {
assert(nbMaxManifolds >= 1);
ContactManifoldSet::ContactManifoldSet(ProxyShape* _shape1,
ProxyShape* _shape2,
int32_t _nbMaxManifolds):
m_nbMaxManifolds(_nbMaxManifolds),
m_nbManifolds(0),
m_shape1(_shape1),
m_shape2(_shape2) {
assert(_nbMaxManifolds >= 1);
}
ContactManifoldSet::~ContactManifoldSet() {
@ -71,8 +74,8 @@ void ContactManifoldSet::addContactPoint(ContactPoint* contact) {
// new contact point
if (smallestDepthIndex == -1) {
// Delete the new contact
contact->~ContactPoint();
m_memoryAllocator.release(contact, sizeof(ContactPoint));
delete contact;
contact = nullptr;
return;
}
assert(smallestDepthIndex >= 0 && smallestDepthIndex < m_nbManifolds);
@ -150,7 +153,7 @@ void ContactManifoldSet::clear() {
void ContactManifoldSet::createManifold(int16_t normalDirectionId) {
assert(m_nbManifolds < m_nbMaxManifolds);
m_manifolds[m_nbManifolds] = new ContactManifold(m_shape1, m_shape2, m_memoryAllocator, normalDirectionId);
m_manifolds[m_nbManifolds] = new ContactManifold(m_shape1, m_shape2, normalDirectionId);
m_nbManifolds++;
}

View File

@ -22,7 +22,6 @@ namespace ephysics {
int32_t m_nbManifolds; //!< Current number of contact manifolds in the set
ProxyShape* m_shape1; //!< Pointer to the first proxy shape of the contact
ProxyShape* m_shape2; //!< Pointer to the second proxy shape of the contact
MemoryAllocator& m_memoryAllocator; //!< Reference to the memory allocator
ContactManifold* m_manifolds[MAX_MANIFOLDS_IN_CONTACT_MANIFOLD_SET]; //!< Contact manifolds of the set
/// Create a new contact manifold and add it to the set
void createManifold(short _normalDirectionId);
@ -38,7 +37,6 @@ namespace ephysics {
/// Constructor
ContactManifoldSet(ProxyShape* _shape1,
ProxyShape* _shape2,
MemoryAllocator& _memoryAllocator,
int32_t _nbMaxManifolds);
/// Destructor
~ContactManifoldSet();

View File

@ -20,8 +20,8 @@ namespace ephysics {
/// Destructor
virtual ~CollisionDispatch() = default;
/// Initialize the collision dispatch configuration
virtual void init(CollisionDetection* _collisionDetection,
MemoryAllocator* _memoryAllocator) {
virtual void init(CollisionDetection* _collisionDetection) {
// Nothing to do ...
}
/// Select and return the narrow-phase collision detection algorithm to
/// use between two types of collision shapes.

View File

@ -10,36 +10,35 @@
using namespace ephysics;
// Constructor
DefaultCollisionDispatch::DefaultCollisionDispatch() {
}
/// Initialize the collision dispatch configuration
void DefaultCollisionDispatch::init(CollisionDetection* collisionDetection,
MemoryAllocator* memoryAllocator) {
void DefaultCollisionDispatch::init(CollisionDetection* _collisionDetection) {
// Initialize the collision algorithms
mSphereVsSphereAlgorithm.init(collisionDetection, memoryAllocator);
mGJKAlgorithm.init(collisionDetection, memoryAllocator);
mConcaveVsConvexAlgorithm.init(collisionDetection, memoryAllocator);
m_sphereVsSphereAlgorithm.init(_collisionDetection);
m_GJKAlgorithm.init(_collisionDetection);
m_concaveVsConvexAlgorithm.init(_collisionDetection);
}
// Select and return the narrow-phase collision detection algorithm to
// use between two types of collision shapes.
NarrowPhaseAlgorithm* DefaultCollisionDispatch::selectAlgorithm(int32_t type1, int32_t type2) {
CollisionShapeType shape1Type = static_cast<CollisionShapeType>(type1);
CollisionShapeType shape2Type = static_cast<CollisionShapeType>(type2);
NarrowPhaseAlgorithm* DefaultCollisionDispatch::selectAlgorithm(int32_t _type1, int32_t _type2) {
CollisionShapeType shape1Type = static_cast<CollisionShapeType>(_type1);
CollisionShapeType shape2Type = static_cast<CollisionShapeType>(_type2);
// Sphere vs Sphere algorithm
if (shape1Type == SPHERE && shape2Type == SPHERE) {
return &mSphereVsSphereAlgorithm;
} else if ( (!CollisionShape::isConvex(shape1Type) && CollisionShape::isConvex(shape2Type))
|| (!CollisionShape::isConvex(shape2Type) && CollisionShape::isConvex(shape1Type))) {
return &m_sphereVsSphereAlgorithm;
} else if ( ( !CollisionShape::isConvex(shape1Type)
&& CollisionShape::isConvex(shape2Type) )
|| ( !CollisionShape::isConvex(shape2Type)
&& CollisionShape::isConvex(shape1Type) ) ) {
// Concave vs Convex algorithm
return &mConcaveVsConvexAlgorithm;
return &m_concaveVsConvexAlgorithm;
} else if (CollisionShape::isConvex(shape1Type) && CollisionShape::isConvex(shape2Type)) {
// Convex vs Convex algorithm (GJK algorithm)
return &mGJKAlgorithm;
return &m_GJKAlgorithm;
} else {
return nullptr;
}

View File

@ -11,23 +11,24 @@
#include <ephysics/collision/narrowphase/GJK/GJKAlgorithm.hpp>
namespace ephysics {
/**
* @brief This is the default collision dispatch configuration use in ephysics.
* Collision dispatching decides which collision
* algorithm to use given two types of proxy collision shapes.
*/
class DefaultCollisionDispatch : public CollisionDispatch {
protected:
SphereVsSphereAlgorithm mSphereVsSphereAlgorithm; //!< Sphere vs Sphere collision algorithm
ConcaveVsConvexAlgorithm mConcaveVsConvexAlgorithm; //!< Concave vs Convex collision algorithm
GJKAlgorithm mGJKAlgorithm; //!< GJK Algorithm
public:
/// Constructor
DefaultCollisionDispatch();
void init(CollisionDetection* _collisionDetection, MemoryAllocator* _memoryAllocator) override;
NarrowPhaseAlgorithm* selectAlgorithm(int32_t _type1, int32_t _type2) override;
};
/**
* @brief This is the default collision dispatch configuration use in ephysics.
* Collision dispatching decides which collision
* algorithm to use given two types of proxy collision shapes.
*/
class DefaultCollisionDispatch : public CollisionDispatch {
protected:
SphereVsSphereAlgorithm m_sphereVsSphereAlgorithm; //!< Sphere vs Sphere collision algorithm
ConcaveVsConvexAlgorithm m_concaveVsConvexAlgorithm; //!< Concave vs Convex collision algorithm
GJKAlgorithm m_GJKAlgorithm; //!< GJK Algorithm
public:
/**
* @brief Constructor
*/
DefaultCollisionDispatch();
void init(CollisionDetection* _collisionDetection) override;
NarrowPhaseAlgorithm* selectAlgorithm(int32_t _type1, int32_t _type2) override;
};
}

View File

@ -11,7 +11,6 @@
#include <ephysics/collision/narrowphase/NarrowPhaseAlgorithm.hpp>
#include <ephysics/mathematics/mathematics.hpp>
#include <ephysics/collision/narrowphase/EPA/TriangleEPA.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <algorithm>
namespace ephysics {
@ -51,7 +50,6 @@ namespace ephysics {
*/
class EPAAlgorithm {
private:
MemoryAllocator* m_memoryAllocator; //!< Reference to the memory allocator
TriangleComparison m_triangleComparison; //!< Triangle comparison operator
/// Private copy-constructor
EPAAlgorithm(const EPAAlgorithm& _algorithm);
@ -84,8 +82,8 @@ namespace ephysics {
/// Destructor
~EPAAlgorithm();
/// Initalize the algorithm
void init(MemoryAllocator* _memoryAllocator) {
m_memoryAllocator = _memoryAllocator;
void init() {
}
// Compute the penetration depth with the EPA algorithm.
/// This method computes the penetration depth and contact points between two

View File

@ -53,9 +53,9 @@ namespace ephysics {
/// Destructor
~GJKAlgorithm();
/// Initalize the algorithm
virtual void init(CollisionDetection* _collisionDetection, MemoryAllocator* _memoryAllocator) {
NarrowPhaseAlgorithm::init(_collisionDetection, _memoryAllocator);
m_algoEPA.init(_memoryAllocator);
virtual void init(CollisionDetection* _collisionDetection) {
NarrowPhaseAlgorithm::init(_collisionDetection);
m_algoEPA.init();
};
// Compute a contact info if the two collision shapes collide.
/// This method implements the Hybrid Technique for computing the penetration depth by

View File

@ -8,18 +8,13 @@
using namespace ephysics;
NarrowPhaseAlgorithm::NarrowPhaseAlgorithm()
: m_memoryAllocator(NULL), m_currentOverlappingPair(NULL) {
NarrowPhaseAlgorithm::NarrowPhaseAlgorithm():
m_currentOverlappingPair(nullptr) {
}
NarrowPhaseAlgorithm::~NarrowPhaseAlgorithm() {
}
void NarrowPhaseAlgorithm::init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) {
m_collisionDetection = collisionDetection;
m_memoryAllocator = memoryAllocator;
void NarrowPhaseAlgorithm::init(CollisionDetection* _collisionDetection) {
m_collisionDetection = _collisionDetection;
}
void NarrowPhaseAlgorithm::setCurrentOverlappingPair(OverlappingPair* _overlappingPair) {

View File

@ -7,7 +7,6 @@
#include <ephysics/body/Body.hpp>
#include <ephysics/constraint/ContactPoint.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/engine/OverlappingPair.hpp>
#include <ephysics/collision/CollisionShapeInfo.hpp>
@ -36,7 +35,6 @@ namespace ephysics {
class NarrowPhaseAlgorithm {
protected :
CollisionDetection* m_collisionDetection; //!< Pointer to the collision detection object
MemoryAllocator* m_memoryAllocator; //!< Pointer to the memory allocator
OverlappingPair* m_currentOverlappingPair; //!< Overlapping pair of the bodies currently tested for collision
/// Private copy-constructor
NarrowPhaseAlgorithm(const NarrowPhaseAlgorithm& algorithm) = delete;
@ -46,10 +44,9 @@ namespace ephysics {
/// Constructor
NarrowPhaseAlgorithm();
/// Destructor
virtual ~NarrowPhaseAlgorithm();
virtual ~NarrowPhaseAlgorithm() = default;
/// Initalize the algorithm
virtual void init(CollisionDetection* _collisionDetection,
MemoryAllocator* _memoryAllocator);
virtual void init(CollisionDetection* _collisionDetection);
/// Set the current overlapping pair of bodies
void setCurrentOverlappingPair(OverlappingPair* _overlappingPair);
/// Compute a contact info if the two bounding volume collide

View File

@ -11,7 +11,6 @@
#include <ephysics/mathematics/Ray.hpp>
#include <ephysics/collision/shapes/AABB.hpp>
#include <ephysics/collision/RaycastInfo.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
namespace ephysics {
enum CollisionShapeType {TRIANGLE, BOX, SPHERE, CONE, CYLINDER,

View File

@ -4,40 +4,28 @@
* @license BSD 3 clauses (see license file)
*/
// Libraries
#include <ephysics/collision/shapes/ConvexShape.hpp>
// We want to use the ReactPhysics3D namespace
using namespace ephysics;
// Constructor
ConvexShape::ConvexShape(CollisionShapeType type, float margin)
: CollisionShape(type), m_margin(margin) {
ephysics::ConvexShape::ConvexShape(ephysics::CollisionShapeType _type, float _margin):
CollisionShape(_type),
m_margin(_margin) {
}
// Destructor
ConvexShape::~ConvexShape() {
ephysics::ConvexShape::~ConvexShape() {
}
// Return a local support point in a given direction with the object margin
vec3 ConvexShape::getLocalSupportPointWithMargin(const vec3& direction,
void** cachedCollisionData) const {
vec3 ephysics::ConvexShape::getLocalSupportPointWithMargin(const vec3& _direction, void** _cachedCollisionData) const {
// Get the support point without margin
vec3 supportPoint = getLocalSupportPointWithoutMargin(direction, cachedCollisionData);
vec3 supportPoint = getLocalSupportPointWithoutMargin(_direction, _cachedCollisionData);
if (m_margin != 0.0f) {
// Add the margin to the support point
vec3 unitVec(0.0, -1.0, 0.0);
if (direction.length2() > FLT_EPSILON * FLT_EPSILON) {
unitVec = direction.safeNormalized();
if (_direction.length2() > FLT_EPSILON * FLT_EPSILON) {
unitVec = _direction.safeNormalized();
}
supportPoint += unitVec * m_margin;
}
return supportPoint;
}

View File

@ -4,24 +4,20 @@
* @license BSD 3 clauses (see license file)
*/
// Libraries
#include <ephysics/engine/CollisionWorld.hpp>
#include <ephysics/debug.hpp>
// Namespaces
using namespace ephysics;
using namespace std;
// Constructor
CollisionWorld::CollisionWorld()
: m_collisionDetection(this, m_memoryAllocator), m_currentBodyID(0),
m_eventListener(nullptr) {
CollisionWorld::CollisionWorld() :
m_collisionDetection(this),
m_currentBodyID(0),
m_eventListener(nullptr) {
}
// Destructor
CollisionWorld::~CollisionWorld() {
// Destroy all the collision bodies that have not been removed
etk::Set<CollisionBody*>::Iterator itBodies;
for (itBodies = m_bodies.begin(); itBodies != m_bodies.end(); ) {
@ -29,38 +25,30 @@ CollisionWorld::~CollisionWorld() {
++itBodies;
destroyCollisionBody(*itToRemove);
}
assert(m_bodies.empty());
}
// Create a collision body and add it to the world
/**
* @brief Create a collision body and add it to the world
* @param transform etk::Transform3Dation mapping the local-space of the body to world-space
* @return A pointer to the body that has been created in the world
*/
CollisionBody* CollisionWorld::createCollisionBody(const etk::Transform3D& transform) {
// Get the next available body ID
bodyindex bodyID = computeNextAvailableBodyID();
// Largest index cannot be used (it is used for invalid index)
EPHY_ASSERT(bodyID < std::numeric_limits<ephysics::bodyindex>::max(), "index too big");
// Create the collision body
CollisionBody* collisionBody = new (m_memoryAllocator.allocate(sizeof(CollisionBody)))
CollisionBody(transform, *this, bodyID);
CollisionBody* collisionBody = new CollisionBody(transform, *this, bodyID);
EPHY_ASSERT(collisionBody != nullptr, "empty Body collision");
// Add the collision body to the world
m_bodies.add(collisionBody);
// Return the pointer to the rigid body
return collisionBody;
}
// Destroy a collision body
/**
* @brief Destroy a collision body
* @param collisionBody Pointer to the body to destroy
*/
void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
@ -71,14 +59,11 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
// Add the body ID to the list of free IDs
m_freeBodiesIDs.pushBack(collisionBody->getID());
// Call the destructor of the collision body
collisionBody->~CollisionBody();
// Remove the collision body from the list of bodies
m_bodies.erase(m_bodies.find(collisionBody));
// Free the object from the memory allocator
m_memoryAllocator.release(collisionBody, sizeof(CollisionBody));
delete collisionBody;
collisionBody = nullptr;
}
// Return the next available body ID

View File

@ -14,7 +14,6 @@
#include <ephysics/collision/CollisionDetection.hpp>
#include <ephysics/constraint/Joint.hpp>
#include <ephysics/constraint/ContactPoint.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/engine/EventListener.hpp>
namespace ephysics {
@ -30,7 +29,6 @@ namespace ephysics {
etk::Set<CollisionBody*> m_bodies; //!< All the bodies (rigid and soft) of the world
bodyindex m_currentBodyID; //!< Current body ID
etk::Vector<uint64_t> m_freeBodiesIDs; //!< List of free ID for rigid bodies
MemoryAllocator m_memoryAllocator; //!< Memory allocator
EventListener* m_eventListener; //!< Pointer to an event listener object
/// Private copy-constructor
CollisionWorld(const CollisionWorld& world);

View File

@ -26,10 +26,12 @@ namespace ephysics {
const etk::Map<RigidBody*, uint32_t>& mapBodyToConstrainedVelocityIndex; //!< Reference to the map that associates rigid body to their index in the constrained velocities array
bool isWarmStartingActive; //!< True if warm starting of the solver is active
/// Constructor
ConstraintSolverData(const etk::Map<RigidBody*, uint32_t>& refMapBodyToConstrainedVelocityIndex)
:linearVelocities(NULL), angularVelocities(NULL),
positions(NULL), orientations(NULL),
mapBodyToConstrainedVelocityIndex(refMapBodyToConstrainedVelocityIndex){
ConstraintSolverData(const etk::Map<RigidBody*, uint32_t>& refMapBodyToConstrainedVelocityIndex):
linearVelocities(nullptr),
angularVelocities(nullptr),
positions(nullptr),
orientations(nullptr),
mapBodyToConstrainedVelocityIndex(refMapBodyToConstrainedVelocityIndex) {
}
};

View File

@ -15,31 +15,34 @@
using namespace ephysics;
using namespace std;
// Constructor
/**
* @param gravity Gravity vector in the world (in meters per second squared)
*/
DynamicsWorld::DynamicsWorld(const vec3 &gravity)
: CollisionWorld(),
m_contactSolver(m_mapBodyToConstrainedVelocityIndex),
m_constraintSolver(m_mapBodyToConstrainedVelocityIndex),
m_nbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
m_nbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
m_isSleepingEnabled(SPLEEPING_ENABLED), m_gravity(gravity),
m_isGravityEnabled(true), m_constrainedLinearVelocities(nullptr),
m_constrainedAngularVelocities(nullptr), m_splitLinearVelocities(nullptr),
m_splitAngularVelocities(nullptr), m_constrainedPositions(nullptr),
m_constrainedOrientations(nullptr), m_numberIslands(0),
m_numberIslandsCapacity(0), m_islands(nullptr), m_numberBodiesCapacity(0),
m_sleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
m_sleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
m_timeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
DynamicsWorld::DynamicsWorld(const vec3& _gravity):
CollisionWorld(),
m_contactSolver(m_mapBodyToConstrainedVelocityIndex),
m_constraintSolver(m_mapBodyToConstrainedVelocityIndex),
m_nbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
m_nbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
m_isSleepingEnabled(SPLEEPING_ENABLED),
m_gravity(_gravity),
m_isGravityEnabled(true),
m_constrainedLinearVelocities(nullptr),
m_constrainedAngularVelocities(nullptr),
m_splitLinearVelocities(nullptr),
m_splitAngularVelocities(nullptr),
m_constrainedPositions(nullptr),
m_constrainedOrientations(nullptr),
m_islands(),
m_numberBodiesCapacity(0),
m_sleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
m_sleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
m_timeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
}
// Destructor
DynamicsWorld::~DynamicsWorld() {
// Destroy all the joints that have not been removed
etk::Set<Joint*>::Iterator itJoints;
for (itJoints = m_joints.begin(); itJoints != m_joints.end();) {
@ -47,7 +50,6 @@ DynamicsWorld::~DynamicsWorld() {
++itJoints;
destroyJoint(*itToRemove);
}
// Destroy all the rigid bodies that have not been removed
etk::Set<RigidBody*>::Iterator itRigidBodies;
for (itRigidBodies = m_rigidBodies.begin(); itRigidBodies != m_rigidBodies.end();) {
@ -55,20 +57,13 @@ DynamicsWorld::~DynamicsWorld() {
++itRigidBodies;
destroyRigidBody(*itToRemove);
}
// Release the memory allocated for the islands
for (uint32_t i=0; i<m_numberIslands; i++) {
for (auto &it: m_islands) {
// Call the island destructor
m_islands[i]->~Island();
// Release the allocated memory for the island
m_memoryAllocator.release(m_islands[i], sizeof(Island));
delete it;
it = nullptr;
}
if (m_numberIslandsCapacity > 0) {
m_memoryAllocator.release(m_islands, sizeof(Island*) * m_numberIslandsCapacity);
}
m_islands.clear();
// Release the memory allocated for the bodies velocity arrays
if (m_numberBodiesCapacity > 0) {
delete[] m_splitLinearVelocities;
@ -78,16 +73,13 @@ DynamicsWorld::~DynamicsWorld() {
delete[] m_constrainedPositions;
delete[] m_constrainedOrientations;
}
assert(m_joints.size() == 0);
assert(m_rigidBodies.size() == 0);
#ifdef IS_PROFILING_ACTIVE
// Print32_t the profiling report
etk::Stream tmp;
Profiler::print32_tReport(tmp);
EPHYSIC_PRINT(tmp.str());
// Destroy the profiler (release the allocated memory)
Profiler::destroy();
#endif
@ -160,7 +152,7 @@ void DynamicsWorld::int32_tegrateRigidBodiesPositions() {
PROFILE("DynamicsWorld::int32_tegrateRigidBodiesPositions()");
// For each island of the world
for (uint32_t i=0; i < m_numberIslands; i++) {
for (uint32_t i=0; i < m_islands.size(); i++) {
RigidBody** bodies = m_islands[i]->getBodies();
@ -201,7 +193,7 @@ void DynamicsWorld::updateBodiesState() {
PROFILE("DynamicsWorld::updateBodiesState()");
// For each island of the world
for (uint32_t islandIndex = 0; islandIndex < m_numberIslands; islandIndex++) {
for (uint32_t islandIndex = 0; islandIndex < m_islands.size(); islandIndex++) {
// For each body of the island
RigidBody** bodies = m_islands[islandIndex]->getBodies();
@ -286,7 +278,7 @@ void DynamicsWorld::int32_tegrateRigidBodiesVelocities() {
initVelocityArrays();
// For each island of the world
for (uint32_t i=0; i < m_numberIslands; i++) {
for (uint32_t i=0; i < m_islands.size(); i++) {
RigidBody** bodies = m_islands[i]->getBodies();
@ -355,7 +347,7 @@ void DynamicsWorld::solveContactsAndConstraints() {
// ---------- Solve velocity constraints for joints and contacts ---------- //
// For each island of the world
for (uint32_t islandIndex = 0; islandIndex < m_numberIslands; islandIndex++) {
for (uint32_t islandIndex = 0; islandIndex < m_islands.size(); islandIndex++) {
// Check if there are contacts and constraints to solve
bool isConstraintsToSolve = m_islands[islandIndex]->getNbJoints() > 0;
@ -409,7 +401,7 @@ void DynamicsWorld::solvePositionCorrection() {
if (m_joints.empty()) return;
// For each island of the world
for (uint32_t islandIndex = 0; islandIndex < m_numberIslands; islandIndex++) {
for (uint32_t islandIndex = 0; islandIndex < m_islands.size(); islandIndex++) {
// ---------- Solve the position error correction for the constraints ---------- //
@ -436,8 +428,7 @@ RigidBody* DynamicsWorld::createRigidBody(const etk::Transform3D& transform) {
assert(bodyID < std::numeric_limits<ephysics::bodyindex>::max());
// Create the rigid body
RigidBody* rigidBody = new (m_memoryAllocator.allocate(sizeof(RigidBody))) RigidBody(transform,
*this, bodyID);
RigidBody* rigidBody = new RigidBody(transform, *this, bodyID);
assert(rigidBody != nullptr);
// Add the rigid body to the physics world
@ -453,31 +444,23 @@ RigidBody* DynamicsWorld::createRigidBody(const etk::Transform3D& transform) {
* @param rigidBody Pointer to the body you want to destroy
*/
void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
// Remove all the collision shapes of the body
rigidBody->removeAllCollisionShapes();
// Add the body ID to the list of free IDs
m_freeBodiesIDs.pushBack(rigidBody->getID());
// Destroy all the joints in which the rigid body to be destroyed is involved
JointListElement* element;
for (element = rigidBody->m_jointsList; element != nullptr; element = element->next) {
destroyJoint(element->joint);
}
// Reset the contact manifold list of the body
rigidBody->resetContactManifoldsList();
// Call the destructor of the rigid body
rigidBody->~RigidBody();
// Remove the rigid body from the list of rigid bodies
m_bodies.erase(m_bodies.find(rigidBody));
m_rigidBodies.erase(m_rigidBodies.find(rigidBody));
// Free the object from the memory allocator
m_memoryAllocator.release(rigidBody, sizeof(RigidBody));
// Call the destructor of the rigid body
delete rigidBody;
rigidBody = nullptr;
}
// Create a joint between two bodies in the world and return a pointer to the new joint
@ -495,37 +478,33 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
// Ball-and-Socket joint
case BALLSOCKETJOINT:
{
void* allocatedMemory = m_memoryAllocator.allocate(sizeof(BallAndSocketJoint));
const BallAndSocketJointInfo& info = static_cast<const BallAndSocketJointInfo&>(
jointInfo);
newJoint = new (allocatedMemory) BallAndSocketJoint(info);
newJoint = new BallAndSocketJoint(info);
break;
}
// Slider joint
case SLIDERJOINT:
{
void* allocatedMemory = m_memoryAllocator.allocate(sizeof(SliderJoint));
const SliderJointInfo& info = static_cast<const SliderJointInfo&>(jointInfo);
newJoint = new (allocatedMemory) SliderJoint(info);
newJoint = new SliderJoint(info);
break;
}
// Hinge joint
case HINGEJOINT:
{
void* allocatedMemory = m_memoryAllocator.allocate(sizeof(HingeJoint));
const HingeJointInfo& info = static_cast<const HingeJointInfo&>(jointInfo);
newJoint = new (allocatedMemory) HingeJoint(info);
newJoint = new HingeJoint(info);
break;
}
// Fixed joint
case FIXEDJOINT:
{
void* allocatedMemory = m_memoryAllocator.allocate(sizeof(FixedJoint));
const FixedJointInfo& info = static_cast<const FixedJointInfo&>(jointInfo);
newJoint = new (allocatedMemory) FixedJoint(info);
newJoint = new FixedJoint(info);
break;
}
@ -576,16 +555,14 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
m_joints.erase(m_joints.find(joint));
// Remove the joint from the joint list of the bodies involved in the joint
joint->m_body1->removeJointFrom_jointsList(m_memoryAllocator, joint);
joint->m_body2->removeJointFrom_jointsList(m_memoryAllocator, joint);
joint->m_body1->removeJointFrom_jointsList(joint);
joint->m_body2->removeJointFrom_jointsList(joint);
size_t nbBytes = joint->getSizeInBytes();
// Call the destructor of the joint
joint->~Joint();
// Release the allocated memory
m_memoryAllocator.release(joint, nbBytes);
delete joint;
joint = nullptr;
}
// Add the joint to the list of joints of the two bodies involved in the joint
@ -594,16 +571,10 @@ 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 = m_memoryAllocator.allocate(sizeof(JointListElement));
JointListElement* jointListElement1 = new (allocatedMemory1) JointListElement(joint,
joint->m_body1->m_jointsList);
joint->m_body1->m_jointsList = jointListElement1;
joint->m_body1->m_jointsList = new JointListElement(joint, joint->m_body1->m_jointsList);;
// Add the joint at the beginning of the linked list of joints of the second body
void* allocatedMemory2 = m_memoryAllocator.allocate(sizeof(JointListElement));
JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint,
joint->m_body2->m_jointsList);
joint->m_body2->m_jointsList = jointListElement2;
joint->m_body2->m_jointsList = new JointListElement(joint, joint->m_body2->m_jointsList);
}
// Compute the islands of awake bodies.
@ -614,30 +585,15 @@ void DynamicsWorld::addJointToBody(Joint* joint) {
/// find all the bodies that are connected with it (the bodies that share joints or contacts with
/// it). Then, we create an island with this group of connected bodies.
void DynamicsWorld::computeIslands() {
PROFILE("DynamicsWorld::computeIslands()");
uint32_t nbBodies = m_rigidBodies.size();
// Clear all the islands
for (uint32_t i=0; i<m_numberIslands; i++) {
// Call the island destructor
m_islands[i]->~Island();
// Release the allocated memory for the island
m_memoryAllocator.release(m_islands[i], sizeof(Island));
for (auto &it: m_islands) {
delete it;
it = nullptr;
}
// Allocate and create the array of islands
if (m_numberIslandsCapacity != nbBodies && nbBodies > 0) {
if (m_numberIslandsCapacity > 0) {
m_memoryAllocator.release(m_islands, sizeof(Island*) * m_numberIslandsCapacity);
}
m_numberIslandsCapacity = nbBodies;
m_islands = (Island**)m_memoryAllocator.allocate(sizeof(Island*) * m_numberIslandsCapacity);
}
m_numberIslands = 0;
// Call the island destructor
m_islands.clear();
int32_t nbContactManifolds = 0;
@ -652,7 +608,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**)m_memoryAllocator.allocate(nbBytesStack);
RigidBody** stackBodiesToVisit = new RigidBody*[nbBodies];
// For each rigid body of the world
for (etk::Set<RigidBody*>::Iterator it = m_rigidBodies.begin(); it != m_rigidBodies.end(); ++it) {
@ -675,10 +631,7 @@ void DynamicsWorld::computeIslands() {
body->m_isAlreadyInIsland = true;
// Create the new island
void* allocatedMemoryIsland = m_memoryAllocator.allocate(sizeof(Island));
m_islands[m_numberIslands] = new (allocatedMemoryIsland) Island(nbBodies,
nbContactManifolds,
m_joints.size(), m_memoryAllocator);
m_islands.pushBack(new Island(nbBodies, nbContactManifolds, m_joints.size()));
// While there are still some bodies to visit in the stack
while (stackIndex > 0) {
@ -692,7 +645,7 @@ void DynamicsWorld::computeIslands() {
bodyToVisit->setIsSleeping(false);
// Add the body int32_to the island
m_islands[m_numberIslands]->addBody(bodyToVisit);
m_islands.back()->addBody(bodyToVisit);
// If the current body is static, we do not want to perform the DFS
// search across that body
@ -711,7 +664,7 @@ void DynamicsWorld::computeIslands() {
if (contactManifold->isAlreadyInIsland()) continue;
// Add the contact manifold int32_to the island
m_islands[m_numberIslands]->addContactManifold(contactManifold);
m_islands.back()->addContactManifold(contactManifold);
contactManifold->m_isAlreadyInIsland = true;
// Get the other body of the contact manifold
@ -739,7 +692,7 @@ void DynamicsWorld::computeIslands() {
if (joint->isAlreadyInIsland()) continue;
// Add the joint int32_to the island
m_islands[m_numberIslands]->addJoint(joint);
m_islands.back()->addJoint(joint);
joint->m_isAlreadyInIsland = true;
// Get the other body of the contact manifold
@ -759,18 +712,16 @@ void DynamicsWorld::computeIslands() {
// Reset the isAlreadyIsland variable of the static bodies so that they
// can also be included in the other islands
for (uint32_t i=0; i < m_islands[m_numberIslands]->m_numberBodies; i++) {
for (uint32_t i=0; i < m_islands.back()->m_numberBodies; i++) {
if (m_islands[m_numberIslands]->m_bodies[i]->getType() == STATIC) {
m_islands[m_numberIslands]->m_bodies[i]->m_isAlreadyInIsland = false;
if (m_islands.back()->m_bodies[i]->getType() == STATIC) {
m_islands.back()->m_bodies[i]->m_isAlreadyInIsland = false;
}
}
m_numberIslands++;
}
}
// Release the allocated memory for the stack of bodies to visit
m_memoryAllocator.release(stackBodiesToVisit, nbBytesStack);
delete[] stackBodiesToVisit;
}
// Put bodies to sleep if needed.
@ -784,7 +735,7 @@ void DynamicsWorld::updateSleepingBodies() {
const float sleepAngularVelocitySquare = m_sleepAngularVelocity * m_sleepAngularVelocity;
// For each island of the world
for (uint32_t i=0; i<m_numberIslands; i++) {
for (uint32_t i=0; i<m_islands.size(); i++) {
float minSleepTime = FLT_MAX;

View File

@ -38,9 +38,7 @@ namespace ephysics {
vec3* m_constrainedPositions; //!< Array of constrained rigid bodies position (for position error correction)
etk::Quaternion* m_constrainedOrientations; //!< Array of constrained rigid bodies orientation (for position error correction)
etk::Map<RigidBody*, uint32_t> m_mapBodyToConstrainedVelocityIndex; //!< Map body to their index in the constrained velocities array
uint32_t m_numberIslands; //!< Number of islands in the world
uint32_t m_numberIslandsCapacity; //!< Current allocated capacity for the islands
Island** m_islands; //!< Array with all the islands of awaken bodies
etk::Vector<Island*> m_islands; //!< Array with all the islands of awaken bodies
uint32_t m_numberBodiesCapacity; //!< Current allocated capacity for the bodies
float m_sleepLinearVelocity; //!< Sleep linear velocity threshold
float m_sleepAngularVelocity; //!< Sleep angular velocity threshold
@ -56,8 +54,7 @@ namespace ephysics {
/// Reset the external force and torque applied to the bodies
void resetBodiesForceAndTorque();
/// Update the position and orientation of a body
void updatePositionAndOrientationOfBody(RigidBody* body, vec3 newLinVelocity,
vec3 newAngVelocity);
void updatePositionAndOrientationOfBody(RigidBody* _body, vec3 _newLinVelocity, vec3 _newAngVelocity);
/// Compute and set the int32_terpolation factor to all bodies
void setInterpolationFactorToAllBodies();
/// Initialize the bodies velocities arrays for the next simulation step.
@ -79,7 +76,10 @@ namespace ephysics {
/// Add the joint to the list of joints of the two bodies involved in the joint
void addJointToBody(Joint* joint);
public :
/// Constructor
/**
* @brief Constructor
* @param gravity Gravity vector in the world (in meters per second squared)
*/
DynamicsWorld(const vec3& m_gravity);
/// Destructor
virtual ~DynamicsWorld();

View File

@ -8,29 +8,29 @@
using namespace ephysics;
// Constructor
Island::Island(uint32_t nbMaxBodies, uint32_t nbMaxContactManifolds, uint32_t nbMaxJoints,
MemoryAllocator& memoryAllocator)
: m_bodies(NULL), m_contactManifolds(NULL), m_joints(NULL), m_numberBodies(0),
m_numberContactManifolds(0), m_numberJoints(0), m_memoryAllocator(memoryAllocator) {
ephysics::Island::Island(uint32_t _nbMaxBodies,
uint32_t _nbMaxContactManifolds,
uint32_t _nbMaxJoints):
m_bodies(nullptr),
m_contactManifolds(nullptr),
m_joints(nullptr),
m_numberBodies(0),
m_numberContactManifolds(0),
m_numberJoints(0) {
// Allocate memory for the arrays
m_numberAllocatedBytesBodies = sizeof(RigidBody*) * nbMaxBodies;
m_bodies = (RigidBody**) m_memoryAllocator.allocate(m_numberAllocatedBytesBodies);
m_numberAllocatedBytesContactManifolds = sizeof(ContactManifold*) * nbMaxContactManifolds;
m_contactManifolds = (ContactManifold**) m_memoryAllocator.allocate(
m_numberAllocatedBytesContactManifolds);
m_numberAllocatedBytesJoints = sizeof(Joint*) * nbMaxJoints;
m_joints = (Joint**) m_memoryAllocator.allocate(m_numberAllocatedBytesJoints);
m_numberAllocatedBytesBodies = sizeof(RigidBody*) * _nbMaxBodies;
m_bodies = new RigidBody*[_nbMaxBodies];
m_numberAllocatedBytesContactManifolds = sizeof(ContactManifold*) * _nbMaxContactManifolds;
m_contactManifolds = new ContactManifold*[_nbMaxContactManifolds];
m_numberAllocatedBytesJoints = sizeof(Joint*) * _nbMaxJoints;
m_joints = new Joint*[_nbMaxJoints];
}
// Destructor
Island::~Island() {
// Release the memory of the arrays
m_memoryAllocator.release(m_bodies, m_numberAllocatedBytesBodies);
m_memoryAllocator.release(m_contactManifolds, m_numberAllocatedBytesContactManifolds);
m_memoryAllocator.release(m_joints, m_numberAllocatedBytesJoints);
delete[] m_bodies;
delete[] m_contactManifolds;
delete[] m_joints;
}
// Add a body int32_to the island

View File

@ -5,7 +5,6 @@
*/
#pragma once
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/body/RigidBody.hpp>
#include <ephysics/constraint/Joint.hpp>
#include <ephysics/collision/ContactManifold.hpp>
@ -23,7 +22,6 @@ namespace ephysics {
uint32_t m_numberBodies; //!< Current number of bodies in the island
uint32_t m_numberContactManifolds; //!< Current number of contact manifold in the island
uint32_t m_numberJoints; //!< Current number of joints in the island
MemoryAllocator& m_memoryAllocator; //!< Reference to the memory allocator
size_t m_numberAllocatedBytesBodies; //!< Number of bytes allocated for the bodies array
size_t m_numberAllocatedBytesContactManifolds; //!< Number of bytes allocated for the contact manifolds array
size_t m_numberAllocatedBytesJoints; //!< Number of bytes allocated for the joints array
@ -33,8 +31,7 @@ namespace ephysics {
Island(const Island& island);
public:
/// Constructor
Island(uint32_t nbMaxBodies, uint32_t nbMaxContactManifolds, uint32_t nbMaxJoints,
MemoryAllocator& memoryAllocator);
Island(uint32_t nbMaxBodies, uint32_t nbMaxContactManifolds, uint32_t nbMaxJoints);
/// Destructor
~Island();
/// Add a body int32_to the island

View File

@ -9,59 +9,47 @@
using namespace ephysics;
// Constructor
OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, int32_t nbMaxContactManifolds, MemoryAllocator& memoryAllocator):
m_contactManifoldSet(shape1, shape2, memoryAllocator, nbMaxContactManifolds),
OverlappingPair::OverlappingPair(ProxyShape* _shape1, ProxyShape* _shape2, int32_t _nbMaxContactManifolds):
m_contactManifoldSet(_shape1, _shape2, _nbMaxContactManifolds),
m_cachedSeparatingAxis(1.0, 1.0, 1.0) {
}
// Return the pointer to first body
ProxyShape* OverlappingPair::getShape1() const {
return m_contactManifoldSet.getShape1();
}
// Return the pointer to second body
ProxyShape* OverlappingPair::getShape2() const {
return m_contactManifoldSet.getShape2();
}
// Add a contact to the contact manifold
void OverlappingPair::addContact(ContactPoint* contact) {
m_contactManifoldSet.addContactPoint(contact);
void OverlappingPair::addContact(ContactPoint* _contact) {
m_contactManifoldSet.addContactPoint(_contact);
}
// Update the contact manifold
void OverlappingPair::update() {
m_contactManifoldSet.update();
}
// Return the cached separating axis
vec3 OverlappingPair::getCachedSeparatingAxis() const {
return m_cachedSeparatingAxis;
}
// Set the cached separating axis
void OverlappingPair::setCachedSeparatingAxis(const vec3& _axis) {
m_cachedSeparatingAxis = _axis;
}
// Return the number of contact points in the contact manifold
uint32_t OverlappingPair::getNbContactPoints() const {
return m_contactManifoldSet.getTotalNbContactPoints();
}
// Return the contact manifold
const ContactManifoldSet& OverlappingPair::getContactManifoldSet() {
return m_contactManifoldSet;
}
// Return the pair of bodies index
overlappingpairid OverlappingPair::computeID(ProxyShape* _shape1, ProxyShape* _shape2) {
assert( _shape1->m_broadPhaseID >= 0
&& _shape2->m_broadPhaseID >= 0);
// Construct the pair of body index
overlappingpairid pairID = _shape1->m_broadPhaseID < _shape2->m_broadPhaseID ?
etk::makePair(_shape1->m_broadPhaseID, _shape2->m_broadPhaseID) :
@ -70,10 +58,8 @@ overlappingpairid OverlappingPair::computeID(ProxyShape* _shape1, ProxyShape* _s
return pairID;
}
// Return the pair of bodies index
bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* _body1,
CollisionBody* _body2) {
// Construct the pair of body index
bodyindexpair indexPair = _body1->getID() < _body2->getID() ?
etk::makePair(_body1->getID(), _body2->getID()) :
@ -82,7 +68,7 @@ bodyindexpair OverlappingPair::computeBodiesIndexPair(CollisionBody* _body1,
return indexPair;
}
// Clear the contact points of the contact manifold
void OverlappingPair::clearContactPoints() {
m_contactManifoldSet.clear();
}

View File

@ -30,8 +30,7 @@ namespace ephysics {
/// Constructor
OverlappingPair(ProxyShape* shape1,
ProxyShape* shape2,
int32_t nbMaxContactManifolds,
MemoryAllocator& memoryAllocator);
int32_t nbMaxContactManifolds);
/// Return the pointer to first proxy collision shape
ProxyShape* getShape1() const;
/// Return the pointer to second body

View File

@ -5,60 +5,41 @@
*/
#pragma once
// Libraries
#include <etk/math/Vector3D.hpp>
/// ReactPhysics3D namespace
namespace ephysics {
// Class Ray
/**
* This structure represents a 3D ray represented by two points.
* The ray goes from point1 to point1 + maxFraction * (point2 - point1).
* The points are specified in world-space coordinates.
*/
struct Ray {
public:
// -------------------- Attributes -------------------- //
/// First point of the ray (origin)
vec3 point1;
/// Second point of the ray
vec3 point2;
/// Maximum fraction value
float maxFraction;
// -------------------- Methods -------------------- //
/// Constructor with arguments
Ray(const vec3& p1, const vec3& p2, float maxFrac = 1.0f)
: point1(p1), point2(p2), maxFraction(maxFrac) {
}
/// Copy-constructor
Ray(const Ray& ray) : point1(ray.point1), point2(ray.point2), maxFraction(ray.maxFraction) {
}
/// Destructor
~Ray() {
}
/// Overloaded assignment operator
Ray& operator=(const Ray& ray) {
if (&ray != this) {
point1 = ray.point1;
point2 = ray.point2;
maxFraction = ray.maxFraction;
/**
* This structure represents a 3D ray represented by two points.
* The ray goes from point1 to point1 + maxFraction * (point2 - point1).
* The points are specified in world-space coordinates.
*/
struct Ray {
public:
vec3 point1; //!<First point of the ray (origin)
vec3 point2; //!< Second point of the ray
float maxFraction; //!< Maximum fraction value
/// Constructor with arguments
Ray(const vec3& _p1, const vec3& _p2, float _maxFrac = 1.0f):
point1(_p1),
point2(_p2),
maxFraction(_maxFrac) {
}
return *this;
}
};
/// Copy-constructor
Ray(const Ray& _ray):
point1(_ray.point1),
point2(_ray.point2),
maxFraction(_ray.maxFraction) {
}
/// Overloaded assignment operator
Ray& operator=(const Ray& _ray) {
if (&_ray != this) {
point1 = _ray.point1;
point2 = _ray.point2;
maxFraction = _ray.maxFraction;
}
return *this;
}
};
}

View File

@ -1,172 +0,0 @@
/** @file
* @author Daniel Chappuis
* @copyright 2010-2016 Daniel Chappuis
* @license BSD 3 clauses (see license file)
*/
// Libraries
#include <ephysics/memory/MemoryAllocator.hpp>
using namespace ephysics;
// Initialization of static variables
bool MemoryAllocator::isMapSizeToHeadIndexInitialized = false;
size_t MemoryAllocator::m_unitSizes[NB_HEAPS];
int32_t MemoryAllocator::m_mapSizeToHeapIndex[MAX_UNIT_SIZE + 1];
// Constructor
MemoryAllocator::MemoryAllocator() {
// Allocate some memory to manage the blocks
m_numberAllocatedMemoryBlocks = 64;
m_numberCurrentMemoryBlocks = 0;
const size_t sizeToAllocate = m_numberAllocatedMemoryBlocks * sizeof(MemoryBlock);
m_memoryBlocks = (MemoryBlock*) malloc(sizeToAllocate);
memset(m_memoryBlocks, 0, sizeToAllocate);
memset(m_freeMemoryUnits, 0, sizeof(m_freeMemoryUnits));
#ifndef NDEBUG
m_numberTimesAllocateMethodCalled = 0;
#endif
// If the m_mapSizeToHeapIndex has not been initialized yet
if (!isMapSizeToHeadIndexInitialized) {
// Initialize the array that contains the sizes the memory units that will
// be allocated in each different heap
for (int32_t i=0; i < NB_HEAPS; i++) {
m_unitSizes[i] = (i+1) * 8;
}
// Initialize the lookup table that maps the size to allocated to the
// corresponding heap we will use for the allocation
uint32_t j = 0;
m_mapSizeToHeapIndex[0] = -1; // This element should not be used
for (uint32_t i=1; i <= MAX_UNIT_SIZE; i++) {
if (i <= m_unitSizes[j]) {
m_mapSizeToHeapIndex[i] = j;
}
else {
j++;
m_mapSizeToHeapIndex[i] = j;
}
}
isMapSizeToHeadIndexInitialized = true;
}
}
// Destructor
MemoryAllocator::~MemoryAllocator() {
// Release the memory allocated for each block
for (uint32_t i=0; i<m_numberCurrentMemoryBlocks; i++) {
free(m_memoryBlocks[i].memoryUnits);
}
free(m_memoryBlocks);
#ifndef NDEBUG
// Check that the allocate() and release() methods have been called the same
// number of times to avoid memory leaks.
assert(m_numberTimesAllocateMethodCalled == 0);
#endif
}
// Allocate memory of a given size (in bytes) and return a pointer to the
// allocated memory.
void* MemoryAllocator::allocate(size_t size) {
// We cannot allocate zero bytes
if (size == 0) return NULL;
#ifndef NDEBUG
m_numberTimesAllocateMethodCalled++;
#endif
// 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);
}
// Get the index of the heap that will take care of the allocation request
int32_t indexHeap = m_mapSizeToHeapIndex[size];
assert(indexHeap >= 0 && indexHeap < NB_HEAPS);
// If there still are free memory units in the corresponding heap
if (m_freeMemoryUnits[indexHeap] != NULL) {
// Return a pointer to the memory unit
MemoryUnit* unit = m_freeMemoryUnits[indexHeap];
m_freeMemoryUnits[indexHeap] = unit->nextUnit;
return unit;
}
else { // If there is no more free memory units in the corresponding heap
// If we need to allocate more memory to containsthe blocks
if (m_numberCurrentMemoryBlocks == m_numberAllocatedMemoryBlocks) {
// Allocate more memory to contain the blocks
MemoryBlock* currentMemoryBlocks = m_memoryBlocks;
m_numberAllocatedMemoryBlocks += 64;
m_memoryBlocks = (MemoryBlock*) malloc(m_numberAllocatedMemoryBlocks * sizeof(MemoryBlock));
memcpy(m_memoryBlocks, currentMemoryBlocks,m_numberCurrentMemoryBlocks * sizeof(MemoryBlock));
memset(m_memoryBlocks + m_numberCurrentMemoryBlocks, 0, 64 * sizeof(MemoryBlock));
free(currentMemoryBlocks);
}
// Allocate a new memory blocks for the corresponding heap and divide it in many
// memory units
MemoryBlock* newBlock = m_memoryBlocks + m_numberCurrentMemoryBlocks;
newBlock->memoryUnits = (MemoryUnit*) malloc(BLOCK_SIZE);
assert(newBlock->memoryUnits != NULL);
size_t unitSize = m_unitSizes[indexHeap];
uint32_t nbUnits = BLOCK_SIZE / unitSize;
assert(nbUnits * unitSize <= BLOCK_SIZE);
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));
unit->nextUnit = nextUnit;
}
MemoryUnit* lastUnit = (MemoryUnit*) ((size_t)newBlock->memoryUnits + unitSize*(nbUnits-1));
lastUnit->nextUnit = NULL;
// Add the new allocated block int32_to the list of free memory units in the heap
m_freeMemoryUnits[indexHeap] = newBlock->memoryUnits->nextUnit;
m_numberCurrentMemoryBlocks++;
// Return the pointer to the first memory unit of the new allocated block
return newBlock->memoryUnits;
}
}
// Release previously allocated memory.
void MemoryAllocator::release(void* pointer, size_t size) {
// Cannot release a 0-byte allocated memory
if (size == 0) return;
#ifndef NDEBUG
m_numberTimesAllocateMethodCalled--;
#endif
// 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);
return;
}
// Get the index of the heap that has handled the corresponding allocation request
int32_t indexHeap = m_mapSizeToHeapIndex[size];
assert(indexHeap >= 0 && indexHeap < NB_HEAPS);
// Insert the released memory unit int32_to the list of free memory units of the
// corresponding heap
MemoryUnit* releasedUnit = (MemoryUnit*) pointer;
releasedUnit->nextUnit = m_freeMemoryUnits[indexHeap];
m_freeMemoryUnits[indexHeap] = releasedUnit;
}

View File

@ -1,86 +0,0 @@
/** @file
* @author Daniel Chappuis
* @copyright 2010-2016 Daniel Chappuis
* @license BSD 3 clauses (see license file)
*/
#pragma once
// Libraries
#include <ephysics/configuration.hpp>
/// ReactPhysics3D namespace
namespace ephysics {
// Class MemoryAllocator
/**
* This class is used to efficiently allocate memory on the heap.
* It allows us to allocate small blocks of memory (smaller or equal to 1024 bytes)
* efficiently. This implementation is inspired by the small block allocator
* described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp
*/
class MemoryAllocator {
private :
// Structure MemoryUnit
/**
* Represent a memory unit that is used for a single memory allocation
* request.
*/
struct MemoryUnit {
public :
/// Pointer to the next memory unit inside a memory block
MemoryUnit* nextUnit;
};
// Structure MemoryBlock
/**
* A memory block is a large piece of memory that is allocated once and that
* will contain multiple memory unity.
*/
struct MemoryBlock {
public :
/// Pointer to the first element of a linked-list of memory unity.
MemoryUnit* memoryUnits;
};
/// Number of heaps
static const int32_t NB_HEAPS = 128;
/// Maximum memory unit size. An allocation request of a size smaller or equal to
/// this size will be handled using the small block allocator. However, for an
/// allocation request larger than the maximum block size, the standard malloc()
/// will be used.
static const size_t MAX_UNIT_SIZE = 1024;
/// Size a memory chunk
static const size_t BLOCK_SIZE = 16 * MAX_UNIT_SIZE;
// -------------------- Attributes -------------------- //
/// Size of the memory units that each heap is responsible to allocate
static size_t m_unitSizes[NB_HEAPS];
/// Lookup table that mape size to allocate to the index of the
/// corresponding heap we will use for the allocation.
static int32_t m_mapSizeToHeapIndex[MAX_UNIT_SIZE + 1];
/// True if the m_mapSizeToHeapIndex array has already been initialized
static bool isMapSizeToHeadIndexInitialized;
/// Pointers to the first free memory unit for each heap
MemoryUnit* m_freeMemoryUnits[NB_HEAPS];
/// All the allocated memory blocks
MemoryBlock* m_memoryBlocks;
/// Number of allocated memory blocks
uint32_t m_numberAllocatedMemoryBlocks;
/// Current number of used memory blocks
uint32_t m_numberCurrentMemoryBlocks;
#ifndef NDEBUG
/// This variable is incremented by one when the allocate() method has been
/// called and decreased by one when the release() method has been called.
/// This variable is used in debug mode to check that the allocate() and release()
/// methods are called the same number of times
int32_t m_numberTimesAllocateMethodCalled;
#endif
public :
// -------------------- Methods -------------------- //
/// Constructor
MemoryAllocator();
/// Destructor
~MemoryAllocator();
/// Allocate memory of a given size (in bytes) and return a pointer to the
/// allocated memory.
void* allocate(size_t size);
/// Release previously allocated memory.
void release(void* pointer, size_t size);
};
}

View File

@ -5,64 +5,44 @@
*/
#pragma once
// Libraries
#include <ephysics/configuration.hpp>
namespace ephysics {
// Class Stack
/**
* This class represents a simple generic stack with an initial capacity. If the number
* of elements exceeds the capacity, the heap will be used to allocated more memory.
*/
template<typename T, uint32_t capacity>
class Stack {
private:
// -------------------- Attributes -------------------- //
/// Initial array that contains the elements of the stack
T mInitArray[capacity];
/// Pointer to the first element of the stack
T* mElements;
/// Number of elements in the stack
uint32_t mNbElements;
/// Number of allocated elements in the stack
uint32_t mNbAllocatedElements;
public:
// -------------------- Methods -------------------- //
/// Constructor
Stack() : mElements(mInitArray), mNbElements(0), mNbAllocatedElements(capacity) {
}
/// Destructor
~Stack() {
// If elements have been allocated on the heap
if (mInitArray != mElements) {
// Release the memory allocated on the heap
free(mElements);
}
}
/// Push an element int32_to the stack
void push(const T& element);
/// Pop an element from the stack (remove it from the stack and return it)
T pop();
/// Return the number of elments in the stack
uint32_t getNbElements() const;
};
// Push an element int32_to the stack

View File

@ -29,7 +29,6 @@ def configure(target, my_module):
# add the file to compile:
my_module.add_src_file([
'ephysics/debug.cpp',
'ephysics/memory/MemoryAllocator.cpp',
'ephysics/constraint/Joint.cpp',
'ephysics/constraint/HingeJoint.cpp',
'ephysics/constraint/ContactPoint.cpp',
@ -85,7 +84,6 @@ def configure(target, my_module):
my_module.add_header_file([
'ephysics/debug.hpp',
'ephysics/memory/MemoryAllocator.hpp',
'ephysics/memory/Stack.hpp',
'ephysics/constraint/BallAndSocketJoint.hpp',
'ephysics/constraint/Joint.hpp',