But as you told, for a ConvexHullShape you can't jsut grab the moments of inertia from M11.
So to get the inertia of the x-axis, I can't just multiply with the vector (1,0,0), rather I should know the direction of the x-axis.
Using the world space vector (1,0,0) and the world space inertia tensor does essentially grab M11 from the tensor, but it is still the correct moment of inertia around the axis (1,0,0).
It is not generally a principal moment of inertia, because (1,0,0) is not generally a principal axis.
If you want the principal axes and moments of inertia, the matrix needs to be diagonalized.
If you just want the moment of inertia around an arbitrary axis, the formula is all that's needed.
The multiplication with (1,0,0)T and (1,0,0) would result in 61. But I guess that's wrong, because the matrix is not diagonalized.
61 isn't a principal moment, but it would be the correct scalar moment of inertia for that axis given that inertia tensor.
It can be a little difficult to visualize 'correctness' for nonprincipal axes, since they don't have the property that an angular impulse results in a parallel change in angular velocity. Applying an angular impulse around an off-axis can produce an angular velocity with an unintuitive axis of rotation, unlike with principal axes.
For example, applying an impulse around (1,0,0) for that particular compound body produces an angular velocity almost perfectly aligned with the principal axis of lowest inertia instead of anything near (1/61, 0, 0).
Another way to think about it: the scalar moment of inertia does show the relationship between an impulse around an axis and the resulting velocity about the axis, but the scalar moment does not give you information about the additional off-axis rotations which make the change in angular velocity not parallel to the impulse.
To see it more clearly, try constraining the compound to behave as if it's anchored on an axis, and then apply an angular impulse:
Code: Select all
Space.Add(new RevoluteJoint(null, compoundBody, compoundBody.Position, momentMeasurementAxis));
//Keep the object from deactivating or slowing down artificially.
compoundBody.AngularDamping = 0;
compoundBody.ActivityInformation.IsAlwaysActive = true;
compoundBody.ActivityInformation.AllowStabilization = false;
var impulse = momentMeasurementAxis;
compoundBody.ApplyAngularImpulse(ref impulse);
//Do a bunch of updates to give the constraint time to converge.
//The default settings on the joint are pretty rigid, but it still has some softness.
//The initial impulse will introduce some error that these iterated updates will eliminate.
for (int i = 0; i < 100; ++i)
Space.Update();
var velocity = compoundBody.AngularVelocity;
After the Space.Updates (required for the constraint to have an effect), you should see the velocity be suspiciously close to 1/moment.
It's also possible to work to a similar answer from a different direction. Sum the moment of inertia contributions for a given axis from point masses:
I = sum(m * r^2)
where
I is the scalar moment of inertia around the axis,
m is the mass of each contributor, and
r is the perpendicular distance from the axis.
The boxes are taken to be point masses at (0,0,0) and (10,10,0) with 0.5 mass each. The moment of inertia is to be measured around the axis (1,0,0). The axis goes through the center of mass at (5,5,0).
This gives:
I = 0.5 * 5^2 + 0.5 * 5^2 = 25
BEPUphysics scales the inertia tensor by InertiaHelper.InertiaScaleFactor which defaults to 2.5. The moment computed from the BEPUphysics tensor in your example is then 62.9/2.5 = 25.16. So, with some error introduced by the point mass approximation, the same result is found.