| |
| | ||||
![]() | ||||||
| | | |||||
|
Contact PhysicsOne of my first jobs in game physics was writing the flight models for the fighter sim EF2000. Back in the mid-90's, the physics challenges were well suited to the PC's of the time, and contact physics wasn't part of the picture. A plane can be modelled very accurately as a point mass in the sky, and the challenge for the physics programmer is to get the right lift coefficients, drag, and engine model. It's hard to believe now, but combat flight sims were one of the biggest PC genres in 1996. Microprose's F15 Strike Eagle kicked the whole thing off, Spectrum Holobyte responded with the classic Falcon. Meanwhile, British upstarts DID challenged the big boys with TFX, and then EF2000. And a shareware game called Doom was slowing up development time, taking over office networks at lunch and dinnertime.
Today, flying and shooting is a niche market; todays games are much more "close-in", and it's ground-based car simulations like World Rally Championship that occupy the hardcore sim niche that flight sims once did. We now have the challenge of making games feel solid, creating an illusion of tangible physical presence. With today's advanced graphics you really notice when the physics are lagging behind. My colleagues at Evolution Studios (many of them DID alumni), are looking to bring that all-important sense of solidity to new levels as they begin work on their next WRC title. In this article I will show how solid contact physics can
be implemented, and describe some of the problems the programmer will
encounter. The article should be of help to physics programmers, users
of 3rd party engines, and decision makers who need to evaluate competing
technologies.
A Solid Contact An example: A car has flipped over, and hits the ground, as in Figure 2. With a single contact point and no friction, we do the math to calculate its motion. This simplest case has been covered by other authors, so I'll be brief. The mass of the car is m, and it has a 3×3 moment of inertia matrix J. We're looking for the force that the ground exerts on the car at the contact. The vector equations for linear and angular motion are:
where x is the car's position, g is the gravitational acceleration; w is the car's angular velocity, and q is the vector from x to the contact point. We've called the mystery contact force f, and N is the surface normal, which is also the direction our force will act in. In Matrix form, this is our "equation of motion":
I've put subscripts to describe the exact number of rows and columns. A 6 by 1 matrix and a 6-vector are interchangeable. The "constraint equation" should complete the picture by specifying that objects should not occupy the same space. We require that the car's contact point remains exactly on the surface. Call this r1 in world space.
i.e. r2 is just the projection of r1 onto the surface. Our constraint is that r1 remains on the surface:
and that works out as just
So after a little re-arrangement, we have the constraint equation in matrix form:
The left-hand term is a "centripetal acceleration" - all points on a rotating solid accelerate towards the centre. Note that the 1 by 6 matrix in the middle is the exact transpose of the one in the equation of motion: this is true in general. I prefer to use a single vector for the acceleration degrees of freedom, so:
Now, although I've used
So we can define the scalars:
This is our main equation. The solution is just f =- l/G. It's good to define l so it appears negative in our expression, as l is the acceleration that would exist between the contact points without the contact force. The force f acts in the opposite direction. If you calculate f and it turns out to be negative, that means we're pulling, not pushing, and you should deactivate the contact. Now applying this acceleration over several timesteps will keep the car skidding along the surface in the correct manner provided the initial velocity between the contact points was zero. If it wasn't (e.g. when they first collided) we would need to apply an impulse to fix that. Without going into details, the answer is: i = - v/G, where v is the velocity of r1 relative to r2, normal to N and i is the impulse to be applied at the point of impact. You can apply this correction every frame to prevent drift, alternatively add a heuristic term to l which is proportional to v, so that the force will increase when the relative velocity is negative and decrease when it's positive. Do the same for the position so the contact points line up nicely. ________________________________________________________ |
|||||||||||||||||||||||||||||||||
|
|