on Jun 10, 2012
When I do the “ask me a question” things, I generally stick to questions I can actually answer. But in this case I think what the curious person is looking for is a rough overview, not a detailed white paper. This being the case, I think I can help. As always, remember that my understanding is probably a few years out of date.
Reader Kronski asks:
I don’t know if you’ve seen this video.
It’s demonstration of a physics engine where a truck gets banged up all to hell. My question is, how does a physics engine like this work?
So you don’t have to head over to YouTube, the video in question is this one:
The basics of a physics engine are easy to grasp. The finer details are beyond me. Let’s start with the essentials. You can see the ultimate demonstration of basic physics at work in the bridge builder game.
The idea is pretty simple: It’s a simulation of points in space. You have a bunch of points and you subject them to gravity and collision. The trick is that you link the points together. Let me swipe a screen shot from the bridge game:
The goal is to subject the points to gravity and collision, with the requirement that all of the lines between them remain the same length. Now, you can’t insist that all lines remain exactly the same length. Simple rounding errors and limits on precision make that impossible, or at least a pain in the ass to code. If you try to make the links 100% rigid then you’ll end up with all sorts of nonsense behavior, division by zero problems, or other unwanted side-effects.
So what you do is you make each line have a desired length. The more it deviates from that length, the harder it will push to return to the desired size. Internally, this is a multi-pass excercise:
- Gravity and momentum. Look at each point, see if it’s moving and how fast, and have it try to maintain that speed, as objects in motion tend to do. Also inflict gravity on it. Again, we’re just doing this to points and ignoring the lines for now.
- Do collision. Keep the points from going through things. If a falling point hits the ground, make it stop.
- Pass over the simulation on a per-line basis. Have each line try to correct its length. If it’s too long, it will pull its two endpoints together, and if it’s being crushed or compressed it will try to push them apart. Don’t apply these changes right away. Save them until you’re done processing all lines.
- Take all of the “corrections” generated in the previous step and apply it to your points. For example check out the top-most point of the bridge in the screenshot above. Gravity will pull it down a bit, moving it closer to the three points to which it’s joined. Those three lines will push back, holding the top-most point up but also pushing down on the lower points, thus letting the “weight” of the upper point rest on them.
- Now, in a perfect world you’d be done at this point. But here we have the thorny problem that maybe some of those corrections we just applied have created a need for more collision detection. Points may have been shoved into the ground, for example. We can do another round of collision if we want, which will lift those points out of the ground. But doing this will create a need for us to go back and process all the lines again, which might push points into the ground, which…
We could be here all freakin’ day, is what I’m saying. How you handle this very much depends on what’s important to your simulation and how much you value the speed vs. accuracy tradeoff. Right here is generally where things seem to get kind of glitchy. If you’ve ever stepped out of your car in Saints Row The Third and saw your tire was half-buried in the street and was jittering up and down in an attempt to dislodge itself, then you were probably seeing a problem with this part of the simulation.
Ignoring this thorny issue, we now have everything required to make our own bridge builder game. That’s it. Everything else: Sagging, balance, center of gravity, weight distribution… it’s all emergent. Following these simple rules will make it possible to build a lopsided tower and have it fall over as expected. It’s actually kind of beautiful how such simplicity can create such a robust set of behaviors.
However, this presents the programmer with a bit of a trap. They see these simple rules and how amazing the results are, and they assume that just a few more rules can yield even more amazing results. (And to be fair, in a AAA game you would need a bit more than this. In the system I’ve outlined, all points weigh the same, which can lead to undesirable outcomes. Also, collision is a bit more complicated in a real game environment, but I’m trying to keep this simple.) And so the hapless coder blunders into the dangerous waters of oversimulation.
At any rate, everything we’re doing can be applied to 3D just as easily as 2D. So now we have the makings of a physics engine. This is probably not the only approach, but it’s the one I’m familiar with.
How much “play” your lines have in them will determine how our physics object behaves. If the lines try to stay as close to their desired length as possible, then you’ll have a very rigid object. If the lines don’t start pushing back until they’re far from the original size, then your object will be very rubbery. If lines resist stretching but ignore compression, then you’ll have something that behaves like it’s made out of rope. If you have lines that are rigid until they undergo enough compressing force, after which they will compress and then treat their new, smaller size as the new “proper” size, then you will have an object that can be crumpled up like a soda can.
For making objects move in a game, an artist usually creates the visible model. This is then joined to our scaffolding of physics points and lines. Similar to how a 3D character model will be animated by a skeleton, our model will move according to what the physics object is doing.
As always, there’s a trade-off at work here. You can make a simple eight-cornered cube and make that the physics model for the entire pickup truck. The result will not be particularly convincing. If you want a good simulation then you’ll make the body of the physics model out of many, many points. You’ll use very rigid links for most of the body, and more “rubbery” ones for the link between the car body and the axle. (Or the wheels. Depends on how meticulous you are about your car simulation. The fidelity requirements of Gran Turismo are obviously very different from, say, Burnout.) Do this right and you’ll have a working suspension system and you’ll be able to see the car rock and shift as it corners and brakes. However, the more points and lines you use, the more CPU power you need.
As for making the body of the visible model crumple up like that? How does it know when to crumple up the fenders, when to shear them off, or when to have them detach entirely?
I have no idea. I mean, I could take a guess and muse over how I’d research such a problem, but it would be all conjecture and hard for me to relate in non-technical terms. And above all, it would probably be wrong.