Inertia Tensor Scale - Please help solving this riddle once and for all

Hello folks,

please bear with me when this is in the wrong category or so. For ages we are trying to figure out how to scale the inertia tensor in UE4 like we imagine it and other game engines do it also like this (So there shouldn’t be any black magic involved).
What we need is scaling of the inertia tensor around one single axis. Thus when we scale the z-component of the ‘inertia tensor scale’ the object has a higher moment of inertia around the z axis. As we all know (I assume) UE4 does it incorrect(or the physx code is simply not doing what it states in the docs. The docs of Nvidia DO NOT match with what the code is actually doing.

See here in the section ‘Mass Properties’ the example with a windmill. This example wouldn’t even be possible in UE4 according to my tests.

https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/guide/Manual/RigidBodyDynamics.html

In the following is the source code of the computation of the inertia tensor scale. Legit is every principal axis and the products of inertia somehow multiplied with every component of the inertia tensor scale. Look at ‘scaleInertia’ starting at line 254.

This simply affects always all axes as soon you change the ‘inertia tensor scale’ to something else than (1.0, 1.0, 1.0).

So what I found out is that Nvidia PhysX calculates everything down to the principal axis so you can do easy math on them. If I understand it correctly it is possible to scale the inertia tensor just with die diagonal components of the 3x3 inertia tensor matrix along the principal axis.

But the results are waaay different. I am using a custom compiled version of UE4.27 so I have the ability to fiddle a bit more in depth around with such stuff. When multiplying the diagonal elements of the inertia tensor matrix, before OR after the diagonalization (doesnt even matter) without using the 'scaleInertia#-function you get a much more explainable solution that is also not correct:

When changing just the z-component of the ‘inertia tensor scale’ the object has more moment of inertia around the XY axis, when changing the y-component more MOI around XZ axis.

What the hell on earth do I have to do to change the scale around one single axis? This whole venture is the final super duper crucial step in our vehicle physics. Everything runs really well but we need to change MOI just around the objects yaw axis.

Please help us or give us a hint.

Best regards

1 Like

Hi, Its a bit shame that everyone is ignoring this. I was programming custom racing simulator from scratch with physx using ue4 & later found that ue4 completely sets tensor scale wrongly. I had to use c++ physx code and make custom library to compute mass manually. Physics will act more accurate and predictable. As you write , if you set tensor scale for Z axis it will scale two axes. I cant explain how the fatal failure like that can be here for that long time implemented in unreal engine without anyone trying to solve this internally in Epic Games, omg !!! I think that some things are implemented in UE in very unanswerable way. For example , there are many basic things missing in bp libs, or bodyinstance like set contact offset for each body separately, aggregates (“very important!!!”), and many more.

Uh I found it already. Its stupid but check out the MMT plugin repository, I dont remember the file but it is i think inside the suspension class. What you have to do is whenever you change anything of a bodyinstance that forces it to update its mass properties let it do its thing. When it is done (you updated all properties and added all meshes) you take the mass space inertia tensor and multiply the axis you want by the factor you need. then it works without any problems.

I have found quick solution for that , but you will need c++;
Just use →

FPhysicsActorHandle_PhysX actorHandle = inPrimitiveComponent->GetBodyInstance()->ActorHandle;
FPhysicsInterface::SetMass_AssumesLocked(actorHandle, Mass);
&
FPhysicsInterface::SetMassSpaceInertiaTensor_AssumesLocked(actorHandle, yourCustomTensor);

Optionaly you can also use : FPhysicsInterface::SetComLocalPose_AssumesLocked(actorHandle, In_COMLocalPose);

Enjoy! Now physics will work in natural way !
I dont even f*** understand why unreal computes this diagonally for ages, wt*