I fixed the links and paste my code for computing inertia. Then you don't need to worry about the math too much.
struct RnMassProperties
{
float Mass;
RnMatrix3 Inertia;
RnVector3 Center;
};
RnMassProperties RnHullShape::ComputeMassProperties( float Density ) const
{
// M. Kallay - "Computing the Moment of Inertia of a Solid Defined by a Triangle Mesh"
float Volume = 0.0f;
RnVector3 Center = RN_VEC3_ZERO;
float XX = 0.0f; float XY = 0.0f;
float YY = 0.0f; float XZ = 0.0f;
float ZZ = 0.0f; float YZ = 0.0f;
// Iterate over faces and triangulate in-place
for ( int I = 0; I < mHull->FaceCount; ++I )
{
const RnFace* Face = mHull->GetFace( I );
const RnHalfEdge* Edge1 = mHull->GetEdge( Face->Edge );
const RnHalfEdge* Edge2 = mHull->GetEdge( Edge1->Next );
const RnHalfEdge* Edge3 = mHull->GetEdge( Edge2->Next );
RN_ASSERT( Edge1 != Edge3 );
RnVector3 V1 = mHull->GetVertex( Edge1->Origin );
do
{
RnVector3 V2 = mHull->GetVertex( Edge2->Origin );
RnVector3 V3 = mHull->GetVertex( Edge3->Origin );
// Signed volume of this tetrahedron
float Det = rnDet( V1, V2, V3 );
// Contribution to mass
Volume += Det;
// Contribution to centroid
RnVector3 V4 = V1 + V2 + V3;
Center += Det * V4;
// Contribution to inertia monomials
XX += Det * ( V1.X * V1.X + V2.X * V2.X + V3.X * V3.X + V4.X * V4.X );
YY += Det * ( V1.Y * V1.Y + V2.Y * V2.Y + V3.Y * V3.Y + V4.Y * V4.Y );
ZZ += Det * ( V1.Z * V1.Z + V2.Z * V2.Z + V3.Z * V3.Z + V4.Z * V4.Z );
XY += Det * ( V1.X * V1.Y + V2.X * V2.Y + V3.X * V3.Y + V4.X * V4.Y );
XZ += Det * ( V1.X * V1.Z + V2.X * V2.Z + V3.X * V3.Z + V4.X * V4.Z );
YZ += Det * ( V1.Y * V1.Z + V2.Y * V2.Z + V3.Y * V3.Z + V4.Y * V4.Z );
Edge2 = Edge3;
Edge3 = mHull->GetEdge( Edge3->Next );
}
while ( Edge1 != Edge3 );
}
RN_ASSERT( Volume > 0.0f );
// Fetch result
RnMatrix3 Inertia;
Inertia.C1.X = YY + ZZ; Inertia.C2.X = -XY; Inertia.C3.X = -XZ;
Inertia.C1.Y = -XY; Inertia.C2.Y = XX + ZZ; Inertia.C3.Y = -YZ;
Inertia.C1.Z = -XZ; Inertia.C2.Z = -YZ; Inertia.C3.Z = XX + YY;
RnMassProperties Out;
Out.Mass = Density * Volume / 6.0f;
Out.Center = Center / ( 4.0f * Volume );
Out.Inertia = ( Density / 120.0f ) * Inertia;
return Out;
}
Note that the inertia is relative to the origin. You can shift the inertia to the center of mass using the Parallel Axis Theorem: https://en.wikipedia.org/wiki/Parallel_axis_theorem
Here is some helper code:
// Inertia helper
RnMatrix3 rnSteiner( float Mass, const RnVector3& Origin )
{
// Usage: Io = Ic + Is and Ic = Io - Is
float Ixx = Mass * ( Origin.Y * Origin.Y + Origin.Z * Origin.Z );
float Iyy = Mass * ( Origin.X * Origin.X + Origin.Z * Origin.Z );
float Izz = Mass * ( Origin.X * Origin.X + Origin.Y * Origin.Y );
float Ixy = -Mass * Origin.X * Origin.Y;
float Ixz = -Mass * Origin.X * Origin.Z;
float Iyz = -Mass * Origin.Y * Origin.Z;
// Write
RnMatrix3 Out;
Out.C1.X = Ixx; Out.C2.X = Ixy; Out.C3.X = Ixz;
Out.C1.Y = Ixy; Out.C2.Y = Iyy; Out.C3.Y = Iyz;
Out.C1.Z = Ixz; Out.C2.Z = Iyz; Out.C3.Z = Izz;
return Out;
}
E.g. to shift the mass to the center use
Inertia -= rnSteiner( Mass, Center );