SwingTwistConstraint.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Physics/Constraints/TwoBodyConstraint.h>
  6. #include <Jolt/Physics/Constraints/MotorSettings.h>
  7. #include <Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h>
  8. #include <Jolt/Physics/Constraints/ConstraintPart/AngleConstraintPart.h>
  9. #include <Jolt/Physics/Constraints/ConstraintPart/SwingTwistConstraintPart.h>
  10. JPH_NAMESPACE_BEGIN
  11. /// Swing twist constraint settings, used to create a swing twist constraint
  12. /// All values in this structure are copied to the swing twist constraint and the settings object is no longer needed afterwards.
  13. ///
  14. /// This image describes the limit settings:
  15. /// @image html Docs/SwingTwistConstraint.png
  16. class JPH_EXPORT SwingTwistConstraintSettings final : public TwoBodyConstraintSettings
  17. {
  18. public:
  19. JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, SwingTwistConstraintSettings)
  20. // See: ConstraintSettings::SaveBinaryState
  21. virtual void SaveBinaryState(StreamOut &inStream) const override;
  22. /// Create an instance of this constraint
  23. virtual TwoBodyConstraint * Create(Body &inBody1, Body &inBody2) const override;
  24. /// This determines in which space the constraint is setup, all properties below should be in the specified space
  25. EConstraintSpace mSpace = EConstraintSpace::WorldSpace;
  26. ///@name Body 1 constraint reference frame (space determined by mSpace)
  27. RVec3 mPosition1 = RVec3::sZero();
  28. Vec3 mTwistAxis1 = Vec3::sAxisX();
  29. Vec3 mPlaneAxis1 = Vec3::sAxisY();
  30. ///@name Body 2 constraint reference frame (space determined by mSpace)
  31. RVec3 mPosition2 = RVec3::sZero();
  32. Vec3 mTwistAxis2 = Vec3::sAxisX();
  33. Vec3 mPlaneAxis2 = Vec3::sAxisY();
  34. /// The type of swing constraint that we want to use.
  35. ESwingType mSwingType = ESwingType::Cone;
  36. ///@name Swing rotation limits
  37. float mNormalHalfConeAngle = 0.0f; ///< See image at Detailed Description. Angle in radians.
  38. float mPlaneHalfConeAngle = 0.0f; ///< See image at Detailed Description. Angle in radians.
  39. ///@name Twist rotation limits
  40. float mTwistMinAngle = 0.0f; ///< See image at Detailed Description. Angle in radians. Should be \f$\in [-\pi, \pi]\f$.
  41. float mTwistMaxAngle = 0.0f; ///< See image at Detailed Description. Angle in radians. Should be \f$\in [-\pi, \pi]\f$.
  42. ///@name Friction
  43. float mMaxFrictionTorque = 0.0f; ///< Maximum amount of torque (N m) to apply as friction when the constraint is not powered by a motor
  44. ///@name In case the constraint is powered, this determines the motor settings around the swing and twist axis
  45. MotorSettings mSwingMotorSettings;
  46. MotorSettings mTwistMotorSettings;
  47. protected:
  48. // See: ConstraintSettings::RestoreBinaryState
  49. virtual void RestoreBinaryState(StreamIn &inStream) override;
  50. };
  51. /// A swing twist constraint is a specialized constraint for humanoid ragdolls that allows limited rotation only
  52. ///
  53. /// @see SwingTwistConstraintSettings for a description of the limits
  54. class JPH_EXPORT SwingTwistConstraint final : public TwoBodyConstraint
  55. {
  56. public:
  57. JPH_OVERRIDE_NEW_DELETE
  58. /// Construct swing twist constraint
  59. SwingTwistConstraint(Body &inBody1, Body &inBody2, const SwingTwistConstraintSettings &inSettings);
  60. ///@name Generic interface of a constraint
  61. virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::SwingTwist; }
  62. virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
  63. virtual void SetupVelocityConstraint(float inDeltaTime) override;
  64. virtual void ResetWarmStart() override;
  65. virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
  66. virtual bool SolveVelocityConstraint(float inDeltaTime) override;
  67. virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;
  68. #ifdef JPH_DEBUG_RENDERER
  69. virtual void DrawConstraint(DebugRenderer *inRenderer) const override;
  70. virtual void DrawConstraintLimits(DebugRenderer *inRenderer) const override;
  71. #endif // JPH_DEBUG_RENDERER
  72. virtual void SaveState(StateRecorder &inStream) const override;
  73. virtual void RestoreState(StateRecorder &inStream) override;
  74. virtual Ref<ConstraintSettings> GetConstraintSettings() const override;
  75. // See: TwoBodyConstraint
  76. virtual Mat44 GetConstraintToBody1Matrix() const override { return Mat44::sRotationTranslation(mConstraintToBody1, mLocalSpacePosition1); }
  77. virtual Mat44 GetConstraintToBody2Matrix() const override { return Mat44::sRotationTranslation(mConstraintToBody2, mLocalSpacePosition2); }
  78. ///@name Constraint reference frame
  79. inline Vec3 GetLocalSpacePosition1() const { return mLocalSpacePosition1; }
  80. inline Vec3 GetLocalSpacePosition2() const { return mLocalSpacePosition2; }
  81. inline Quat GetConstraintToBody1() const { return mConstraintToBody1; }
  82. inline Quat GetConstraintToBody2() const { return mConstraintToBody2; }
  83. ///@name Constraint limits
  84. inline float GetNormalHalfConeAngle() const { return mNormalHalfConeAngle; }
  85. inline void SetNormalHalfConeAngle(float inAngle) { mNormalHalfConeAngle = inAngle; UpdateLimits(); }
  86. inline float GetPlaneHalfConeAngle() const { return mPlaneHalfConeAngle; }
  87. inline void SetPlaneHalfConeAngle(float inAngle) { mPlaneHalfConeAngle = inAngle; UpdateLimits(); }
  88. inline float GetTwistMinAngle() const { return mTwistMinAngle; }
  89. inline void SetTwistMinAngle(float inAngle) { mTwistMinAngle = inAngle; UpdateLimits(); }
  90. inline float GetTwistMaxAngle() const { return mTwistMaxAngle; }
  91. inline void SetTwistMaxAngle(float inAngle) { mTwistMaxAngle = inAngle; UpdateLimits(); }
  92. ///@name Motor settings
  93. const MotorSettings & GetSwingMotorSettings() const { return mSwingMotorSettings; }
  94. MotorSettings & GetSwingMotorSettings() { return mSwingMotorSettings; }
  95. const MotorSettings & GetTwistMotorSettings() const { return mTwistMotorSettings; }
  96. MotorSettings & GetTwistMotorSettings() { return mTwistMotorSettings; }
  97. ///@name Friction control
  98. void SetMaxFrictionTorque(float inFrictionTorque) { mMaxFrictionTorque = inFrictionTorque; }
  99. float GetMaxFrictionTorque() const { return mMaxFrictionTorque; }
  100. ///@name Motor controls
  101. /// Controls if the motors are on or off
  102. void SetSwingMotorState(EMotorState inState);
  103. EMotorState GetSwingMotorState() const { return mSwingMotorState; }
  104. void SetTwistMotorState(EMotorState inState);
  105. EMotorState GetTwistMotorState() const { return mTwistMotorState; }
  106. /// Set the target angular velocity of body 2 in constraint space of body 2
  107. void SetTargetAngularVelocityCS(Vec3Arg inAngularVelocity) { mTargetAngularVelocity = inAngularVelocity; }
  108. Vec3 GetTargetAngularVelocityCS() const { return mTargetAngularVelocity; }
  109. /// Set the target orientation in constraint space (drives constraint to: GetRotationInConstraintSpace() == inOrientation)
  110. void SetTargetOrientationCS(QuatArg inOrientation);
  111. Quat GetTargetOrientationCS() const { return mTargetOrientation; }
  112. /// Set the target orientation in body space (R2 = R1 * inOrientation, where R1 and R2 are the world space rotations for body 1 and 2).
  113. /// Solve: R2 * ConstraintToBody2 = R1 * ConstraintToBody1 * q (see SwingTwistConstraint::GetSwingTwist) and R2 = R1 * inOrientation for q.
  114. void SetTargetOrientationBS(QuatArg inOrientation) { SetTargetOrientationCS(mConstraintToBody1.Conjugated() * inOrientation * mConstraintToBody2); }
  115. /// Get current rotation of constraint in constraint space.
  116. /// Solve: R2 * ConstraintToBody2 = R1 * ConstraintToBody1 * q for q.
  117. Quat GetRotationInConstraintSpace() const;
  118. ///@name Get Lagrange multiplier from last physics update (the linear/angular impulse applied to satisfy the constraint)
  119. inline Vec3 GetTotalLambdaPosition() const { return mPointConstraintPart.GetTotalLambda(); }
  120. inline float GetTotalLambdaTwist() const { return mSwingTwistConstraintPart.GetTotalTwistLambda(); }
  121. inline float GetTotalLambdaSwingY() const { return mSwingTwistConstraintPart.GetTotalSwingYLambda(); }
  122. inline float GetTotalLambdaSwingZ() const { return mSwingTwistConstraintPart.GetTotalSwingZLambda(); }
  123. inline Vec3 GetTotalLambdaMotor() const { return Vec3(mMotorConstraintPart[0].GetTotalLambda(), mMotorConstraintPart[1].GetTotalLambda(), mMotorConstraintPart[2].GetTotalLambda()); }
  124. private:
  125. // Update the limits in the swing twist constraint part
  126. void UpdateLimits();
  127. // CONFIGURATION PROPERTIES FOLLOW
  128. // Local space constraint positions
  129. Vec3 mLocalSpacePosition1;
  130. Vec3 mLocalSpacePosition2;
  131. // Transforms from constraint space to body space
  132. Quat mConstraintToBody1;
  133. Quat mConstraintToBody2;
  134. // Limits
  135. float mNormalHalfConeAngle;
  136. float mPlaneHalfConeAngle;
  137. float mTwistMinAngle;
  138. float mTwistMaxAngle;
  139. // Friction
  140. float mMaxFrictionTorque;
  141. // Motor controls
  142. MotorSettings mSwingMotorSettings;
  143. MotorSettings mTwistMotorSettings;
  144. EMotorState mSwingMotorState = EMotorState::Off;
  145. EMotorState mTwistMotorState = EMotorState::Off;
  146. Vec3 mTargetAngularVelocity = Vec3::sZero();
  147. Quat mTargetOrientation = Quat::sIdentity();
  148. // RUN TIME PROPERTIES FOLLOW
  149. // Rotation axis for motor constraint parts
  150. Vec3 mWorldSpaceMotorAxis[3];
  151. // The constraint parts
  152. PointConstraintPart mPointConstraintPart;
  153. SwingTwistConstraintPart mSwingTwistConstraintPart;
  154. AngleConstraintPart mMotorConstraintPart[3];
  155. };
  156. JPH_NAMESPACE_END