Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Constraints/SliderConstraint.h
9913 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/DualAxisConstraintPart.h>
10
#include <Jolt/Physics/Constraints/ConstraintPart/RotationEulerConstraintPart.h>
11
#include <Jolt/Physics/Constraints/ConstraintPart/AxisConstraintPart.h>
12
13
JPH_NAMESPACE_BEGIN
14
15
/// Slider constraint settings, used to create a slider constraint
16
class JPH_EXPORT SliderConstraintSettings final : public TwoBodyConstraintSettings
17
{
18
JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, SliderConstraintSettings)
19
20
public:
21
// See: ConstraintSettings::SaveBinaryState
22
virtual void SaveBinaryState(StreamOut &inStream) const override;
23
24
/// Create an instance of this constraint.
25
/// Note that the rotation constraint will be solved from body 1. This means that if body 1 and body 2 have different masses / inertias (kinematic body = infinite mass / inertia), body 1 should be the heaviest body.
26
virtual TwoBodyConstraint * Create(Body &inBody1, Body &inBody2) const override;
27
28
/// Simple way of setting the slider and normal axis in world space (assumes the bodies are already oriented correctly when the constraint is created)
29
void SetSliderAxis(Vec3Arg inSliderAxis);
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
/// When mSpace is WorldSpace mPoint1 and mPoint2 can be automatically calculated based on the positions of the bodies when the constraint is created (the current relative position/orientation is chosen as the '0' position). Set this to false if you want to supply the attachment points yourself.
35
bool mAutoDetectPoint = false;
36
37
/// Body 1 constraint reference frame (space determined by mSpace).
38
/// Slider axis is the axis along which movement is possible (direction), normal axis is a perpendicular vector to define the frame.
39
RVec3 mPoint1 = RVec3::sZero();
40
Vec3 mSliderAxis1 = Vec3::sAxisX();
41
Vec3 mNormalAxis1 = Vec3::sAxisY();
42
43
/// Body 2 constraint reference frame (space determined by mSpace)
44
RVec3 mPoint2 = RVec3::sZero();
45
Vec3 mSliderAxis2 = Vec3::sAxisX();
46
Vec3 mNormalAxis2 = Vec3::sAxisY();
47
48
/// When the bodies move so that mPoint1 coincides with mPoint2 the slider position is defined to be 0, movement will be limited between [mLimitsMin, mLimitsMax] where mLimitsMin e [-inf, 0] and mLimitsMax e [0, inf]
49
float mLimitsMin = -FLT_MAX;
50
float mLimitsMax = FLT_MAX;
51
52
/// When enabled, this makes the limits soft. When the constraint exceeds the limits, a spring force will pull it back.
53
SpringSettings mLimitsSpringSettings;
54
55
/// Maximum amount of friction force to apply (N) when not driven by a motor.
56
float mMaxFrictionForce = 0.0f;
57
58
/// In case the constraint is powered, this determines the motor settings around the sliding axis
59
MotorSettings mMotorSettings;
60
61
protected:
62
// See: ConstraintSettings::RestoreBinaryState
63
virtual void RestoreBinaryState(StreamIn &inStream) override;
64
};
65
66
/// A slider constraint allows movement in only 1 axis (and no rotation). Also known as a prismatic constraint.
67
class JPH_EXPORT SliderConstraint final : public TwoBodyConstraint
68
{
69
public:
70
JPH_OVERRIDE_NEW_DELETE
71
72
/// Construct slider constraint
73
SliderConstraint(Body &inBody1, Body &inBody2, const SliderConstraintSettings &inSettings);
74
75
// Generic interface of a constraint
76
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Slider; }
77
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
78
virtual void SetupVelocityConstraint(float inDeltaTime) override;
79
virtual void ResetWarmStart() override;
80
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
81
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
82
virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;
83
#ifdef JPH_DEBUG_RENDERER
84
virtual void DrawConstraint(DebugRenderer *inRenderer) const override;
85
virtual void DrawConstraintLimits(DebugRenderer *inRenderer) const override;
86
#endif // JPH_DEBUG_RENDERER
87
virtual void SaveState(StateRecorder &inStream) const override;
88
virtual void RestoreState(StateRecorder &inStream) override;
89
virtual Ref<ConstraintSettings> GetConstraintSettings() const override;
90
91
// See: TwoBodyConstraint
92
virtual Mat44 GetConstraintToBody1Matrix() const override;
93
virtual Mat44 GetConstraintToBody2Matrix() const override;
94
95
/// Get the current distance from the rest position
96
float GetCurrentPosition() const;
97
98
/// Friction control
99
void SetMaxFrictionForce(float inFrictionForce) { mMaxFrictionForce = inFrictionForce; }
100
float GetMaxFrictionForce() const { return mMaxFrictionForce; }
101
102
/// Motor settings
103
MotorSettings & GetMotorSettings() { return mMotorSettings; }
104
const MotorSettings & GetMotorSettings() const { return mMotorSettings; }
105
106
// Motor controls
107
void SetMotorState(EMotorState inState) { JPH_ASSERT(inState == EMotorState::Off || mMotorSettings.IsValid()); mMotorState = inState; }
108
EMotorState GetMotorState() const { return mMotorState; }
109
void SetTargetVelocity(float inVelocity) { mTargetVelocity = inVelocity; }
110
float GetTargetVelocity() const { return mTargetVelocity; }
111
void SetTargetPosition(float inPosition) { mTargetPosition = mHasLimits? Clamp(inPosition, mLimitsMin, mLimitsMax) : inPosition; }
112
float GetTargetPosition() const { return mTargetPosition; }
113
114
/// Update the limits of the slider constraint (see SliderConstraintSettings)
115
void SetLimits(float inLimitsMin, float inLimitsMax);
116
float GetLimitsMin() const { return mLimitsMin; }
117
float GetLimitsMax() const { return mLimitsMax; }
118
bool HasLimits() const { return mHasLimits; }
119
120
/// Update the limits spring settings
121
const SpringSettings & GetLimitsSpringSettings() const { return mLimitsSpringSettings; }
122
SpringSettings & GetLimitsSpringSettings() { return mLimitsSpringSettings; }
123
void SetLimitsSpringSettings(const SpringSettings &inLimitsSpringSettings) { mLimitsSpringSettings = inLimitsSpringSettings; }
124
125
///@name Get Lagrange multiplier from last physics update (the linear/angular impulse applied to satisfy the constraint)
126
inline Vector<2> GetTotalLambdaPosition() const { return mPositionConstraintPart.GetTotalLambda(); }
127
inline float GetTotalLambdaPositionLimits() const { return mPositionLimitsConstraintPart.GetTotalLambda(); }
128
inline Vec3 GetTotalLambdaRotation() const { return mRotationConstraintPart.GetTotalLambda(); }
129
inline float GetTotalLambdaMotor() const { return mMotorConstraintPart.GetTotalLambda(); }
130
131
private:
132
// Internal helper function to calculate the values below
133
void CalculateR1R2U(Mat44Arg inRotation1, Mat44Arg inRotation2);
134
void CalculateSlidingAxisAndPosition(Mat44Arg inRotation1);
135
void CalculatePositionConstraintProperties(Mat44Arg inRotation1, Mat44Arg inRotation2);
136
void CalculatePositionLimitsConstraintProperties(float inDeltaTime);
137
void CalculateMotorConstraintProperties(float inDeltaTime);
138
139
// CONFIGURATION PROPERTIES FOLLOW
140
141
// Local space constraint positions
142
Vec3 mLocalSpacePosition1;
143
Vec3 mLocalSpacePosition2;
144
145
// Local space sliding direction
146
Vec3 mLocalSpaceSliderAxis1;
147
148
// Local space normals to the sliding direction (in body 1 space)
149
Vec3 mLocalSpaceNormal1;
150
Vec3 mLocalSpaceNormal2;
151
152
// Inverse of initial rotation from body 1 to body 2 in body 1 space
153
Quat mInvInitialOrientation;
154
155
// Slider limits
156
bool mHasLimits;
157
float mLimitsMin;
158
float mLimitsMax;
159
160
// Soft constraint limits
161
SpringSettings mLimitsSpringSettings;
162
163
// Friction
164
float mMaxFrictionForce;
165
166
// Motor controls
167
MotorSettings mMotorSettings;
168
EMotorState mMotorState = EMotorState::Off;
169
float mTargetVelocity = 0.0f;
170
float mTargetPosition = 0.0f;
171
172
// RUN TIME PROPERTIES FOLLOW
173
174
// Positions where the point constraint acts on (middle point between center of masses)
175
Vec3 mR1;
176
Vec3 mR2;
177
178
// X2 + R2 - X1 - R1
179
Vec3 mU;
180
181
// World space sliding direction
182
Vec3 mWorldSpaceSliderAxis;
183
184
// Normals to the slider axis
185
Vec3 mN1;
186
Vec3 mN2;
187
188
// Distance along the slide axis
189
float mD = 0.0f;
190
191
// The constraint parts
192
DualAxisConstraintPart mPositionConstraintPart;
193
RotationEulerConstraintPart mRotationConstraintPart;
194
AxisConstraintPart mPositionLimitsConstraintPart;
195
AxisConstraintPart mMotorConstraintPart;
196
};
197
198
JPH_NAMESPACE_END
199
200