I am building a game physics engine following Ian Millington's book Game Physics Engine Development and I am confused by one of his implementations when changing matrix bases.
In order to apply rotation to rigid bodies, I have stored the inverse of the inertia tensor in the RigidBody
class. It is given in local space, however, so in order to use it, I need to transform it into world space.
This is the code he's using (I know it's a lot of code, but I didn't want to alter the original). The function takes in the inverse inertia tensor in local space (iitBody
) and the rotation matrix of the rigid body (rotmat
), and outputs the inverse inertia tensor in world space (iitWorld
).
static inline void _transformInertiaTensor(Matrix3 &iitWorld, const Quaternion &q, const Matrix3 &iitBody, const Matrix4 &rotmat)
{
real t4 = rotmat.data[0]*iitBody.data[0] + rotmat.data[1]*iitBody.data[3] + rotmat.data[2]*iitBody.data[6];
real t9 = rotmat.data[0]*iitBody.data[1] + rotmat.data[1]*iitBody.data[4] + rotmat.data[2]*iitBody.data[7];
real t14 = rotmat.data[0]*iitBody.data[2] + rotmat.data[1]*iitBody.data[5] + rotmat.data[2]*iitBody.data[8];
real t28 = rotmat.data[4]*iitBody.data[0] + rotmat.data[5]*iitBody.data[3] + rotmat.data[6]*iitBody.data[6];
real t33 = rotmat.data[4]*iitBody.data[1] + rotmat.data[5]*iitBody.data[4] + rotmat.data[6]*iitBody.data[7];
real t38 = rotmat.data[4]*iitBody.data[2] + rotmat.data[5]*iitBody.data[5] + rotmat.data[6]*iitBody.data[8];
real t52 = rotmat.data[8]*iitBody.data[0] + rotmat.data[9]*iitBody.data[3] + rotmat.data[10]*iitBody.data[6];
real t57 = rotmat.data[8]*iitBody.data[1] + rotmat.data[9]*iitBody.data[4] + rotmat.data[10]*iitBody.data[7];
real t62 = rotmat.data[8]*iitBody.data[2] + rotmat.data[9]*iitBody.data[5] + rotmat.data[10]*iitBody.data[8];
iitWorld.data[0] = t4*rotmat.data[0] + t9*rotmat.data[1] + t14*rotmat.data[2];
iitWorld.data[1] = t4*rotmat.data[4] + t9*rotmat.data[5] + t14*rotmat.data[6];
iitWorld.data[2] = t4*rotmat.data[8] + t9*rotmat.data[9] + t14*rotmat.data[10];
iitWorld.data[3] = t28*rotmat.data[0] + t33*rotmat.data[1] + t38*rotmat.data[2];
iitWorld.data[4] = t28*rotmat.data[4] + t33*rotmat.data[5] + t38*rotmat.data[6];
iitWorld.data[5] = t28*rotmat.data[8] + t33*rotmat.data[9] + t38*rotmat.data[10];
iitWorld.data[6] = t52*rotmat.data[0] + t57*rotmat.data[1] + t62*rotmat.data[2];
iitWorld.data[7] = t52*rotmat.data[4] + t57*rotmat.data[5] + t62*rotmat.data[6];
iitWorld.data[8] = t52*rotmat.data[8] + t57*rotmat.data[9] + t62*rotmat.data[10];
}
To my understanding, in order to change the matrix from local to world space, I would simply need to multiply the rotation matrix by the inverse inertia tensor in world space. However, Millington's implementation includes a second multiplication by the rotation matrix and I haven't been able to understand why.