OffsetCenterOfMassShapeTests.cpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include "UnitTestFramework.h"
  4. #include "PhysicsTestContext.h"
  5. #include "Layers.h"
  6. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  7. #include <Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h>
  8. TEST_SUITE("OffsetCenterOfMassShapeTests")
  9. {
  10. TEST_CASE("TestAngularImpulseCOMZero")
  11. {
  12. PhysicsTestContext c;
  13. c.ZeroGravity();
  14. // Create box
  15. const Vec3 cHalfExtent = Vec3(0.5f, 1.0f, 1.5f);
  16. BoxShapeSettings box(cHalfExtent);
  17. box.SetEmbedded();
  18. // Create body with COM offset 0
  19. OffsetCenterOfMassShapeSettings com(Vec3::sZero(), &box);
  20. com.SetEmbedded();
  21. Body &body = c.CreateBody(&com, RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING, EActivation::DontActivate);
  22. // Check mass and inertia calculated correctly
  23. float mass = (8.0f * cHalfExtent.GetX() * cHalfExtent.GetY() * cHalfExtent.GetZ()) * box.mDensity;
  24. CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseMass(), 1.0f / mass);
  25. float inertia_y = mass / 12.0f * (Square(2.0f * cHalfExtent.GetX()) + Square(2.0f * cHalfExtent.GetZ())); // See: https://en.wikipedia.org/wiki/List_of_moments_of_inertia
  26. CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseInertiaForRotation(Mat44::sIdentity())(1, 1), 1.0f / inertia_y);
  27. // Add impulse
  28. Vec3 cImpulse(0, 10000, 0);
  29. body.AddAngularImpulse(cImpulse);
  30. // Check resulting velocity change
  31. // dv = I^-1 * L
  32. float delta_v = (1.0f / inertia_y) * cImpulse.GetY();
  33. CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
  34. CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
  35. }
  36. TEST_CASE("TestAngularImpulseCOMOffset")
  37. {
  38. PhysicsTestContext c;
  39. c.ZeroGravity();
  40. // Create box
  41. const Vec3 cHalfExtent = Vec3(0.5f, 1.0f, 1.5f);
  42. BoxShapeSettings box(cHalfExtent);
  43. box.SetEmbedded();
  44. // Create body with COM offset
  45. const Vec3 cCOMOffset(5.0f, 0, 0);
  46. OffsetCenterOfMassShapeSettings com(cCOMOffset, &box);
  47. com.SetEmbedded();
  48. Body &body = c.CreateBody(&com, RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, EMotionQuality::Discrete, Layers::MOVING, EActivation::DontActivate);
  49. // Check mass and inertia calculated correctly
  50. float mass = (8.0f * cHalfExtent.GetX() * cHalfExtent.GetY() * cHalfExtent.GetZ()) * box.mDensity;
  51. CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseMass(), 1.0f / mass);
  52. float inertia_y = mass / 12.0f * (Square(2.0f * cHalfExtent.GetX()) + Square(2.0f * cHalfExtent.GetZ())) + mass * Square(cCOMOffset.GetX()); // See: https://en.wikipedia.org/wiki/List_of_moments_of_inertia & https://en.wikipedia.org/wiki/Parallel_axis_theorem
  53. CHECK_APPROX_EQUAL(body.GetMotionProperties()->GetInverseInertiaForRotation(Mat44::sIdentity())(1, 1), 1.0f / inertia_y);
  54. // Add impulse
  55. Vec3 cImpulse(0, 10000, 0);
  56. body.AddAngularImpulse(cImpulse);
  57. // Check resulting velocity change
  58. // dv = I^-1 * L
  59. float delta_v = (1.0f / inertia_y) * cImpulse.GetY();
  60. CHECK_APPROX_EQUAL(body.GetLinearVelocity(), Vec3::sZero());
  61. CHECK_APPROX_EQUAL(body.GetAngularVelocity(), Vec3(0, delta_v, 0));
  62. }
  63. }