[DEV] remove allocator (not full implemented and offuscation of code ==> bettre way to do it
This commit is contained in:
parent
fc1a41f768
commit
7ead46281c
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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++;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
};
|
||||
}
|
@ -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
|
||||
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user