• 14
• 12
• 9
• 10
• 13

# Common bug(s) in PhysX, Havok and Bullet SOLVED! - fixed timesteps/maxSubStep

This topic is 3473 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

##### Share on other sites
Definitely interesting post. What advantage does that have over the simplistic accumulator approach?

real accum = 0;game loop{    const real FREQ = 1.0 / 60.0, MIN_DT = 1.0 / 10.0; // 60 FPS integration, min. 10 FPS    for (accum += min(dt, MIN_DT); accum => FREQ; accum -= FREQ)        integratePhysics(FREQ);    render();}

##### Share on other sites
thats it.. how wonderful!

- so where were you hiding all this time?
- why didnt you tell us about it before?
- why all the 3 mayor Physics engines have implementation with *maxSubsteps*?
- and why is such a confusion around such a simple thing?

>>"What advantage does that have over the simplistic accumulator approach?"

im not sure, i just got around realizing all "this" a few days ago.. and it took a month of confusion trying to figure out what in the world is going on?!!

i basically constructed algorithm around so i can prove to people why is old algorithm with maxSubSteps bad and why we must not have any MAX number of anything ..and no one actually believed me!?

but you got it to the point really.. beautiful!

anyway, i feel you know more about all this then i do,
so what do you think how these two compare?

cheers

[Edited by - abaraba1 on September 8, 2008 5:42:45 AM]

##### Share on other sites
all right,
i'll do my inner dialog thing again,
but everyone is of course welcome to join any time ..whether to improve algorithm or to explain why PhysX, Havok and Bullet use maxSubSteps?

"simplistic accumulator"
lets turn few things around, make it bit more general and we get something like this, that can too effectively substitute Bullet's stepSimulation() function:

//------------------------------------------------------
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;
}
//------------------------------------------------------

again,
there is no need to change anything anywhere else

- maxSubSteps is completely disregarded and used as a counter
- this time you need to supply deltaTime, here called timeStep

main loop:
dt = timeSinceLastFrame();
stepSimulation(dt);
//stepSimulation(dt, 0, 1.0/60);

renderScene();

..solution B is simply about switching simulation frequency which might suit some cases better,
but the one above is probably more general and give desired visual effect considering the circumstances
//-------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------

- it basically replaces all this,
and i suppose there is similar equivalent of "maxSubSteps" implementation in Havok, PhysX, ODE, Newton.. ?

****** ORIGINAL STEPPING FUNCTION with "maxSubSteps" ******
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------

[Edited by - abaraba1 on September 12, 2008 7:12:14 PM]

##### Share on other sites
hi agi_shi,

could you tell us what Physics library do you use and could you point some reference that talk about this "simplistic accumulator"? ..i find that term did not really exist and does not return any search results, so id appreciate if you can point where did you find about it and if there is something i failed to notice about the whole thing?

anyway, as it seem you have been using this much longer than i managed to test it in the last couple of days - could you share some of your experience with stepping the simulation in fixedTimeSteps?

thank you

//---------------------------------
all kinds of feedback/comments appreciated.. anyone?

##### Share on other sites
hi grhodes_at_work,

- can you confirm that algorithms indeed work in practice as i described?
- would you agree that this is nicer design solution with much better visual results?

thank you

##### Share on other sites
..surely this is in everyones interest and someone could at least confirm am i right or wrong?

i can only test it as much, and i ask everyone for help,
hope thats not too much to ask.. after all, if it works then we all benefit, right?

thank you

##### Share on other sites
Quote:
 Original post by agi_shiDefinitely interesting post. What advantage does that have over the simplistic accumulator approach?real accum = 0;game loop{ const real FREQ = 1.0 / 60.0, MIN_DT = 1.0 / 10.0; // 60 FPS integration, min. 10 FPS for (accum += min(dt, MIN_DT); accum => FREQ; accum -= FREQ) integratePhysics(FREQ); render();}

If dt is based on real time there's the possibility that the time taken to simulate it causes an increase of dt to the next loop. On a bad system that may cause dt to keep increasing over several loops, and there'll be a long time lapse between visual updates, so it looks choppy.

It seems abaraba1's algorithm is intended to cause shorter/smoother time lapses, but slow motion instead (though I must say I'm not clear on all details in the code). So if I understood it'll look smoother and still be stable, is that right? (Question to abaraba1)

Quote:
 Original post by abaraba1- and why is such a confusion around such a simple thing?

