Julio Jerez wrote:look at the part where they talk of principal axis.
"Inertia matrix in different reference frames"
basically, the moment of inertia of a matrix can be decompose int a rotation matrix and a scale vector.
I'm stopping right here, because (i think) the math you quote is built on the assumption/restriction that any rigid body has the inertial shape of an ellipsoid. It's an approximation. And it can represent the Rattle Back things you did, but only so because this object has an ellipsoid alike shape, so the approximation becomes very (or precisely) accurate.
You are the expert, and we talked about that before. But i think the acceptance on the approximation is so deeply founded in the physics community, that almost nobody remembers it's an approximation. And that it would be eventually worth to research improvements if needed.
I'll try to proof my claim by showing you the code i use to generate this lobe shape, which can't be well approximated with the established methods.
The math should be the same as if you calculate inertia for a set of point masses, or spherical bodies to be precise. (I can do this because i give each ragdoll body a uniform inertia, so the inertia sphere has the same volume as the textbook ellipsoid we use for capsules or boxes.)
- Code: Select all
float CalcInertia (const Vec3 axis, const float *weights) const // current pose
{
float inertia = 0;
for (int i=0; i<NUM_BONES; i++)
{
float w = (weights ? weights[i] : 1.f);
if (w == 0.f) continue;
auto &pose = bodyPose[i];
auto &info = bodyInfos[i];
// pose.com is the com of the unique body
// com is the precalculated com of all bodies
Vec3 d = pose.com - com;
inertia += w * info.mass * Vec3(axis * axis.Dot(d) - d).SqL(); // SqL gives squared length
inertia += w * info.uniformInertia;
}
return inertia;
}
I have just copied this from the old project and did not verify again. But initially i got the math from Wikipedia or some other source.
The code to visualize is this:
- Code: Select all
for (int i=0; i<360; i++)
{
float angle = float(i) / 180.f * float(PI);
Vec3 axis (sin(angle), cos(angle), 0);
float inertia = m_controller->CalcInertia(axis, 0);
RenderVector (m_controller->com, axis * inertia * 0.00001f, 0,1,0);
}
Her is another function i have used to get Inertia for given direction, but using the standard approximation:
- Code: Select all
inline float GetInertia (const sVec3 &localaxis, const float Ixx, const float Iyy, const float Izz)
{
sVec3 axis = localaxis;
axis[0] /= Ixx;
axis[1] /= Iyy;
axis[2] /= Izz;
return 1.0f / axis.Length();
}
Not sure that's right, but it seemed to be.
I hope you can verify those things just from reading the code. I can't express myself with math notation
Now here comes my claim based on that code:
If i would make a compound from my ragdoll, your engine would calculate the 3 inertia values Ixx,Iyy,Izz.
And i could visualize them using the third code snippet.
But then i would see an ellipsoid shape, which tries to approximate the lobes i get from looping over all bodies and accumulating precisely.
So if all i said is right, it proofs the traditional method is just an approximation.
Now we have 3 options:
1. Talk bullshit, and i came up with that because my code is wrong.
2. Some of my code is wrong, but my claim is right regardless.
3. I'm totally wrong, and a rotation matrix and a scale vector is indeed enough to represent MOI for any rigid body, whatever it's shape and mass distribution is.
So what do you think?
If you insist on 3 my code must be buggy, and i shall fix it to turn lobes into an ellipsoid.
And i could also represent my ragdoll with the standard inertia representation, getting rid of the cost to iterate over all the bodies each time i need it. But i have tried this first, and it did not work. The ragdoll fell on its node.