How do I programmatically Combine Inertia Tensors?


I’m making a complex compound “ship” that I’m trying to simulate with a certain level of accuracy. The ship maneuvers in an atmospheric zero-G environment and is maneuvered through thrusters and aerodynamic control surfaces.

Ultimately I want the ship to handle as if it were the sum of its parts. In other words, the overall center of gravity and moment of inertia should be relative to the placement, size, and mass of each of the individual parts of the ship. Generator, engine, cockpit, fuel tanks, frame parts, etc.

Now, in Unity, I realize you can have multiple colliders as children of a rigidbody and Unity automatically calculates the COG and InertiaTensor for the rigidbody based on all the colliders, but with one major drawback. It assumes that all the colliders have exactly the same density. It spreads all the mass of the rigidbody out evenly across the combined volumes of all the colliders. As a result, something like an empty carbon fiber cockpit would way as much as an engine of the same size, made entirely of metal.

One solution that I’m using right now is to have a bunch of rigidbodies connected by fixed joints, but this is less than optimal in many ways (especially when you figure networking into the mix)

The only solution I can think of is to manually figure the inertia tensor myself, but I’m having one major problem:

All of the textbooks and documents and, well, everything that I can find online everywhere speaks of inertia tensors as a 3x3 array, but Unity describes them as a combination of a vector and a Quaternion rotation! Waugh!

Anyone have a clue on this? Either on how to translate the vector+rotation format into a matrix and then back again, or how to do the math using the existing structure?

As a matter of fact, one of the values in a tensor matrix is it’s rotation, as demonstrated here. In Unity, what you’ll probably want to do is grab the rotation as a Vector3 using eulerAngles. This way you can use the traditional math, but convert the rotation back and forth for Unity.

Hope that helps.