From 1273f3a83c6a0eeb8bdaee9d7db72d1c3db8f902 Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Thu, 9 Sep 2021 00:05:45 +0200 Subject: [PATCH] Change the function used for the linear and angular damping of the rigid bodies --- CHANGELOG.md | 1 + src/body/RigidBody.cpp | 14 ++++++-------- src/systems/DynamicsSystem.cpp | 20 +++++++++++--------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0492cee7..37433d0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,7 @@ do not hesitate to take a look at the user manual. - The RigidBody::recomputeMassInformation() method has been renamed to RigidBody::updateMassPropertiesFromColliders. - Now, you need to manually call the RigidBody::updateMassPropertiesFromColliders() method after adding colliders to a rigid body to recompute its inertia tensor, center of mass and mass. There are other methods that you can use form that (see the user manual) - The RigidBody::applyForce() method has been renamed to RigidBody::applyForceAtWorldPosition() + - The linear and angular damping function of the rigid bodies has been changed - The rendering in the testbed application has been improved - Many of the data inside the library have been refactored for better caching and easier parallelization in the future - The old Logger class has been renamed to DefaultLogger diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 770d5cdc..adb88b6a 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -302,7 +302,7 @@ void RigidBody::applyWorldForceAtCenterOfMass(const Vector3& force) { // Return the linear velocity damping factor /** - * @return The linear damping factor of this body + * @return The linear damping factor of this body (in range [0; +inf]). Zero means no damping. */ decimal RigidBody::getLinearDamping() const { return mWorld.mRigidBodyComponents.getLinearDamping(mEntity); @@ -310,7 +310,7 @@ decimal RigidBody::getLinearDamping() const { // Return the angular velocity damping factor /** - * @return The angular damping factor of this body + * @return The angular damping factor of this body (in range [0; +inf]). Zero means no damping. */ decimal RigidBody::getAngularDamping() const { return mWorld.mRigidBodyComponents.getAngularDamping(mEntity); @@ -730,10 +730,9 @@ void RigidBody::enableGravity(bool isEnabled) { (isEnabled ? "true" : "false"), __FILE__, __LINE__); } -// Set the linear damping factor. This is the ratio of the linear velocity -// that the body will lose every at seconds of simulation. +// Set the linear damping factor. /** - * @param linearDamping The linear damping factor of this body + * @param linearDamping The linear damping factor of this body (in range [0; +inf]). Zero means no damping. */ void RigidBody::setLinearDamping(decimal linearDamping) { assert(linearDamping >= decimal(0.0)); @@ -752,10 +751,9 @@ void RigidBody::setLinearDamping(decimal linearDamping) { } } -// Set the angular damping factor. This is the ratio of the angular velocity -// that the body will lose at every seconds of simulation. +// Set the angular damping factor. /** - * @param angularDamping The angular damping factor of this body + * @param angularDamping The angular damping factor of this body (in range [0; +inf]). Zero means no damping. */ void RigidBody::setAngularDamping(decimal angularDamping) { assert(angularDamping >= decimal(0.0)); diff --git a/src/systems/DynamicsSystem.cpp b/src/systems/DynamicsSystem.cpp index d650ba8a..8cc20543 100644 --- a/src/systems/DynamicsSystem.cpp +++ b/src/systems/DynamicsSystem.cpp @@ -157,24 +157,26 @@ void DynamicsSystem::integrateRigidBodiesVelocities(decimal timeStep) { // Apply the velocity damping // Damping force : F_c = -c' * v (c=damping factor) - // Equation : m * dv/dt = -c' * v - // => dv/dt = -c * v (with c=c'/m) - // => dv/dt + c * v = 0 + // Differential Equation : m * dv/dt = -c' * v + // => dv/dt = -c * v (with c=c'/m) + // => dv/dt + c * v = 0 // Solution : v(t) = v0 * e^(-c * t) // => v(t + dt) = v0 * e^(-c(t + dt)) - // = v0 * e^(-ct) * e^(-c * dt) + // = v0 * e^(-c * t) * e^(-c * dt) // = v(t) * e^(-c * dt) // => v2 = v1 * e^(-c * dt) - // Using Taylor Serie for e^(-x) : e^x ~ 1 + x + x^2/2! + ... - // => e^(-x) ~ 1 - x - // => v2 = v1 * (1 - c * dt) + // Using Padé's approximation of the exponential function: + // Reference: https://mathworld.wolfram.com/PadeApproximant.html + // e^x ~ 1 / (1 - x) + // => e^(-c * dt) ~ 1 / (1 + c * dt) + // => v2 = v1 * 1 / (1 + c * dt) const uint32 nbRigidBodyComponents = mRigidBodyComponents.getNbEnabledComponents(); for (uint32 i=0; i < nbRigidBodyComponents; i++) { const decimal linDampingFactor = mRigidBodyComponents.mLinearDampings[i]; const decimal angDampingFactor = mRigidBodyComponents.mAngularDampings[i]; - const decimal linearDamping = std::pow(decimal(1.0) - linDampingFactor, timeStep); - const decimal angularDamping = std::pow(decimal(1.0) - angDampingFactor, timeStep); + const decimal linearDamping = decimal(1.0) / (decimal(1.0) + linDampingFactor * timeStep); + const decimal angularDamping = decimal(1.0) / (decimal(1.0) + angDampingFactor * timeStep); mRigidBodyComponents.mConstrainedLinearVelocities[i] = mRigidBodyComponents.mConstrainedLinearVelocities[i] * linearDamping; mRigidBodyComponents.mConstrainedAngularVelocities[i] = mRigidBodyComponents.mConstrainedAngularVelocities[i] * angularDamping; }