Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by PedroCoriAG · Mar 24, 2018 at 07:25 AM · physicsrigidbody physicsinertiatensor

How to calculate inertia tensor and tensor rotation manually

I'm trying to set the moment of inertia of a compound object (one object with a Rigidbody and multiple child objects with simple colliders). I need to set the Rigidbody.inertiaTensor and Rigidbody.inertiaTensorRotation manually because the child objects have different material densities.


I have calculated the inertia tensors for each child object around its center of mass as well as the center of mass of the parent object. I believe I can calculate the moment of inertia around the parent center of mass by adding all the individual moments of inertia of the child objects and then adding the moments of inertia of the children as point masses around the parent center of mass (might be wrong on this?).


What I don't understand is how to translate this into this Vector3 inertia tensor and Quaternion tensor rotation that Unity uses; the tensor rotation in particular I don't really understand what it represents. If I had the final moment of inertia of the compound object as a Matrix4x4, could I turn it into this Vector3 + Quaternion system? Is it possible to do these calculations while staying in the Vector3 + Quaternion space?


If nothing else, I want to know how the Rigidbody.inertiaTensorRotation is calculated and what it actually represents. The documentation says that "the inertia tensor is rotated by the inertiaTensorRotation", but I can't seem to find a relationship between the child transform rotation and it's effect on the inertiaTensorRotation. I've tried visualizing it by making a parent object with a Rigidbody with one child 1x1x1m cube and drawing the inertiaTensor vector rotated by the inertiaTensorRotation, but it just seems to jump around wildly as I slowly rotate the different axes of the box. The only pattern I've noticed is that if I only rotate 1 axis and all the others are 0, then the inertiaTensorRotation == Quaternion.identity alt text

Appreciate any help with this.

