ConveyorBeltTest.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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/ConveyorBeltTest.h>
  6. #include <Jolt/Physics/Collision/Shape/BoxShape.h>
  7. #include <Jolt/Physics/Collision/Shape/CylinderShape.h>
  8. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  9. #include <Layers.h>
  10. JPH_IMPLEMENT_RTTI_VIRTUAL(ConveyorBeltTest)
  11. {
  12. JPH_ADD_BASE_CLASS(ConveyorBeltTest, Test)
  13. }
  14. void ConveyorBeltTest::Initialize()
  15. {
  16. // Floor
  17. CreateFloor();
  18. // Create conveyor belts
  19. const float cBeltWidth = 10.0f;
  20. const float cBeltLength = 50.0f;
  21. BodyCreationSettings belt_settings(new BoxShape(Vec3(cBeltWidth, 0.1f, cBeltLength)), RVec3::sZero(), Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING);
  22. for (int i = 0; i < 4; ++i)
  23. {
  24. belt_settings.mFriction = 0.25f * (i + 1);
  25. belt_settings.mRotation = Quat::sRotation(Vec3::sAxisY(), 0.5f * JPH_PI * i) * Quat::sRotation(Vec3::sAxisX(), DegreesToRadians(1.0f));
  26. belt_settings.mPosition = RVec3(belt_settings.mRotation * Vec3(cBeltLength, 6.0f, cBeltWidth));
  27. mBelts.push_back(mBodyInterface->CreateAndAddBody(belt_settings, EActivation::DontActivate));
  28. }
  29. // Bodies with decreasing friction
  30. BodyCreationSettings cargo_settings(new BoxShape(Vec3::sReplicate(2.0f)), RVec3::sZero(), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  31. for (int i = 0; i <= 10; ++i)
  32. {
  33. cargo_settings.mPosition = RVec3(-cBeltLength + i * 10.0f, 10.0f, -cBeltLength);
  34. cargo_settings.mFriction = 1.0f - 0.1f * i;
  35. mBodyInterface->CreateAndAddBody(cargo_settings, EActivation::Activate);
  36. }
  37. // Create 2 cylinders
  38. BodyCreationSettings cylinder_settings(new CylinderShape(6.0f, 1.0f), RVec3(0, 1.0f, -20.0f), Quat::sRotation(Vec3::sAxisZ(), 0.5f * JPH_PI), EMotionType::Dynamic, Layers::MOVING);
  39. mBodyInterface->CreateAndAddBody(cylinder_settings, EActivation::Activate);
  40. cylinder_settings.mPosition.SetZ(20.0f);
  41. mBodyInterface->CreateAndAddBody(cylinder_settings, EActivation::Activate);
  42. // Let a dynamic belt rest on it
  43. BodyCreationSettings dynamic_belt(new BoxShape(Vec3(5.0f, 0.1f, 25.0f), 0.0f), RVec3(0, 3.0f, 0), Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING);
  44. mBelts.push_back(mBodyInterface->CreateAndAddBody(dynamic_belt, EActivation::Activate));
  45. // Create cargo on the dynamic belt
  46. cargo_settings.mPosition = RVec3(0, 6.0f, 15.0f);
  47. cargo_settings.mFriction = 1.0f;
  48. mBodyInterface->CreateAndAddBody(cargo_settings, EActivation::Activate);
  49. }
  50. void ConveyorBeltTest::OnContactAdded(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  51. {
  52. // Determine the world space surface velocity of both bodies
  53. const Vec3 cLocalSpaceVelocity(0, 0, -10.0f);
  54. bool body1_belt = std::find(mBelts.begin(), mBelts.end(), inBody1.GetID()) != mBelts.end();
  55. Vec3 body1_surface_velocity = body1_belt? inBody1.GetRotation() * cLocalSpaceVelocity : Vec3::sZero();
  56. bool body2_belt = std::find(mBelts.begin(), mBelts.end(), inBody2.GetID()) != mBelts.end();
  57. Vec3 body2_surface_velocity = body2_belt? inBody2.GetRotation() * cLocalSpaceVelocity : Vec3::sZero();
  58. // Calculate the relative surface velocity
  59. ioSettings.mRelativeSurfaceVelocity = body2_surface_velocity - body1_surface_velocity;
  60. }
  61. void ConveyorBeltTest::OnContactPersisted(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, ContactSettings &ioSettings)
  62. {
  63. // Same behavior as contact added
  64. OnContactAdded(inBody1, inBody2, inManifold, ioSettings);
  65. }