[ODE] world update - best practices?

Greg Mayer gmayer at hotheadgames.com
Wed May 23 15:00:07 MST 2007


Hello
I apologize if this issue has alreday been answered in the mailing lists 
- I did not have any success searching the mailing list for this topic.

I am evaluating various physics APIs and I'm trying to understand the 
best way to setup the main update loop in ODE.

It seems for any game application with more than a small amount of 
physics, dWorldQuickStep is the way to go.

The documentation heavily stresses that this function should be called 
with a constant-size time step.

Also, there is a function to set dWorldSetQuickStepNumIterations.

However, there are a few things I'm not clear on.


Presumably, if you have an app running in real-time, you will have some 
sort of update loop like:


UpdateWorld(float dtSeconds)
{

}

In which you do your collision detection and solving and stepping of the 
dynamic simulation.

One would hope that this update is being called very frequently and with 
a value that doesn't vary much. Ideally dtSeconds would be something 
like 0.016 for a game running at 60fps.

However, as anyone who's written a game knows, in practice the incoming 
value will vary slightly, and in bad scenarios (especially during 
development) it could be several times higher than the desired 0.016.

Therefore, it seems like good practice to wrap the dWorldQuickStep (and 
collision detection/solving, and external game force applications) call 
in a loop which breaks down the incoming dtSeconds into the 
constant-size time steps that ODE desires.

Where things get unclear though are the values that are close to, but 
not exactly, the desired constant-sized step.

Say for example you have an incoming value of 0.017.
What is the best practice in this case??

Does it _really_ matter to ODE if you pass in 0.016 one update, and 
0.017 the next? Does it explicitly cache the 0.016
and have some sort of optimization for the _exact_ same value being used 
repeatedly.
This would seem odd to me, but I ask because in the wiki-manual, in 
large red letters it says "Variable Step Size: Don't!"

So an alternative in this case would be to have a loop which starts 
taking 0.016 sized bites out of the incoming step and calls 
dWorldQuickStep. However, in this case that would mean you make on call 
with 0.016, and are left with a remainder of 0.001. Now what to do? 
Making a second call to the update with this value seems to deviate far 
more from the constant-step-size requirement than to have simply called 
dWorldQuickStep with 0.017.
Or one could have some sort of static "remaninder" variable in the 
update loop and wait until the value accumulates to at least 0.016, but 
then you are not strictly running in sync with the rendering and the 
rest of the game (though the difference may not be noticeable)

A further complication on this is the dWorldSetQuickStepNumIterations - 
this seems to set an internal counter for substeps so that you do not 
need to maintain such a loop manually in your WorldUpdate, but shouldn't 
this number of substeps be dependent on the size of the incoming dtSeconds?

So are you supposed to call dWorldSetQuickStepNumIterations every frame?

If someone could please explain these issues in ODE and suggest the best 
practice I would really appreciate it.
Thanks in advance
Greg




More information about the ODE mailing list