Implement linear and angular velocity damping
This commit is contained in:
parent
d2f7f6e28c
commit
2e6f571b98
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user