diff --git a/examples/fallingcubes/Scene.cpp b/examples/fallingcubes/Scene.cpp index 360a0cb9..dc2082cc 100644 --- a/examples/fallingcubes/Scene.cpp +++ b/examples/fallingcubes/Scene.cpp @@ -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(); diff --git a/examples/joints/Scene.cpp b/examples/joints/Scene.cpp index 44211770..8e5e4e5c 100644 --- a/examples/joints/Scene.cpp +++ b/examples/joints/Scene.cpp @@ -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)); } diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index e18ac82a..757af86d 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -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); } diff --git a/src/body/RigidBody.h b/src/body/RigidBody.h index 4af18f37..6136f1dd 100644 --- a/src/body/RigidBody.h +++ b/src/body/RigidBody.h @@ -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 diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 27a8fc12..605aec54 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -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(); }