Add linear/angular damping into DynamicsComponents

This commit is contained in:
Daniel Chappuis 2019-05-18 14:00:25 +02:00
parent aa4935f396
commit 29c8587c85
5 changed files with 90 additions and 33 deletions

View File

@ -42,7 +42,7 @@ using namespace reactphysics3d;
RigidBody::RigidBody(const Transform& transform, CollisionWorld& world, Entity entity, bodyindex id) RigidBody::RigidBody(const Transform& transform, CollisionWorld& world, Entity entity, bodyindex id)
: CollisionBody(world, entity, id), mArrayIndex(0), mInitMass(decimal(1.0)), : CollisionBody(world, entity, id), mArrayIndex(0), mInitMass(decimal(1.0)),
mCenterOfMassLocal(0, 0, 0), mCenterOfMassWorld(transform.getPosition()), mCenterOfMassLocal(0, 0, 0), mCenterOfMassWorld(transform.getPosition()),
mIsGravityEnabled(true), mMaterial(world.mConfig), mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)), mIsGravityEnabled(true), mMaterial(world.mConfig),
mJointsList(nullptr), mIsCenterOfMassSetByUser(false), mIsInertiaTensorSetByUser(false) { mJointsList(nullptr), mIsCenterOfMassSetByUser(false), mIsInertiaTensorSetByUser(false) {
// Compute the inverse mass // Compute the inverse mass
@ -195,6 +195,22 @@ inline void RigidBody::applyForceToCenterOfMass(const Vector3& force) {
mWorld.mDynamicsComponents.setExternalForce(mEntity, externalForce + force); mWorld.mDynamicsComponents.setExternalForce(mEntity, externalForce + force);
} }
// Return the linear velocity damping factor
/**
* @return The linear damping factor of this body
*/
decimal RigidBody::getLinearDamping() const {
return mWorld.mDynamicsComponents.getLinearDamping(mEntity);
}
// Return the angular velocity damping factor
/**
* @return The angular damping factor of this body
*/
decimal RigidBody::getAngularDamping() const {
return mWorld.mDynamicsComponents.getAngularDamping(mEntity);
}
// Set the inverse local inertia tensor of the body (in local-space coordinates) // Set the inverse local inertia tensor of the body (in local-space coordinates)
/// If the inverse inertia tensor is set with this method, it will not be computed /// If the inverse inertia tensor is set with this method, it will not be computed
/// using the collision shapes of the body. /// using the collision shapes of the body.
@ -427,10 +443,10 @@ void RigidBody::enableGravity(bool isEnabled) {
*/ */
void RigidBody::setLinearDamping(decimal linearDamping) { void RigidBody::setLinearDamping(decimal linearDamping) {
assert(linearDamping >= decimal(0.0)); assert(linearDamping >= decimal(0.0));
mLinearDamping = linearDamping; mWorld.mDynamicsComponents.setLinearDamping(mEntity, linearDamping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mID) + ": Set linearDamping=" + std::to_string(mLinearDamping)); "Body " + std::to_string(mID) + ": Set linearDamping=" + std::to_string(linearDamping));
} }
// Set the angular damping factor. This is the ratio of the angular velocity // Set the angular damping factor. This is the ratio of the angular velocity
@ -440,10 +456,10 @@ void RigidBody::setLinearDamping(decimal linearDamping) {
*/ */
void RigidBody::setAngularDamping(decimal angularDamping) { void RigidBody::setAngularDamping(decimal angularDamping) {
assert(angularDamping >= decimal(0.0)); assert(angularDamping >= decimal(0.0));
mAngularDamping = angularDamping; mWorld.mDynamicsComponents.setAngularDamping(mEntity, angularDamping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mID) + ": Set angularDamping=" + std::to_string(mAngularDamping)); "Body " + std::to_string(mID) + ": Set angularDamping=" + std::to_string(angularDamping));
} }
/// 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

View File

