PDA

View Full Version : Real-time Physics



cragwolf
06-04-2006, 02:04 AM
How do game developers handle the situation of a simulation taking longer to calculate than it does to evolve in real-time? For example with a game loop like this...


while Runing do begin
HandleEvents;
DoPhysics(elapsedtime);
Render;
end;

...between one DoPhysics loop and the next, 50ms may have elapsed. So DoPhysics must simulate 50ms worth of physics. But what if the calculation of these 50ms of physics takes 100ms? Then the next DoPhysics loop must calculate at least 100ms worth of physics, which might take 200ms to calculate. And so on, until the simulation crawls to a virtual halt!

Does this problem really exist or am I imagining it? If it's real, how does one avoid a situation like this?

technomage
06-04-2006, 06:43 AM
I don't know how professional game companies do it. One option would be to put you physics on a separate thread, but that brings up all sorts of sync issues with your event handling and rendering.

Other options are different physics for objects in view (i.e more detailed) and simple physcs for those out of view. Take collision detection, do you really need pixel perfect or full 3d mesh collisions on objects not in view? or can you get away with only doing details collisions in screen where it matters.

Anyone else got any thoughts?

Huehnerschaender
06-04-2006, 08:23 AM
I don't think that a calculation of 100ms should need the double of time of a calculation of 50s, because the time component is simply passed to physical calculations which don't iterate through time, but use the elapsed time as a constant for movement. In special cases where objects move very fast and could pass through other objects in one step maybe rays are used to calc the movement and collision.

So every calculation in your example should need nearly the same time to process no matter if 10 ms or 10 seconds elapsed.

I think thats the way it is done in games, don't know how it is done in physical simulations.

Clootie
06-04-2006, 09:19 PM
It's actually not a good idea to calculate physics with variable steps (i.e. each physics calculation takes time to simulate as a paramater). This is bad for various steps: debugging hell, network simulation, demo record playback, etc.

Best thing is to use fixed time tick to simulate physics. So once a while you do simulation for your 50ms and then render world using interpolation between previous positions and newly calculated (or use some kind of predicting future object position). But render main (user controllable item) using positions recalculated for each frame from user input. This way world simulation will be less apprearing to be lagging.

And this way you'll solve your problem: if time passed from last render exceeds your simulation step (50ms) then just assume that exactly 50ms passed and calculate next state. it will not make your game playable if PC is not able to constantly simulate world in smaller time periods than real time, but user will get predictable behaviour (if these slowdowns are just happen from time to time) AND you get predictable behaviour while debugging your code using GUI debugger (pausing, stepping throught code etc.)

aidave
07-04-2006, 05:58 AM
yeah i dont think your imagined problem really happens.

i've never encountered it with aiplanet or with ODE or Newton.

the physics do not accumulate recursively..
each time step can get longer tho, thats for sure.

User137
07-04-2006, 01:22 PM
Actually it may not go any slower. The fact that mostly effect on physics is the amount of stuff happening, not the speed they move.

JSoftware
07-04-2006, 03:28 PM
I think you have misunderstood the physics calculations. the procedure shouldn't take longer to calculate if the step is bigger but that is ofcourse not the case if you are using loops to simulate physics

cragwolf
09-04-2006, 07:16 AM
Thanks for the replies, I think Clootie's explanation made the most sense to me. I have come to see the light on fixed time-steps. The idea, as I understand it, is to decouple one's physics from the display frame-rate. My loop is currently looking something like the following:

var
bRunning: Boolean = False;
dt: Cardinal = 10;
currTime: Cardinal = 0;
accumTime:Cardinal = 0;
newTime: Cardinal;
deltaTime: Cardinal;
prevState: TState;
currState: TState;
rendState: TState;
alpha: Single;
begin
// other stuff might go here
while bRunning do begin
newTime := SDL_GetTicks;
deltaTime := newTime - currTime;
currTime := newTime;

accTime += deltaTime;

while (accTime > dt) do begin
prevState := currState;
DoPhysics(currState, t, dt);
t += dt;
accTime -= dt;
end;

alpha := accTime / dt;

rendState := currState*alpha + prevState*(1-alpha);

DoRender(rendState);
end;
end;

The above code I essentially stole from this article (http://www.gaffer.org/articles/Timestep.html).

So the question I asked in the first post translates to: what if DoPhysics takes 2*dt milliseconds to run? Then, the first time around you do two physics loops. This will take 2*2*dt = 4*dt milliseconds. So the next time around you have to do 4 physics loops, which will take 8*dt milliseconds to run. And the next time around you will have to do 8 physics loops, which will take 16*dt milliseconds to run, and so on. Your display frame rate will go through the roof!

Two solutions present themselves to me. One is to limit the size of accTime to, say, 200 milliseconds or so. But then your simulation is no longer real-time; the simulation will run slower than reality. The other solution, the one I prefer, is to increase your time-step by a factor of greater than 2 (rendering will take a little bit of time, too), so let's say a factor of 3. Now, as long as the rendering is really quick, you're guaranteed to avoid the runaway behaviour.

The trick, then, is to optimise your DoPhysics procedure as much as possible, and then choose an appropriate dt: not too small that DoPhysics doesn't have enough time to finish within dt, and not too large that the subsequently poor resolution of your physics leads to obviously unphysical behaviour.

Well, that's the theory. Now to actually try coding it and displaying something on the screen!

aidave
09-04-2006, 07:34 AM
sounds way too complicated !

my advice is to
just do something simple to start.
especially if you havent gotten anything on the screen yet.

the problem with such a loop, depending on your physics engine,
is that the call to the physics engine isnt going to improve by passing smaller values. it will still take the same time to calculate (roughly, same number of obj colliding), the items just wont be going as far.

i could be wrong but thats my experience

Clootie
10-04-2006, 08:41 PM
Yes, seems you really over-engineering here. If your phys calculations start to take more time than it was plannded by you - then anyway gameplay will be sloppy. So just calculate one step at time and if after calculations check current time. If it's required to calculate phys one more time - just skip calculation and reset your timer, so next calculation will happen after another fixed period of time - this will make your game stable. And this is the best thing required in that kind of situation: DONT CRASH!