SwingTwistConstraintFrictionTest.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Tests/Constraints/SwingTwistConstraintFrictionTest.h>
  6. #include <Jolt/Physics/Collision/Shape/CapsuleShape.h>
  7. #include <Jolt/Physics/Collision/GroupFilterTable.h>
  8. #include <Jolt/Physics/Constraints/SwingTwistConstraint.h>
  9. #include <Jolt/Physics/Body/BodyCreationSettings.h>
  10. #include <Layers.h>
  11. JPH_IMPLEMENT_RTTI_VIRTUAL(SwingTwistConstraintFrictionTest)
  12. {
  13. JPH_ADD_BASE_CLASS(SwingTwistConstraintFrictionTest, Test)
  14. }
  15. void SwingTwistConstraintFrictionTest::Initialize()
  16. {
  17. // Floor
  18. CreateFloor();
  19. // Create group filter
  20. Ref<GroupFilterTable> group_filter = new GroupFilterTable;
  21. float half_cylinder_height = 1.5f;
  22. RefConst<Shape> capsule = new CapsuleShape(half_cylinder_height, 0.5f);
  23. RVec3 body1_position(0, 10, 0);
  24. Body &body1 = *mBodyInterface->CreateBody(BodyCreationSettings(capsule, body1_position, Quat::sIdentity(), EMotionType::Static, Layers::NON_MOVING));
  25. body1.SetCollisionGroup(CollisionGroup(group_filter, 0, 0));
  26. mBodyInterface->AddBody(body1.GetID(), EActivation::DontActivate);
  27. RVec3 body2_position = body1_position + Vec3(0, -2.0f * half_cylinder_height, 0);
  28. Body &body2 = *mBodyInterface->CreateBody(BodyCreationSettings(capsule, body2_position, Quat::sIdentity(), EMotionType::Dynamic, Layers::MOVING));
  29. body2.SetCollisionGroup(CollisionGroup(group_filter, 0, 0));
  30. body2.GetMotionProperties()->SetLinearDamping(0.0f);
  31. body2.GetMotionProperties()->SetAngularDamping(0.0f);
  32. body2.SetAllowSleeping(false);
  33. mBodyInterface->AddBody(body2.GetID(), EActivation::Activate);
  34. SwingTwistConstraintSettings settings;
  35. settings.mPosition1 = settings.mPosition2 = body1_position + Vec3(0, -half_cylinder_height, 0);
  36. settings.mTwistAxis1 = settings.mTwistAxis2 = Vec3(0, -1, 0);
  37. settings.mPlaneAxis1 = settings.mPlaneAxis2 = Vec3::sAxisX();
  38. settings.mNormalHalfConeAngle = DegreesToRadians(90);
  39. settings.mPlaneHalfConeAngle = DegreesToRadians(90);
  40. settings.mTwistMinAngle = -JPH_PI;
  41. settings.mTwistMaxAngle = JPH_PI;
  42. float body2_inertia = (body2.GetMotionProperties()->GetLocalSpaceInverseInertia().Inversed3x3() * Vec3::sAxisY()).Length();
  43. constexpr float max_angular_acceleration = DegreesToRadians(90.0f); // rad/s^2
  44. settings.mMaxFrictionTorque = body2_inertia * max_angular_acceleration;
  45. settings.mTwistMotorSettings = settings.mSwingMotorSettings = MotorSettings(10.0f, 2.0f);
  46. mConstraint = static_cast<SwingTwistConstraint *>(settings.Create(body1, body2));
  47. mPhysicsSystem->AddConstraint(mConstraint);
  48. }
  49. void SwingTwistConstraintFrictionTest::PrePhysicsUpdate(const PreUpdateParams &inParams)
  50. {
  51. mTime += inParams.mDeltaTime;
  52. bool pause = fmod(mTime, 5.0f) > 2.5f;
  53. if (pause)
  54. {
  55. mConstraint->SetSwingMotorState(EMotorState::Off);
  56. mConstraint->SetTwistMotorState(EMotorState::Off);
  57. }
  58. else
  59. {
  60. mConstraint->SetSwingMotorState(EMotorState::Velocity);
  61. mConstraint->SetTwistMotorState(EMotorState::Velocity);
  62. mConstraint->SetTargetAngularVelocityCS(Vec3(DegreesToRadians(180.0f), 0, 0));
  63. }
  64. }
  65. void SwingTwistConstraintFrictionTest::SaveState(StateRecorder &inStream) const
  66. {
  67. inStream.Write(mTime);
  68. }
  69. void SwingTwistConstraintFrictionTest::RestoreState(StateRecorder &inStream)
  70. {
  71. inStream.Read(mTime);
  72. }