@ -89,12 +89,6 @@ class RigidBody : public CollisionBody {
/// Material properties of the rigid body /// Material properties of the rigid body
Material mMaterial; Material mMaterial;
/// Linear velocity damping factor
decimal mLinearDamping;
/// Angular velocity damping factor
decimal mAngularDamping;
/// First element of the linked list of joints involving this body /// First element of the linked list of joints involving this body
JointListElement* mJointsList; JointListElement* mJointsList;
@ -286,22 +280,6 @@ inline Material& RigidBody::getMaterial() {
return mMaterial; return mMaterial;
} }
// Return the linear velocity damping factor
/**
* @return The linear damping factor of this body
*/
inline decimal RigidBody::getLinearDamping() const {
return mLinearDamping;
}
// Return the angular velocity damping factor
/**
* @return The angular damping factor of this body
*/
inline decimal RigidBody::getAngularDamping() const {
return mAngularDamping;
}
// Return the first element of the linked list of joints involving this body // Return the first element of the linked list of joints involving this body
/** /**
* @return The first element of the linked-list of all the joints involving this body * @return The first element of the linked-list of all the joints involving this body

View File

@ -36,7 +36,8 @@ using namespace reactphysics3d;
// Constructor // Constructor
DynamicsComponents::DynamicsComponents(MemoryAllocator& allocator) DynamicsComponents::DynamicsComponents(MemoryAllocator& allocator)
:Components(allocator, sizeof(Entity) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + :Components(allocator, sizeof(Entity) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(bool)) { sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
sizeof(Vector3) + sizeof(bool)) {
// Allocate memory for the components data // Allocate memory for the components data
allocate(INIT_NB_ALLOCATED_COMPONENTS); allocate(INIT_NB_ALLOCATED_COMPONENTS);
@ -64,7 +65,9 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
Vector3* newSplitAngularVelocities = reinterpret_cast<Vector3*>(newSplitLinearVelocities + nbComponentsToAllocate); Vector3* newSplitAngularVelocities = reinterpret_cast<Vector3*>(newSplitLinearVelocities + nbComponentsToAllocate);
Vector3* newExternalForces = reinterpret_cast<Vector3*>(newSplitAngularVelocities + nbComponentsToAllocate); Vector3* newExternalForces = reinterpret_cast<Vector3*>(newSplitAngularVelocities + nbComponentsToAllocate);
Vector3* newExternalTorques = reinterpret_cast<Vector3*>(newExternalForces + nbComponentsToAllocate); Vector3* newExternalTorques = reinterpret_cast<Vector3*>(newExternalForces + nbComponentsToAllocate);
bool* newIsAlreadyInIsland = reinterpret_cast<bool*>(newExternalTorques + nbComponentsToAllocate); decimal* newLinearDampings = reinterpret_cast<decimal*>(newExternalTorques + nbComponentsToAllocate);
decimal* newAngularDampings = reinterpret_cast<decimal*>(newLinearDampings + nbComponentsToAllocate);
bool* newIsAlreadyInIsland = reinterpret_cast<bool*>(newAngularDampings + nbComponentsToAllocate);
// If there was already components before // If there was already components before
if (mNbComponents > 0) { if (mNbComponents > 0) {
@ -79,6 +82,8 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
memcpy(newSplitAngularVelocities, mSplitAngularVelocities, mNbComponents * sizeof(Vector3)); memcpy(newSplitAngularVelocities, mSplitAngularVelocities, mNbComponents * sizeof(Vector3));
memcpy(newExternalForces, mExternalForces, mNbComponents * sizeof(Vector3)); memcpy(newExternalForces, mExternalForces, mNbComponents * sizeof(Vector3));
memcpy(newExternalTorques, mExternalTorques, mNbComponents * sizeof(Vector3)); memcpy(newExternalTorques, mExternalTorques, mNbComponents * sizeof(Vector3));
memcpy(newLinearDampings, mLinearDampings, mNbComponents * sizeof(decimal));
memcpy(newAngularDampings, mAngularDampings, mNbComponents * sizeof(decimal));
memcpy(newIsAlreadyInIsland, mIsAlreadyInIsland, mNbComponents * sizeof(bool)); memcpy(newIsAlreadyInIsland, mIsAlreadyInIsland, mNbComponents * sizeof(bool));
// Deallocate previous memory // Deallocate previous memory
@ -95,6 +100,8 @@ void DynamicsComponents::allocate(uint32 nbComponentsToAllocate) {
mSplitAngularVelocities = newSplitAngularVelocities; mSplitAngularVelocities = newSplitAngularVelocities;
mExternalForces = newExternalForces; mExternalForces = newExternalForces;
mExternalTorques = newExternalTorques; mExternalTorques = newExternalTorques;
mLinearDampings = newLinearDampings;
mAngularDampings = newAngularDampings;
mIsAlreadyInIsland = newIsAlreadyInIsland; mIsAlreadyInIsland = newIsAlreadyInIsland;
mNbAllocatedComponents = nbComponentsToAllocate; mNbAllocatedComponents = nbComponentsToAllocate;
} }
@ -115,6 +122,8 @@ void DynamicsComponents::addComponent(Entity bodyEntity, bool isSleeping, const
new (mSplitAngularVelocities + index) Vector3(0, 0, 0); new (mSplitAngularVelocities + index) Vector3(0, 0, 0);
new (mExternalForces + index) Vector3(0, 0, 0); new (mExternalForces + index) Vector3(0, 0, 0);
new (mExternalTorques + index) Vector3(0, 0, 0); new (mExternalTorques + index) Vector3(0, 0, 0);
mLinearDampings[index] = decimal(0.0);
mAngularDampings[index] = decimal(0.0);
mIsAlreadyInIsland[index] = false; mIsAlreadyInIsland[index] = false;
// Map the entity with the new component lookup index // Map the entity with the new component lookup index
@ -142,6 +151,8 @@ void DynamicsComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex)
new (mSplitAngularVelocities + destIndex) Vector3(mSplitAngularVelocities[srcIndex]); new (mSplitAngularVelocities + destIndex) Vector3(mSplitAngularVelocities[srcIndex]);
new (mExternalForces + destIndex) Vector3(mExternalForces[srcIndex]); new (mExternalForces + destIndex) Vector3(mExternalForces[srcIndex]);
new (mExternalTorques + destIndex) Vector3(mExternalTorques[srcIndex]); new (mExternalTorques + destIndex) Vector3(mExternalTorques[srcIndex]);
mLinearDampings[destIndex] = mLinearDampings[srcIndex];
mAngularDampings[destIndex] = mAngularDampings[srcIndex];
mIsAlreadyInIsland[destIndex] = mIsAlreadyInIsland[srcIndex]; mIsAlreadyInIsland[destIndex] = mIsAlreadyInIsland[srcIndex];
// Destroy the source component // Destroy the source component
@ -171,6 +182,8 @@ void DynamicsComponents::swapComponents(uint32 index1, uint32 index2) {
Vector3 splitAngularVelocity1(mSplitAngularVelocities[index1]); Vector3 splitAngularVelocity1(mSplitAngularVelocities[index1]);
Vector3 externalForce1(mExternalForces[index1]); Vector3 externalForce1(mExternalForces[index1]);
Vector3 externalTorque1(mExternalTorques[index1]); Vector3 externalTorque1(mExternalTorques[index1]);
decimal linearDamping1 = mLinearDampings[index1];
decimal angularDamping1 = mAngularDampings[index1];
bool isAlreadyInIsland1 = mIsAlreadyInIsland[index1]; bool isAlreadyInIsland1 = mIsAlreadyInIsland[index1];
// Destroy component 1 // Destroy component 1
@ -188,6 +201,8 @@ void DynamicsComponents::swapComponents(uint32 index1, uint32 index2) {
new (mSplitAngularVelocities + index2) Vector3(splitAngularVelocity1); new (mSplitAngularVelocities + index2) Vector3(splitAngularVelocity1);
new (mExternalForces + index2) Vector3(externalForce1); new (mExternalForces + index2) Vector3(externalForce1);
new (mExternalTorques + index2) Vector3(externalTorque1); new (mExternalTorques + index2) Vector3(externalTorque1);
mLinearDampings[index2] = linearDamping1;
mAngularDampings[index2] = angularDamping1;
mIsAlreadyInIsland[index2] = isAlreadyInIsland1; mIsAlreadyInIsland[index2] = isAlreadyInIsland1;
// Update the entity to component index mapping // Update the entity to component index mapping

View File

@ -77,6 +77,12 @@ class DynamicsComponents : public Components {
/// Array with the external torque of each component /// Array with the external torque of each component
Vector3* mExternalTorques; Vector3* mExternalTorques;
/// Array with the linear damping factor of each component
decimal* mLinearDampings;
/// Array with the angular damping factor of each component
decimal* mAngularDampings;
/// Array with the boolean value to know if the body has already been added into an island /// Array with the boolean value to know if the body has already been added into an island
bool* mIsAlreadyInIsland; bool* mIsAlreadyInIsland;
@ -144,6 +150,12 @@ class DynamicsComponents : public Components {
/// Return the external torque of an entity /// Return the external torque of an entity
const Vector3& getExternalTorque(Entity bodyEntity) const; const Vector3& getExternalTorque(Entity bodyEntity) const;
/// Return the linear damping factor of an entity
decimal getLinearDamping(Entity bodyEntity) const;
/// Return the angular damping factor of an entity
decimal getAngularDamping(Entity bodyEntity) const;
/// Return true if the entity is already in an island /// Return true if the entity is already in an island
bool getIsAlreadyInIsland(Entity bodyEntity) const; bool getIsAlreadyInIsland(Entity bodyEntity) const;
@ -171,11 +183,15 @@ class DynamicsComponents : public Components {
/// Set the external force of an entity /// Set the external force of an entity
void setExternalTorque(Entity bodyEntity, const Vector3& externalTorque); void setExternalTorque(Entity bodyEntity, const Vector3& externalTorque);
/// Set the linear damping factor of an entity
void setLinearDamping(Entity bodyEntity, decimal linearDamping);
/// Set the angular damping factor of an entity
void setAngularDamping(Entity bodyEntity, decimal angularDamping);
/// Set the value to know if the entity is already in an island /// Set the value to know if the entity is already in an island
bool setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland); bool setIsAlreadyInIsland(Entity bodyEntity, bool isAlreadyInIsland);
// -------------------- Friendship -------------------- // // -------------------- Friendship -------------------- //
friend class BroadPhaseSystem; friend class BroadPhaseSystem;
@ -268,6 +284,22 @@ inline const Vector3& DynamicsComponents::getExternalTorque(Entity bodyEntity) c
return mExternalTorques[mMapEntityToComponentIndex[bodyEntity]]; return mExternalTorques[mMapEntityToComponentIndex[bodyEntity]];
} }
// Return the linear damping factor of an entity
inline decimal DynamicsComponents::getLinearDamping(Entity bodyEntity) const {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mLinearDampings[mMapEntityToComponentIndex[bodyEntity]];
}
// Return the angular damping factor of an entity
inline decimal DynamicsComponents::getAngularDamping(Entity bodyEntity) const {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
return mAngularDampings[mMapEntityToComponentIndex[bodyEntity]];
}
// Set the constrained linear velocity of an entity // Set the constrained linear velocity of an entity
inline void DynamicsComponents::setConstrainedLinearVelocity(Entity bodyEntity, const Vector3& constrainedLinearVelocity) { inline void DynamicsComponents::setConstrainedLinearVelocity(Entity bodyEntity, const Vector3& constrainedLinearVelocity) {
@ -316,6 +348,22 @@ inline void DynamicsComponents::setExternalTorque(Entity bodyEntity, const Vecto
mExternalTorques[mMapEntityToComponentIndex[bodyEntity]] = externalTorque; mExternalTorques[mMapEntityToComponentIndex[bodyEntity]] = externalTorque;
} }
// Set the linear damping factor of an entity
inline void DynamicsComponents::setLinearDamping(Entity bodyEntity, decimal linearDamping) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mLinearDampings[mMapEntityToComponentIndex[bodyEntity]] = linearDamping;
}
// Set the angular damping factor of an entity
inline void DynamicsComponents::setAngularDamping(Entity bodyEntity, decimal angularDamping) {
assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
mAngularDampings[mMapEntityToComponentIndex[bodyEntity]] = angularDamping;
}
// Return true if the entity is already in an island // Return true if the entity is already in an island
inline bool DynamicsComponents::getIsAlreadyInIsland(Entity bodyEntity) const { inline bool DynamicsComponents::getIsAlreadyInIsland(Entity bodyEntity) const {

View File

@ -340,8 +340,8 @@ void DynamicsWorld::integrateRigidBodiesVelocities() {
// Using Taylor Serie for e^(-x) : e^x ~ 1 + x + x^2/2! + ... // Using Taylor Serie for e^(-x) : e^x ~ 1 + x + x^2/2! + ...
// => e^(-x) ~ 1 - x // => e^(-x) ~ 1 - x
// => v2 = v1 * (1 - c * dt) // => v2 = v1 * (1 - c * dt)
decimal linDampingFactor = body->getLinearDamping(); decimal linDampingFactor = mDynamicsComponents.getLinearDamping(bodyEntity);
decimal angDampingFactor = body->getAngularDamping(); decimal angDampingFactor = mDynamicsComponents.getAngularDamping(bodyEntity);
decimal linearDamping = pow(decimal(1.0) - linDampingFactor, mTimeStep); decimal linearDamping = pow(decimal(1.0) - linDampingFactor, mTimeStep);
decimal angularDamping = pow(decimal(1.0) - angDampingFactor, mTimeStep); decimal angularDamping = pow(decimal(1.0) - angDampingFactor, mTimeStep);
mDynamicsComponents.setConstrainedLinearVelocity(bodyEntity, mDynamicsComponents.getConstrainedLinearVelocity(bodyEntity) * linearDamping); mDynamicsComponents.setConstrainedLinearVelocity(bodyEntity, mDynamicsComponents.getConstrainedLinearVelocity(bodyEntity) * linearDamping);