Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Constraints/SwingTwistConstraint.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Constraints/TwoBodyConstraint.h>7#include <Jolt/Physics/Constraints/MotorSettings.h>8#include <Jolt/Physics/Constraints/ConstraintPart/PointConstraintPart.h>9#include <Jolt/Physics/Constraints/ConstraintPart/AngleConstraintPart.h>10#include <Jolt/Physics/Constraints/ConstraintPart/SwingTwistConstraintPart.h>1112JPH_NAMESPACE_BEGIN1314/// Swing twist constraint settings, used to create a swing twist constraint15/// All values in this structure are copied to the swing twist constraint and the settings object is no longer needed afterwards.16///17/// This image describes the limit settings:18/// @image html Docs/SwingTwistConstraint.png19class JPH_EXPORT SwingTwistConstraintSettings final : public TwoBodyConstraintSettings20{21JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, SwingTwistConstraintSettings)2223public:24// See: ConstraintSettings::SaveBinaryState25virtual void SaveBinaryState(StreamOut &inStream) const override;2627/// Create an instance of this constraint28virtual TwoBodyConstraint * Create(Body &inBody1, Body &inBody2) const override;2930/// This determines in which space the constraint is setup, all properties below should be in the specified space31EConstraintSpace mSpace = EConstraintSpace::WorldSpace;3233///@name Body 1 constraint reference frame (space determined by mSpace)34RVec3 mPosition1 = RVec3::sZero();35Vec3 mTwistAxis1 = Vec3::sAxisX();36Vec3 mPlaneAxis1 = Vec3::sAxisY();3738///@name Body 2 constraint reference frame (space determined by mSpace)39RVec3 mPosition2 = RVec3::sZero();40Vec3 mTwistAxis2 = Vec3::sAxisX();41Vec3 mPlaneAxis2 = Vec3::sAxisY();4243/// The type of swing constraint that we want to use.44ESwingType mSwingType = ESwingType::Cone;4546///@name Swing rotation limits47float mNormalHalfConeAngle = 0.0f; ///< See image at Detailed Description. Angle in radians.48float mPlaneHalfConeAngle = 0.0f; ///< See image at Detailed Description. Angle in radians.4950///@name Twist rotation limits51float mTwistMinAngle = 0.0f; ///< See image at Detailed Description. Angle in radians. Should be \f$\in [-\pi, \pi]\f$.52float mTwistMaxAngle = 0.0f; ///< See image at Detailed Description. Angle in radians. Should be \f$\in [-\pi, \pi]\f$.5354///@name Friction55float mMaxFrictionTorque = 0.0f; ///< Maximum amount of torque (N m) to apply as friction when the constraint is not powered by a motor5657///@name In case the constraint is powered, this determines the motor settings around the swing and twist axis58MotorSettings mSwingMotorSettings;59MotorSettings mTwistMotorSettings;6061protected:62// See: ConstraintSettings::RestoreBinaryState63virtual void RestoreBinaryState(StreamIn &inStream) override;64};6566/// A swing twist constraint is a specialized constraint for humanoid ragdolls that allows limited rotation only67///68/// @see SwingTwistConstraintSettings for a description of the limits69class JPH_EXPORT SwingTwistConstraint final : public TwoBodyConstraint70{71public:72JPH_OVERRIDE_NEW_DELETE7374/// Construct swing twist constraint75SwingTwistConstraint(Body &inBody1, Body &inBody2, const SwingTwistConstraintSettings &inSettings);7677///@name Generic interface of a constraint78virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::SwingTwist; }79virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;80virtual void SetupVelocityConstraint(float inDeltaTime) override;81virtual void ResetWarmStart() override;82virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;83virtual bool SolveVelocityConstraint(float inDeltaTime) override;84virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;85#ifdef JPH_DEBUG_RENDERER86virtual void DrawConstraint(DebugRenderer *inRenderer) const override;87virtual void DrawConstraintLimits(DebugRenderer *inRenderer) const override;88#endif // JPH_DEBUG_RENDERER89virtual void SaveState(StateRecorder &inStream) const override;90virtual void RestoreState(StateRecorder &inStream) override;91virtual Ref<ConstraintSettings> GetConstraintSettings() const override;9293// See: TwoBodyConstraint94virtual Mat44 GetConstraintToBody1Matrix() const override { return Mat44::sRotationTranslation(mConstraintToBody1, mLocalSpacePosition1); }95virtual Mat44 GetConstraintToBody2Matrix() const override { return Mat44::sRotationTranslation(mConstraintToBody2, mLocalSpacePosition2); }9697///@name Constraint reference frame98inline Vec3 GetLocalSpacePosition1() const { return mLocalSpacePosition1; }99inline Vec3 GetLocalSpacePosition2() const { return mLocalSpacePosition2; }100inline Quat GetConstraintToBody1() const { return mConstraintToBody1; }101inline Quat GetConstraintToBody2() const { return mConstraintToBody2; }102103///@name Constraint limits104inline float GetNormalHalfConeAngle() const { return mNormalHalfConeAngle; }105inline void SetNormalHalfConeAngle(float inAngle) { mNormalHalfConeAngle = inAngle; UpdateLimits(); }106inline float GetPlaneHalfConeAngle() const { return mPlaneHalfConeAngle; }107inline void SetPlaneHalfConeAngle(float inAngle) { mPlaneHalfConeAngle = inAngle; UpdateLimits(); }108inline float GetTwistMinAngle() const { return mTwistMinAngle; }109inline void SetTwistMinAngle(float inAngle) { mTwistMinAngle = inAngle; UpdateLimits(); }110inline float GetTwistMaxAngle() const { return mTwistMaxAngle; }111inline void SetTwistMaxAngle(float inAngle) { mTwistMaxAngle = inAngle; UpdateLimits(); }112113///@name Motor settings114const MotorSettings & GetSwingMotorSettings() const { return mSwingMotorSettings; }115MotorSettings & GetSwingMotorSettings() { return mSwingMotorSettings; }116const MotorSettings & GetTwistMotorSettings() const { return mTwistMotorSettings; }117MotorSettings & GetTwistMotorSettings() { return mTwistMotorSettings; }118119///@name Friction control120void SetMaxFrictionTorque(float inFrictionTorque) { mMaxFrictionTorque = inFrictionTorque; }121float GetMaxFrictionTorque() const { return mMaxFrictionTorque; }122123///@name Motor controls124125/// Controls if the motors are on or off126void SetSwingMotorState(EMotorState inState);127EMotorState GetSwingMotorState() const { return mSwingMotorState; }128void SetTwistMotorState(EMotorState inState);129EMotorState GetTwistMotorState() const { return mTwistMotorState; }130131/// Set the target angular velocity of body 2 in constraint space of body 2132void SetTargetAngularVelocityCS(Vec3Arg inAngularVelocity) { mTargetAngularVelocity = inAngularVelocity; }133Vec3 GetTargetAngularVelocityCS() const { return mTargetAngularVelocity; }134135/// Set the target orientation in constraint space (drives constraint to: GetRotationInConstraintSpace() == inOrientation)136void SetTargetOrientationCS(QuatArg inOrientation);137Quat GetTargetOrientationCS() const { return mTargetOrientation; }138139/// Set the target orientation in body space (R2 = R1 * inOrientation, where R1 and R2 are the world space rotations for body 1 and 2).140/// Solve: R2 * ConstraintToBody2 = R1 * ConstraintToBody1 * q (see SwingTwistConstraint::GetSwingTwist) and R2 = R1 * inOrientation for q.141void SetTargetOrientationBS(QuatArg inOrientation) { SetTargetOrientationCS(mConstraintToBody1.Conjugated() * inOrientation * mConstraintToBody2); }142143/// Get current rotation of constraint in constraint space.144/// Solve: R2 * ConstraintToBody2 = R1 * ConstraintToBody1 * q for q.145Quat GetRotationInConstraintSpace() const;146147///@name Get Lagrange multiplier from last physics update (the linear/angular impulse applied to satisfy the constraint)148inline Vec3 GetTotalLambdaPosition() const { return mPointConstraintPart.GetTotalLambda(); }149inline float GetTotalLambdaTwist() const { return mSwingTwistConstraintPart.GetTotalTwistLambda(); }150inline float GetTotalLambdaSwingY() const { return mSwingTwistConstraintPart.GetTotalSwingYLambda(); }151inline float GetTotalLambdaSwingZ() const { return mSwingTwistConstraintPart.GetTotalSwingZLambda(); }152inline Vec3 GetTotalLambdaMotor() const { return Vec3(mMotorConstraintPart[0].GetTotalLambda(), mMotorConstraintPart[1].GetTotalLambda(), mMotorConstraintPart[2].GetTotalLambda()); }153154private:155// Update the limits in the swing twist constraint part156void UpdateLimits();157158// CONFIGURATION PROPERTIES FOLLOW159160// Local space constraint positions161Vec3 mLocalSpacePosition1;162Vec3 mLocalSpacePosition2;163164// Transforms from constraint space to body space165Quat mConstraintToBody1;166Quat mConstraintToBody2;167168// Limits169float mNormalHalfConeAngle;170float mPlaneHalfConeAngle;171float mTwistMinAngle;172float mTwistMaxAngle;173174// Friction175float mMaxFrictionTorque;176177// Motor controls178MotorSettings mSwingMotorSettings;179MotorSettings mTwistMotorSettings;180EMotorState mSwingMotorState = EMotorState::Off;181EMotorState mTwistMotorState = EMotorState::Off;182Vec3 mTargetAngularVelocity = Vec3::sZero();183Quat mTargetOrientation = Quat::sIdentity();184185// RUN TIME PROPERTIES FOLLOW186187// Rotation axis for motor constraint parts188Vec3 mWorldSpaceMotorAxis[3];189190// The constraint parts191PointConstraintPart mPointConstraintPart;192SwingTwistConstraintPart mSwingTwistConstraintPart;193AngleConstraintPart mMotorConstraintPart[3];194};195196JPH_NAMESPACE_END197198199