Monday, July 23, 2007

Rigid body dynamics, part 5

Not much to report this week as I haven't done any coding. I've continued to think about friction.

My current model is to integrate gravity's effects, then iteratively fix up interpenetrations, adjusting position and/or velocity if objects are colliding. Because the position fixup moves objects apart along their minimum separating axis this can cause unintended sliding:



I remember seeing this in a prerelease version of the original Quake (I don't remember if it made it into the shipping version). If you stood on a ramp you would slowly slide down it.

I don't mind if, when an object first collides, the interpenetration fixup moves it sideways from where it ought to be. People don't notice a small one-time offset like that. It's when an object is supposed to be resting on a surface but doesn't stay put that the problem is very noticeable.

Friction is conceptually a force, which means it is applied over time. My model up to now has been that only gravity is applied over time; collisions are resolved instantaneously. This means that objects are never pressed against each other for a duration of time, so they wouldn't ever have friction. Obviously it ought to be possible to convert the concept of friction into impulses that are applied instantaneously each frame, but I haven't quite seen clearly how to do that in a way that interacts correctly with the collisions.

A bit more Googling turned up some promising leads:

Continuous Physics seems to be a place where the cool kids of game physics hang out. One of them is Erin Catto who has developed a library called Box2D that does almost exactly what I've been developing these past few weeks. Erin has presented at the last few Game Developer Conferences as well. I'm looking over these materials now. Thank you, Erin!

One of the ideas I got from Erin's code is to integrate velocity, then apply fixups to velocity, before integrating position. This should enable me to get around the creeping problem; nonpenetration constraints would cancel the acceleration into the ground, and friction would cancel the tangential acceleration.

Another library I've started looking at is JigLib, by Danny Chapman.

Both of these libraries use a technique called split impulses to correct interpenetration, which seems at first blush very similar to my approach of fixing up positions directly. They generate per-frame fixup velocities which are not added to the object's overall momentum; so far as I can see this ought to do the same thing as just fixing up the positions directly. I'll continue to dig into it, though. The Box2D library, in particular, is simple enough to be readily digested.

No comments: