Implement linear and angular velocity damping

This commit is contained in:
Daniel Chappuis 2013-08-06 20:51:56 +02:00
parent d2f7f6e28c
commit 2e6f571b98
5 changed files with 89 additions and 24 deletions

View File

@ -45,7 +45,7 @@ Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
mViewer->setScenePosition(center, radiusScene);
// Gravity vector in the dynamics world
rp3d::Vector3 gravity(0, -9.81, 0);
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
// Time step for the physics simulation
rp3d::decimal timeStep = 1.0f / 60.0f;
@ -74,7 +74,7 @@ Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
// Change the material properties of the rigid body
rp3d::Material& material = cube->getRigidBody()->getMaterial();
material.setBounciness(0.4);
material.setBounciness(rp3d::decimal(0.4));
// Add the box the list of box in the scene
mBoxes.push_back(cube);
@ -89,7 +89,7 @@ Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
// Change the material properties of the floor rigid body
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
material.setBounciness(0.3);
material.setBounciness(rp3d::decimal(0.3));
// Start the simulation
startSimulation();

View File

@ -34,7 +34,6 @@ using namespace openglframework;
Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
mPhongShader("shaders/phong.vert",
"shaders/phong.frag"), mIsRunning(false) {
// Move the light 0
mLight0.translateWorld(Vector3(7, 15, 15));
@ -46,7 +45,7 @@ Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
mViewer->setScenePosition(center, radiusScene);
// Gravity vector in the dynamics world
rp3d::Vector3 gravity(0, -9.81, 0);
rp3d::Vector3 gravity(0, rp3d::decimal(-9.81), 0);
// Time step for the physics simulation
rp3d::decimal timeStep = 1.0f / 60.0f;
@ -129,7 +128,7 @@ void Scene::simulate() {
// Update the motor speed of the Slider Joint (to move up and down)
long double motorSpeed = 3 * cos(mDynamicsWorld->getPhysicsTime() * 1.5);
mSliderJoint->setMotorSpeed(motorSpeed);
mSliderJoint->setMotorSpeed(rp3d::decimal(motorSpeed));
// Take a simulation step
mDynamicsWorld->update();
@ -209,11 +208,14 @@ void Scene::createBallAndSocketJoints() {
if (i == 0) mBallAndSocketJointChainBoxes[i]->getRigidBody()->setIsMotionEnabled(false);
else mBallAndSocketJointChainBoxes[i]->getRigidBody()->setIsMotionEnabled(true);
// Add some angular velocity damping
mBallAndSocketJointChainBoxes[i]->getRigidBody()->setAngularDamping(rp3d::decimal(0.2));
// Change the material properties of the rigid body
rp3d::Material& material = mBallAndSocketJointChainBoxes[i]->getRigidBody()->getMaterial();
material.setBounciness(0.4);
material.setBounciness(rp3d::decimal(0.4));
positionBox.y -= boxDimension.y + 0.5;
positionBox.y -= boxDimension.y + 0.5f;
}
// --------------- Create the joints --------------- //
@ -240,7 +242,7 @@ void Scene::createSliderJoint() {
// --------------- Create the first box --------------- //
// Position of the box
openglframework::Vector3 positionBox1(0, 2.1, 0);
openglframework::Vector3 positionBox1(0, 2.1f, 0);
// Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 box1Dimension(2, 4, 2);
@ -251,15 +253,15 @@ void Scene::createSliderJoint() {
// Change the material properties of the rigid body
rp3d::Material& material1 = mSliderJointBottomBox->getRigidBody()->getMaterial();
material1.setBounciness(0.4);
material1.setBounciness(0.4f);
// --------------- Create the second box --------------- //
// Position of the box
openglframework::Vector3 positionBox2(0, 4.2, 0);
openglframework::Vector3 positionBox2(0, 4.2f, 0);
// Create a box and a corresponding rigid in the dynamics world
openglframework::Vector3 box2Dimension(1.5, 4, 1.5);
openglframework::Vector3 box2Dimension(1.5f, 4, 1.5f);
mSliderJointTopBox = new Box(box2Dimension, positionBox2 , CUBE_MASS, mDynamicsWorld);
// The second box is allowed to move
@ -267,7 +269,7 @@ void Scene::createSliderJoint() {
// Change the material properties of the rigid body
rp3d::Material& material2 = mSliderJointTopBox->getRigidBody()->getMaterial();
material2.setBounciness(0.4);
material2.setBounciness(0.4f);
// --------------- Create the joint --------------- //
@ -276,10 +278,10 @@ void Scene::createSliderJoint() {
rp3d::RigidBody* body2 = mSliderJointTopBox->getRigidBody();
const rp3d::Vector3& body1Position = body1->getTransform().getPosition();
const rp3d::Vector3& body2Position = body2->getTransform().getPosition();
const rp3d::Vector3 anchorPointWorldSpace = 0.5 * (body2Position + body1Position);
const rp3d::Vector3 anchorPointWorldSpace = rp3d::decimal(0.5) * (body2Position + body1Position);
const rp3d::Vector3 sliderAxisWorldSpace = (body2Position - body1Position);
rp3d::SliderJointInfo jointInfo(body1, body2, anchorPointWorldSpace, sliderAxisWorldSpace,
-1.7, 1.7);
rp3d::decimal(-1.7), rp3d::decimal(1.7));
jointInfo.isMotorEnabled = true;
jointInfo.motorSpeed = 0.0;
jointInfo.maxMotorForce = 10000.0;
@ -306,7 +308,7 @@ void Scene::createPropellerHingeJoint() {
// Change the material properties of the rigid body
rp3d::Material& material = mPropellerBox->getRigidBody()->getMaterial();
material.setBounciness(0.4);
material.setBounciness(rp3d::decimal(0.4));
// --------------- Create the Hinge joint --------------- //
@ -319,8 +321,8 @@ void Scene::createPropellerHingeJoint() {
const rp3d::Vector3 hingeAxisWorldSpace(0, 1, 0);
rp3d::HingeJointInfo jointInfo(body1, body2, anchorPointWorldSpace, hingeAxisWorldSpace);
jointInfo.isMotorEnabled = true;
jointInfo.motorSpeed = -0.5 * PI;
jointInfo.maxMotorTorque = 60.0;
jointInfo.motorSpeed = - rp3d::decimal(0.5) * PI;
jointInfo.maxMotorTorque = rp3d::decimal(60.0);
jointInfo.isCollisionEnabled = false;
// Create the joint in the dynamics world
@ -344,7 +346,7 @@ void Scene::createFixedJoints() {
// Change the material properties of the rigid body
rp3d::Material& material1 = mFixedJointBox1->getRigidBody()->getMaterial();
material1.setBounciness(0.4);
material1.setBounciness(rp3d::decimal(0.4));
// --------------- Create the second box --------------- //
@ -359,7 +361,7 @@ void Scene::createFixedJoints() {
// Change the material properties of the rigid body
rp3d::Material& material2 = mFixedJointBox2->getRigidBody()->getMaterial();
material2.setBounciness(0.4);
material2.setBounciness(rp3d::decimal(0.4));
// --------------- Create the first fixed joint --------------- //
@ -398,5 +400,5 @@ void Scene::createFloor() {
// Change the material properties of the rigid body
rp3d::Material& material = mFloor->getRigidBody()->getMaterial();
material.setBounciness(0.3);
material.setBounciness(rp3d::decimal(0.3));
}

View File

@ -30,12 +30,13 @@
// We want to use the ReactPhysics3D namespace
using namespace reactphysics3d;
// Constructor
RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal,
// Constructor
RigidBody::RigidBody(const Transform& transform, decimal mass, const Matrix3x3& inertiaTensorLocal,
CollisionShape *collisionShape, bodyindex id)
: CollisionBody(transform, collisionShape, id), mInertiaTensorLocal(inertiaTensorLocal),
mMass(mass), mInertiaTensorLocalInverse(inertiaTensorLocal.getInverse()),
mMassInverse(decimal(1.0) / mass), mIsGravityEnabled(true) {
mMassInverse(decimal(1.0) / mass), mIsGravityEnabled(true),
mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)) {
assert(collisionShape);
}

View File

@ -80,6 +80,12 @@ class RigidBody : public CollisionBody {
/// Material properties of the rigid body
Material mMaterial;
/// Linear velocity damping factor
decimal mLinearDamping;
/// Angular velocity damping factor
decimal mAngularDamping;
// -------------------- Methods -------------------- //
/// Private copy-constructor
@ -161,6 +167,18 @@ class RigidBody : public CollisionBody {
/// Set a new material for this rigid body
void setMaterial(const Material& material);
/// Return the linear velocity damping factor
decimal getLinearDamping() const;
/// Set the linear damping factor
void setLinearDamping(decimal linearDamping);
/// Return the angular velocity damping factor
decimal getAngularDamping() const;
/// Set the angular damping factor
void setAngularDamping(decimal angularDamping);
};
// Method that return the mass of the body
@ -288,6 +306,28 @@ inline void RigidBody::setMaterial(const Material& material) {
mMaterial = material;
}
// Return the linear velocity damping factor
inline decimal RigidBody::getLinearDamping() const {
return mLinearDamping;
}
// Set the linear damping factor
inline void RigidBody::setLinearDamping(decimal linearDamping) {
assert(linearDamping >= decimal(0.0));
mLinearDamping = linearDamping;
}
// Return the angular velocity damping factor
inline decimal RigidBody::getAngularDamping() const {
return mAngularDamping;
}
// Set the angular damping factor
inline void RigidBody::setAngularDamping(decimal angularDamping) {
assert(angularDamping >= decimal(0.0));
mAngularDamping = angularDamping;
}
}
#endif

View File

@ -258,6 +258,28 @@ void DynamicsWorld::integrateRigidBodiesVelocities() {
rigidBody->getMass() * mGravity;
}
// 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
// Solution : v(t) = v0 * e^(-c * t)
// => v(t + dt) = v0 * e^(-c(t + dt))
// = v0 * e^(-ct) * 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)
decimal linDampingFactor = rigidBody->getLinearDamping();
decimal angDampingFactor = rigidBody->getAngularDamping();
decimal linearDamping = clamp(decimal(1.0) - dt * linDampingFactor,
decimal(0.0), decimal(1.0));
decimal angularDamping = clamp(decimal(1.0) - dt * angDampingFactor,
decimal(0.0), decimal(1.0));
mConstrainedLinearVelocities[i] *= clamp(linearDamping, decimal(0.0), decimal(1.0));
mConstrainedAngularVelocities[i] *= clamp(angularDamping, decimal(0.0), decimal(1.0));
// Update the old Transform of the body
rigidBody->updateOldTransform();
}