hey cjameshuff, thank you!
you actually did it,
you confirmed the basic premise from which most of the problems spawned
let me take back everything i said ..can i do that?
thanks again..
i'll soon post some practical examples of source code i have here
but let me tell you there are TWO main bugs and there are about 4-5 other "bugs" or common mistakes that go closely related to this - so, although very simple in nature, this may appear complicated just because it interconnects somewhat unrelated stuff...
[edit]
ok, so the code below is ACTUAL code from Open Source Bullet physics library... as much as i know so far, i can tell you the similar/same implementation exist in Intel Havok, NVIDIA PhysX, ODE, Newton...
i've also seen it in molecular dynamics software that is used by universities and large scientific institutions
actually, as far as i know - EVERYONE has some similar implementation that has 1, 2, 3.. or more of these bugs
in this particular case i will concentrate on 2nd bug - "MAX SUBSTEPS BUG"
this is original:
Code:
//-----------------------------------------------------------------------
int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
{
startProfiling(timeStep);
BT_PROFILE("stepSimulation");
int numSimulationSubSteps = 0;
if (maxSubSteps)
{
//fixed timestep with interpolation
m_localTime += timeStep;
if (m_localTime >= fixedTimeStep)
{
numSimulationSubSteps = int( m_localTime / fixedTimeStep);
m_localTime -= numSimulationSubSteps * fixedTimeStep;
}
} else
{
//variable timestep
fixedTimeStep = timeStep;
m_localTime = timeStep;
if (btFuzzyZero(timeStep))
{
numSimulationSubSteps = 0;
maxSubSteps = 0;
} else
{
numSimulationSubSteps = 1;
maxSubSteps = 1;
}
}
//process some debugging flags
if (getDebugDrawer())
{
gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
}
if (numSimulationSubSteps)
{
saveKinematicState(fixedTimeStep);
applyGravity();
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
for (int i=0;i<clampedSimulationSteps;i++)
{
internalSingleStepSimulation(fixedTimeStep);
synchronizeMotionStates();
}
}
synchronizeMotionStates();
clearForces();
#ifndef BT_NO_PROFILE
CProfileManager::Increment_Frame_Counter();
#endif //BT_NO_PROFILE
return numSimulationSubSteps;
}
//-----------------------------------------------------------------------
this completely replaces that thing from above, and fixes 1st & 2nd bug (in most cases):
Code:
//-----------------------------------------------------------------------
int btDiscreteDynamicsWorld::stepSimulation(
btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
{
m_localTime+= (timeStep < fixedTimeStep*2)? timeStep : fixedTimeStep*2;
saveKinematicState(fixedTimeStep); applyGravity(); maxSubSteps= 0;
while( m_localTime >= fixedTimeStep )
{
internalSingleStepSimulation(fixedTimeStep);
m_localTime-= fixedTimeStep; maxSubSteps++;
}
synchronizeMotionStates(); clearForces();
return maxSubSteps;
}
//-----------------------------------------------------------------------
this is actual, practical example implementation and you can try it in a matter of minutes: http://www.bulletphysics.com/Bullet/phpBB3/
+++symbolic explanation:
--- PROBLEM, "NUMERICAL INTEGRATION" ---
Code:
//-------------------------- *** ORIGINAL algo - capping the NUMBER
cnt= 0;
time= 10;
maxSteps= 5;
while(time > 0 && cnt < maxSteps)
{
step(); cnt++;
time--;
}
//--------------------------
Iterations, cnt= 5
"Time left", time= 5 <<<--- TIME REMAINDER
combination of bug1 & bug2 (integration + maxSubSteps)
"integration" wrongly trying to deal with this reminder of time caused by MAX sybSteps- in all of the implementations of this algorithm i've seen.. all physics libraries, ALL ..and some molecular dynamics software.. SAME!
this mostly has to do with smooth animation and FPS under loaded CPU with real-time applications, but if implemented in scientific software, scientist could, in effect, observe some "energy drift" not knowing there was a bug inside the software
this bug would heavily depend on the definition of "MAX ITERATIONS", "MAX NUM of SUBSTEPS" or similarly named variable and the size of time-step (fixed time-step, deltaTime)