-
-
Notifications
You must be signed in to change notification settings - Fork 23.5k
Add Products of Inertia to RigidBody3D #112367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add Products of Inertia to RigidBody3D #112367
Conversation
Added UI inputs for product of inertia
Initial jolt implementation of products of inertia
Products of inertia have been added and implemented for both GodotPhysics3D and JoltPhysics engines.
Added documentation for the Product of Inertia parameter in RigidBody3D
Remove unused `use_products_of_inertia` flag. Added enum to doc.
…/godot into products_of_inertia
Updated the file header for eigen_value_symmetric.h to the proper Godot format.
| Vector3 principal_inertia = Vector3(); | ||
|
|
||
| // Compute the principal axes and moments of inertia. | ||
| eigen_value_symmetric(inertia_tensor_local, principal_inertia_axes_local, principal_inertia); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can fail. Better check the return value and decide what to do. Use a fallback inertia of some sorts, e.g. set the principal_inertia_axis_local to identity and use _inv_inertia = inertia.inverse().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea. I'd like to have it throw a warning when that happens so that the user is aware of it. What's the proper way to do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see people use WARN_PRINT (there are more similar macros in the file where that comes from)
Cleanup of code using clang-format
Added protection to the eigenvalue/vector calculation such that, if it fails, the principal axes revert to the body-aligned frame, and the on-axis moments of inertia are used.
Added warning if unable to find principle axes. Updated #define name to GODOT_EVS_ROTATE. Included math_funcs library and added Math namespace to abs functions.
Added `BIND_ENUM_CONSTANT(BODY_PARAM_PROD_INERTIA);` to `PhysicsServer3D`. Updated RigidBody3D.xml to put product_of_inertia in proper alphabetical order.
|
Could someone help me understand the remaining error I seem to be having the the automatic checks? |
New enum must be added to end of list (but before max). Doc updated.
|
Thanks for the feedback and help so far guys (and I apologize for my ignorance. This really is my first time formally contributing to an open project like this). There are some remaining things I want to actually discuss regarding final implementation:
Finally, I recently happened across issue #80703. This is something I hope to address in a future pull request once I'm finished with this one, but it's something I wanted to bring to people's attention. Should we chose to properly implement Euler's rigid body equations (something I will very much push for) I believe there's performance that could be gained by not computing the principle axes of inertia at all and instead only relying on the local inertia tensor. The entire scope of work would have to be identified, but I understand this would not be a trivial change. However, this pull request would lay the groundwork for that effort. |
Changed the order in which the enum entries are bound to reflect new order.
Current Situation
Currently users can only define custom inertia parallel to the body axes of a
RigidBody3Dnode. That is, the inertia's principle axes are assumed to be aligned with the body axes, and only the principle moments of inertia (Ixx, Iyy, Izz) can be defined.Improvements Made
This branch adds the ability to set the off diagonal products of inertia (Iyz, Ixz, Ixy) such that the entire local inertia tensor can be defined without the ability for the user to accidentally define an invalid, non-symmetrical matrix. The functionality is implemented for both the GodotPhysics3D and Jolt Physics engines. Behavior in each engine has been shown to be identical. The products of inertia are ordered (Iyz, Ixz, Ixy). If combined with the on-axis
inertiavalue, the 6-element array is consistent with Voigt notation for representing symmetric tensors.Benefits
Bodies with non-zero products of inertia will respond differently to external moments. For instance, applying a pure x-axis moment to a body with non-zero Ixz and/or Ixy values will result in rotation not purely about the x-axis. This allows for realistic behavior of physics objects, such as vehicles, with one or more off-axis inertia terms.
Implementation Details
The products of inertia are passed to
GodotBody3DorJoltBody3Din the same way as the on-axisinertia. In the Jolt engine, a full local inertia tensor is already provided as part of theMass Propertiesobject, and the inertia values need only be set to the correct elements. In the Godot physics engine, this functionality had to be added. A local inertia tensor object now exists within theGodotBody3Dclass and the inertia values are assigned to the proper elements. This matrix is then decomposed into its eigenvalues (principle moments of inertia) and eigenvectors (principle axes of inertia) for use within the existing Godot implementation. The algorithm for this was copied from the Jolt physics engine library but modified to use Godot'sVector3andBasisclasses. The algorithm is an implementation of the Jacobi eigenvalue algorithm, which only works for real-symmetric matrices.The appropriate doc .xml files have been updated to reflect the new
product_of_inertiafield, and the addition ofBODY_PARAM_PROD_INERTIAto theBodyParamenum.Anticipated Discussion Points
eigen_value_symmetricfunction is currently implemented in a new, separate file. This should probably be moved to either theBasisclass as a method, or to the math_funcs.h/.cpp files. I defer this decision to someone more familiar with how Godot is and should be laid out. It duplicates thediagonalizemethod already present in theBasisclass, except that it also returns the eigenvalues, which are necessary.