add "latency motion state interpolation", using previous frame/current, instead of current->next
See Demos/ForkLiftDemo for example (F7 to toggle, use single-frame stepping, press 'i' and 's' to see the effect)
This commit is contained in:
@@ -465,7 +465,7 @@ void ForkLiftDemo::renderme()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lineWidth=250;
|
int lineWidth=400;
|
||||||
int xStart = m_glutScreenWidth - lineWidth;
|
int xStart = m_glutScreenWidth - lineWidth;
|
||||||
int yStart = 20;
|
int yStart = 20;
|
||||||
|
|
||||||
@@ -476,39 +476,44 @@ void ForkLiftDemo::renderme()
|
|||||||
glColor3f(0, 0, 0);
|
glColor3f(0, 0, 0);
|
||||||
char buf[124];
|
char buf[124];
|
||||||
|
|
||||||
glRasterPos3f(xStart, yStart, 0);
|
|
||||||
sprintf(buf,"SHIFT+Cursor Left/Right - rotate lift");
|
sprintf(buf,"SHIFT+Cursor Left/Right - rotate lift");
|
||||||
GLDebugDrawString(xStart,20,buf);
|
GLDebugDrawString(xStart,20,buf);
|
||||||
yStart+=20;
|
yStart+=20;
|
||||||
glRasterPos3f(xStart, yStart, 0);
|
sprintf(buf,"SHIFT+Cursor UP/Down - fork up/down");
|
||||||
sprintf(buf,"SHIFT+Cursor UP/Down - move fork up/down");
|
|
||||||
yStart+=20;
|
yStart+=20;
|
||||||
GLDebugDrawString(xStart,yStart,buf);
|
GLDebugDrawString(xStart,yStart,buf);
|
||||||
|
|
||||||
yStart+=20;
|
if (m_useDefaultCamera)
|
||||||
glRasterPos3f(xStart, yStart, 0);
|
|
||||||
sprintf(buf,"F6 - toggle solver");
|
|
||||||
GLDebugDrawString(xStart,yStart,buf);
|
|
||||||
|
|
||||||
yStart+=20;
|
|
||||||
glRasterPos3f(xStart, yStart, 0);
|
|
||||||
if (m_dynamicsWorld->getConstraintSolver()->getSolverType()==BT_MLCP_SOLVER)
|
|
||||||
{
|
{
|
||||||
sprintf(buf,"Using direct MLCP solver");
|
sprintf(buf,"F5 - camera mode (free)");
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
sprintf(buf,"Using sequential impulse solver");
|
sprintf(buf,"F5 - camera mode (follow)");
|
||||||
}
|
}
|
||||||
GLDebugDrawString(xStart,yStart,buf);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glRasterPos3f(xStart, yStart, 0);
|
|
||||||
sprintf(buf,"F5 - toggle camera mode");
|
|
||||||
yStart+=20;
|
yStart+=20;
|
||||||
GLDebugDrawString(xStart,yStart,buf);
|
GLDebugDrawString(xStart,yStart,buf);
|
||||||
glRasterPos3f(xStart, yStart, 0);
|
|
||||||
sprintf(buf,"Click inside this window for keyboard focus");
|
yStart+=20;
|
||||||
|
if (m_dynamicsWorld->getConstraintSolver()->getSolverType()==BT_MLCP_SOLVER)
|
||||||
|
{
|
||||||
|
sprintf(buf,"F6 - solver (direct MLCP)");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
sprintf(buf,"F6 - solver (sequential impulse)");
|
||||||
|
}
|
||||||
|
GLDebugDrawString(xStart,yStart,buf);
|
||||||
|
btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*) m_dynamicsWorld;
|
||||||
|
if (world->getLatencyMotionStateInterpolation())
|
||||||
|
{
|
||||||
|
sprintf(buf,"F7 - motionstate interpolation (on)");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
sprintf(buf,"F7 - motionstate interpolation (off)");
|
||||||
|
}
|
||||||
|
yStart+=20;
|
||||||
|
GLDebugDrawString(xStart,yStart,buf);
|
||||||
|
|
||||||
|
sprintf(buf,"Click window for keyboard focus");
|
||||||
yStart+=20;
|
yStart+=20;
|
||||||
GLDebugDrawString(xStart,yStart,buf);
|
GLDebugDrawString(xStart,yStart,buf);
|
||||||
|
|
||||||
@@ -809,6 +814,13 @@ void ForkLiftDemo::specialKeyboard(int key, int x, int y)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GLUT_KEY_F7:
|
||||||
|
{
|
||||||
|
btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)m_dynamicsWorld;
|
||||||
|
world->setLatencyMotionStateInterpolation(!world->getLatencyMotionStateInterpolation());
|
||||||
|
printf("world latencyMotionStateInterpolation = %d\n", world->getLatencyMotionStateInterpolation());
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GLUT_KEY_F6:
|
case GLUT_KEY_F6:
|
||||||
{
|
{
|
||||||
//switch solver (needs demo restart)
|
//switch solver (needs demo restart)
|
||||||
|
|||||||
@@ -208,7 +208,9 @@ m_gravity(0,-10,0),
|
|||||||
m_localTime(0),
|
m_localTime(0),
|
||||||
m_synchronizeAllMotionStates(false),
|
m_synchronizeAllMotionStates(false),
|
||||||
m_applySpeculativeContactRestitution(false),
|
m_applySpeculativeContactRestitution(false),
|
||||||
m_profileTimings(0)
|
m_profileTimings(0),
|
||||||
|
m_fixedTimeStep(0),
|
||||||
|
m_latencyMotionStateInterpolation(true)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!m_constraintSolver)
|
if (!m_constraintSolver)
|
||||||
@@ -357,7 +359,9 @@ void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
|
|||||||
{
|
{
|
||||||
btTransform interpolatedTransform;
|
btTransform interpolatedTransform;
|
||||||
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
|
btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
|
||||||
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
|
body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),
|
||||||
|
(m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(),
|
||||||
|
interpolatedTransform);
|
||||||
body->getMotionState()->setWorldTransform(interpolatedTransform);
|
body->getMotionState()->setWorldTransform(interpolatedTransform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,6 +405,7 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
|
|||||||
if (maxSubSteps)
|
if (maxSubSteps)
|
||||||
{
|
{
|
||||||
//fixed timestep with interpolation
|
//fixed timestep with interpolation
|
||||||
|
m_fixedTimeStep = fixedTimeStep;
|
||||||
m_localTime += timeStep;
|
m_localTime += timeStep;
|
||||||
if (m_localTime >= fixedTimeStep)
|
if (m_localTime >= fixedTimeStep)
|
||||||
{
|
{
|
||||||
@@ -411,7 +416,8 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
|
|||||||
{
|
{
|
||||||
//variable timestep
|
//variable timestep
|
||||||
fixedTimeStep = timeStep;
|
fixedTimeStep = timeStep;
|
||||||
m_localTime = timeStep;
|
m_localTime = m_latencyMotionStateInterpolation ? 0 : timeStep;
|
||||||
|
m_fixedTimeStep = 0;
|
||||||
if (btFuzzyZero(timeStep))
|
if (btFuzzyZero(timeStep))
|
||||||
{
|
{
|
||||||
numSimulationSubSteps = 0;
|
numSimulationSubSteps = 0;
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ protected:
|
|||||||
|
|
||||||
//for variable timesteps
|
//for variable timesteps
|
||||||
btScalar m_localTime;
|
btScalar m_localTime;
|
||||||
|
btScalar m_fixedTimeStep;
|
||||||
//for variable timesteps
|
//for variable timesteps
|
||||||
|
|
||||||
bool m_ownsIslandManager;
|
bool m_ownsIslandManager;
|
||||||
@@ -64,6 +65,8 @@ protected:
|
|||||||
|
|
||||||
int m_profileTimings;
|
int m_profileTimings;
|
||||||
|
|
||||||
|
bool m_latencyMotionStateInterpolation;
|
||||||
|
|
||||||
btAlignedObjectArray<btPersistentManifold*> m_predictiveManifolds;
|
btAlignedObjectArray<btPersistentManifold*> m_predictiveManifolds;
|
||||||
|
|
||||||
virtual void predictUnconstraintMotion(btScalar timeStep);
|
virtual void predictUnconstraintMotion(btScalar timeStep);
|
||||||
@@ -216,6 +219,16 @@ public:
|
|||||||
///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo)
|
///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo)
|
||||||
virtual void serialize(btSerializer* serializer);
|
virtual void serialize(btSerializer* serializer);
|
||||||
|
|
||||||
|
///Interpolate motion state between previous and current transform, instead of current and next transform.
|
||||||
|
///This can relieve discontinuities in the rendering, due to penetrations
|
||||||
|
void setLatencyMotionStateInterpolation(bool latencyInterpolation )
|
||||||
|
{
|
||||||
|
m_latencyMotionStateInterpolation = latencyInterpolation;
|
||||||
|
}
|
||||||
|
bool getLatencyMotionStateInterpolation() const
|
||||||
|
{
|
||||||
|
return m_latencyMotionStateInterpolation;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
|
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
|
||||||
|
|||||||
Reference in New Issue
Block a user