[ODE] ODE in Myst V: A Postmortem
SJS
ode at pulsecode.net
Wed Jun 22 18:05:05 MST 2005
Colin's feedback is good. I've seen a lot of the same problems and I'll
share what solutions I can.
We use what I would call an "ODE derivation." It's inspired much by ODE,
but there are some useful changes that I'll point out below.
If someone has the time to actively work on these issues and apply them to
the public code, ODE would be much improved (and though free software may
never have the support that commercial stuff does, hey, it's free!, and you
can modify it as necessary). Everyone wishes they had more time.
> Going from Havok to ODE, the main issues were the lack of convex hull
> support and the fact that collisions weren't completely resolved each
> step. In Uru, pretty much all detectors were made from convex hulls.
Convex hulls would be very nice. I currently get by by creating composite
objects made up of a bunch of spheres, but this has it's problems.
> The bigger problem was the collision resolution. Since ODE uses the ERP
> to resolve collisions over multiple steps you can run into cases where
> an object being forced into some static geometry will push in and out
> instead of stopping dead. In Havok the penetrations were always
> resolved, so our character controller was much simpler.
ERP seems to be the recurring headache of everyone here. As mentioned in a
previous thread, projection would probably be more suitable. This has been
successfully tried in a fairly inefficient way with ODE's solver.
Optimizing this projection method and getting rid of ERP all together would
be very nice. see Adam Moss's last message with subject "[ODE] patch -
position-correcting constraints"
> For the Myst V avatar I used a capped cylinder. In Havok we kept our
> characters upright by setting an inertial tensor that was wacked out
> enough to make it impossible to get any angular rotation.
I'm glad someone mentioned this, because I think it's very useful, and an
optimization as well. I diverged from the rigid-body representation that
ODE uses a bit--
ODE stores each object's inertia tensor. Our system stores the inverse of
the inertia tensor, with the object's mass divided out (the mass is like a
diagonal matrix, so multiplication order doesn't matter here so this is safe
to do). The mass gets multiplied back in within the solver (e.g. stepisland
or quickstep).
If you set one of the rows (or maybe columns for ODE-- we use D3D-style 4x4
matrices) of the inverse inertia tensor to zero, you get "infinite inertia"
around that local axis. Basically this is useful for game objects that you
want remaining upright but allowing them to spin in a reasonable way. After
all, many have seen that storing "inverse mass" is usually more useful than
storing mass, so it follows that "inverse inertia tensor" is the way to go
also.
ODE stores each object's accumulated forces and torques. Our system
stores accumulated accelerations (both angular and linear). This, combined
with storing the inverse of the inertia tensor rather than the non-inverse
removes a bunch of unnecessary vector/matrix operations from the solver--
quite a bit, really. (like the block in the island stepper that's commented
with "compute the inertia tensor and its inverse...").
The "Add Torque" functions can be transparently modified to immediately
multiply by the mass' world-frame inverse inertia tensor (to convert to an
effective acceleration). We store the world and local inverse inertia
tensor and keep a dirty flag so we know if the world tensor needs updating.
This would cause a touch of overhead if you had multiple "add torque" calls
per frame for the same object, but this overhead is usually insignificant,
and usually ends of saving time since you're not doing extra multiplications
within the solver.
In addition, since we're multiplying the mass back into the inertia tensor
within the solver, we tack on a scaling factor since this is practically
free. This lets us choose our range of precision-- our masses can
externally be 1000-100,000 and get automatically scaled down to a range of
"around 1.0" just before the solver and the forces/torques get scaled back
up after the solver output. Just a minor benefit, since the ratio of
extents still has to be reasonable, but we can choose our mass extents
rather than being limited to ~1.0.
The fact that mass is multiplied in at a late stage also lets us change
the mass on the fly (by just changing the scalar, without needing to mess
with the inertia tensor at all).
We also put in "center of mass" for our bodies, and modified all of the
joint computations accordingly. There is just a bit of overhead involved in
this, but nothing too significant, and it is very nice to be able to easily
move the center-of-mass just by changing a vector.
I don't have all that much time, but I'll fill in details where I can (and
maybe provide some code snippits) if someone is interested in implementing
any of these changes in ODE.
Anyway, if you've read this far, you can see
http://www.angrydentist.com/
for some of our game clips with physics in action.
in particular, under "Gameplay highlights" there's a nice looking military
"MPV" vehicle, some basketball, and a few nice balloons in
http://www.angrydentist.com/videos/GSGameClips.wmv
There's also a quick shot of a fully operational "crane game" in the main
movie.
SJS
-------------------------
Stephen Schlueter
sschluet at alum.mit.edu
-------------------------
More information about the ODE
mailing list