Doing gravity right
Now you may be thinking: "baah, I know how to do gravity.." but there's a big flaw in the commonly used Euler's method to handle the gravity (or other forces). Even all the Quake games have this problem. Then what is it? If you have more frames per second in Quake, your player will run faster and jump higher. There are some places in Quake where you can't jump high enough if you don't have enough frames per second. Sounds odd, right?
Most of the programmers do the gravity something like this:
velocity = velocity + gravity*delta_time position = position + velocity*delta_time
The algorithm above is ok but when delta_time changes or delta_time is too high, it causes many unwanted problems. Gravity adding should actually be done like this:
velocity = velocity + gravity*delta_time/2 position = position + velocity*delta_time velocity = velocity + gravity*delta_time/2
That's it.. but you need proof, right?
Picture on the left shows that you should integrate the blue area to get the correct position values after deltatime (you should know from physics that velocity integrated by time gives you position).
But what the bad algorithm actually does is shown in the picture on right. It integrates the velocity incorrectly and causes many troubles.
|Real integration||Wrong algorithm|
Here is how the new algorithm handles the integration:
Now the blue area is exactly the same as in the picture on top left. You first add half of the acceleration to velocity, then add velocity to the position and then add half of the acceleration to velocity again.
Results in practice
Here is a "jumping" parabola with different delta times, using the bad algorithm. The picture on the right corresponds almost exactly to Quake. As you can see, you can't jump in Quake if you have less than 3 fps.
As delta time (dt) gets higher, the jumping curve gets lower.
Now here are results with the new algorithm:
Quite nice, don't you think? Accelerating physics are no longer approximation!
Remember that you should do all the accelerating forces like described above, not just gravity.
Integrating to the same results
The proving of the formula can also be done using integration (of course, because you are calculating areas..)
After integrating you'll get this formula:
pos = pos + 1/2*acc*dt^2 + vel*dt vel = vel + acc*dt
Note that pos = position, vel = velocity, acc = acceleration and dt = delta_time
And optimizing that formula leads to this:
temp = acc*dt pos = pos + dt*(vel + temp/2) vel = vel + temp
This equals to the second formula given at the beginning of this document.