MotionProperties.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <Jolt/Jolt.h>
  5. #include <Jolt/Physics/Body/MotionProperties.h>
  6. #include <Jolt/Physics/StateRecorder.h>
  7. JPH_NAMESPACE_BEGIN
  8. void MotionProperties::SetMassProperties(EAllowedDOFs inAllowedDOFs, const MassProperties &inMassProperties)
  9. {
  10. // Store allowed DOFs
  11. mAllowedDOFs = inAllowedDOFs;
  12. // Decompose DOFs
  13. uint allowed_translation_axis = uint(inAllowedDOFs) & 0b111;
  14. uint allowed_rotation_axis = (uint(inAllowedDOFs) >> 3) & 0b111;
  15. // Set inverse mass
  16. if (allowed_translation_axis == 0)
  17. {
  18. // No translation possible
  19. mInvMass = 0.0f;
  20. }
  21. else
  22. {
  23. JPH_ASSERT(inMassProperties.mMass > 0.0f, "Invalid mass. "
  24. "Some shapes like MeshShape or TriangleShape cannot calculate mass automatically, "
  25. "in this case you need to provide it by setting BodyCreationSettings::mOverrideMassProperties and mMassPropertiesOverride.");
  26. mInvMass = 1.0f / inMassProperties.mMass;
  27. }
  28. if (allowed_rotation_axis == 0)
  29. {
  30. // No rotation possible
  31. mInvInertiaDiagonal = Vec3::sZero();
  32. mInertiaRotation = Quat::sIdentity();
  33. }
  34. else
  35. {
  36. // Set inverse inertia
  37. Mat44 rotation;
  38. Vec3 diagonal;
  39. if (inMassProperties.DecomposePrincipalMomentsOfInertia(rotation, diagonal)
  40. && !diagonal.IsNearZero())
  41. {
  42. mInvInertiaDiagonal = diagonal.Reciprocal();
  43. mInertiaRotation = rotation.GetQuaternion();
  44. }
  45. else
  46. {
  47. // Failed! Fall back to inertia tensor of sphere with radius 1.
  48. mInvInertiaDiagonal = Vec3::sReplicate(2.5f * mInvMass);
  49. mInertiaRotation = Quat::sIdentity();
  50. }
  51. }
  52. JPH_ASSERT(mInvMass != 0.0f || mInvInertiaDiagonal != Vec3::sZero(), "Can't lock all axes, use a static body for this. This will crash with a division by zero later!");
  53. }
  54. void MotionProperties::SaveState(StateRecorder &inStream) const
  55. {
  56. // Only write properties that can change at runtime
  57. inStream.Write(mLinearVelocity);
  58. inStream.Write(mAngularVelocity);
  59. inStream.Write(mForce);
  60. inStream.Write(mTorque);
  61. #ifdef JPH_DOUBLE_PRECISION
  62. inStream.Write(mSleepTestOffset);
  63. #endif // JPH_DOUBLE_PRECISION
  64. inStream.Write(mSleepTestSpheres);
  65. inStream.Write(mSleepTestTimer);
  66. inStream.Write(mAllowSleeping);
  67. }
  68. void MotionProperties::RestoreState(StateRecorder &inStream)
  69. {
  70. inStream.Read(mLinearVelocity);
  71. inStream.Read(mAngularVelocity);
  72. inStream.Read(mForce);
  73. inStream.Read(mTorque);
  74. #ifdef JPH_DOUBLE_PRECISION
  75. inStream.Read(mSleepTestOffset);
  76. #endif // JPH_DOUBLE_PRECISION
  77. inStream.Read(mSleepTestSpheres);
  78. inStream.Read(mSleepTestTimer);
  79. inStream.Read(mAllowSleeping);
  80. }
  81. JPH_NAMESPACE_END