Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Constraints/DistanceConstraint.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/ConstraintPart/AxisConstraintPart.h>
9
10
JPH_NAMESPACE_BEGIN
11
12
/// Distance constraint settings, used to create a distance constraint
13
class JPH_EXPORT DistanceConstraintSettings final : public TwoBodyConstraintSettings
14
{
15
JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, DistanceConstraintSettings)
16
17
public:
18
// See: ConstraintSettings::SaveBinaryState
19
virtual void SaveBinaryState(StreamOut &inStream) const override;
20
21
/// Create an instance of this constraint
22
virtual TwoBodyConstraint * Create(Body &inBody1, Body &inBody2) const override;
23
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
27
/// Body 1 constraint reference frame (space determined by mSpace).
28
/// Constraint will keep mPoint1 (a point on body 1) and mPoint2 (a point on body 2) at the same distance.
29
/// Note that this constraint can be used as a cheap PointConstraint by setting mPoint1 = mPoint2 (but this removes only 1 degree of freedom instead of 3).
30
RVec3 mPoint1 = RVec3::sZero();
31
32
/// Body 2 constraint reference frame (space determined by mSpace)
33
RVec3 mPoint2 = RVec3::sZero();
34
35
/// Ability to override the distance range at which the two points are kept apart. If the value is negative, it will be replaced by the distance between mPoint1 and mPoint2 (works only if mSpace is world space).
36
float mMinDistance = -1.0f;
37
float mMaxDistance = -1.0f;
38
39
/// When enabled, this makes the limits soft. When the constraint exceeds the limits, a spring force will pull it back.
40
SpringSettings mLimitsSpringSettings;
41
42
protected:
43
// See: ConstraintSettings::RestoreBinaryState
44
virtual void RestoreBinaryState(StreamIn &inStream) override;
45
};
46
47
/// This constraint is a stiff spring that holds 2 points at a fixed distance from each other
48
class JPH_EXPORT DistanceConstraint final : public TwoBodyConstraint
49
{
50
public:
51
JPH_OVERRIDE_NEW_DELETE
52
53
/// Construct distance constraint
54
DistanceConstraint(Body &inBody1, Body &inBody2, const DistanceConstraintSettings &inSettings);
55
56
// Generic interface of a constraint
57
virtual EConstraintSubType GetSubType() const override { return EConstraintSubType::Distance; }
58
virtual void NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM) override;
59
virtual void SetupVelocityConstraint(float inDeltaTime) override;
60
virtual void ResetWarmStart() override;
61
virtual void WarmStartVelocityConstraint(float inWarmStartImpulseRatio) override;
62
virtual bool SolveVelocityConstraint(float inDeltaTime) override;
63
virtual bool SolvePositionConstraint(float inDeltaTime, float inBaumgarte) override;
64
#ifdef JPH_DEBUG_RENDERER
65
virtual void DrawConstraint(DebugRenderer *inRenderer) const override;
66
#endif // JPH_DEBUG_RENDERER
67
virtual void SaveState(StateRecorder &inStream) const override;
68
virtual void RestoreState(StateRecorder &inStream) override;
69
virtual Ref<ConstraintSettings> GetConstraintSettings() const override;
70
71
// See: TwoBodyConstraint
72
virtual Mat44 GetConstraintToBody1Matrix() const override { return Mat44::sTranslation(mLocalSpacePosition1); }
73
virtual Mat44 GetConstraintToBody2Matrix() const override { return Mat44::sTranslation(mLocalSpacePosition2); } // Note: Incorrect rotation as we don't track the original rotation difference, should not matter though as the constraint is not limiting rotation.
74
75
/// Update the minimum and maximum distance for the constraint
76
void SetDistance(float inMinDistance, float inMaxDistance) { JPH_ASSERT(inMinDistance <= inMaxDistance); mMinDistance = inMinDistance; mMaxDistance = inMaxDistance; }
77
float GetMinDistance() const { return mMinDistance; }
78
float GetMaxDistance() const { return mMaxDistance; }
79
80
/// Update the limits spring settings
81
const SpringSettings & GetLimitsSpringSettings() const { return mLimitsSpringSettings; }
82
SpringSettings & GetLimitsSpringSettings() { return mLimitsSpringSettings; }
83
void SetLimitsSpringSettings(const SpringSettings &inLimitsSpringSettings) { mLimitsSpringSettings = inLimitsSpringSettings; }
84
85
///@name Get Lagrange multiplier from last physics update (the linear impulse applied to satisfy the constraint)
86
inline float GetTotalLambdaPosition() const { return mAxisConstraint.GetTotalLambda(); }
87
88
private:
89
// Internal helper function to calculate the values below
90
void CalculateConstraintProperties(float inDeltaTime);
91
92
// CONFIGURATION PROPERTIES FOLLOW
93
94
// Local space constraint positions
95
Vec3 mLocalSpacePosition1;
96
Vec3 mLocalSpacePosition2;
97
98
// Min/max distance that must be kept between the world space points
99
float mMinDistance;
100
float mMaxDistance;
101
102
// Soft constraint limits
103
SpringSettings mLimitsSpringSettings;
104
105
// RUN TIME PROPERTIES FOLLOW
106
107
// World space positions and normal
108
RVec3 mWorldSpacePosition1;
109
RVec3 mWorldSpacePosition2;
110
Vec3 mWorldSpaceNormal;
111
112
// Depending on if the distance < min or distance > max we can apply forces to prevent further violations
113
float mMinLambda;
114
float mMaxLambda;
115
116
// The constraint part
117
AxisConstraintPart mAxisConstraint;
118
};
119
120
JPH_NAMESPACE_END
121
122