fixes to allow applying impulses during interpolated timesteps (avoid visual discontinuities)

experimental jitter removal (doesn't work very well yet)
This commit is contained in:
ejcoumans
2006-10-30 19:37:08 +00:00
parent b14ccdaa57
commit d1a1b3d492
4 changed files with 42 additions and 7 deletions

View File

@@ -43,6 +43,11 @@ struct btCollisionObject
///m_interpolationWorldTransform is used for CCD and interpolation ///m_interpolationWorldTransform is used for CCD and interpolation
///it can be either previous or future (predicted) transform ///it can be either previous or future (predicted) transform
btTransform m_interpolationWorldTransform; 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 enum CollisionFlags
{ {

View File

@@ -150,7 +150,8 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
if (body->GetActivationState() != ISLAND_SLEEPING) if (body->GetActivationState() != ISLAND_SLEEPING)
{ {
btTransform interpolatedTransform; 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); body->getMotionState()->setWorldTransform(interpolatedTransform);
} }
} }

View File

@@ -45,7 +45,9 @@ btRigidBody::btRigidBody(float mass, btMotionState* motionState, btCollisionShap
motionState->getWorldTransform(m_worldTransform); motionState->getWorldTransform(m_worldTransform);
m_interpolationWorldTransform = m_worldTransform; m_interpolationWorldTransform = m_worldTransform;
m_interpolationLinearVelocity.setValue(0,0,0);
m_interpolationAngularVelocity.setValue(0,0,0);
//moved to btCollisionObject //moved to btCollisionObject
m_friction = friction; m_friction = friction;
m_restitution = restitution; m_restitution = restitution;
@@ -79,6 +81,8 @@ btRigidBody::btRigidBody( float mass,const btTransform& worldTransform,btCollisi
m_worldTransform = worldTransform; m_worldTransform = worldTransform;
m_interpolationWorldTransform = m_worldTransform; m_interpolationWorldTransform = m_worldTransform;
m_interpolationLinearVelocity.setValue(0,0,0);
m_interpolationAngularVelocity.setValue(0,0,0);
//moved to btCollisionObject //moved to btCollisionObject
m_friction = friction; 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)
void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) const
{ {
#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); btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform);
} }
@@ -114,7 +138,10 @@ void btRigidBody::saveKinematicState(btScalar timeStep)
if (getMotionState()) if (getMotionState())
getMotionState()->getWorldTransform(m_worldTransform); getMotionState()->getWorldTransform(m_worldTransform);
btVector3 linVel,angVel; btVector3 linVel,angVel;
btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity); btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity);
m_interpolationLinearVelocity = m_linearVelocity;
m_interpolationAngularVelocity = m_angularVelocity;
m_interpolationWorldTransform = m_worldTransform; m_interpolationWorldTransform = m_worldTransform;
//printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ()); //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) void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
{ {
m_interpolationWorldTransform = m_worldTransform; m_interpolationWorldTransform = m_worldTransform;
m_interpolationLinearVelocity = getLinearVelocity();
m_interpolationAngularVelocity = getAngularVelocity();
m_worldTransform = xform; m_worldTransform = xform;
updateInertiaTensor(); updateInertiaTensor();
} }

View File

@@ -79,7 +79,7 @@ public:
} }
/// continuous collision detection needs prediction /// continuous collision detection needs prediction
void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) const; void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
void saveKinematicState(btScalar step); void saveKinematicState(btScalar step);