Misc ODE questions

So I’ve been playing with ODE for the first time. I’ve written this sample in C++:

panda3d.org/manual/index.php/C … n_with_ODE

Except I’ve placed lots of spheres on (X=0, Y=0) on top of each other with a slight constant variation to a side so that they collapse eventually. When they come down the result is always slightly different, it’s not being deterministic even though the starting conditions are the same.

I expected a physical simulation to be deterministic, otherwise how am I supposed to sync it over the net with prediction? Is there any way to make it predictable?

Edit: For the record, it happens both in DirectX and OpenGL, so no double-precision FPU issue here.

Edit2: I found the issue, ODE has a random component for an optimization, and you get determinism by providing a fixed seed. I still don’t see how to do that in Panda, though.

Edit3: I found “OdeUtil::rand_set_seed();”. I set it to 0 just before every quickstep but that won’t do it either.

Renaming the thread cause I have more questions.

  1. About the post above, I figured that it’s impossible to make ODE deterministic, although I read everywhere (also heard it on the ODE lecture) that fixing the random number generation is supposed to help a lot, since the collisions will no longer use randomness to decide the joints (or something like that). I’m doing “OdeUtil::rand_set_seed(0);” before auto_collide() and before quick_step(), and it doesn’t seem to make it more stable at all. Am I missing something or is that it?

  2. What’s the best way to prevent spheres from rolling forever? Right now what I’m doing is, right after every quickstep I multiply every sphere by the opposite of the linear velocity by 50 or so. This works fine. However, since I’m doing this at every Panda step and not at every ODE step I have to think that this would contribute to randomness in the simulation somehow. I.e: If the simulation runs in 105 panda frames, I’m doing this multiplication 105 times, if I run it in 100 frames I’m doing it 100 times, so they will take longer to stop rolling. I could take into account the DT, I guess, but that still seems inaccurate. Isn’t there a way of running something at every ODE step? Like a world.set_quickstep_event()? Maybe I’m misunderstanding how things work here.