From d1a1b3d492758a9e801bf2e503b78f94294c7351 Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Mon, 30 Oct 2006 19:37:08 +0000 Subject: [PATCH] fixes to allow applying impulses during interpolated timesteps (avoid visual discontinuities) experimental jitter removal (doesn't work very well yet) --- .../CollisionDispatch/btCollisionObject.h | 5 +++ .../Dynamics/btDiscreteDynamicsWorld.cpp | 3 +- src/BulletDynamics/Dynamics/btRigidBody.cpp | 39 ++++++++++++++++--- src/BulletDynamics/Dynamics/btRigidBody.h | 2 +- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/src/BulletCollision/CollisionDispatch/btCollisionObject.h index f2ab42946..5df3de489 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionObject.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -43,6 +43,11 @@ struct btCollisionObject ///m_interpolationWorldTransform is used for CCD and interpolation ///it can be either previous or future (predicted) transform btTransform m_interpolationWorldTransform; + //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) + //without destroying the continuous interpolated motion (which uses this interpolation velocities) + btVector3 m_interpolationLinearVelocity; + btVector3 m_interpolationAngularVelocity; + enum CollisionFlags { diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index b1a47e7c4..f00c95f0f 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -150,7 +150,8 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates() if (body->GetActivationState() != ISLAND_SLEEPING) { btTransform interpolatedTransform; - btTransformUtil::integrateTransform(body->m_interpolationWorldTransform,body->getLinearVelocity(),body->getAngularVelocity(),m_localTime,interpolatedTransform); + btTransformUtil::integrateTransform(body->m_interpolationWorldTransform, + body->m_interpolationLinearVelocity,body->m_interpolationAngularVelocity,m_localTime,interpolatedTransform); body->getMotionState()->setWorldTransform(interpolatedTransform); } } diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp index baa176f96..a434f5e41 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -45,7 +45,9 @@ btRigidBody::btRigidBody(float mass, btMotionState* motionState, btCollisionShap motionState->getWorldTransform(m_worldTransform); m_interpolationWorldTransform = m_worldTransform; - + m_interpolationLinearVelocity.setValue(0,0,0); + m_interpolationAngularVelocity.setValue(0,0,0); + //moved to btCollisionObject m_friction = friction; m_restitution = restitution; @@ -79,6 +81,8 @@ btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisi m_worldTransform = worldTransform; m_interpolationWorldTransform = m_worldTransform; + m_interpolationLinearVelocity.setValue(0,0,0); + m_interpolationAngularVelocity.setValue(0,0,0); //moved to btCollisionObject m_friction = friction; @@ -96,12 +100,32 @@ btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisi } +#define EXPERIMENTAL_JITTER_REMOVAL 1 +#ifdef EXPERIMENTAL_JITTER_REMOVAL +//Bullet 2.20b has experimental code to reduce jitter just before objects fall asleep/deactivate +//doesn't work very well yet (value 0 only reduces performance a bit, no difference in functionality) +float gClippedAngvelThresholdSqr = 0.f; +float gClippedLinearThresholdSqr = 0.f; +#endif //EXPERIMENTAL_JITTER_REMOVAL - - - -void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) const +void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) { + +#ifdef EXPERIMENTAL_JITTER_REMOVAL + //clip to avoid jitter + if (m_angularVelocity.length2() < gClippedAngvelThresholdSqr) + { + m_angularVelocity.setValue(0,0,0); + printf("clipped!\n"); + } + + if (m_linearVelocity.length2() < gClippedLinearThresholdSqr) + { + m_linearVelocity.setValue(0,0,0); + printf("clipped!\n"); + } +#endif //EXPERIMENTAL_JITTER_REMOVAL + btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform); } @@ -114,7 +138,10 @@ void btRigidBody::saveKinematicState(btScalar timeStep) if (getMotionState()) getMotionState()->getWorldTransform(m_worldTransform); btVector3 linVel,angVel; + btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity); + m_interpolationLinearVelocity = m_linearVelocity; + m_interpolationAngularVelocity = m_angularVelocity; m_interpolationWorldTransform = m_worldTransform; //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ()); } @@ -257,6 +284,8 @@ btQuaternion btRigidBody::getOrientation() const void btRigidBody::setCenterOfMassTransform(const btTransform& xform) { m_interpolationWorldTransform = m_worldTransform; + m_interpolationLinearVelocity = getLinearVelocity(); + m_interpolationAngularVelocity = getAngularVelocity(); m_worldTransform = xform; updateInertiaTensor(); } diff --git a/src/BulletDynamics/Dynamics/btRigidBody.h b/src/BulletDynamics/Dynamics/btRigidBody.h index ffb2af2d2..fca3658cb 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.h +++ b/src/BulletDynamics/Dynamics/btRigidBody.h @@ -79,7 +79,7 @@ public: } /// continuous collision detection needs prediction - void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) const; + void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ; void saveKinematicState(btScalar step);