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

View File

@ -11,7 +11,6 @@
#include <ephysics/collision/shapes/AABB.hpp> #include <ephysics/collision/shapes/AABB.hpp>
#include <ephysics/collision/shapes/CollisionShape.hpp> #include <ephysics/collision/shapes/CollisionShape.hpp>
#include <ephysics/collision/RaycastInfo.hpp> #include <ephysics/collision/RaycastInfo.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/configuration.hpp> #include <ephysics/configuration.hpp>
namespace ephysics { 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(_joint != nullptr);
assert(m_jointsList != nullptr); assert(m_jointsList != nullptr);
// Remove the joint from the linked list of the joints of the first body // 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 if (m_jointsList->joint == _joint) { // If the first element is the one to remove
JointListElement* elementToRemove = m_jointsList; JointListElement* elementToRemove = m_jointsList;
m_jointsList = elementToRemove->next; m_jointsList = elementToRemove->next;
elementToRemove->~JointListElement(); delete elementToRemove;
_memoryAllocator.release(elementToRemove, sizeof(JointListElement)); elementToRemove = nullptr;
} }
else { // If the element to remove is not the first one in the list else { // If the element to remove is not the first one in the list
JointListElement* currentElement = m_jointsList; JointListElement* currentElement = m_jointsList;
@ -111,8 +111,8 @@ void RigidBody::removeJointFrom_jointsList(MemoryAllocator& _memoryAllocator, co
if (currentElement->next->joint == _joint) { if (currentElement->next->joint == _joint) {
JointListElement* elementToRemove = currentElement->next; JointListElement* elementToRemove = currentElement->next;
currentElement->next = elementToRemove->next; currentElement->next = elementToRemove->next;
elementToRemove->~JointListElement(); delete elementToRemove;
_memoryAllocator.release(elementToRemove, sizeof(JointListElement)); elementToRemove = nullptr;
break; break;
} }
currentElement = currentElement->next; currentElement = currentElement->next;
@ -126,7 +126,7 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* _collisionShape,
float _mass) { float _mass) {
assert(_mass > 0.0f); assert(_mass > 0.0f);
// Create a new proxy collision shape to attach the collision shape to the body // 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 // Add it to the list of proxy collision shapes of the body
if (m_proxyCollisionShapes == nullptr) { if (m_proxyCollisionShapes == nullptr) {
m_proxyCollisionShapes = proxyShape; m_proxyCollisionShapes = proxyShape;

View File

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

View File

@ -10,7 +10,6 @@
#include <ephysics/engine/OverlappingPair.hpp> #include <ephysics/engine/OverlappingPair.hpp>
#include <ephysics/engine/EventListener.hpp> #include <ephysics/engine/EventListener.hpp>
#include <ephysics/collision/narrowphase/DefaultCollisionDispatch.hpp> #include <ephysics/collision/narrowphase/DefaultCollisionDispatch.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/constraint/ContactPoint.hpp> #include <ephysics/constraint/ContactPoint.hpp>
#include <etk/Vector.hpp> #include <etk/Vector.hpp>
#include <etk/Map.hpp> #include <etk/Map.hpp>
@ -31,7 +30,6 @@ namespace ephysics {
m_collisionCallback(_callback) { m_collisionCallback(_callback) {
} }
// Called by a narrow-phase collision algorithm when a new contact has been found // Called by a narrow-phase collision algorithm when a new contact has been found
virtual void notifyContact(OverlappingPair* _overlappingPair, virtual void notifyContact(OverlappingPair* _overlappingPair,
const ContactPointInfo& _contactInfo); const ContactPointInfo& _contactInfo);
@ -48,7 +46,6 @@ namespace ephysics {
CollisionDispatch* m_collisionDispatch; //!< Collision Detection Dispatch configuration CollisionDispatch* m_collisionDispatch; //!< Collision Detection Dispatch configuration
DefaultCollisionDispatch m_defaultCollisionDispatch; //!< Default collision 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) 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 CollisionWorld* m_world; //!< Pointer to the physics world
etk::Map<overlappingpairid, OverlappingPair*> m_overlappingPairs; //!< Broad-phase overlapping pairs 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) 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(); void addAllContactManifoldsToBodies();
public : public :
/// Constructor /// Constructor
CollisionDetection(CollisionWorld* _world, MemoryAllocator& _memoryAllocator); CollisionDetection(CollisionWorld* _world);
/// Destructor /// Destructor
~CollisionDetection(); ~CollisionDetection();
/// Set the collision dispatch configuration /// Set the collision dispatch configuration
@ -132,8 +129,6 @@ namespace ephysics {
CollisionWorld* getWorld(); CollisionWorld* getWorld();
/// Return the world event listener /// Return the world event listener
EventListener* getWorldEventListener(); 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 /// Called by a narrow-phase collision algorithm when a new contact has been found
virtual void notifyContact(OverlappingPair* _overlappingPair, const ContactPointInfo& _contactInfo) override; virtual void notifyContact(OverlappingPair* _overlappingPair, const ContactPointInfo& _contactInfo) override;
/// Create a new contact /// Create a new contact

View File

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

View File

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

View File

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

View File

@ -22,7 +22,6 @@ namespace ephysics {
int32_t m_nbManifolds; //!< Current number of contact manifolds in the set 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_shape1; //!< Pointer to the first proxy shape of the contact
ProxyShape* m_shape2; //!< Pointer to the second 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 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 /// Create a new contact manifold and add it to the set
void createManifold(short _normalDirectionId); void createManifold(short _normalDirectionId);
@ -38,7 +37,6 @@ namespace ephysics {
/// Constructor /// Constructor
ContactManifoldSet(ProxyShape* _shape1, ContactManifoldSet(ProxyShape* _shape1,
ProxyShape* _shape2, ProxyShape* _shape2,
MemoryAllocator& _memoryAllocator,
int32_t _nbMaxManifolds); int32_t _nbMaxManifolds);
/// Destructor /// Destructor
~ContactManifoldSet(); ~ContactManifoldSet();

View File

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

View File

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

View File

@ -11,23 +11,24 @@
#include <ephysics/collision/narrowphase/GJK/GJKAlgorithm.hpp> #include <ephysics/collision/narrowphase/GJK/GJKAlgorithm.hpp>
namespace ephysics { namespace ephysics {
/** /**
* @brief This is the default collision dispatch configuration use in ephysics. * @brief This is the default collision dispatch configuration use in ephysics.
* Collision dispatching decides which collision * Collision dispatching decides which collision
* algorithm to use given two types of proxy collision shapes. * algorithm to use given two types of proxy collision shapes.
*/ */
class DefaultCollisionDispatch : public CollisionDispatch { class DefaultCollisionDispatch : public CollisionDispatch {
protected: protected:
SphereVsSphereAlgorithm mSphereVsSphereAlgorithm; //!< Sphere vs Sphere collision algorithm SphereVsSphereAlgorithm m_sphereVsSphereAlgorithm; //!< Sphere vs Sphere collision algorithm
ConcaveVsConvexAlgorithm mConcaveVsConvexAlgorithm; //!< Concave vs Convex collision algorithm ConcaveVsConvexAlgorithm m_concaveVsConvexAlgorithm; //!< Concave vs Convex collision algorithm
GJKAlgorithm mGJKAlgorithm; //!< GJK Algorithm GJKAlgorithm m_GJKAlgorithm; //!< GJK Algorithm
public: public:
/// Constructor /**
DefaultCollisionDispatch(); * @brief Constructor
void init(CollisionDetection* _collisionDetection, MemoryAllocator* _memoryAllocator) override; */
NarrowPhaseAlgorithm* selectAlgorithm(int32_t _type1, int32_t _type2) override; 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/collision/narrowphase/NarrowPhaseAlgorithm.hpp>
#include <ephysics/mathematics/mathematics.hpp> #include <ephysics/mathematics/mathematics.hpp>
#include <ephysics/collision/narrowphase/EPA/TriangleEPA.hpp> #include <ephysics/collision/narrowphase/EPA/TriangleEPA.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <algorithm> #include <algorithm>
namespace ephysics { namespace ephysics {
@ -51,7 +50,6 @@ namespace ephysics {
*/ */
class EPAAlgorithm { class EPAAlgorithm {
private: private:
MemoryAllocator* m_memoryAllocator; //!< Reference to the memory allocator
TriangleComparison m_triangleComparison; //!< Triangle comparison operator TriangleComparison m_triangleComparison; //!< Triangle comparison operator
/// Private copy-constructor /// Private copy-constructor
EPAAlgorithm(const EPAAlgorithm& _algorithm); EPAAlgorithm(const EPAAlgorithm& _algorithm);
@ -84,8 +82,8 @@ namespace ephysics {
/// Destructor /// Destructor
~EPAAlgorithm(); ~EPAAlgorithm();
/// Initalize the algorithm /// Initalize the algorithm
void init(MemoryAllocator* _memoryAllocator) { void init() {
m_memoryAllocator = _memoryAllocator;
} }
// Compute the penetration depth with the EPA algorithm. // Compute the penetration depth with the EPA algorithm.
/// This method computes the penetration depth and contact points between two /// This method computes the penetration depth and contact points between two

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,6 @@
#include <ephysics/collision/CollisionDetection.hpp> #include <ephysics/collision/CollisionDetection.hpp>
#include <ephysics/constraint/Joint.hpp> #include <ephysics/constraint/Joint.hpp>
#include <ephysics/constraint/ContactPoint.hpp> #include <ephysics/constraint/ContactPoint.hpp>
#include <ephysics/memory/MemoryAllocator.hpp>
#include <ephysics/engine/EventListener.hpp> #include <ephysics/engine/EventListener.hpp>
namespace ephysics { namespace ephysics {
@ -30,7 +29,6 @@ namespace ephysics {
etk::Set<CollisionBody*> m_bodies; //!< All the bodies (rigid and soft) of the world etk::Set<CollisionBody*> m_bodies; //!< All the bodies (rigid and soft) of the world
bodyindex m_currentBodyID; //!< Current body ID bodyindex m_currentBodyID; //!< Current body ID
etk::Vector<uint64_t> m_freeBodiesIDs; //!< List of free ID for rigid bodies 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 EventListener* m_eventListener; //!< Pointer to an event listener object
/// Private copy-constructor /// Private copy-constructor
CollisionWorld(const CollisionWorld& world); 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 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 bool isWarmStartingActive; //!< True if warm starting of the solver is active
/// Constructor /// Constructor
ConstraintSolverData(const etk::Map<RigidBody*, uint32_t>& refMapBodyToConstrainedVelocityIndex) ConstraintSolverData(const etk::Map<RigidBody*, uint32_t>& refMapBodyToConstrainedVelocityIndex):
:linearVelocities(NULL), angularVelocities(NULL), linearVelocities(nullptr),
positions(NULL), orientations(NULL), angularVelocities(nullptr),
mapBodyToConstrainedVelocityIndex(refMapBodyToConstrainedVelocityIndex){ positions(nullptr),
orientations(nullptr),
mapBodyToConstrainedVelocityIndex(refMapBodyToConstrainedVelocityIndex) {
} }
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,60 +5,41 @@
*/ */
#pragma once #pragma once
// Libraries
#include <etk/math/Vector3D.hpp> #include <etk/math/Vector3D.hpp>
/// ReactPhysics3D namespace
namespace ephysics { namespace ephysics {
/**
// Class Ray * This structure represents a 3D ray represented by two points.
/** * The ray goes from point1 to point1 + maxFraction * (point2 - point1).
* This structure represents a 3D ray represented by two points. * The points are specified in world-space coordinates.
* The ray goes from point1 to point1 + maxFraction * (point2 - point1). */
* The points are specified in world-space coordinates. struct Ray {
*/ public:
struct Ray { vec3 point1; //!<First point of the ray (origin)
vec3 point2; //!< Second point of the ray
public: float maxFraction; //!< Maximum fraction value
/// Constructor with arguments
// -------------------- Attributes -------------------- // Ray(const vec3& _p1, const vec3& _p2, float _maxFrac = 1.0f):
point1(_p1),
/// First point of the ray (origin) point2(_p2),
vec3 point1; maxFraction(_maxFrac) {
/// 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;
} }
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 #pragma once
// Libraries
#include <ephysics/configuration.hpp> #include <ephysics/configuration.hpp>
namespace ephysics { namespace ephysics {
// Class Stack
/** /**
* This class represents a simple generic stack with an initial capacity. If the number * 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. * of elements exceeds the capacity, the heap will be used to allocated more memory.
*/ */
template<typename T, uint32_t capacity> template<typename T, uint32_t capacity>
class Stack { class Stack {
private: private:
// -------------------- Attributes -------------------- //
/// Initial array that contains the elements of the stack /// Initial array that contains the elements of the stack
T mInitArray[capacity]; T mInitArray[capacity];
/// Pointer to the first element of the stack /// Pointer to the first element of the stack
T* mElements; T* mElements;
/// Number of elements in the stack /// Number of elements in the stack
uint32_t mNbElements; uint32_t mNbElements;
/// Number of allocated elements in the stack /// Number of allocated elements in the stack
uint32_t mNbAllocatedElements; uint32_t mNbAllocatedElements;
public: public:
// -------------------- Methods -------------------- //
/// Constructor /// Constructor
Stack() : mElements(mInitArray), mNbElements(0), mNbAllocatedElements(capacity) { Stack() : mElements(mInitArray), mNbElements(0), mNbAllocatedElements(capacity) {
} }
/// Destructor /// Destructor
~Stack() { ~Stack() {
// If elements have been allocated on the heap // If elements have been allocated on the heap
if (mInitArray != mElements) { if (mInitArray != mElements) {
// Release the memory allocated on the heap // Release the memory allocated on the heap
free(mElements); free(mElements);
} }
} }
/// Push an element int32_to the stack /// Push an element int32_to the stack
void push(const T& element); void push(const T& element);
/// Pop an element from the stack (remove it from the stack and return it) /// Pop an element from the stack (remove it from the stack and return it)
T pop(); T pop();
/// Return the number of elments in the stack /// Return the number of elments in the stack
uint32_t getNbElements() const; uint32_t getNbElements() const;
}; };
// Push an element int32_to the stack // Push an element int32_to the stack

View File

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