Merge branch 'opti_solver2' into optimization
This commit is contained in:
commit
05f665040f
|
@ -147,7 +147,6 @@ SET (REACTPHYSICS3D_SOURCES
|
||||||
"src/engine/DynamicsWorld.h"
|
"src/engine/DynamicsWorld.h"
|
||||||
"src/engine/DynamicsWorld.cpp"
|
"src/engine/DynamicsWorld.cpp"
|
||||||
"src/engine/EventListener.h"
|
"src/engine/EventListener.h"
|
||||||
"src/engine/Impulse.h"
|
|
||||||
"src/engine/Island.h"
|
"src/engine/Island.h"
|
||||||
"src/engine/Island.cpp"
|
"src/engine/Island.cpp"
|
||||||
"src/engine/Material.h"
|
"src/engine/Material.h"
|
||||||
|
@ -174,8 +173,10 @@ SET (REACTPHYSICS3D_SOURCES
|
||||||
"src/mathematics/Vector3.h"
|
"src/mathematics/Vector3.h"
|
||||||
"src/mathematics/Ray.h"
|
"src/mathematics/Ray.h"
|
||||||
"src/mathematics/Vector3.cpp"
|
"src/mathematics/Vector3.cpp"
|
||||||
"src/memory/MemoryAllocator.h"
|
"src/memory/PoolAllocator.h"
|
||||||
"src/memory/MemoryAllocator.cpp"
|
"src/memory/PoolAllocator.cpp"
|
||||||
|
"src/memory/SingleFrameAllocator.h"
|
||||||
|
"src/memory/SingleFrameAllocator.cpp"
|
||||||
"src/memory/Stack.h"
|
"src/memory/Stack.h"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ ProxyShape* CollisionBody::addCollisionShape(CollisionShape* collisionShape,
|
||||||
const Transform& transform) {
|
const Transform& 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 (mWorld.mMemoryAllocator.allocate(
|
ProxyShape* proxyShape = new (mWorld.mPoolAllocator.allocate(
|
||||||
sizeof(ProxyShape))) ProxyShape(this, collisionShape,
|
sizeof(ProxyShape))) ProxyShape(this, collisionShape,
|
||||||
transform, decimal(1));
|
transform, decimal(1));
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current->~ProxyShape();
|
current->~ProxyShape();
|
||||||
mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape));
|
mWorld.mPoolAllocator.release(current, sizeof(ProxyShape));
|
||||||
mNbCollisionShapes--;
|
mNbCollisionShapes--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ void CollisionBody::removeCollisionShape(const ProxyShape* proxyShape) {
|
||||||
}
|
}
|
||||||
|
|
||||||
elementToRemove->~ProxyShape();
|
elementToRemove->~ProxyShape();
|
||||||
mWorld.mMemoryAllocator.release(elementToRemove, sizeof(ProxyShape));
|
mWorld.mPoolAllocator.release(elementToRemove, sizeof(ProxyShape));
|
||||||
mNbCollisionShapes--;
|
mNbCollisionShapes--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +162,7 @@ void CollisionBody::removeAllCollisionShapes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
current->~ProxyShape();
|
current->~ProxyShape();
|
||||||
mWorld.mMemoryAllocator.release(current, sizeof(ProxyShape));
|
mWorld.mPoolAllocator.release(current, sizeof(ProxyShape));
|
||||||
|
|
||||||
// Get the next element in the list
|
// Get the next element in the list
|
||||||
current = nextElement;
|
current = nextElement;
|
||||||
|
@ -181,7 +181,7 @@ void CollisionBody::resetContactManifoldsList() {
|
||||||
|
|
||||||
// Delete the current element
|
// Delete the current element
|
||||||
currentElement->~ContactManifoldListElement();
|
currentElement->~ContactManifoldListElement();
|
||||||
mWorld.mMemoryAllocator.release(currentElement, sizeof(ContactManifoldListElement));
|
mWorld.mPoolAllocator.release(currentElement, sizeof(ContactManifoldListElement));
|
||||||
|
|
||||||
currentElement = nextElement;
|
currentElement = nextElement;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "collision/shapes/AABB.h"
|
#include "collision/shapes/AABB.h"
|
||||||
#include "collision/shapes/CollisionShape.h"
|
#include "collision/shapes/CollisionShape.h"
|
||||||
#include "collision/RaycastInfo.h"
|
#include "collision/RaycastInfo.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
/// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
|
|
|
@ -46,6 +46,9 @@ RigidBody::RigidBody(const Transform& transform, CollisionWorld& world, bodyinde
|
||||||
|
|
||||||
// Compute the inverse mass
|
// Compute the inverse mass
|
||||||
mMassInverse = decimal(1.0) / mInitMass;
|
mMassInverse = decimal(1.0) / mInitMass;
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor
|
||||||
|
updateInertiaTensorInverseWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
@ -90,11 +93,15 @@ void RigidBody::setType(BodyType type) {
|
||||||
mMassInverse = decimal(0.0);
|
mMassInverse = decimal(0.0);
|
||||||
mInertiaTensorLocal.setToZero();
|
mInertiaTensorLocal.setToZero();
|
||||||
mInertiaTensorLocalInverse.setToZero();
|
mInertiaTensorLocalInverse.setToZero();
|
||||||
|
mInertiaTensorInverseWorld.setToZero();
|
||||||
|
|
||||||
}
|
}
|
||||||
else { // If it is a dynamic body
|
else { // If it is a dynamic body
|
||||||
mMassInverse = decimal(1.0) / mInitMass;
|
mMassInverse = decimal(1.0) / mInitMass;
|
||||||
mInertiaTensorLocalInverse = mInertiaTensorLocal.getInverse();
|
mInertiaTensorLocalInverse = mInertiaTensorLocal.getInverse();
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor
|
||||||
|
updateInertiaTensorInverseWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Awake the body
|
// Awake the body
|
||||||
|
@ -125,6 +132,9 @@ void RigidBody::setInertiaTensorLocal(const Matrix3x3& inertiaTensorLocal) {
|
||||||
|
|
||||||
// Compute the inverse local inertia tensor
|
// Compute the inverse local inertia tensor
|
||||||
mInertiaTensorLocalInverse = mInertiaTensorLocal.getInverse();
|
mInertiaTensorLocalInverse = mInertiaTensorLocal.getInverse();
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor
|
||||||
|
updateInertiaTensorInverseWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the local center of mass of the body (in local-space coordinates)
|
// Set the local center of mass of the body (in local-space coordinates)
|
||||||
|
@ -166,7 +176,7 @@ void RigidBody::setMass(decimal mass) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a joint from the joints list
|
// Remove a joint from the joints list
|
||||||
void RigidBody::removeJointFromJointsList(MemoryAllocator& memoryAllocator, const Joint* joint) {
|
void RigidBody::removeJointFromJointsList(PoolAllocator& memoryAllocator, const Joint* joint) {
|
||||||
|
|
||||||
assert(joint != nullptr);
|
assert(joint != nullptr);
|
||||||
assert(mJointsList != nullptr);
|
assert(mJointsList != nullptr);
|
||||||
|
@ -214,7 +224,7 @@ ProxyShape* RigidBody::addCollisionShape(CollisionShape* collisionShape,
|
||||||
decimal mass) {
|
decimal mass) {
|
||||||
|
|
||||||
// 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 (mWorld.mMemoryAllocator.allocate(
|
ProxyShape* proxyShape = new (mWorld.mPoolAllocator.allocate(
|
||||||
sizeof(ProxyShape))) ProxyShape(this, collisionShape,
|
sizeof(ProxyShape))) ProxyShape(this, collisionShape,
|
||||||
transform, mass);
|
transform, mass);
|
||||||
|
|
||||||
|
@ -314,6 +324,9 @@ void RigidBody::setTransform(const Transform& transform) {
|
||||||
// Update the linear velocity of the center of mass
|
// Update the linear velocity of the center of mass
|
||||||
mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass);
|
mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass);
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor
|
||||||
|
updateInertiaTensorInverseWorld();
|
||||||
|
|
||||||
// Update the broad-phase state of the body
|
// Update the broad-phase state of the body
|
||||||
updateBroadPhaseState();
|
updateBroadPhaseState();
|
||||||
}
|
}
|
||||||
|
@ -326,6 +339,7 @@ void RigidBody::recomputeMassInformation() {
|
||||||
mMassInverse = decimal(0.0);
|
mMassInverse = decimal(0.0);
|
||||||
mInertiaTensorLocal.setToZero();
|
mInertiaTensorLocal.setToZero();
|
||||||
mInertiaTensorLocalInverse.setToZero();
|
mInertiaTensorLocalInverse.setToZero();
|
||||||
|
mInertiaTensorInverseWorld.setToZero();
|
||||||
mCenterOfMassLocal.setToZero();
|
mCenterOfMassLocal.setToZero();
|
||||||
|
|
||||||
// If it is STATIC or KINEMATIC body
|
// If it is STATIC or KINEMATIC body
|
||||||
|
@ -386,6 +400,9 @@ void RigidBody::recomputeMassInformation() {
|
||||||
// Compute the local inverse inertia tensor
|
// Compute the local inverse inertia tensor
|
||||||
mInertiaTensorLocalInverse = mInertiaTensorLocal.getInverse();
|
mInertiaTensorLocalInverse = mInertiaTensorLocal.getInverse();
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor
|
||||||
|
updateInertiaTensorInverseWorld();
|
||||||
|
|
||||||
// Update the linear velocity of the center of mass
|
// Update the linear velocity of the center of mass
|
||||||
mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass);
|
mLinearVelocity += mAngularVelocity.cross(mCenterOfMassWorld - oldCenterOfMass);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "CollisionBody.h"
|
#include "CollisionBody.h"
|
||||||
#include "engine/Material.h"
|
#include "engine/Material.h"
|
||||||
#include "mathematics/mathematics.h"
|
#include "mathematics/mathematics.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
|
|
||||||
/// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -83,6 +83,9 @@ class RigidBody : public CollisionBody {
|
||||||
/// Inverse of the inertia tensor of the body
|
/// Inverse of the inertia tensor of the body
|
||||||
Matrix3x3 mInertiaTensorLocalInverse;
|
Matrix3x3 mInertiaTensorLocalInverse;
|
||||||
|
|
||||||
|
/// Inverse of the world inertia tensor of the body
|
||||||
|
Matrix3x3 mInertiaTensorInverseWorld;
|
||||||
|
|
||||||
/// Inverse of the mass of the body
|
/// Inverse of the mass of the body
|
||||||
decimal mMassInverse;
|
decimal mMassInverse;
|
||||||
|
|
||||||
|
@ -104,7 +107,7 @@ class RigidBody : public CollisionBody {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Remove a joint from the joints list
|
/// Remove a joint from the joints list
|
||||||
void removeJointFromJointsList(MemoryAllocator& memoryAllocator, const Joint* joint);
|
void removeJointFromJointsList(PoolAllocator& memoryAllocator, const Joint* joint);
|
||||||
|
|
||||||
/// Update the transform of the body after a change of the center of mass
|
/// Update the transform of the body after a change of the center of mass
|
||||||
void updateTransformWithCenterOfMass();
|
void updateTransformWithCenterOfMass();
|
||||||
|
@ -112,6 +115,9 @@ class RigidBody : public CollisionBody {
|
||||||
/// Update the broad-phase state for this body (because it has moved for instance)
|
/// Update the broad-phase state for this body (because it has moved for instance)
|
||||||
virtual void updateBroadPhaseState() const override;
|
virtual void updateBroadPhaseState() const override;
|
||||||
|
|
||||||
|
/// Update the world inverse inertia tensor of the body
|
||||||
|
void updateInertiaTensorInverseWorld();
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -291,12 +297,19 @@ inline Matrix3x3 RigidBody::getInertiaTensorWorld() const {
|
||||||
*/
|
*/
|
||||||
inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
|
inline Matrix3x3 RigidBody::getInertiaTensorInverseWorld() const {
|
||||||
|
|
||||||
// TODO : DO NOT RECOMPUTE THE MATRIX MULTIPLICATION EVERY TIME. WE NEED TO STORE THE
|
|
||||||
// INVERSE WORLD TENSOR IN THE CLASS AND UPLDATE IT WHEN THE ORIENTATION OF THE BODY CHANGES
|
|
||||||
|
|
||||||
// Compute and return the inertia tensor in world coordinates
|
// Compute and return the inertia tensor in world coordinates
|
||||||
return mTransform.getOrientation().getMatrix() * mInertiaTensorLocalInverse *
|
return mInertiaTensorInverseWorld;
|
||||||
mTransform.getOrientation().getMatrix().getTranspose();
|
}
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor of the body
|
||||||
|
/// The inertia tensor I_w in world coordinates is computed with the
|
||||||
|
/// local inverse inertia tensor I_b^-1 in body coordinates
|
||||||
|
/// by I_w = R * I_b^-1 * R^T
|
||||||
|
/// where R is the rotation matrix (and R^T its transpose) of the
|
||||||
|
/// current orientation quaternion of the body
|
||||||
|
inline void RigidBody::updateInertiaTensorInverseWorld() {
|
||||||
|
Matrix3x3 orientation = mTransform.getOrientation().getMatrix();
|
||||||
|
mInertiaTensorInverseWorld = orientation * mInertiaTensorLocalInverse * orientation.getTranspose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the gravity needs to be applied to this rigid body
|
// Return true if the gravity needs to be applied to this rigid body
|
||||||
|
|
|
@ -41,7 +41,7 @@ using namespace reactphysics3d;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CollisionDetection::CollisionDetection(CollisionWorld* world, MemoryAllocator& memoryAllocator)
|
CollisionDetection::CollisionDetection(CollisionWorld* world, PoolAllocator& memoryAllocator)
|
||||||
: mMemoryAllocator(memoryAllocator),
|
: mMemoryAllocator(memoryAllocator),
|
||||||
mWorld(world), mBroadPhaseAlgorithm(*this),
|
mWorld(world), mBroadPhaseAlgorithm(*this),
|
||||||
mIsCollisionShapesAdded(false) {
|
mIsCollisionShapesAdded(false) {
|
||||||
|
@ -189,7 +189,7 @@ void CollisionDetection::computeNarrowPhase() {
|
||||||
|
|
||||||
// Destroy the overlapping pair
|
// Destroy the overlapping pair
|
||||||
itToRemove->second->~OverlappingPair();
|
itToRemove->second->~OverlappingPair();
|
||||||
mWorld->mMemoryAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
||||||
mOverlappingPairs.erase(itToRemove);
|
mOverlappingPairs.erase(itToRemove);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ void CollisionDetection::computeNarrowPhaseBetweenShapes(CollisionCallback* call
|
||||||
|
|
||||||
// Destroy the overlapping pair
|
// Destroy the overlapping pair
|
||||||
itToRemove->second->~OverlappingPair();
|
itToRemove->second->~OverlappingPair();
|
||||||
mWorld->mMemoryAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
||||||
mOverlappingPairs.erase(itToRemove);
|
mOverlappingPairs.erase(itToRemove);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -370,8 +370,8 @@ void CollisionDetection::broadPhaseNotifyOverlappingPair(ProxyShape* shape1, Pro
|
||||||
shape2->getCollisionShape()->getType());
|
shape2->getCollisionShape()->getType());
|
||||||
|
|
||||||
// Create the overlapping pair and add it into the set of overlapping pairs
|
// Create the overlapping pair and add it into the set of overlapping pairs
|
||||||
OverlappingPair* newPair = new (mWorld->mMemoryAllocator.allocate(sizeof(OverlappingPair)))
|
OverlappingPair* newPair = new (mWorld->mPoolAllocator.allocate(sizeof(OverlappingPair)))
|
||||||
OverlappingPair(shape1, shape2, nbMaxManifolds, mWorld->mMemoryAllocator);
|
OverlappingPair(shape1, shape2, nbMaxManifolds, mWorld->mPoolAllocator);
|
||||||
assert(newPair != nullptr);
|
assert(newPair != nullptr);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -400,7 +400,7 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) {
|
||||||
|
|
||||||
// Destroy the overlapping pair
|
// Destroy the overlapping pair
|
||||||
itToRemove->second->~OverlappingPair();
|
itToRemove->second->~OverlappingPair();
|
||||||
mWorld->mMemoryAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
mWorld->mPoolAllocator.release(itToRemove->second, sizeof(OverlappingPair));
|
||||||
mOverlappingPairs.erase(itToRemove);
|
mOverlappingPairs.erase(itToRemove);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -434,7 +434,7 @@ void CollisionDetection::createContact(OverlappingPair* overlappingPair,
|
||||||
const ContactPointInfo& contactInfo) {
|
const ContactPointInfo& contactInfo) {
|
||||||
|
|
||||||
// Create a new contact
|
// Create a new contact
|
||||||
ContactPoint* contact = new (mWorld->mMemoryAllocator.allocate(sizeof(ContactPoint)))
|
ContactPoint* contact = new (mWorld->mPoolAllocator.allocate(sizeof(ContactPoint)))
|
||||||
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
|
||||||
|
@ -477,7 +477,7 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
|
||||||
|
|
||||||
// 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 = mWorld->mMemoryAllocator.allocate(sizeof(ContactManifoldListElement));
|
void* allocatedMemory1 = mWorld->mPoolAllocator.allocate(sizeof(ContactManifoldListElement));
|
||||||
ContactManifoldListElement* listElement1 = new (allocatedMemory1)
|
ContactManifoldListElement* listElement1 = new (allocatedMemory1)
|
||||||
ContactManifoldListElement(contactManifold,
|
ContactManifoldListElement(contactManifold,
|
||||||
body1->mContactManifoldsList);
|
body1->mContactManifoldsList);
|
||||||
|
@ -485,7 +485,7 @@ void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) {
|
||||||
|
|
||||||
// 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 = mWorld->mMemoryAllocator.allocate(sizeof(ContactManifoldListElement));
|
void* allocatedMemory2 = mWorld->mPoolAllocator.allocate(sizeof(ContactManifoldListElement));
|
||||||
ContactManifoldListElement* listElement2 = new (allocatedMemory2)
|
ContactManifoldListElement* listElement2 = new (allocatedMemory2)
|
||||||
ContactManifoldListElement(contactManifold,
|
ContactManifoldListElement(contactManifold,
|
||||||
body2->mContactManifoldsList);
|
body2->mContactManifoldsList);
|
||||||
|
@ -520,8 +520,8 @@ EventListener* CollisionDetection::getWorldEventListener() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a reference to the world memory allocator
|
/// Return a reference to the world memory allocator
|
||||||
MemoryAllocator& CollisionDetection::getWorldMemoryAllocator() {
|
PoolAllocator& CollisionDetection::getWorldMemoryAllocator() {
|
||||||
return mWorld->mMemoryAllocator;
|
return mWorld->mPoolAllocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include "engine/OverlappingPair.h"
|
#include "engine/OverlappingPair.h"
|
||||||
#include "engine/EventListener.h"
|
#include "engine/EventListener.h"
|
||||||
#include "narrowphase/DefaultCollisionDispatch.h"
|
#include "narrowphase/DefaultCollisionDispatch.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -93,7 +93,7 @@ class CollisionDetection : public NarrowPhaseCallback {
|
||||||
NarrowPhaseAlgorithm* mCollisionMatrix[NB_COLLISION_SHAPE_TYPES][NB_COLLISION_SHAPE_TYPES];
|
NarrowPhaseAlgorithm* mCollisionMatrix[NB_COLLISION_SHAPE_TYPES][NB_COLLISION_SHAPE_TYPES];
|
||||||
|
|
||||||
/// Reference to the memory allocator
|
/// Reference to the memory allocator
|
||||||
MemoryAllocator& mMemoryAllocator;
|
PoolAllocator& mMemoryAllocator;
|
||||||
|
|
||||||
/// Pointer to the physics world
|
/// Pointer to the physics world
|
||||||
CollisionWorld* mWorld;
|
CollisionWorld* mWorld;
|
||||||
|
@ -143,7 +143,7 @@ class CollisionDetection : public NarrowPhaseCallback {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CollisionDetection(CollisionWorld* world, MemoryAllocator& memoryAllocator);
|
CollisionDetection(CollisionWorld* world, PoolAllocator& memoryAllocator);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~CollisionDetection() = default;
|
~CollisionDetection() = default;
|
||||||
|
@ -220,7 +220,7 @@ class CollisionDetection : public NarrowPhaseCallback {
|
||||||
EventListener* getWorldEventListener();
|
EventListener* getWorldEventListener();
|
||||||
|
|
||||||
/// Return a reference to the world memory allocator
|
/// Return a reference to the world memory allocator
|
||||||
MemoryAllocator& getWorldMemoryAllocator();
|
PoolAllocator& 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;
|
||||||
|
|
|
@ -31,7 +31,7 @@ using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ContactManifold::ContactManifold(ProxyShape* shape1, ProxyShape* shape2,
|
ContactManifold::ContactManifold(ProxyShape* shape1, ProxyShape* shape2,
|
||||||
MemoryAllocator& memoryAllocator, short normalDirectionId)
|
PoolAllocator& memoryAllocator, short normalDirectionId)
|
||||||
: mShape1(shape1), mShape2(shape2), mNormalDirectionId(normalDirectionId),
|
: mShape1(shape1), mShape2(shape2), mNormalDirectionId(normalDirectionId),
|
||||||
mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
|
mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
|
||||||
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),
|
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "body/CollisionBody.h"
|
#include "body/CollisionBody.h"
|
||||||
#include "collision/ProxyShape.h"
|
#include "collision/ProxyShape.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
|
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
@ -102,7 +102,7 @@ class ContactManifold {
|
||||||
short int mNormalDirectionId;
|
short int mNormalDirectionId;
|
||||||
|
|
||||||
/// Number of contacts in the cache
|
/// Number of contacts in the cache
|
||||||
uint mNbContactPoints;
|
int8 mNbContactPoints;
|
||||||
|
|
||||||
/// First friction vector of the contact manifold
|
/// First friction vector of the contact manifold
|
||||||
Vector3 mFrictionVector1;
|
Vector3 mFrictionVector1;
|
||||||
|
@ -126,7 +126,7 @@ class ContactManifold {
|
||||||
bool mIsAlreadyInIsland;
|
bool mIsAlreadyInIsland;
|
||||||
|
|
||||||
/// Reference to the memory allocator
|
/// Reference to the memory allocator
|
||||||
MemoryAllocator& mMemoryAllocator;
|
PoolAllocator& mMemoryAllocator;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ class ContactManifold {
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ContactManifold(ProxyShape* shape1, ProxyShape* shape2,
|
ContactManifold(ProxyShape* shape1, ProxyShape* shape2,
|
||||||
MemoryAllocator& memoryAllocator, short int normalDirectionId);
|
PoolAllocator& memoryAllocator, short int normalDirectionId);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~ContactManifold();
|
~ContactManifold();
|
||||||
|
@ -187,7 +187,7 @@ class ContactManifold {
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
/// Return the number of contact points in the manifold
|
/// Return the number of contact points in the manifold
|
||||||
uint getNbContactPoints() const;
|
int8 getNbContactPoints() const;
|
||||||
|
|
||||||
/// Return the first friction vector at the center of the contact manifold
|
/// Return the first friction vector at the center of the contact manifold
|
||||||
const Vector3& getFrictionVector1() const;
|
const Vector3& getFrictionVector1() const;
|
||||||
|
@ -264,7 +264,7 @@ inline short int ContactManifold::getNormalDirectionId() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of contact points in the manifold
|
// Return the number of contact points in the manifold
|
||||||
inline uint ContactManifold::getNbContactPoints() const {
|
inline int8 ContactManifold::getNbContactPoints() const {
|
||||||
return mNbContactPoints;
|
return mNbContactPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
|
ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
|
||||||
MemoryAllocator& memoryAllocator, int nbMaxManifolds)
|
PoolAllocator& memoryAllocator, int nbMaxManifolds)
|
||||||
: mNbMaxManifolds(nbMaxManifolds), mNbManifolds(0), mShape1(shape1),
|
: mNbMaxManifolds(nbMaxManifolds), mNbManifolds(0), mShape1(shape1),
|
||||||
mShape2(shape2), mMemoryAllocator(memoryAllocator) {
|
mShape2(shape2), mMemoryAllocator(memoryAllocator) {
|
||||||
assert(nbMaxManifolds >= 1);
|
assert(nbMaxManifolds >= 1);
|
||||||
|
|
|
@ -61,7 +61,7 @@ class ContactManifoldSet {
|
||||||
ProxyShape* mShape2;
|
ProxyShape* mShape2;
|
||||||
|
|
||||||
/// Reference to the memory allocator
|
/// Reference to the memory allocator
|
||||||
MemoryAllocator& mMemoryAllocator;
|
PoolAllocator& mMemoryAllocator;
|
||||||
|
|
||||||
/// Contact manifolds of the set
|
/// Contact manifolds of the set
|
||||||
ContactManifold* mManifolds[MAX_MANIFOLDS_IN_CONTACT_MANIFOLD_SET];
|
ContactManifold* mManifolds[MAX_MANIFOLDS_IN_CONTACT_MANIFOLD_SET];
|
||||||
|
@ -88,7 +88,7 @@ class ContactManifoldSet {
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
|
ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2,
|
||||||
MemoryAllocator& memoryAllocator, int nbMaxManifolds);
|
PoolAllocator& memoryAllocator, int nbMaxManifolds);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~ContactManifoldSet();
|
~ContactManifoldSet();
|
||||||
|
|
|
@ -51,7 +51,7 @@ class CollisionDispatch {
|
||||||
|
|
||||||
/// Initialize the collision dispatch configuration
|
/// Initialize the collision dispatch configuration
|
||||||
virtual void init(CollisionDetection* collisionDetection,
|
virtual void init(CollisionDetection* collisionDetection,
|
||||||
MemoryAllocator* memoryAllocator) {
|
PoolAllocator* memoryAllocator) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ using namespace reactphysics3d;
|
||||||
|
|
||||||
/// Initialize the collision dispatch configuration
|
/// Initialize the collision dispatch configuration
|
||||||
void DefaultCollisionDispatch::init(CollisionDetection* collisionDetection,
|
void DefaultCollisionDispatch::init(CollisionDetection* collisionDetection,
|
||||||
MemoryAllocator* memoryAllocator) {
|
PoolAllocator* memoryAllocator) {
|
||||||
|
|
||||||
// Initialize the collision algorithms
|
// Initialize the collision algorithms
|
||||||
mSphereVsSphereAlgorithm.init(collisionDetection, memoryAllocator);
|
mSphereVsSphereAlgorithm.init(collisionDetection, memoryAllocator);
|
||||||
|
|
|
@ -63,7 +63,7 @@ class DefaultCollisionDispatch : public CollisionDispatch {
|
||||||
|
|
||||||
/// Initialize the collision dispatch configuration
|
/// Initialize the collision dispatch configuration
|
||||||
virtual void init(CollisionDetection* collisionDetection,
|
virtual void init(CollisionDetection* collisionDetection,
|
||||||
MemoryAllocator* memoryAllocator) override;
|
PoolAllocator* memoryAllocator) override;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "collision/narrowphase/NarrowPhaseAlgorithm.h"
|
#include "collision/narrowphase/NarrowPhaseAlgorithm.h"
|
||||||
#include "mathematics/mathematics.h"
|
#include "mathematics/mathematics.h"
|
||||||
#include "TriangleEPA.h"
|
#include "TriangleEPA.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
|
@ -88,7 +88,7 @@ class EPAAlgorithm {
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
/// Reference to the memory allocator
|
/// Reference to the memory allocator
|
||||||
MemoryAllocator* mMemoryAllocator;
|
PoolAllocator* mMemoryAllocator;
|
||||||
|
|
||||||
/// Triangle comparison operator
|
/// Triangle comparison operator
|
||||||
TriangleComparison mTriangleComparison;
|
TriangleComparison mTriangleComparison;
|
||||||
|
@ -120,7 +120,7 @@ class EPAAlgorithm {
|
||||||
EPAAlgorithm& operator=(const EPAAlgorithm& algorithm) = delete;
|
EPAAlgorithm& operator=(const EPAAlgorithm& algorithm) = delete;
|
||||||
|
|
||||||
/// Initalize the algorithm
|
/// Initalize the algorithm
|
||||||
void init(MemoryAllocator* memoryAllocator);
|
void init(PoolAllocator* memoryAllocator);
|
||||||
|
|
||||||
/// Compute the penetration depth with EPA algorithm.
|
/// Compute the penetration depth with EPA algorithm.
|
||||||
bool computePenetrationDepthAndContactPoints(const VoronoiSimplex& simplex,
|
bool computePenetrationDepthAndContactPoints(const VoronoiSimplex& simplex,
|
||||||
|
@ -151,7 +151,7 @@ inline void EPAAlgorithm::addFaceCandidate(TriangleEPA* triangle, TriangleEPA**
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initalize the algorithm
|
// Initalize the algorithm
|
||||||
inline void EPAAlgorithm::init(MemoryAllocator* memoryAllocator) {
|
inline void EPAAlgorithm::init(PoolAllocator* memoryAllocator) {
|
||||||
mMemoryAllocator = memoryAllocator;
|
mMemoryAllocator = memoryAllocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
|
||||||
|
|
||||||
/// Initalize the algorithm
|
/// Initalize the algorithm
|
||||||
virtual void init(CollisionDetection* collisionDetection,
|
virtual void init(CollisionDetection* collisionDetection,
|
||||||
MemoryAllocator* memoryAllocator) override;
|
PoolAllocator* memoryAllocator) override;
|
||||||
|
|
||||||
/// Compute a contact info if the two bounding volumes collide.
|
/// Compute a contact info if the two bounding volumes collide.
|
||||||
virtual void testCollision(const CollisionShapeInfo& shape1Info,
|
virtual void testCollision(const CollisionShapeInfo& shape1Info,
|
||||||
|
@ -110,7 +110,7 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm {
|
||||||
|
|
||||||
// Initalize the algorithm
|
// Initalize the algorithm
|
||||||
inline void GJKAlgorithm::init(CollisionDetection* collisionDetection,
|
inline void GJKAlgorithm::init(CollisionDetection* collisionDetection,
|
||||||
MemoryAllocator* memoryAllocator) {
|
PoolAllocator* memoryAllocator) {
|
||||||
NarrowPhaseAlgorithm::init(collisionDetection, memoryAllocator);
|
NarrowPhaseAlgorithm::init(collisionDetection, memoryAllocator);
|
||||||
mAlgoEPA.init(memoryAllocator);
|
mAlgoEPA.init(memoryAllocator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -563,7 +563,6 @@ bool VoronoiSimplex::computeClosestPointOnTetrahedron(const Vector3& a, const Ve
|
||||||
if (squareDist < closestSquareDistance) {
|
if (squareDist < closestSquareDistance) {
|
||||||
|
|
||||||
// Use it as the current closest point
|
// Use it as the current closest point
|
||||||
closestSquareDistance = squareDist;
|
|
||||||
baryCoordsAB.setAllValues(0.0, triangleBaryCoords[0]);
|
baryCoordsAB.setAllValues(0.0, triangleBaryCoords[0]);
|
||||||
baryCoordsCD.setAllValues(triangleBaryCoords[2], triangleBaryCoords[1]);
|
baryCoordsCD.setAllValues(triangleBaryCoords[2], triangleBaryCoords[1]);
|
||||||
bitsUsedPoints = mapTriangleUsedVerticesToTetrahedron(tempUsedVertices, 1, 3, 2);
|
bitsUsedPoints = mapTriangleUsedVerticesToTetrahedron(tempUsedVertices, 1, 3, 2);
|
||||||
|
|
|
@ -36,7 +36,7 @@ NarrowPhaseAlgorithm::NarrowPhaseAlgorithm()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initalize the algorithm
|
// Initalize the algorithm
|
||||||
void NarrowPhaseAlgorithm::init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator) {
|
void NarrowPhaseAlgorithm::init(CollisionDetection* collisionDetection, PoolAllocator* memoryAllocator) {
|
||||||
mCollisionDetection = collisionDetection;
|
mCollisionDetection = collisionDetection;
|
||||||
mMemoryAllocator = memoryAllocator;
|
mMemoryAllocator = memoryAllocator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "body/Body.h"
|
#include "body/Body.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
#include "engine/OverlappingPair.h"
|
#include "engine/OverlappingPair.h"
|
||||||
#include "collision/CollisionShapeInfo.h"
|
#include "collision/CollisionShapeInfo.h"
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class NarrowPhaseAlgorithm {
|
||||||
CollisionDetection* mCollisionDetection;
|
CollisionDetection* mCollisionDetection;
|
||||||
|
|
||||||
/// Pointer to the memory allocator
|
/// Pointer to the memory allocator
|
||||||
MemoryAllocator* mMemoryAllocator;
|
PoolAllocator* mMemoryAllocator;
|
||||||
|
|
||||||
/// Overlapping pair of the bodies currently tested for collision
|
/// Overlapping pair of the bodies currently tested for collision
|
||||||
OverlappingPair* mCurrentOverlappingPair;
|
OverlappingPair* mCurrentOverlappingPair;
|
||||||
|
@ -93,7 +93,7 @@ class NarrowPhaseAlgorithm {
|
||||||
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete;
|
NarrowPhaseAlgorithm& operator=(const NarrowPhaseAlgorithm& algorithm) = delete;
|
||||||
|
|
||||||
/// Initalize the algorithm
|
/// Initalize the algorithm
|
||||||
virtual void init(CollisionDetection* collisionDetection, MemoryAllocator* memoryAllocator);
|
virtual void init(CollisionDetection* collisionDetection, PoolAllocator* memoryAllocator);
|
||||||
|
|
||||||
/// Set the current overlapping pair of bodies
|
/// Set the current overlapping pair of bodies
|
||||||
void setCurrentOverlappingPair(OverlappingPair* overlappingPair);
|
void setCurrentOverlappingPair(OverlappingPair* overlappingPair);
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "mathematics/Ray.h"
|
#include "mathematics/Ray.h"
|
||||||
#include "AABB.h"
|
#include "AABB.h"
|
||||||
#include "collision/RaycastInfo.h"
|
#include "collision/RaycastInfo.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
|
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <cstdint>
|
||||||
#include "decimal.h"
|
#include "decimal.h"
|
||||||
|
|
||||||
// Windows platform
|
// Windows platform
|
||||||
|
@ -51,10 +52,9 @@ using luint = long unsigned int;
|
||||||
using bodyindex = luint;
|
using bodyindex = luint;
|
||||||
using bodyindexpair = std::pair<bodyindex, bodyindex>;
|
using bodyindexpair = std::pair<bodyindex, bodyindex>;
|
||||||
|
|
||||||
using int16 = signed short;
|
using int8 = int8_t;
|
||||||
using int32 = signed int;
|
using int16 = int16_t;
|
||||||
using uint16 = unsigned short;
|
using int32 = int32_t;
|
||||||
using uint32 = unsigned int;
|
|
||||||
|
|
||||||
// ------------------- Enumerations ------------------- //
|
// ------------------- Enumerations ------------------- //
|
||||||
|
|
||||||
|
@ -144,6 +144,9 @@ constexpr int NB_MAX_CONTACT_MANIFOLDS_CONVEX_SHAPE = 1;
|
||||||
/// least one concave collision shape.
|
/// least one concave collision shape.
|
||||||
constexpr int NB_MAX_CONTACT_MANIFOLDS_CONCAVE_SHAPE = 3;
|
constexpr int NB_MAX_CONTACT_MANIFOLDS_CONCAVE_SHAPE = 3;
|
||||||
|
|
||||||
|
/// Size (in bytes) of the single frame allocator
|
||||||
|
constexpr size_t SIZE_SINGLE_FRAME_ALLOCATOR_BYTES = 15728640; // 15 Mb
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,9 +45,6 @@ ContactPoint::ContactPoint(const ContactPointInfo& contactInfo)
|
||||||
contactInfo.localPoint2),
|
contactInfo.localPoint2),
|
||||||
mIsRestingContact(false) {
|
mIsRestingContact(false) {
|
||||||
|
|
||||||
mFrictionVectors[0] = Vector3(0, 0, 0);
|
assert(mPenetrationDepth > decimal(0.0));
|
||||||
mFrictionVectors[1] = Vector3(0, 0, 0);
|
|
||||||
|
|
||||||
assert(mPenetrationDepth > 0.0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,21 +128,9 @@ class ContactPoint {
|
||||||
/// True if the contact is a resting contact (exists for more than one time step)
|
/// True if the contact is a resting contact (exists for more than one time step)
|
||||||
bool mIsRestingContact;
|
bool mIsRestingContact;
|
||||||
|
|
||||||
/// Two orthogonal vectors that span the tangential friction plane
|
|
||||||
Vector3 mFrictionVectors[2];
|
|
||||||
|
|
||||||
/// Cached penetration impulse
|
/// Cached penetration impulse
|
||||||
decimal mPenetrationImpulse;
|
decimal mPenetrationImpulse;
|
||||||
|
|
||||||
/// Cached first friction impulse
|
|
||||||
decimal mFrictionImpulse1;
|
|
||||||
|
|
||||||
/// Cached second friction impulse
|
|
||||||
decimal mFrictionImpulse2;
|
|
||||||
|
|
||||||
/// Cached rolling resistance impulse
|
|
||||||
Vector3 mRollingResistanceImpulse;
|
|
||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
@ -186,27 +174,9 @@ class ContactPoint {
|
||||||
/// Return the cached penetration impulse
|
/// Return the cached penetration impulse
|
||||||
decimal getPenetrationImpulse() const;
|
decimal getPenetrationImpulse() const;
|
||||||
|
|
||||||
/// Return the cached first friction impulse
|
|
||||||
decimal getFrictionImpulse1() const;
|
|
||||||
|
|
||||||
/// Return the cached second friction impulse
|
|
||||||
decimal getFrictionImpulse2() const;
|
|
||||||
|
|
||||||
/// Return the cached rolling resistance impulse
|
|
||||||
Vector3 getRollingResistanceImpulse() const;
|
|
||||||
|
|
||||||
/// Set the cached penetration impulse
|
/// Set the cached penetration impulse
|
||||||
void setPenetrationImpulse(decimal impulse);
|
void setPenetrationImpulse(decimal impulse);
|
||||||
|
|
||||||
/// Set the first cached friction impulse
|
|
||||||
void setFrictionImpulse1(decimal impulse);
|
|
||||||
|
|
||||||
/// Set the second cached friction impulse
|
|
||||||
void setFrictionImpulse2(decimal impulse);
|
|
||||||
|
|
||||||
/// Set the cached rolling resistance impulse
|
|
||||||
void setRollingResistanceImpulse(const Vector3& impulse);
|
|
||||||
|
|
||||||
/// Set the contact world point on body 1
|
/// Set the contact world point on body 1
|
||||||
void setWorldPointOnBody1(const Vector3& worldPoint);
|
void setWorldPointOnBody1(const Vector3& worldPoint);
|
||||||
|
|
||||||
|
@ -219,18 +189,6 @@ class ContactPoint {
|
||||||
/// Set the mIsRestingContact variable
|
/// Set the mIsRestingContact variable
|
||||||
void setIsRestingContact(bool isRestingContact);
|
void setIsRestingContact(bool isRestingContact);
|
||||||
|
|
||||||
/// Get the first friction vector
|
|
||||||
Vector3 getFrictionVector1() const;
|
|
||||||
|
|
||||||
/// Set the first friction vector
|
|
||||||
void setFrictionVector1(const Vector3& frictionVector1);
|
|
||||||
|
|
||||||
/// Get the second friction vector
|
|
||||||
Vector3 getFrictionVector2() const;
|
|
||||||
|
|
||||||
/// Set the second friction vector
|
|
||||||
void setFrictionVector2(const Vector3& frictionVector2);
|
|
||||||
|
|
||||||
/// Return the penetration depth
|
/// Return the penetration depth
|
||||||
decimal getPenetrationDepth() const;
|
decimal getPenetrationDepth() const;
|
||||||
|
|
||||||
|
@ -283,41 +241,11 @@ inline decimal ContactPoint::getPenetrationImpulse() const {
|
||||||
return mPenetrationImpulse;
|
return mPenetrationImpulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the cached first friction impulse
|
|
||||||
inline decimal ContactPoint::getFrictionImpulse1() const {
|
|
||||||
return mFrictionImpulse1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the cached second friction impulse
|
|
||||||
inline decimal ContactPoint::getFrictionImpulse2() const {
|
|
||||||
return mFrictionImpulse2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the cached rolling resistance impulse
|
|
||||||
inline Vector3 ContactPoint::getRollingResistanceImpulse() const {
|
|
||||||
return mRollingResistanceImpulse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the cached penetration impulse
|
// Set the cached penetration impulse
|
||||||
inline void ContactPoint::setPenetrationImpulse(decimal impulse) {
|
inline void ContactPoint::setPenetrationImpulse(decimal impulse) {
|
||||||
mPenetrationImpulse = impulse;
|
mPenetrationImpulse = impulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the first cached friction impulse
|
|
||||||
inline void ContactPoint::setFrictionImpulse1(decimal impulse) {
|
|
||||||
mFrictionImpulse1 = impulse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the second cached friction impulse
|
|
||||||
inline void ContactPoint::setFrictionImpulse2(decimal impulse) {
|
|
||||||
mFrictionImpulse2 = impulse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the cached rolling resistance impulse
|
|
||||||
inline void ContactPoint::setRollingResistanceImpulse(const Vector3& impulse) {
|
|
||||||
mRollingResistanceImpulse = impulse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the contact world point on body 1
|
// Set the contact world point on body 1
|
||||||
inline void ContactPoint::setWorldPointOnBody1(const Vector3& worldPoint) {
|
inline void ContactPoint::setWorldPointOnBody1(const Vector3& worldPoint) {
|
||||||
mWorldPointOnBody1 = worldPoint;
|
mWorldPointOnBody1 = worldPoint;
|
||||||
|
@ -338,26 +266,6 @@ inline void ContactPoint::setIsRestingContact(bool isRestingContact) {
|
||||||
mIsRestingContact = isRestingContact;
|
mIsRestingContact = isRestingContact;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the first friction vector
|
|
||||||
inline Vector3 ContactPoint::getFrictionVector1() const {
|
|
||||||
return mFrictionVectors[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the first friction vector
|
|
||||||
inline void ContactPoint::setFrictionVector1(const Vector3& frictionVector1) {
|
|
||||||
mFrictionVectors[0] = frictionVector1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the second friction vector
|
|
||||||
inline Vector3 ContactPoint::getFrictionVector2() const {
|
|
||||||
return mFrictionVectors[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the second friction vector
|
|
||||||
inline void ContactPoint::setFrictionVector2(const Vector3& frictionVector2) {
|
|
||||||
mFrictionVectors[1] = frictionVector2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the penetration depth of the contact
|
// Return the penetration depth of the contact
|
||||||
inline decimal ContactPoint::getPenetrationDepth() const {
|
inline decimal ContactPoint::getPenetrationDepth() const {
|
||||||
return mPenetrationDepth;
|
return mPenetrationDepth;
|
||||||
|
|
|
@ -33,7 +33,7 @@ using namespace std;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
CollisionWorld::CollisionWorld()
|
CollisionWorld::CollisionWorld()
|
||||||
: mCollisionDetection(this, mMemoryAllocator), mCurrentBodyID(0),
|
: mCollisionDetection(this, mPoolAllocator), mCurrentBodyID(0),
|
||||||
mEventListener(nullptr) {
|
mEventListener(nullptr) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ CollisionBody* CollisionWorld::createCollisionBody(const Transform& transform) {
|
||||||
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
||||||
|
|
||||||
// Create the collision body
|
// Create the collision body
|
||||||
CollisionBody* collisionBody = new (mMemoryAllocator.allocate(sizeof(CollisionBody)))
|
CollisionBody* collisionBody = new (mPoolAllocator.allocate(sizeof(CollisionBody)))
|
||||||
CollisionBody(transform, *this, bodyID);
|
CollisionBody(transform, *this, bodyID);
|
||||||
|
|
||||||
assert(collisionBody != nullptr);
|
assert(collisionBody != nullptr);
|
||||||
|
@ -97,7 +97,7 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) {
|
||||||
mBodies.erase(collisionBody);
|
mBodies.erase(collisionBody);
|
||||||
|
|
||||||
// Free the object from the memory allocator
|
// Free the object from the memory allocator
|
||||||
mMemoryAllocator.release(collisionBody, sizeof(CollisionBody));
|
mPoolAllocator.release(collisionBody, sizeof(CollisionBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the next available body ID
|
// Return the next available body ID
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include "collision/CollisionDetection.h"
|
#include "collision/CollisionDetection.h"
|
||||||
#include "constraint/Joint.h"
|
#include "constraint/Joint.h"
|
||||||
#include "constraint/ContactPoint.h"
|
#include "constraint/ContactPoint.h"
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/PoolAllocator.h"
|
||||||
#include "EventListener.h"
|
#include "EventListener.h"
|
||||||
|
|
||||||
/// Namespace reactphysics3d
|
/// Namespace reactphysics3d
|
||||||
|
@ -72,8 +72,8 @@ class CollisionWorld {
|
||||||
/// List of free ID for rigid bodies
|
/// List of free ID for rigid bodies
|
||||||
std::vector<luint> mFreeBodiesIDs;
|
std::vector<luint> mFreeBodiesIDs;
|
||||||
|
|
||||||
/// Memory allocator
|
/// Pool Memory allocator
|
||||||
MemoryAllocator mMemoryAllocator;
|
PoolAllocator mPoolAllocator;
|
||||||
|
|
||||||
/// Pointer to an event listener object
|
/// Pointer to an event listener object
|
||||||
EventListener* mEventListener;
|
EventListener* mEventListener;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,6 @@
|
||||||
#include "constraint/Joint.h"
|
#include "constraint/Joint.h"
|
||||||
#include "collision/ContactManifold.h"
|
#include "collision/ContactManifold.h"
|
||||||
#include "Island.h"
|
#include "Island.h"
|
||||||
#include "Impulse.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
@ -120,80 +119,41 @@ class ContactSolver {
|
||||||
*/
|
*/
|
||||||
struct ContactPointSolver {
|
struct ContactPointSolver {
|
||||||
|
|
||||||
/// Accumulated normal impulse
|
/// Pointer to the external contact
|
||||||
decimal penetrationImpulse;
|
ContactPoint* externalContact;
|
||||||
|
|
||||||
/// Accumulated impulse in the 1st friction direction
|
|
||||||
decimal friction1Impulse;
|
|
||||||
|
|
||||||
/// Accumulated impulse in the 2nd friction direction
|
|
||||||
decimal friction2Impulse;
|
|
||||||
|
|
||||||
/// Accumulated split impulse for penetration correction
|
|
||||||
decimal penetrationSplitImpulse;
|
|
||||||
|
|
||||||
/// Accumulated rolling resistance impulse
|
|
||||||
Vector3 rollingResistanceImpulse;
|
|
||||||
|
|
||||||
/// Normal vector of the contact
|
/// Normal vector of the contact
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
|
|
||||||
/// First friction vector in the tangent plane
|
|
||||||
Vector3 frictionVector1;
|
|
||||||
|
|
||||||
/// Second friction vector in the tangent plane
|
|
||||||
Vector3 frictionVector2;
|
|
||||||
|
|
||||||
/// Old first friction vector in the tangent plane
|
|
||||||
Vector3 oldFrictionVector1;
|
|
||||||
|
|
||||||
/// Old second friction vector in the tangent plane
|
|
||||||
Vector3 oldFrictionVector2;
|
|
||||||
|
|
||||||
/// Vector from the body 1 center to the contact point
|
/// Vector from the body 1 center to the contact point
|
||||||
Vector3 r1;
|
Vector3 r1;
|
||||||
|
|
||||||
/// Vector from the body 2 center to the contact point
|
/// Vector from the body 2 center to the contact point
|
||||||
Vector3 r2;
|
Vector3 r2;
|
||||||
|
|
||||||
/// Cross product of r1 with 1st friction vector
|
|
||||||
Vector3 r1CrossT1;
|
|
||||||
|
|
||||||
/// Cross product of r1 with 2nd friction vector
|
|
||||||
Vector3 r1CrossT2;
|
|
||||||
|
|
||||||
/// Cross product of r2 with 1st friction vector
|
|
||||||
Vector3 r2CrossT1;
|
|
||||||
|
|
||||||
/// Cross product of r2 with 2nd friction vector
|
|
||||||
Vector3 r2CrossT2;
|
|
||||||
|
|
||||||
/// Cross product of r1 with the contact normal
|
|
||||||
Vector3 r1CrossN;
|
|
||||||
|
|
||||||
/// Cross product of r2 with the contact normal
|
|
||||||
Vector3 r2CrossN;
|
|
||||||
|
|
||||||
/// Penetration depth
|
/// Penetration depth
|
||||||
decimal penetrationDepth;
|
decimal penetrationDepth;
|
||||||
|
|
||||||
/// Velocity restitution bias
|
/// Velocity restitution bias
|
||||||
decimal restitutionBias;
|
decimal restitutionBias;
|
||||||
|
|
||||||
|
/// Accumulated normal impulse
|
||||||
|
decimal penetrationImpulse;
|
||||||
|
|
||||||
|
/// Accumulated split impulse for penetration correction
|
||||||
|
decimal penetrationSplitImpulse;
|
||||||
|
|
||||||
/// Inverse of the matrix K for the penenetration
|
/// Inverse of the matrix K for the penenetration
|
||||||
decimal inversePenetrationMass;
|
decimal inversePenetrationMass;
|
||||||
|
|
||||||
/// Inverse of the matrix K for the 1st friction
|
/// Cross product of r1 with the contact normal
|
||||||
decimal inverseFriction1Mass;
|
Vector3 i1TimesR1CrossN;
|
||||||
|
|
||||||
/// Inverse of the matrix K for the 2nd friction
|
/// Cross product of r2 with the contact normal
|
||||||
decimal inverseFriction2Mass;
|
Vector3 i2TimesR2CrossN;
|
||||||
|
|
||||||
/// True if the contact was existing last time step
|
/// True if the contact was existing last time step
|
||||||
bool isRestingContact;
|
bool isRestingContact;
|
||||||
|
|
||||||
/// Pointer to the external contact
|
|
||||||
ContactPoint* externalContact;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Structure ContactManifoldSolver
|
// Structure ContactManifoldSolver
|
||||||
|
@ -203,11 +163,14 @@ class ContactSolver {
|
||||||
*/
|
*/
|
||||||
struct ContactManifoldSolver {
|
struct ContactManifoldSolver {
|
||||||
|
|
||||||
|
/// Pointer to the external contact manifold
|
||||||
|
ContactManifold* externalContactManifold;
|
||||||
|
|
||||||
/// Index of body 1 in the constraint solver
|
/// Index of body 1 in the constraint solver
|
||||||
uint indexBody1;
|
int32 indexBody1;
|
||||||
|
|
||||||
/// Index of body 2 in the constraint solver
|
/// Index of body 2 in the constraint solver
|
||||||
uint indexBody2;
|
int32 indexBody2;
|
||||||
|
|
||||||
/// Inverse of the mass of body 1
|
/// Inverse of the mass of body 1
|
||||||
decimal massInverseBody1;
|
decimal massInverseBody1;
|
||||||
|
@ -221,30 +184,12 @@ class ContactSolver {
|
||||||
/// Inverse inertia tensor of body 2
|
/// Inverse inertia tensor of body 2
|
||||||
Matrix3x3 inverseInertiaTensorBody2;
|
Matrix3x3 inverseInertiaTensorBody2;
|
||||||
|
|
||||||
/// Contact point constraints
|
|
||||||
ContactPointSolver contacts[MAX_CONTACT_POINTS_IN_MANIFOLD];
|
|
||||||
|
|
||||||
/// Number of contact points
|
|
||||||
uint nbContacts;
|
|
||||||
|
|
||||||
/// True if the body 1 is of type dynamic
|
|
||||||
bool isBody1DynamicType;
|
|
||||||
|
|
||||||
/// True if the body 2 is of type dynamic
|
|
||||||
bool isBody2DynamicType;
|
|
||||||
|
|
||||||
/// Mix of the restitution factor for two bodies
|
|
||||||
decimal restitutionFactor;
|
|
||||||
|
|
||||||
/// Mix friction coefficient for the two bodies
|
/// Mix friction coefficient for the two bodies
|
||||||
decimal frictionCoefficient;
|
decimal frictionCoefficient;
|
||||||
|
|
||||||
/// Rolling resistance factor between the two bodies
|
/// Rolling resistance factor between the two bodies
|
||||||
decimal rollingResistanceFactor;
|
decimal rollingResistanceFactor;
|
||||||
|
|
||||||
/// Pointer to the external contact manifold
|
|
||||||
ContactManifold* externalContactManifold;
|
|
||||||
|
|
||||||
// - Variables used when friction constraints are apply at the center of the manifold-//
|
// - Variables used when friction constraints are apply at the center of the manifold-//
|
||||||
|
|
||||||
/// Average normal vector of the contact manifold
|
/// Average normal vector of the contact manifold
|
||||||
|
@ -309,6 +254,9 @@ class ContactSolver {
|
||||||
|
|
||||||
/// Rolling resistance impulse
|
/// Rolling resistance impulse
|
||||||
Vector3 rollingResistanceImpulse;
|
Vector3 rollingResistanceImpulse;
|
||||||
|
|
||||||
|
/// Number of contact points
|
||||||
|
int8 nbContacts;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Constants --------------------- //
|
// -------------------- Constants --------------------- //
|
||||||
|
@ -336,9 +284,18 @@ class ContactSolver {
|
||||||
/// Contact constraints
|
/// Contact constraints
|
||||||
ContactManifoldSolver* mContactConstraints;
|
ContactManifoldSolver* mContactConstraints;
|
||||||
|
|
||||||
|
/// Contact points
|
||||||
|
ContactPointSolver* mContactPoints;
|
||||||
|
|
||||||
|
/// Number of contact point constraints
|
||||||
|
uint mNbContactPoints;
|
||||||
|
|
||||||
/// Number of contact constraints
|
/// Number of contact constraints
|
||||||
uint mNbContactManifolds;
|
uint mNbContactManifolds;
|
||||||
|
|
||||||
|
/// Single frame memory allocator
|
||||||
|
SingleFrameAllocator& mSingleFrameAllocator;
|
||||||
|
|
||||||
/// Array of linear velocities
|
/// Array of linear velocities
|
||||||
Vector3* mLinearVelocities;
|
Vector3* mLinearVelocities;
|
||||||
|
|
||||||
|
@ -348,28 +305,11 @@ class ContactSolver {
|
||||||
/// Reference to the map of rigid body to their index in the constrained velocities array
|
/// Reference to the map of rigid body to their index in the constrained velocities array
|
||||||
const std::map<RigidBody*, uint>& mMapBodyToConstrainedVelocityIndex;
|
const std::map<RigidBody*, uint>& mMapBodyToConstrainedVelocityIndex;
|
||||||
|
|
||||||
/// True if the warm starting of the solver is active
|
|
||||||
bool mIsWarmStartingActive;
|
|
||||||
|
|
||||||
/// True if the split impulse position correction is active
|
/// True if the split impulse position correction is active
|
||||||
bool mIsSplitImpulseActive;
|
bool mIsSplitImpulseActive;
|
||||||
|
|
||||||
/// True if we solve 3 friction constraints at the contact manifold center only
|
|
||||||
/// instead of 2 friction constraints at each contact point
|
|
||||||
bool mIsSolveFrictionAtContactManifoldCenterActive;
|
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Initialize the contact constraints before solving the system
|
|
||||||
void initializeContactConstraints();
|
|
||||||
|
|
||||||
/// Apply an impulse to the two bodies of a constraint
|
|
||||||
void applyImpulse(const Impulse& impulse, const ContactManifoldSolver& manifold);
|
|
||||||
|
|
||||||
/// Apply an impulse to the two bodies of a constraint
|
|
||||||
void applySplitImpulse(const Impulse& impulse,
|
|
||||||
const ContactManifoldSolver& manifold);
|
|
||||||
|
|
||||||
/// Compute the collision restitution factor from the restitution factor of each body
|
/// Compute the collision restitution factor from the restitution factor of each body
|
||||||
decimal computeMixedRestitutionFactor(RigidBody *body1,
|
decimal computeMixedRestitutionFactor(RigidBody *body1,
|
||||||
RigidBody *body2) const;
|
RigidBody *body2) const;
|
||||||
|
@ -381,42 +321,31 @@ class ContactSolver {
|
||||||
/// Compute th mixed rolling resistance factor between two bodies
|
/// Compute th mixed rolling resistance factor between two bodies
|
||||||
decimal computeMixedRollingResistance(RigidBody* body1, RigidBody* body2) const;
|
decimal computeMixedRollingResistance(RigidBody* body1, RigidBody* body2) const;
|
||||||
|
|
||||||
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
|
||||||
/// plane for a contact point. The two vectors have to be
|
|
||||||
/// such that : t1 x t2 = contactNormal.
|
|
||||||
void computeFrictionVectors(const Vector3& deltaVelocity,
|
|
||||||
ContactPointSolver &contactPoint) const;
|
|
||||||
|
|
||||||
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
||||||
/// plane for a contact manifold. The two vectors have to be
|
/// plane for a contact manifold. The two vectors have to be
|
||||||
/// such that : t1 x t2 = contactNormal.
|
/// such that : t1 x t2 = contactNormal.
|
||||||
void computeFrictionVectors(const Vector3& deltaVelocity,
|
void computeFrictionVectors(const Vector3& deltaVelocity,
|
||||||
ContactManifoldSolver& contactPoint) const;
|
ContactManifoldSolver& contactPoint) const;
|
||||||
|
|
||||||
/// Compute a penetration constraint impulse
|
/// Warm start the solver.
|
||||||
const Impulse computePenetrationImpulse(decimal deltaLambda,
|
void warmStart();
|
||||||
const ContactPointSolver& contactPoint) const;
|
|
||||||
|
|
||||||
/// Compute the first friction constraint impulse
|
|
||||||
const Impulse computeFriction1Impulse(decimal deltaLambda,
|
|
||||||
const ContactPointSolver& contactPoint) const;
|
|
||||||
|
|
||||||
/// Compute the second friction constraint impulse
|
|
||||||
const Impulse computeFriction2Impulse(decimal deltaLambda,
|
|
||||||
const ContactPointSolver& contactPoint) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ContactSolver(const std::map<RigidBody*, uint>& mapBodyToVelocityIndex);
|
ContactSolver(const std::map<RigidBody*, uint>& mapBodyToVelocityIndex,
|
||||||
|
SingleFrameAllocator& allocator);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~ContactSolver() = default;
|
~ContactSolver() = default;
|
||||||
|
|
||||||
|
/// Initialize the contact constraints
|
||||||
|
void init(Island** islands, uint nbIslands, decimal timeStep);
|
||||||
|
|
||||||
/// Initialize the constraint solver for a given island
|
/// Initialize the constraint solver for a given island
|
||||||
void initializeForIsland(decimal dt, Island* island);
|
void initializeForIsland(Island* island);
|
||||||
|
|
||||||
/// Set the split velocities arrays
|
/// Set the split velocities arrays
|
||||||
void setSplitVelocitiesArrays(Vector3* splitLinearVelocities,
|
void setSplitVelocitiesArrays(Vector3* splitLinearVelocities,
|
||||||
|
@ -426,9 +355,6 @@ class ContactSolver {
|
||||||
void setConstrainedVelocitiesArrays(Vector3* constrainedLinearVelocities,
|
void setConstrainedVelocitiesArrays(Vector3* constrainedLinearVelocities,
|
||||||
Vector3* constrainedAngularVelocities);
|
Vector3* constrainedAngularVelocities);
|
||||||
|
|
||||||
/// Warm start the solver.
|
|
||||||
void warmStart();
|
|
||||||
|
|
||||||
/// Store the computed impulses to use them to
|
/// Store the computed impulses to use them to
|
||||||
/// warm start the solver at the next iteration
|
/// warm start the solver at the next iteration
|
||||||
void storeImpulses();
|
void storeImpulses();
|
||||||
|
@ -441,13 +367,6 @@ class ContactSolver {
|
||||||
|
|
||||||
/// Activate or Deactivate the split impulses for contacts
|
/// Activate or Deactivate the split impulses for contacts
|
||||||
void setIsSplitImpulseActive(bool isActive);
|
void setIsSplitImpulseActive(bool isActive);
|
||||||
|
|
||||||
/// Activate or deactivate the solving of friction constraints at the center of
|
|
||||||
/// the contact manifold instead of solving them at each contact point
|
|
||||||
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
|
||||||
|
|
||||||
/// Clean up the constraint solver
|
|
||||||
void cleanup();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set the split velocities arrays
|
// Set the split velocities arrays
|
||||||
|
@ -482,12 +401,6 @@ inline void ContactSolver::setIsSplitImpulseActive(bool isActive) {
|
||||||
mIsSplitImpulseActive = isActive;
|
mIsSplitImpulseActive = isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate or deactivate the solving of friction constraints at the center of
|
|
||||||
// the contact manifold instead of solving them at each contact point
|
|
||||||
inline void ContactSolver::setIsSolveFrictionAtContactManifoldCenterActive(bool isActive) {
|
|
||||||
mIsSolveFrictionAtContactManifoldCenterActive = isActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the collision restitution factor from the restitution factor of each body
|
// Compute the collision restitution factor from the restitution factor of each body
|
||||||
inline decimal ContactSolver::computeMixedRestitutionFactor(RigidBody* body1,
|
inline decimal ContactSolver::computeMixedRestitutionFactor(RigidBody* body1,
|
||||||
RigidBody* body2) const {
|
RigidBody* body2) const {
|
||||||
|
@ -502,7 +415,7 @@ inline decimal ContactSolver::computeMixedRestitutionFactor(RigidBody* body1,
|
||||||
inline decimal ContactSolver::computeMixedFrictionCoefficient(RigidBody *body1,
|
inline decimal ContactSolver::computeMixedFrictionCoefficient(RigidBody *body1,
|
||||||
RigidBody *body2) const {
|
RigidBody *body2) const {
|
||||||
// Use the geometric mean to compute the mixed friction coefficient
|
// Use the geometric mean to compute the mixed friction coefficient
|
||||||
return sqrt(body1->getMaterial().getFrictionCoefficient() *
|
return std::sqrt(body1->getMaterial().getFrictionCoefficient() *
|
||||||
body2->getMaterial().getFrictionCoefficient());
|
body2->getMaterial().getFrictionCoefficient());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,34 +425,6 @@ inline decimal ContactSolver::computeMixedRollingResistance(RigidBody* body1,
|
||||||
return decimal(0.5f) * (body1->getMaterial().getRollingResistance() + body2->getMaterial().getRollingResistance());
|
return decimal(0.5f) * (body1->getMaterial().getRollingResistance() + body2->getMaterial().getRollingResistance());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute a penetration constraint impulse
|
|
||||||
inline const Impulse ContactSolver::computePenetrationImpulse(decimal deltaLambda,
|
|
||||||
const ContactPointSolver& contactPoint)
|
|
||||||
const {
|
|
||||||
return Impulse(-contactPoint.normal * deltaLambda, -contactPoint.r1CrossN * deltaLambda,
|
|
||||||
contactPoint.normal * deltaLambda, contactPoint.r2CrossN * deltaLambda);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the first friction constraint impulse
|
|
||||||
inline const Impulse ContactSolver::computeFriction1Impulse(decimal deltaLambda,
|
|
||||||
const ContactPointSolver& contactPoint)
|
|
||||||
const {
|
|
||||||
return Impulse(-contactPoint.frictionVector1 * deltaLambda,
|
|
||||||
-contactPoint.r1CrossT1 * deltaLambda,
|
|
||||||
contactPoint.frictionVector1 * deltaLambda,
|
|
||||||
contactPoint.r2CrossT1 * deltaLambda);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the second friction constraint impulse
|
|
||||||
inline const Impulse ContactSolver::computeFriction2Impulse(decimal deltaLambda,
|
|
||||||
const ContactPointSolver& contactPoint)
|
|
||||||
const {
|
|
||||||
return Impulse(-contactPoint.frictionVector2 * deltaLambda,
|
|
||||||
-contactPoint.r1CrossT2 * deltaLambda,
|
|
||||||
contactPoint.frictionVector2 * deltaLambda,
|
|
||||||
contactPoint.r2CrossT2 * deltaLambda);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,7 +40,8 @@ using namespace std;
|
||||||
*/
|
*/
|
||||||
DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
|
DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
|
||||||
: CollisionWorld(),
|
: CollisionWorld(),
|
||||||
mContactSolver(mMapBodyToConstrainedVelocityIndex),
|
mSingleFrameAllocator(SIZE_SINGLE_FRAME_ALLOCATOR_BYTES),
|
||||||
|
mContactSolver(mMapBodyToConstrainedVelocityIndex, mSingleFrameAllocator),
|
||||||
mConstraintSolver(mMapBodyToConstrainedVelocityIndex),
|
mConstraintSolver(mMapBodyToConstrainedVelocityIndex),
|
||||||
mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
|
mNbVelocitySolverIterations(DEFAULT_VELOCITY_SOLVER_NB_ITERATIONS),
|
||||||
mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
|
mNbPositionSolverIterations(DEFAULT_POSITION_SOLVER_NB_ITERATIONS),
|
||||||
|
@ -48,8 +49,7 @@ DynamicsWorld::DynamicsWorld(const Vector3 &gravity)
|
||||||
mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr),
|
mIsGravityEnabled(true), mConstrainedLinearVelocities(nullptr),
|
||||||
mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr),
|
mConstrainedAngularVelocities(nullptr), mSplitLinearVelocities(nullptr),
|
||||||
mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr),
|
mSplitAngularVelocities(nullptr), mConstrainedPositions(nullptr),
|
||||||
mConstrainedOrientations(nullptr), mNbIslands(0),
|
mConstrainedOrientations(nullptr), mNbIslands(0), mIslands(nullptr),
|
||||||
mNbIslandsCapacity(0), mIslands(nullptr), mNbBodiesCapacity(0),
|
|
||||||
mSleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
|
mSleepLinearVelocity(DEFAULT_SLEEP_LINEAR_VELOCITY),
|
||||||
mSleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
|
mSleepAngularVelocity(DEFAULT_SLEEP_ANGULAR_VELOCITY),
|
||||||
mTimeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
|
mTimeBeforeSleep(DEFAULT_TIME_BEFORE_SLEEP) {
|
||||||
|
@ -75,29 +75,6 @@ DynamicsWorld::~DynamicsWorld() {
|
||||||
destroyRigidBody(*itToRemove);
|
destroyRigidBody(*itToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release the memory allocated for the islands
|
|
||||||
for (uint i=0; i<mNbIslands; i++) {
|
|
||||||
|
|
||||||
// Call the island destructor
|
|
||||||
mIslands[i]->~Island();
|
|
||||||
|
|
||||||
// Release the allocated memory for the island
|
|
||||||
mMemoryAllocator.release(mIslands[i], sizeof(Island));
|
|
||||||
}
|
|
||||||
if (mNbIslandsCapacity > 0) {
|
|
||||||
mMemoryAllocator.release(mIslands, sizeof(Island*) * mNbIslandsCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release the memory allocated for the bodies velocity arrays
|
|
||||||
if (mNbBodiesCapacity > 0) {
|
|
||||||
delete[] mSplitLinearVelocities;
|
|
||||||
delete[] mSplitAngularVelocities;
|
|
||||||
delete[] mConstrainedLinearVelocities;
|
|
||||||
delete[] mConstrainedAngularVelocities;
|
|
||||||
delete[] mConstrainedPositions;
|
|
||||||
delete[] mConstrainedOrientations;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(mJoints.size() == 0);
|
assert(mJoints.size() == 0);
|
||||||
assert(mRigidBodies.size() == 0);
|
assert(mRigidBodies.size() == 0);
|
||||||
|
|
||||||
|
@ -161,6 +138,9 @@ void DynamicsWorld::update(decimal timeStep) {
|
||||||
|
|
||||||
// Reset the external force and torque applied to the bodies
|
// Reset the external force and torque applied to the bodies
|
||||||
resetBodiesForceAndTorque();
|
resetBodiesForceAndTorque();
|
||||||
|
|
||||||
|
// Reset the single frame memory allocator
|
||||||
|
mSingleFrameAllocator.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Integrate position and orientation of the rigid bodies.
|
// Integrate position and orientation of the rigid bodies.
|
||||||
|
@ -232,6 +212,9 @@ void DynamicsWorld::updateBodiesState() {
|
||||||
// Update the transform of the body (using the new center of mass and new orientation)
|
// Update the transform of the body (using the new center of mass and new orientation)
|
||||||
bodies[b]->updateTransformWithCenterOfMass();
|
bodies[b]->updateTransformWithCenterOfMass();
|
||||||
|
|
||||||
|
// Update the world inverse inertia tensor of the body
|
||||||
|
bodies[b]->updateInertiaTensorInverseWorld();
|
||||||
|
|
||||||
// Update the broad-phase state of the body
|
// Update the broad-phase state of the body
|
||||||
bodies[b]->updateBroadPhaseState();
|
bodies[b]->updateBroadPhaseState();
|
||||||
}
|
}
|
||||||
|
@ -241,31 +224,26 @@ void DynamicsWorld::updateBodiesState() {
|
||||||
// Initialize the bodies velocities arrays for the next simulation step.
|
// Initialize the bodies velocities arrays for the next simulation step.
|
||||||
void DynamicsWorld::initVelocityArrays() {
|
void DynamicsWorld::initVelocityArrays() {
|
||||||
|
|
||||||
|
PROFILE("DynamicsWorld::initVelocityArrays()");
|
||||||
|
|
||||||
// Allocate memory for the bodies velocity arrays
|
// Allocate memory for the bodies velocity arrays
|
||||||
uint nbBodies = mRigidBodies.size();
|
uint nbBodies = mRigidBodies.size();
|
||||||
if (mNbBodiesCapacity != nbBodies && nbBodies > 0) {
|
|
||||||
if (mNbBodiesCapacity > 0) {
|
mSplitLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||||
delete[] mSplitLinearVelocities;
|
mSplitAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||||
delete[] mSplitAngularVelocities;
|
mConstrainedLinearVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||||
}
|
mConstrainedAngularVelocities = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||||
mNbBodiesCapacity = nbBodies;
|
mConstrainedPositions = static_cast<Vector3*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Vector3)));
|
||||||
// TODO : Use better memory allocation here
|
mConstrainedOrientations = static_cast<Quaternion*>(mSingleFrameAllocator.allocate(nbBodies * sizeof(Quaternion)));
|
||||||
mSplitLinearVelocities = new Vector3[mNbBodiesCapacity];
|
assert(mSplitLinearVelocities != nullptr);
|
||||||
mSplitAngularVelocities = new Vector3[mNbBodiesCapacity];
|
assert(mSplitAngularVelocities != nullptr);
|
||||||
mConstrainedLinearVelocities = new Vector3[mNbBodiesCapacity];
|
assert(mConstrainedLinearVelocities != nullptr);
|
||||||
mConstrainedAngularVelocities = new Vector3[mNbBodiesCapacity];
|
assert(mConstrainedAngularVelocities != nullptr);
|
||||||
mConstrainedPositions = new Vector3[mNbBodiesCapacity];
|
assert(mConstrainedPositions != nullptr);
|
||||||
mConstrainedOrientations = new Quaternion[mNbBodiesCapacity];
|
assert(mConstrainedOrientations != nullptr);
|
||||||
assert(mSplitLinearVelocities != nullptr);
|
|
||||||
assert(mSplitAngularVelocities != nullptr);
|
|
||||||
assert(mConstrainedLinearVelocities != nullptr);
|
|
||||||
assert(mConstrainedAngularVelocities != nullptr);
|
|
||||||
assert(mConstrainedPositions != nullptr);
|
|
||||||
assert(mConstrainedOrientations != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset the velocities arrays
|
// Reset the velocities arrays
|
||||||
for (uint i=0; i<mNbBodiesCapacity; i++) {
|
for (uint i=0; i<nbBodies; i++) {
|
||||||
mSplitLinearVelocities[i].setToZero();
|
mSplitLinearVelocities[i].setToZero();
|
||||||
mSplitAngularVelocities[i].setToZero();
|
mSplitAngularVelocities[i].setToZero();
|
||||||
}
|
}
|
||||||
|
@ -364,23 +342,28 @@ void DynamicsWorld::solveContactsAndConstraints() {
|
||||||
|
|
||||||
// ---------- Solve velocity constraints for joints and contacts ---------- //
|
// ---------- Solve velocity constraints for joints and contacts ---------- //
|
||||||
|
|
||||||
|
// Initialize the contact solver
|
||||||
|
mContactSolver.init(mIslands, mNbIslands, mTimeStep);
|
||||||
|
|
||||||
// For each island of the world
|
// For each island of the world
|
||||||
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
|
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
|
||||||
|
|
||||||
// Check if there are contacts and constraints to solve
|
// Check if there are contacts and constraints to solve
|
||||||
bool isConstraintsToSolve = mIslands[islandIndex]->getNbJoints() > 0;
|
bool isConstraintsToSolve = mIslands[islandIndex]->getNbJoints() > 0;
|
||||||
bool isContactsToSolve = mIslands[islandIndex]->getNbContactManifolds() > 0;
|
//bool isContactsToSolve = mIslands[islandIndex]->getNbContactManifolds() > 0;
|
||||||
if (!isConstraintsToSolve && !isContactsToSolve) continue;
|
//if (!isConstraintsToSolve && !isContactsToSolve) continue;
|
||||||
|
|
||||||
// If there are contacts in the current island
|
// If there are contacts in the current island
|
||||||
if (isContactsToSolve) {
|
// if (isContactsToSolve) {
|
||||||
|
|
||||||
// Initialize the solver
|
// // Initialize the solver
|
||||||
mContactSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]);
|
// mContactSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]);
|
||||||
|
|
||||||
// Warm start the contact solver
|
// // Warm start the contact solver
|
||||||
mContactSolver.warmStart();
|
// if (mContactSolver.IsWarmStartingActive()) {
|
||||||
}
|
// mContactSolver.warmStart();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// If there are constraints
|
// If there are constraints
|
||||||
if (isConstraintsToSolve) {
|
if (isConstraintsToSolve) {
|
||||||
|
@ -388,26 +371,32 @@ void DynamicsWorld::solveContactsAndConstraints() {
|
||||||
// Initialize the constraint solver
|
// Initialize the constraint solver
|
||||||
mConstraintSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]);
|
mConstraintSolver.initializeForIsland(mTimeStep, mIslands[islandIndex]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// For each iteration of the velocity solver
|
// For each iteration of the velocity solver
|
||||||
for (uint i=0; i<mNbVelocitySolverIterations; i++) {
|
for (uint i=0; i<mNbVelocitySolverIterations; i++) {
|
||||||
|
|
||||||
|
for (uint islandIndex = 0; islandIndex < mNbIslands; islandIndex++) {
|
||||||
// Solve the constraints
|
// Solve the constraints
|
||||||
|
bool isConstraintsToSolve = mIslands[islandIndex]->getNbJoints() > 0;
|
||||||
if (isConstraintsToSolve) {
|
if (isConstraintsToSolve) {
|
||||||
mConstraintSolver.solveVelocityConstraints(mIslands[islandIndex]);
|
mConstraintSolver.solveVelocityConstraints(mIslands[islandIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solve the contacts
|
|
||||||
if (isContactsToSolve) mContactSolver.solve();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the lambda values in order to use them in the next
|
mContactSolver.solve();
|
||||||
// step and cleanup the contact solver
|
|
||||||
if (isContactsToSolve) {
|
// Solve the contacts
|
||||||
mContactSolver.storeImpulses();
|
// if (isContactsToSolve) {
|
||||||
mContactSolver.cleanup();
|
|
||||||
}
|
// mContactSolver.resetTotalPenetrationImpulse();
|
||||||
|
|
||||||
|
// mContactSolver.solvePenetrationConstraints();
|
||||||
|
// mContactSolver.solveFrictionConstraints();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mContactSolver.storeImpulses();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Solve the position error correction of the constraints
|
// Solve the position error correction of the constraints
|
||||||
|
@ -446,7 +435,7 @@ RigidBody* DynamicsWorld::createRigidBody(const Transform& transform) {
|
||||||
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
assert(bodyID < std::numeric_limits<reactphysics3d::bodyindex>::max());
|
||||||
|
|
||||||
// Create the rigid body
|
// Create the rigid body
|
||||||
RigidBody* rigidBody = new (mMemoryAllocator.allocate(sizeof(RigidBody))) RigidBody(transform,
|
RigidBody* rigidBody = new (mPoolAllocator.allocate(sizeof(RigidBody))) RigidBody(transform,
|
||||||
*this, bodyID);
|
*this, bodyID);
|
||||||
assert(rigidBody != nullptr);
|
assert(rigidBody != nullptr);
|
||||||
|
|
||||||
|
@ -487,7 +476,7 @@ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) {
|
||||||
mRigidBodies.erase(rigidBody);
|
mRigidBodies.erase(rigidBody);
|
||||||
|
|
||||||
// Free the object from the memory allocator
|
// Free the object from the memory allocator
|
||||||
mMemoryAllocator.release(rigidBody, sizeof(RigidBody));
|
mPoolAllocator.release(rigidBody, sizeof(RigidBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -505,7 +494,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
||||||
// Ball-and-Socket joint
|
// Ball-and-Socket joint
|
||||||
case JointType::BALLSOCKETJOINT:
|
case JointType::BALLSOCKETJOINT:
|
||||||
{
|
{
|
||||||
void* allocatedMemory = mMemoryAllocator.allocate(sizeof(BallAndSocketJoint));
|
void* allocatedMemory = mPoolAllocator.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 (allocatedMemory) BallAndSocketJoint(info);
|
||||||
|
@ -515,7 +504,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
||||||
// Slider joint
|
// Slider joint
|
||||||
case JointType::SLIDERJOINT:
|
case JointType::SLIDERJOINT:
|
||||||
{
|
{
|
||||||
void* allocatedMemory = mMemoryAllocator.allocate(sizeof(SliderJoint));
|
void* allocatedMemory = mPoolAllocator.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 (allocatedMemory) SliderJoint(info);
|
||||||
break;
|
break;
|
||||||
|
@ -524,7 +513,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
||||||
// Hinge joint
|
// Hinge joint
|
||||||
case JointType::HINGEJOINT:
|
case JointType::HINGEJOINT:
|
||||||
{
|
{
|
||||||
void* allocatedMemory = mMemoryAllocator.allocate(sizeof(HingeJoint));
|
void* allocatedMemory = mPoolAllocator.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 (allocatedMemory) HingeJoint(info);
|
||||||
break;
|
break;
|
||||||
|
@ -533,7 +522,7 @@ Joint* DynamicsWorld::createJoint(const JointInfo& jointInfo) {
|
||||||
// Fixed joint
|
// Fixed joint
|
||||||
case JointType::FIXEDJOINT:
|
case JointType::FIXEDJOINT:
|
||||||
{
|
{
|
||||||
void* allocatedMemory = mMemoryAllocator.allocate(sizeof(FixedJoint));
|
void* allocatedMemory = mPoolAllocator.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 (allocatedMemory) FixedJoint(info);
|
||||||
break;
|
break;
|
||||||
|
@ -586,8 +575,8 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
||||||
mJoints.erase(joint);
|
mJoints.erase(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->mBody1->removeJointFromJointsList(mMemoryAllocator, joint);
|
joint->mBody1->removeJointFromJointsList(mPoolAllocator, joint);
|
||||||
joint->mBody2->removeJointFromJointsList(mMemoryAllocator, joint);
|
joint->mBody2->removeJointFromJointsList(mPoolAllocator, joint);
|
||||||
|
|
||||||
size_t nbBytes = joint->getSizeInBytes();
|
size_t nbBytes = joint->getSizeInBytes();
|
||||||
|
|
||||||
|
@ -595,7 +584,7 @@ void DynamicsWorld::destroyJoint(Joint* joint) {
|
||||||
joint->~Joint();
|
joint->~Joint();
|
||||||
|
|
||||||
// Release the allocated memory
|
// Release the allocated memory
|
||||||
mMemoryAllocator.release(joint, nbBytes);
|
mPoolAllocator.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
|
||||||
|
@ -604,13 +593,13 @@ 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 = mMemoryAllocator.allocate(sizeof(JointListElement));
|
void* allocatedMemory1 = mPoolAllocator.allocate(sizeof(JointListElement));
|
||||||
JointListElement* jointListElement1 = new (allocatedMemory1) JointListElement(joint,
|
JointListElement* jointListElement1 = new (allocatedMemory1) JointListElement(joint,
|
||||||
joint->mBody1->mJointsList);
|
joint->mBody1->mJointsList);
|
||||||
joint->mBody1->mJointsList = jointListElement1;
|
joint->mBody1->mJointsList = 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 = mMemoryAllocator.allocate(sizeof(JointListElement));
|
void* allocatedMemory2 = mPoolAllocator.allocate(sizeof(JointListElement));
|
||||||
JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint,
|
JointListElement* jointListElement2 = new (allocatedMemory2) JointListElement(joint,
|
||||||
joint->mBody2->mJointsList);
|
joint->mBody2->mJointsList);
|
||||||
joint->mBody2->mJointsList = jointListElement2;
|
joint->mBody2->mJointsList = jointListElement2;
|
||||||
|
@ -629,24 +618,9 @@ void DynamicsWorld::computeIslands() {
|
||||||
|
|
||||||
uint nbBodies = mRigidBodies.size();
|
uint nbBodies = mRigidBodies.size();
|
||||||
|
|
||||||
// Clear all the islands
|
// Allocate and create the array of islands pointer. This memory is allocated
|
||||||
for (uint i=0; i<mNbIslands; i++) {
|
// in the single frame allocator
|
||||||
|
mIslands = static_cast<Island**>(mSingleFrameAllocator.allocate(sizeof(Island*) * nbBodies));
|
||||||
// Call the island destructor
|
|
||||||
mIslands[i]->~Island();
|
|
||||||
|
|
||||||
// Release the allocated memory for the island
|
|
||||||
mMemoryAllocator.release(mIslands[i], sizeof(Island));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate and create the array of islands
|
|
||||||
if (mNbIslandsCapacity != nbBodies && nbBodies > 0) {
|
|
||||||
if (mNbIslandsCapacity > 0) {
|
|
||||||
mMemoryAllocator.release(mIslands, sizeof(Island*) * mNbIslandsCapacity);
|
|
||||||
}
|
|
||||||
mNbIslandsCapacity = nbBodies;
|
|
||||||
mIslands = (Island**)mMemoryAllocator.allocate(sizeof(Island*) * mNbIslandsCapacity);
|
|
||||||
}
|
|
||||||
mNbIslands = 0;
|
mNbIslands = 0;
|
||||||
|
|
||||||
int nbContactManifolds = 0;
|
int nbContactManifolds = 0;
|
||||||
|
@ -662,7 +636,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**)mMemoryAllocator.allocate(nbBytesStack);
|
RigidBody** stackBodiesToVisit = static_cast<RigidBody**>(mSingleFrameAllocator.allocate(nbBytesStack));
|
||||||
|
|
||||||
// For each rigid body of the world
|
// For each rigid body of the world
|
||||||
for (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) {
|
for (std::set<RigidBody*>::iterator it = mRigidBodies.begin(); it != mRigidBodies.end(); ++it) {
|
||||||
|
@ -685,10 +659,9 @@ void DynamicsWorld::computeIslands() {
|
||||||
body->mIsAlreadyInIsland = true;
|
body->mIsAlreadyInIsland = true;
|
||||||
|
|
||||||
// Create the new island
|
// Create the new island
|
||||||
void* allocatedMemoryIsland = mMemoryAllocator.allocate(sizeof(Island));
|
void* allocatedMemoryIsland = mSingleFrameAllocator.allocate(sizeof(Island));
|
||||||
mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies,
|
mIslands[mNbIslands] = new (allocatedMemoryIsland) Island(nbBodies, nbContactManifolds, mJoints.size(),
|
||||||
nbContactManifolds,
|
mSingleFrameAllocator);
|
||||||
mJoints.size(), mMemoryAllocator);
|
|
||||||
|
|
||||||
// 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) {
|
||||||
|
@ -778,9 +751,6 @@ void DynamicsWorld::computeIslands() {
|
||||||
|
|
||||||
mNbIslands++;
|
mNbIslands++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release the allocated memory for the stack of bodies to visit
|
|
||||||
mMemoryAllocator.release(stackBodiesToVisit, nbBytesStack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put bodies to sleep if needed.
|
// Put bodies to sleep if needed.
|
||||||
|
|
|
@ -50,6 +50,9 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
|
/// Single frame Memory allocator
|
||||||
|
SingleFrameAllocator mSingleFrameAllocator;
|
||||||
|
|
||||||
/// Contact solver
|
/// Contact solver
|
||||||
ContactSolver mContactSolver;
|
ContactSolver mContactSolver;
|
||||||
|
|
||||||
|
@ -106,15 +109,9 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
/// Number of islands in the world
|
/// Number of islands in the world
|
||||||
uint mNbIslands;
|
uint mNbIslands;
|
||||||
|
|
||||||
/// Current allocated capacity for the islands
|
|
||||||
uint mNbIslandsCapacity;
|
|
||||||
|
|
||||||
/// Array with all the islands of awaken bodies
|
/// Array with all the islands of awaken bodies
|
||||||
Island** mIslands;
|
Island** mIslands;
|
||||||
|
|
||||||
/// Current allocated capacity for the bodies
|
|
||||||
uint mNbBodiesCapacity;
|
|
||||||
|
|
||||||
/// Sleep linear velocity threshold
|
/// Sleep linear velocity threshold
|
||||||
decimal mSleepLinearVelocity;
|
decimal mSleepLinearVelocity;
|
||||||
|
|
||||||
|
@ -207,10 +204,6 @@ class DynamicsWorld : public CollisionWorld {
|
||||||
/// Set the position correction technique used for joints
|
/// Set the position correction technique used for joints
|
||||||
void setJointsPositionCorrectionTechnique(JointsPositionCorrectionTechnique technique);
|
void setJointsPositionCorrectionTechnique(JointsPositionCorrectionTechnique technique);
|
||||||
|
|
||||||
/// Activate or deactivate the solving of friction constraints at the center of
|
|
||||||
/// the contact manifold instead of solving them at each contact point
|
|
||||||
void setIsSolveFrictionAtContactManifoldCenterActive(bool isActive);
|
|
||||||
|
|
||||||
/// Create a rigid body into the physics world.
|
/// Create a rigid body into the physics world.
|
||||||
RigidBody* createRigidBody(const Transform& transform);
|
RigidBody* createRigidBody(const Transform& transform);
|
||||||
|
|
||||||
|
@ -370,16 +363,6 @@ inline void DynamicsWorld::setJointsPositionCorrectionTechnique(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate or deactivate the solving of friction constraints at the center of
|
|
||||||
// the contact manifold instead of solving them at each contact point
|
|
||||||
/**
|
|
||||||
* @param isActive True if you want the friction to be solved at the center of
|
|
||||||
* the contact manifold and false otherwise
|
|
||||||
*/
|
|
||||||
inline void DynamicsWorld::setIsSolveFrictionAtContactManifoldCenterActive(bool isActive) {
|
|
||||||
mContactSolver.setIsSolveFrictionAtContactManifoldCenterActive(isActive);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the gravity vector of the world
|
// Return the gravity vector of the world
|
||||||
/**
|
/**
|
||||||
* @return The current gravity vector (in meter per seconds squared)
|
* @return The current gravity vector (in meter per seconds squared)
|
||||||
|
|
|
@ -29,26 +29,18 @@
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Island::Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
|
Island::Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints, SingleFrameAllocator& allocator)
|
||||||
MemoryAllocator& memoryAllocator)
|
|
||||||
: mBodies(nullptr), mContactManifolds(nullptr), mJoints(nullptr), mNbBodies(0),
|
: mBodies(nullptr), mContactManifolds(nullptr), mJoints(nullptr), mNbBodies(0),
|
||||||
mNbContactManifolds(0), mNbJoints(0), mMemoryAllocator(memoryAllocator) {
|
mNbContactManifolds(0), mNbJoints(0) {
|
||||||
|
|
||||||
// Allocate memory for the arrays
|
// Allocate memory for the arrays on the single frame allocator
|
||||||
mNbAllocatedBytesBodies = sizeof(RigidBody*) * nbMaxBodies;
|
mBodies = static_cast<RigidBody**>(allocator.allocate(sizeof(RigidBody*) * nbMaxBodies));
|
||||||
mBodies = (RigidBody**) mMemoryAllocator.allocate(mNbAllocatedBytesBodies);
|
mContactManifolds = static_cast<ContactManifold**>(allocator.allocate(sizeof(ContactManifold*) * nbMaxContactManifolds));
|
||||||
mNbAllocatedBytesContactManifolds = sizeof(ContactManifold*) * nbMaxContactManifolds;
|
mJoints = static_cast<Joint**>(allocator.allocate(sizeof(Joint*) * nbMaxJoints));
|
||||||
mContactManifolds = (ContactManifold**) mMemoryAllocator.allocate(
|
|
||||||
mNbAllocatedBytesContactManifolds);
|
|
||||||
mNbAllocatedBytesJoints = sizeof(Joint*) * nbMaxJoints;
|
|
||||||
mJoints = (Joint**) mMemoryAllocator.allocate(mNbAllocatedBytesJoints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
Island::~Island() {
|
Island::~Island() {
|
||||||
|
// This destructor is never called because memory is allocated on the
|
||||||
// Release the memory of the arrays
|
// single frame allocator
|
||||||
mMemoryAllocator.release(mBodies, mNbAllocatedBytesBodies);
|
|
||||||
mMemoryAllocator.release(mContactManifolds, mNbAllocatedBytesContactManifolds);
|
|
||||||
mMemoryAllocator.release(mJoints, mNbAllocatedBytesJoints);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#define REACTPHYSICS3D_ISLAND_H
|
#define REACTPHYSICS3D_ISLAND_H
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "memory/MemoryAllocator.h"
|
#include "memory/SingleFrameAllocator.h"
|
||||||
#include "body/RigidBody.h"
|
#include "body/RigidBody.h"
|
||||||
#include "constraint/Joint.h"
|
#include "constraint/Joint.h"
|
||||||
#include "collision/ContactManifold.h"
|
#include "collision/ContactManifold.h"
|
||||||
|
@ -63,25 +63,13 @@ class Island {
|
||||||
/// Current number of joints in the island
|
/// Current number of joints in the island
|
||||||
uint mNbJoints;
|
uint mNbJoints;
|
||||||
|
|
||||||
/// Reference to the memory allocator
|
|
||||||
MemoryAllocator& mMemoryAllocator;
|
|
||||||
|
|
||||||
/// Number of bytes allocated for the bodies array
|
|
||||||
size_t mNbAllocatedBytesBodies;
|
|
||||||
|
|
||||||
/// Number of bytes allocated for the contact manifolds array
|
|
||||||
size_t mNbAllocatedBytesContactManifolds;
|
|
||||||
|
|
||||||
/// Number of bytes allocated for the joints array
|
|
||||||
size_t mNbAllocatedBytesJoints;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
|
Island(uint nbMaxBodies, uint nbMaxContactManifolds, uint nbMaxJoints,
|
||||||
MemoryAllocator& memoryAllocator);
|
SingleFrameAllocator& allocator);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Island();
|
~Island();
|
||||||
|
@ -114,7 +102,7 @@ class Island {
|
||||||
RigidBody** getBodies();
|
RigidBody** getBodies();
|
||||||
|
|
||||||
/// Return a pointer to the array of contact manifolds
|
/// Return a pointer to the array of contact manifolds
|
||||||
ContactManifold** getContactManifold();
|
ContactManifold** getContactManifolds();
|
||||||
|
|
||||||
/// Return a pointer to the array of joints
|
/// Return a pointer to the array of joints
|
||||||
Joint** getJoints();
|
Joint** getJoints();
|
||||||
|
@ -164,7 +152,7 @@ inline RigidBody** Island::getBodies() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a pointer to the array of contact manifolds
|
// Return a pointer to the array of contact manifolds
|
||||||
inline ContactManifold** Island::getContactManifold() {
|
inline ContactManifold** Island::getContactManifolds() {
|
||||||
return mContactManifolds;
|
return mContactManifolds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
|
OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
|
||||||
int nbMaxContactManifolds, MemoryAllocator& memoryAllocator)
|
int nbMaxContactManifolds, PoolAllocator& memoryAllocator)
|
||||||
: mContactManifoldSet(shape1, shape2, memoryAllocator, nbMaxContactManifolds),
|
: mContactManifoldSet(shape1, shape2, memoryAllocator, nbMaxContactManifolds),
|
||||||
mCachedSeparatingAxis(0.0, 1.0, 0.0) {
|
mCachedSeparatingAxis(0.0, 1.0, 0.0) {
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ class OverlappingPair {
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
|
OverlappingPair(ProxyShape* shape1, ProxyShape* shape2,
|
||||||
int nbMaxContactManifolds, MemoryAllocator& memoryAllocator);
|
int nbMaxContactManifolds, PoolAllocator& memoryAllocator);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~OverlappingPair() = default;
|
~OverlappingPair() = default;
|
||||||
|
|
|
@ -65,17 +65,17 @@ Vector3 Vector3::getOneUnitOrthogonalVector() const {
|
||||||
assert(length() > MACHINE_EPSILON);
|
assert(length() > MACHINE_EPSILON);
|
||||||
|
|
||||||
// Get the minimum element of the vector
|
// Get the minimum element of the vector
|
||||||
Vector3 vectorAbs(fabs(x), fabs(y), fabs(z));
|
Vector3 vectorAbs(std::fabs(x), std::fabs(y), std::fabs(z));
|
||||||
int minElement = vectorAbs.getMinAxis();
|
int minElement = vectorAbs.getMinAxis();
|
||||||
|
|
||||||
if (minElement == 0) {
|
if (minElement == 0) {
|
||||||
return Vector3(0.0, -z, y) / sqrt(y*y + z*z);
|
return Vector3(0.0, -z, y) / std::sqrt(y*y + z*z);
|
||||||
}
|
}
|
||||||
else if (minElement == 1) {
|
else if (minElement == 1) {
|
||||||
return Vector3(-z, 0.0, x) / sqrt(x*x + z*z);
|
return Vector3(-z, 0.0, x) / std::sqrt(x*x + z*z);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Vector3(-y, x, 0.0) / sqrt(x*x + y*y);
|
return Vector3(-y, x, 0.0) / std::sqrt(x*x + y*y);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ inline void Vector3::setAllValues(decimal newX, decimal newY, decimal newZ) {
|
||||||
|
|
||||||
// Return the length of the vector
|
// Return the length of the vector
|
||||||
inline decimal Vector3::length() const {
|
inline decimal Vector3::length() const {
|
||||||
return sqrt(x*x + y*y + z*z);
|
return std::sqrt(x*x + y*y + z*z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the square of the length of the vector
|
// Return the square of the length of the vector
|
||||||
|
|
|
@ -24,19 +24,19 @@
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "MemoryAllocator.h"
|
#include "PoolAllocator.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
using namespace reactphysics3d;
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
// Initialization of static variables
|
// Initialization of static variables
|
||||||
bool MemoryAllocator::isMapSizeToHeadIndexInitialized = false;
|
bool PoolAllocator::isMapSizeToHeadIndexInitialized = false;
|
||||||
size_t MemoryAllocator::mUnitSizes[NB_HEAPS];
|
size_t PoolAllocator::mUnitSizes[NB_HEAPS];
|
||||||
int MemoryAllocator::mMapSizeToHeapIndex[MAX_UNIT_SIZE + 1];
|
int PoolAllocator::mMapSizeToHeapIndex[MAX_UNIT_SIZE + 1];
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
MemoryAllocator::MemoryAllocator() {
|
PoolAllocator::PoolAllocator() {
|
||||||
|
|
||||||
// Allocate some memory to manage the blocks
|
// Allocate some memory to manage the blocks
|
||||||
mNbAllocatedMemoryBlocks = 64;
|
mNbAllocatedMemoryBlocks = 64;
|
||||||
|
@ -78,7 +78,7 @@ MemoryAllocator::MemoryAllocator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
MemoryAllocator::~MemoryAllocator() {
|
PoolAllocator::~PoolAllocator() {
|
||||||
|
|
||||||
// Release the memory allocated for each block
|
// Release the memory allocated for each block
|
||||||
for (uint i=0; i<mNbCurrentMemoryBlocks; i++) {
|
for (uint i=0; i<mNbCurrentMemoryBlocks; i++) {
|
||||||
|
@ -96,7 +96,7 @@ MemoryAllocator::~MemoryAllocator() {
|
||||||
|
|
||||||
// Allocate memory of a given size (in bytes) and return a pointer to the
|
// Allocate memory of a given size (in bytes) and return a pointer to the
|
||||||
// allocated memory.
|
// allocated memory.
|
||||||
void* MemoryAllocator::allocate(size_t size) {
|
void* PoolAllocator::allocate(size_t size) {
|
||||||
|
|
||||||
// We cannot allocate zero bytes
|
// We cannot allocate zero bytes
|
||||||
if (size == 0) return nullptr;
|
if (size == 0) return nullptr;
|
||||||
|
@ -164,7 +164,7 @@ void* MemoryAllocator::allocate(size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release previously allocated memory.
|
// Release previously allocated memory.
|
||||||
void MemoryAllocator::release(void* pointer, size_t size) {
|
void PoolAllocator::release(void* pointer, size_t size) {
|
||||||
|
|
||||||
// Cannot release a 0-byte allocated memory
|
// Cannot release a 0-byte allocated memory
|
||||||
if (size == 0) return;
|
if (size == 0) return;
|
|
@ -23,8 +23,8 @@
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#ifndef REACTPHYSICS3D_MEMORY_ALLOCATOR_H
|
#ifndef REACTPHYSICS3D_POOL_ALLOCATOR_H
|
||||||
#define REACTPHYSICS3D_MEMORY_ALLOCATOR_H
|
#define REACTPHYSICS3D_POOL_ALLOCATOR_H
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -33,14 +33,14 @@
|
||||||
/// ReactPhysics3D namespace
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Class MemoryAllocator
|
// Class PoolAllocator
|
||||||
/**
|
/**
|
||||||
* This class is used to efficiently allocate memory on the heap.
|
* 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)
|
* 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
|
* efficiently. This implementation is inspired by the small block allocator
|
||||||
* described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp
|
* described here : http://www.codeproject.com/useritems/Small_Block_Allocator.asp
|
||||||
*/
|
*/
|
||||||
class MemoryAllocator {
|
class PoolAllocator {
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -126,10 +126,10 @@ class MemoryAllocator {
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
MemoryAllocator();
|
PoolAllocator();
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~MemoryAllocator();
|
~PoolAllocator();
|
||||||
|
|
||||||
/// Allocate memory of a given size (in bytes) and return a pointer to the
|
/// Allocate memory of a given size (in bytes) and return a pointer to the
|
||||||
/// allocated memory.
|
/// allocated memory.
|
80
src/memory/SingleFrameAllocator.cpp
Normal file
80
src/memory/SingleFrameAllocator.cpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
||||||
|
* Copyright (c) 2010-2016 Daniel Chappuis *
|
||||||
|
*********************************************************************************
|
||||||
|
* *
|
||||||
|
* This software is provided 'as-is', without any express or implied warranty. *
|
||||||
|
* In no event will the authors be held liable for any damages arising from the *
|
||||||
|
* use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute it *
|
||||||
|
* freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||||
|
* that you wrote the original software. If you use this software in a *
|
||||||
|
* product, an acknowledgment in the product documentation would be *
|
||||||
|
* appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||||
|
* misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution. *
|
||||||
|
* *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
// Libraries
|
||||||
|
#include "SingleFrameAllocator.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
using namespace reactphysics3d;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
SingleFrameAllocator::SingleFrameAllocator(size_t totalSizeBytes)
|
||||||
|
: mTotalSizeBytes(totalSizeBytes), mCurrentOffset(0) {
|
||||||
|
|
||||||
|
// Allocate a whole block of memory at the beginning
|
||||||
|
mMemoryBufferStart = static_cast<char*>(malloc(mTotalSizeBytes));
|
||||||
|
assert(mMemoryBufferStart != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
SingleFrameAllocator::~SingleFrameAllocator() {
|
||||||
|
|
||||||
|
// Release the memory allocated at the beginning
|
||||||
|
free(mMemoryBufferStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Allocate memory of a given size (in bytes) and return a pointer to the
|
||||||
|
// allocated memory.
|
||||||
|
void* SingleFrameAllocator::allocate(size_t size) {
|
||||||
|
|
||||||
|
// Check that there is enough remaining memory in the buffer
|
||||||
|
if (static_cast<size_t>(mCurrentOffset) + size > mTotalSizeBytes) {
|
||||||
|
|
||||||
|
// This should never occur. If it does, you must increase the initial
|
||||||
|
// size of memory of this allocator
|
||||||
|
assert(false);
|
||||||
|
|
||||||
|
// Return null
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next available memory location
|
||||||
|
void* nextAvailableMemory = mMemoryBufferStart + mCurrentOffset;
|
||||||
|
|
||||||
|
// Increment the offset
|
||||||
|
mCurrentOffset += size;
|
||||||
|
|
||||||
|
// Return the next available memory location
|
||||||
|
return nextAvailableMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the marker of the current allocated memory
|
||||||
|
void SingleFrameAllocator::reset() {
|
||||||
|
|
||||||
|
// Reset the current offset at the beginning of the block
|
||||||
|
mCurrentOffset = 0;
|
||||||
|
}
|
|
@ -23,63 +23,52 @@
|
||||||
* *
|
* *
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#ifndef REACTPHYSICS3D_IMPULSE_H
|
#ifndef REACTPHYSICS3D_SINGLE_FRAME_ALLOCATOR_H
|
||||||
#define REACTPHYSICS3D_IMPULSE_H
|
#define REACTPHYSICS3D_SINGLE_FRAME_ALLOCATOR_H
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#include "mathematics/mathematics.h"
|
#include <cstring>
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
/// ReactPhysics3D namespace
|
||||||
namespace reactphysics3d {
|
namespace reactphysics3d {
|
||||||
|
|
||||||
// Structure Impulse
|
// Class SingleFrameAllocator
|
||||||
/**
|
/**
|
||||||
* Represents an impulse that we can apply to bodies in the contact or constraint solver.
|
* This class represent a memory allocator used to efficiently allocate
|
||||||
|
* memory on the heap that is used during a single frame.
|
||||||
*/
|
*/
|
||||||
struct Impulse {
|
class SingleFrameAllocator {
|
||||||
|
|
||||||
private:
|
private :
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------- Attributes -------------------- //
|
// -------------------- Attributes -------------------- //
|
||||||
|
|
||||||
/// Linear impulse applied to the first body
|
/// Total size (in bytes) of memory of the allocator
|
||||||
const Vector3 linearImpulseBody1;
|
size_t mTotalSizeBytes;
|
||||||
|
|
||||||
/// Angular impulse applied to the first body
|
/// Pointer to the beginning of the allocated memory block
|
||||||
const Vector3 angularImpulseBody1;
|
char* mMemoryBufferStart;
|
||||||
|
|
||||||
/// Linear impulse applied to the second body
|
/// Pointer to the next available memory location in the buffer
|
||||||
const Vector3 linearImpulseBody2;
|
int mCurrentOffset;
|
||||||
|
|
||||||
/// Angular impulse applied to the second body
|
public :
|
||||||
const Vector3 angularImpulseBody2;
|
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
Impulse(const Vector3& initLinearImpulseBody1, const Vector3& initAngularImpulseBody1,
|
SingleFrameAllocator(size_t totalSizeBytes);
|
||||||
const Vector3& initLinearImpulseBody2, const Vector3& initAngularImpulseBody2)
|
|
||||||
: linearImpulseBody1(initLinearImpulseBody1),
|
|
||||||
angularImpulseBody1(initAngularImpulseBody1),
|
|
||||||
linearImpulseBody2(initLinearImpulseBody2),
|
|
||||||
angularImpulseBody2(initAngularImpulseBody2) {
|
|
||||||
|
|
||||||
}
|
/// Destructor
|
||||||
|
~SingleFrameAllocator();
|
||||||
|
|
||||||
/// Copy-constructor
|
/// Allocate memory of a given size (in bytes)
|
||||||
Impulse(const Impulse& impulse)
|
void* allocate(size_t size);
|
||||||
: linearImpulseBody1(impulse.linearImpulseBody1),
|
|
||||||
angularImpulseBody1(impulse.angularImpulseBody1),
|
|
||||||
linearImpulseBody2(impulse.linearImpulseBody2),
|
|
||||||
angularImpulseBody2(impulse.angularImpulseBody2) {
|
|
||||||
|
|
||||||
}
|
/// Reset the marker of the current allocated memory
|
||||||
|
void reset();
|
||||||
|
|
||||||
/// Deleted assignment operator
|
|
||||||
Impulse& operator=(const Impulse& impulse) = delete;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user