Sign in to follow this  
Spa8nky

Debugging my physics engine. How to transform inertia tensor correctly?

Recommended Posts

Here is my method for returning an inertia tensor for a sphere:
        public static Matrix Inertia_Tensor_Sphere_Shell(float object_Mass, float sphere_Radius)
        {
            float mass = 2.0f / 3.0f * object_Mass;
            double powR = Math.Pow(sphere_Radius, 2);

            return new Matrix(
                (float)(mass * powR), 0, 0, 0,
                0, (float)(mass * powR), 0, 0,
                0, 0, (float)(mass * powR), 0,
                0, 0, 0, 1
                );
        }
The problem I am having is transforming that matrix/tensor into world coordinates correctly. If I have the following transform matrix (I assume this is correct):
matrix_Transform = Matrix.CreateFromQuaternion(orientation) * Matrix.CreateTranslation(position);
I then have to transform the inverse of the inertia tensor by the transform matrix to get the inverse inertia tensor in world coordinates
// Tranpose the inertia tensor to get the inverse
inertia_Tensor_Inverse = Matrix.Transpose(inertia_Tensor) 

            // Calculate the inverse inertiaTensor in world space ----IS THIS CORRECT???
            inertia_Tensor_World_Inverse = matrix_Transform * inertia_Tensor_Inverse; 
The last line is the one I am concerned about. Have I done this all correctly? The problem I am having with the physics at the moment is as follows: When I drop a sphere onto another sphere the sphere "bounces" off. However, if the mass of both the sphere are increased, the bounce response increases which doesn't make any sense. Thanks for your help on this.

Share this post


Link to post
Share on other sites
I'm not familiar with what you're doing, but from a math standpoint, you might try reversing the order of your multiplication. It doesn't look right. Your order appears to be transforming the world space into the tensor space, rather than vice-versa.
That is, try:

inertia_Tensor_World_Inverse = inertia_Tensor_Inverse * matrix_Transform;

Share this post


Link to post
Share on other sites
The rebounding velocity is now always the same no matter what the mass of the object is?!

Can I ask, if I want to change from object space to world space then all I have to do is create a transform matrix?

The transform matrix is made up of a SCALE, ROTATE & TRANSLATION matrix (in that order), correct?

In order to transform anything from object space to world space then I would just multiply it by the transform matrix?

E.g.

Object space inertia tensor * transform matrix = world space inertia tensor...

Am I doing this correctly?

Share this post


Link to post
Share on other sites
Ignore the posts so far, they spread misinformation.

You're taking the transpose of the inertia tensor which is likely NOT an orthonormal matrix. The transpose=inverse trick only works for when all columns of the matrix are perpendicular to each other and of unit length.

You'll have to calculate the inverse by hand for anything but orthonormal matrices (i.e. rotation matrices).

Also, you're not transforming the inertia tensor correctly. In order to rotate from body-space to world-space correctly, you'll have to do something like this:

inverseWorldInertiaTensor = orientation*inverseBodyInertiaTensor*orientation.transpose()

Additionally, you're accounting for the object's position when transforming the inertia tensor. This is entirely incorrect. The inertia tensor is defined relative to the CENTER OF MASS of the object in question. Translating it makes no sense unless you are applying the parallel-axis theorem (which you need to do in body space if your center of mass is not at the center of the sphere for which you are computing an inertia tensor). This is necessary if you have compound objects made up of several shapes which may skew the center of mass for the entire object.

An example of why translating the inertia tensor makes little sense is the following: If you look at the equation for applying an impulse to a rigid body, you see that the impulses are applied relative to the center of mass of the object. This means that you don't have to take into account that the object is at some other position than the origin:

r = collisionPoint - centerOfMass
velocity += impulse / mass
angularVelocity += inverseWorldInertiaTensor*cross( r, impulse )


Finally, why are you using 4x4 matrices to represent matrices that are 3x3? It's probably causing you a few problems just because the extra w coordinate makes no sense in application to physics. Its purpose is to be able to perform perspective projection correctly with a point-independent matrix. Look up "homogeneous coordinates" if you want to know more.

Share this post


Link to post
Share on other sites
Thanks for your help with this.

Quote:

Finally, why are you using 4x4 matrices to represent matrices that are 3x3? It's probably causing you a few problems just because the extra w coordinate makes no sense in application to physics.


XNA comes with a Matrix class as a 4x4 matrix only there are no 3x3 matrices. I can always create a class with 3x3 matrices but if M41 - M43 are 0 and M41 is 1 then won't that have absolutely no effect on the inverse of the matrix?

In other words if I set it to an identity matrix then add the information for the inertia tensor in the first 3x3 column/rows, the inverse would be the same if I just had a 3x3 matrix to begin with as the 4th column row won't affect calculations?

Share this post


Link to post
Share on other sites
Yes, that should work out.

BTW, in practice, transforming an inertial tensor mainly needs to happen when you need to combine two tensors in different spaces. For applying torque, it's pretty common to maintain angular velocity in local coordinates, meaning that you just need to transform the torque vector to local coordinates, then use the local-space tensor as-is. The only other place I can think of offhand where you need the world-space tensor is in certain types of constraint solving.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this