ModifyMassTest.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2023 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Tests/General/ModifyMassTest.h>
  6. #include <Jolt/Physics/Collision/Shape/SphereShape.h>
  7. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  8. #include <Renderer/DebugRendererImp.h>
  9. #include <Layers.h>
  10. JPH_IMPLEMENT_RTTI_VIRTUAL(ModifyMassTest)
  11. {
  12. JPH_ADD_BASE_CLASS(ModifyMassTest, Test)
  13. }
  14. void ModifyMassTest::ResetBodies(int inCycle)
  15. {
  16. mBodyInterface->SetPositionAndRotation(mBodies[0], RVec3(-5, 5, 0), Quat::sIdentity(), EActivation::Activate);
  17. mBodyInterface->SetLinearAndAngularVelocity(mBodies[0], Vec3(10, 0, 0), Vec3::sZero());
  18. mBodyInterface->SetUserData(mBodies[0], inCycle << 1);
  19. mBodyInterface->SetPositionAndRotation(mBodies[1], RVec3(5, 5, 0), Quat::sIdentity(), EActivation::Activate);
  20. mBodyInterface->SetLinearAndAngularVelocity(mBodies[1], Vec3(-10, 0, 0), Vec3::sZero());
  21. mBodyInterface->SetUserData(mBodies[1], (inCycle << 1) + 1);
  22. }
  23. void ModifyMassTest::UpdateLabels()
  24. {
  25. for (BodyID id : mBodies)
  26. {
  27. BodyLockRead body_lock(mPhysicsSystem->GetBodyLockInterface(), id);
  28. if (body_lock.Succeeded())
  29. {
  30. const Body &body = body_lock.GetBody();
  31. SetBodyLabel(id, StringFormat("Inv mass scale: %.1f\nVelocity X: %.1f", (double)sGetInvMassScale(body), (double)body.GetLinearVelocity().GetX()));
  32. }
  33. }
  34. }
  35. void ModifyMassTest::Initialize()
  36. {
  37. // Floor
  38. CreateFloor();
  39. // Create two spheres on a collision course
  40. BodyCreationSettings bcs(new SphereShape(1.0f), RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  41. bcs.mRestitution = 1.0f;
  42. mBodies[0] = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
  43. mBodies[1] = mBodyInterface->CreateAndAddBody(bcs, EActivation::Activate);
  44. ResetBodies(0);
  45. UpdateLabels();
  46. }
  47. void ModifyMassTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
  48. {
  49. constexpr float cTimeBetweenTests = 2.0f;
  50. int old_cycle = (int)(mTime / cTimeBetweenTests);
  51. mTime += inParams.mDeltaTime;
  52. int new_cycle = (int)(mTime / cTimeBetweenTests);
  53. if (old_cycle != new_cycle)
  54. ResetBodies(new_cycle);
  55. UpdateLabels();
  56. }
  57. float ModifyMassTest::sGetInvMassScale(const Body &inBody)
  58. {
  59. uint64 ud = inBody.GetUserData();
  60. int index = ((ud & 1) != 0? (ud >> 1) : (ud >> 3)) & 0b11;
  61. float mass_overrides[] = { 1.0f, 0.0f, 0.5f, 2.0f };
  62. return mass_overrides[index];
  63. }
  64. void ModifyMassTest::OnContactAdded(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  65. {
  66. // We're only concerned with dynamic bodies (floor gets normal collision response)
  67. if (!inBody1.IsDynamic() || !inBody2.IsDynamic())
  68. return;
  69. // Override the mass of body 1
  70. float scale1 = sGetInvMassScale(inBody1);
  71. ioSettings.mInvMassScale1 = scale1;
  72. ioSettings.mInvInertiaScale1 = scale1;
  73. // Override the mass of body 2
  74. float scale2 = sGetInvMassScale(inBody2);
  75. ioSettings.mInvMassScale2 = scale2;
  76. ioSettings.mInvInertiaScale2 = scale2;
  77. }
  78. void ModifyMassTest::OnContactPersisted(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  79. {
  80. OnContactAdded(inBody1, inBody2, inManifold, ioSettings);
  81. }
  82. void ModifyMassTest::SaveState(StateRecorder &inStream) const
  83. {
  84. Test::SaveState(inStream);
  85. inStream.Write(mTime);
  86. }
  87. void ModifyMassTest::RestoreState(StateRecorder &inStream)
  88. {
  89. Test::RestoreState(inStream);
  90. inStream.Read(mTime);
  91. }