Because time steps are used in both graphics and physics, and games require both, while their respective implementations are different. Some people wants graphical speed, other wants physical stability and realistic time, so discussions about time steps don't end with one answer, but several answers, and those cause the confusion over which to choose, I believe.

##### Share on other sites
thank you my friend,
you are my 1st normal human contact with the "world community" and i've been trying to discuss this for over a month during which i've been met with strong resistance and disapproval, i've been told nothing but how i "do not understand" and "not getting the point"... i've been banned from public forums merely for asking a questions and trying to figure this thing out ..then, after that - complete silence?!

thanks again!

>>"So if I understood it'll look smoother and still be stable, is that right? (Question to abaraba1)"

yes,
in essence - instead of to cap number of iterations you "cap" or "scale"(with the 1st algo) the accumulator/deltaTime which is in practice very similar thing only the later appear smoother because of the way how the FRAMES get *distributed* in the real time - but indeed it is a difficult thing to imagine..

Unfortunately, no one can be told what the 'temporal interpolation' is. You have to see it for yourself.

ahm.. so, regardless of everything,
i would like to recommend and suggest Bullet physics library if for nothing else but just to test this and practically SEE what is the difference. Bullet library will compile quickly and easily on Windows, Linux or Mac, it comes with lots of demos that compile and build automatically when you build the library. In a matter of minutes you could try to copy/paste algorithm from above, recompile and you will definitively notice the difference and see what is this all about by running the Bullet demos again.

http://www.bulletphysics.com/Bullet/wordpress/

thanks, i wish i knew about it sooner.. that is exactly what im talking about, so in case some people having trouble to read my 'funny english' i too recommend that thread as a good read..

cheers

[Edited by - abaraba1 on September 14, 2008 10:31:54 PM]

##### Share on other sites
The problem solved by abaraba1 is real, e.g., the problem solved here can and does sometimes occur in real-time simulations. Dim_Yimma_H described what is going on here rather elegantly, in a post near the (current) end of the thread (and that post really serves as a helpful introduction to the whole discussion). In fact, in really bad cases, the frame rate can increase to effectively infinity, e.g., the whole application can ultimately enter into a near infinite loop, since the number of simulation steps (at a fixed STEP integration time step) could increase forever. This is an indication of (among other things perhaps) a physics model that is poorly balanced for the target hardware platform.

It appears to me that the solution presented in the first post should indeed prevent the simulation loop from approaching infinite time due to an ever-increasing frame time, in the case that (simDT*N)+anmDT > the last frame time. I really have no time to go and test the solution. The simple heuristic that abaraba1 presents for artifically limiting the number of simulation steps (e.g., the "accum -= ..." line in the generic solution inside the simulation loop) may work well in practice, but I cannot say. I can say that it is only one of many heuristics, and others would likely work just as well.

So, I like that this thread discusses an issue that doesn't always come up when talking about fixed time step simulation in the game loop. It isn't the first time this has been discussed, but it's nice that it is a dedicated thread. The presentation was a bit long and rambling, and the purpose wasn't really made clear (the way I read it) until Dim_Yimma_H wrote a response.

One more thing. An opinion. For a real game design, which might be expected to run on a variety of platforms that may be configured differently and so produce different frame rates, it is unlikely to be acceptable that the physics slows down if the physics is part of gameplay. Any game that uses physics for gameplay, rather than just eye candy, will need to tune the physics model (fewer objects, simpler collision shapes, etc.) to guarantee on the target platforms that the actual simDT is small enough to not cause the frame rate to grow...allowing physics to run at full speed (even with a few multiple fixed-size sim steps per frame). This type of tuning, where each component of the simulation (render, sim, AI, network, art loading, ...) are all balanced to fit a frame time slice is common practice in modern game implementation, and will continue to be done. At least for commercial game development, solutions such as the one presented here can be very beneficial to support eye candy physics, but I don't immediately see it as a huge benefit for gameplay physics.

So, to summarize, I see a simple solution to a very real problem, one that could be added to any game loop with a minimal of effort. For commercial games the solution is likely beneficial only for eye candy physics rather than gameplay physics. Users should be aware of the claim of intellectual property usage rights requirements, though I do not believe the innovation is protectable due to the existence of prior art (my opinion only...I am not a lawyer).

(P.S. I apologize if some of this seems harsh. Just giving my honest, straightforward opinion and pointing out some things that any forum member who peruses this thread should be aware of, e.g., the legal stuff which really doesn't belong here.)

[Edited by - grhodes_at_work on September 16, 2008 2:35:46 PM]