FixedConstraint.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt.h>
  4. #include <Physics/Constraints/FixedConstraint.h>
  5. #include <Physics/Body/Body.h>
  6. #include <ObjectStream/TypeDeclarations.h>
  7. #ifdef JPH_DEBUG_RENDERER
  8. #include <Renderer/DebugRenderer.h>
  9. #endif // JPH_DEBUG_RENDERER
  10. namespace JPH {
  11. JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL(FixedConstraintSettings)
  12. {
  13. JPH_ADD_BASE_CLASS(FixedConstraintSettings, TwoBodyConstraintSettings)
  14. }
  15. TwoBodyConstraint *FixedConstraintSettings::Create(Body &inBody1, Body &inBody2) const
  16. {
  17. return new FixedConstraint(inBody1, inBody2, *this);
  18. }
  19. FixedConstraint::FixedConstraint(Body &inBody1, Body &inBody2, const FixedConstraintSettings &inSettings) :
  20. TwoBodyConstraint(inBody1, inBody2, inSettings)
  21. {
  22. // Determine anchor point: If any of the bodies can never be dynamic use the other body as anchor point, otherwise use the mid point between the two center of masses
  23. Vec3 anchor;
  24. if (!mBody1->CanBeKinematicOrDynamic())
  25. anchor = mBody2->GetCenterOfMassPosition();
  26. else if (!mBody2->CanBeKinematicOrDynamic())
  27. anchor = mBody1->GetCenterOfMassPosition();
  28. else
  29. anchor = 0.5f * (mBody1->GetCenterOfMassPosition() + mBody2->GetCenterOfMassPosition());
  30. // Store local positions
  31. mLocalSpacePosition1 = inBody1.GetInverseCenterOfMassTransform() * anchor;
  32. mLocalSpacePosition2 = inBody2.GetInverseCenterOfMassTransform() * anchor;
  33. // Inverse of initial rotation from body 1 to body 2 in body 1 space
  34. mInvInitialOrientation = RotationEulerConstraintPart::sGetInvInitialOrientation(inBody1, inBody2);
  35. }
  36. void FixedConstraint::SetupVelocityConstraint(float inDeltaTime)
  37. {
  38. // Calculate constraint values that don't change when the bodies don't change position
  39. Mat44 rotation1 = Mat44::sRotation(mBody1->GetRotation());
  40. Mat44 rotation2 = Mat44::sRotation(mBody2->GetRotation());
  41. mRotationConstraintPart.CalculateConstraintProperties(*mBody1, rotation1, *mBody2, rotation2);
  42. mPointConstraintPart.CalculateConstraintProperties(*mBody1, rotation1, mLocalSpacePosition1, *mBody2, rotation2, mLocalSpacePosition2);
  43. }
  44. void FixedConstraint::WarmStartVelocityConstraint(float inWarmStartImpulseRatio)
  45. {
  46. // Warm starting: Apply previous frame impulse
  47. mRotationConstraintPart.WarmStart(*mBody1, *mBody2, inWarmStartImpulseRatio);
  48. mPointConstraintPart.WarmStart(*mBody1, *mBody2, inWarmStartImpulseRatio);
  49. }
  50. bool FixedConstraint::SolveVelocityConstraint(float inDeltaTime)
  51. {
  52. // Solve rotation constraint
  53. bool rot = mRotationConstraintPart.SolveVelocityConstraint(*mBody1, *mBody2);
  54. // Solve position constraint
  55. bool pos = mPointConstraintPart.SolveVelocityConstraint(*mBody1, *mBody2);
  56. return rot || pos;
  57. }
  58. bool FixedConstraint::SolvePositionConstraint(float inDeltaTime, float inBaumgarte)
  59. {
  60. // Solve rotation constraint
  61. mRotationConstraintPart.CalculateConstraintProperties(*mBody1, Mat44::sRotation(mBody1->GetRotation()), *mBody2, Mat44::sRotation(mBody2->GetRotation()));
  62. bool rot = mRotationConstraintPart.SolvePositionConstraint(*mBody1, *mBody2, mInvInitialOrientation, inBaumgarte);
  63. // Solve position constraint
  64. mPointConstraintPart.CalculateConstraintProperties(*mBody1, Mat44::sRotation(mBody1->GetRotation()), mLocalSpacePosition1, *mBody2, Mat44::sRotation(mBody2->GetRotation()), mLocalSpacePosition2);
  65. bool pos = mPointConstraintPart.SolvePositionConstraint(*mBody1, *mBody2, inBaumgarte);
  66. return rot || pos;
  67. }
  68. #ifdef JPH_DEBUG_RENDERER
  69. void FixedConstraint::DrawConstraint(DebugRenderer *inRenderer) const
  70. {
  71. Vec3 com1 = mBody1->GetCenterOfMassPosition();
  72. Vec3 com2 = mBody2->GetCenterOfMassPosition();
  73. // Draw constraint
  74. inRenderer->DrawLine(com1, com2, Color::sGreen);
  75. }
  76. #endif // JPH_DEBUG_RENDERER
  77. void FixedConstraint::SaveState(StateRecorder &inStream) const
  78. {
  79. TwoBodyConstraint::SaveState(inStream);
  80. mRotationConstraintPart.SaveState(inStream);
  81. mPointConstraintPart.SaveState(inStream);
  82. }
  83. void FixedConstraint::RestoreState(StateRecorder &inStream)
  84. {
  85. TwoBodyConstraint::RestoreState(inStream);
  86. mRotationConstraintPart.RestoreState(inStream);
  87. mPointConstraintPart.RestoreState(inStream);
  88. }
  89. } // JPH