tensor.jpg (316.6 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by vpragma · Apr 08, 2020 at 11:07 AM

Unity relies on PhysX to calculate these values. You can inspect ExtRigidBodyExt.cpp and ExtInertiaTensor.h to find out exactly how it's done. The particular points of interest are:

  1. computeMassAndInertia in ExtRigidBodyExt.cpp which orchestrates this process by iterating through all child shapes and combining theirs inertias.

  2. Ext::InertiaTensorComputer::transform and Ext::InertiaTensorComputer::add methods in ExtInertiaTensor.h which are necessary in order to combine child inertias. This file also contains methods for calculating inertias of various primitive shapes.

  3. Finally, inertiaTensor and inertiaTensorRotation are extracted from resulting matrix. This is done via physx::PxDiagonalize in PsMathUtils.cpp


Here is the relevant source for step 3. The return value of physx::PxDiagonalize is what's called inertiaTensor in Unity and inertiaTensorRotationis the massFrame which is the second argument.

 // indexed rotation around axis, with sine and cosine of half-angle
 PxQuat indexedRotation(PxU32 axis, PxReal s, PxReal c)
 {
     PxReal v[3] = { 0, 0, 0 };
     v[axis] = s;
     return PxQuat(v[0], v[1], v[2], c);
 }
 
 PX_FOUNDATION_API PxVec3 physx::PxDiagonalize(const PxMat33& m, PxQuat& massFrame)
 {
     // jacobi rotation using quaternions (from an idea of Stan Melax, with fix for precision issues)
 
     const PxU32 MAX_ITERS = 24;
 
     PxQuat q = PxQuat(PxIdentity);
 
     PxMat33 d;
     for(PxU32 i = 0; i < MAX_ITERS; i++)
     {
         PxMat33 axes(q);
         d = axes.getTranspose() * m * axes;
 
         PxReal d0 = PxAbs(d[1][2]), d1 = PxAbs(d[0][2]), d2 = PxAbs(d[0][1]);
         PxU32 a = PxU32(d0 > d1 && d0 > d2 ? 0 : d1 > d2 ? 1 : 2); // rotation axis index, from largest off-diagonal
         // element
 
         PxU32 a1 = shdfnd::getNextIndex3(a); a2 = shdfnd::getNextIndex3(a1);
         if(d[a1][a2] == 0.0f || PxAbs(d[a1][a1] - d[a2][a2]) > 2e6f * PxAbs(2.0f * d[a1][a2]))
             break;
 
         PxReal w = (d[a1][a1] - d[a2][a2]) / (2.0f * d[a1][a2]); // cot(2 * phi), where phi is the rotation angle
         PxReal absw = PxAbs(w);
 
         PxQuat r;
         if(absw > 1000)
             r = indexedRotation(a, 1 / (4 * w), 1.f); // h will be very close to 1, so use small angle approx instead
         else
         {
             PxReal t = 1 / (absw + PxSqrt(w * w + 1)); // absolute value of tan phi
             PxReal h = 1 / PxSqrt(t * t + 1);          // absolute value of cos phi
 
             PX_ASSERT(h != 1); // |w|<1000 guarantees this with typical IEEE754 machine eps (approx 6e-8)
             r = indexedRotation(a, PxSqrt((1 - h) / 2) * PxSign(w), PxSqrt((1 + h) / 2));
         }
 
         q = (q * r).getNormalized();
     }
 
     massFrame = q;
     return PxVec3(d.column0.x, d.column1.y, d.column2.z);
 }


Note that shdfnd::getNextIndex3 in the above code is simply (a+1)%3. If you perform all the above steps, you will get exact values of inertiaTensor and inertiaTensorRotation.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Edy · Jun 15, 2020 at 11:27 AM 0
Share

Wow! What a wonderful reply! I'm in the need of converting a real inertia matrix to vector-rotation in Unity, and this is exactly what I was looking for. Thanks!

avatar image
1

Answer by nyscersul · Oct 15, 2019 at 09:26 PM

This is degree level math.

The simple answer is to learn about the backgrouns math of matrices, inertia tensors, and their properties. The thing that confuses this is unity are using a non standard (from math perspective) way of representing the data.

In a nutshell, an inertia tensor must be diagonalized before it can be used for calculation easily with physics, and this involves a complex algorithm for finding eigenvectors.

An Eigen vector could be described as a way to change the matrix so it is in a new basis of representation, in the case of inertia tensors, this is the principle axis of rotation. Once calculated, the eigen vectors provide the axis upon which the inertia tensor would "balance" well, and then enters the physics equations easier.

If you decided to take an object which balances well in the long axis, but represent its position diagonally across the centre of mass, such that one tip occupied the position 1,1 and the other tip -1, -1 then the diagonalization and eigenvector representation results in a new orientation to consider the motions from. It then enables the math to be performed on the object with its long axis nicely aligned to the axes in use. This is dependent on the shape and orientation of the object.

So, point is, an object may not wish to rotate about the axis we define for them, and, the result is to turn the axes on the object to be able to align it such that the axes are along the lines it does wish to rotate on. The physically dictated axes of natural balance are referred to as the principle axes of rotation.

It would appear that rather than exposing the complex and somewhat irrelevant math(from the perspective of users of unity) that is used to get to this point, they have nicely tidied up the result into a rotation quaternion, such that if you change the local axes of the object by the quaternion, you have the principle axes of rotation.

I assume your research into inertia tensors found enough to make an inertia tensor, but the rotation part will be very difficult. You may however, be able to define the inertia tensor and have unity create the quaternion for you.

The quaternion is best described as a reformatting of the standard output from this sequence of math, usually you get a new set of basis vectors in the form of a 3x3 matric, calculated from the inertia tensor, but, of course, a 3x3 basis matrix can be made to represent a rotation, and then translated into that quaternion. The quaternion is a seperate derivation of the same data.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image PedroCoriAG · Oct 15, 2019 at 09:59 PM 0
Share

Thank you for taking the time to explain this in detail! Now I finally understand what they were referring to. I ended up coding around the problem to a solution that worked well enough without actually using the physics engine for this, but it still gives me peace of $$anonymous$$d to get it and have it for reference in the future!

avatar image nyscersul · Oct 15, 2019 at 10:05 PM 0
Share

What did you do to get around it in the end?

avatar image PedroCoriAG nyscersul · Oct 16, 2019 at 04:59 PM 0
Share

Unity physics were too unpredictable, so we ended up moving most "physical" movement to a simpler and more fake model that gave us more reliable results (all kinematic rigidbodies and calculating the physics we needed ad-hoc), and for the specific cases we needed these more complex interactions, we calculated matrix moments of inertia and the associated physics directly in C# ins$$anonymous$$d of delegating to the physics engine until it was boiled down into simple physics (linear velocity, angular velocity, etc). $$anonymous$$ight take another crack at trying to understand all of this again and refactor that in the future.

avatar image nyscersul PedroCoriAG · Oct 16, 2019 at 06:03 PM 0
Share

I am doing the same at the moment, what type of game is it?

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

138 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Disable inertia tensor calculations on rigidbody? 0 Answers

What does the "compute mesh inertia tensor failed" error mean? 6 Answers

Compute the torque needed to rotate an object at a constant rate 3 Answers

carrying a physical object on the platform 1 Answer

Wierd Internal Physics problem 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges