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