Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Constraints/PointConstraint.cpp
9913 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#include <Jolt/Jolt.h>
6
7
#include <Jolt/Physics/Constraints/PointConstraint.h>
8
#include <Jolt/Physics/Body/Body.h>
9
#include <Jolt/ObjectStream/TypeDeclarations.h>
10
#include <Jolt/Core/StreamIn.h>
11
#include <Jolt/Core/StreamOut.h>
12
#ifdef JPH_DEBUG_RENDERER
13
#include <Jolt/Renderer/DebugRenderer.h>
14
#endif // JPH_DEBUG_RENDERER
15
16
JPH_NAMESPACE_BEGIN
17
18
JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL(PointConstraintSettings)
19
{
20
JPH_ADD_BASE_CLASS(PointConstraintSettings, TwoBodyConstraintSettings)
21
22
JPH_ADD_ENUM_ATTRIBUTE(PointConstraintSettings, mSpace)
23
JPH_ADD_ATTRIBUTE(PointConstraintSettings, mPoint1)
24
JPH_ADD_ATTRIBUTE(PointConstraintSettings, mPoint2)
25
}
26
27
void PointConstraintSettings::SaveBinaryState(StreamOut &inStream) const
28
{
29
ConstraintSettings::SaveBinaryState(inStream);
30
31
inStream.Write(mSpace);
32
inStream.Write(mPoint1);
33
inStream.Write(mPoint2);
34
}
35
36
void PointConstraintSettings::RestoreBinaryState(StreamIn &inStream)
37
{
38
ConstraintSettings::RestoreBinaryState(inStream);
39
40
inStream.Read(mSpace);
41
inStream.Read(mPoint1);
42
inStream.Read(mPoint2);
43
}
44
45
TwoBodyConstraint *PointConstraintSettings::Create(Body &inBody1, Body &inBody2) const
46
{
47
return new PointConstraint(inBody1, inBody2, *this);
48
}
49
50
PointConstraint::PointConstraint(Body &inBody1, Body &inBody2, const PointConstraintSettings &inSettings) :
51
TwoBodyConstraint(inBody1, inBody2, inSettings)
52
{
53
if (inSettings.mSpace == EConstraintSpace::WorldSpace)
54
{
55
// If all properties were specified in world space, take them to local space now
56
mLocalSpacePosition1 = Vec3(inBody1.GetInverseCenterOfMassTransform() * inSettings.mPoint1);
57
mLocalSpacePosition2 = Vec3(inBody2.GetInverseCenterOfMassTransform() * inSettings.mPoint2);
58
}
59
else
60
{
61
mLocalSpacePosition1 = Vec3(inSettings.mPoint1);
62
mLocalSpacePosition2 = Vec3(inSettings.mPoint2);
63
}
64
}
65
66
void PointConstraint::NotifyShapeChanged(const BodyID &inBodyID, Vec3Arg inDeltaCOM)
67
{
68
if (mBody1->GetID() == inBodyID)
69
mLocalSpacePosition1 -= inDeltaCOM;
70
else if (mBody2->GetID() == inBodyID)
71
mLocalSpacePosition2 -= inDeltaCOM;
72
}
73
74
void PointConstraint::SetPoint1(EConstraintSpace inSpace, RVec3Arg inPoint1)
75
{
76
if (inSpace == EConstraintSpace::WorldSpace)
77
mLocalSpacePosition1 = Vec3(mBody1->GetInverseCenterOfMassTransform() * inPoint1);
78
else
79
mLocalSpacePosition1 = Vec3(inPoint1);
80
}
81
82
void PointConstraint::SetPoint2(EConstraintSpace inSpace, RVec3Arg inPoint2)
83
{
84
if (inSpace == EConstraintSpace::WorldSpace)
85
mLocalSpacePosition2 = Vec3(mBody2->GetInverseCenterOfMassTransform() * inPoint2);
86
else
87
mLocalSpacePosition2 = Vec3(inPoint2);
88
}
89
90
void PointConstraint::CalculateConstraintProperties()
91
{
92
mPointConstraintPart.CalculateConstraintProperties(*mBody1, Mat44::sRotation(mBody1->GetRotation()), mLocalSpacePosition1, *mBody2, Mat44::sRotation(mBody2->GetRotation()), mLocalSpacePosition2);
93
}
94
95
void PointConstraint::SetupVelocityConstraint(float inDeltaTime)
96
{
97
CalculateConstraintProperties();
98
}
99
100
void PointConstraint::ResetWarmStart()
101
{
102
mPointConstraintPart.Deactivate();
103
}
104
105
void PointConstraint::WarmStartVelocityConstraint(float inWarmStartImpulseRatio)
106
{
107
// Warm starting: Apply previous frame impulse
108
mPointConstraintPart.WarmStart(*mBody1, *mBody2, inWarmStartImpulseRatio);
109
}
110
111
bool PointConstraint::SolveVelocityConstraint(float inDeltaTime)
112
{
113
return mPointConstraintPart.SolveVelocityConstraint(*mBody1, *mBody2);
114
}
115
116
bool PointConstraint::SolvePositionConstraint(float inDeltaTime, float inBaumgarte)
117
{
118
// Update constraint properties (bodies may have moved)
119
CalculateConstraintProperties();
120
121
return mPointConstraintPart.SolvePositionConstraint(*mBody1, *mBody2, inBaumgarte);
122
}
123
124
#ifdef JPH_DEBUG_RENDERER
125
void PointConstraint::DrawConstraint(DebugRenderer *inRenderer) const
126
{
127
// Draw constraint
128
inRenderer->DrawMarker(mBody1->GetCenterOfMassTransform() * mLocalSpacePosition1, Color::sRed, 0.1f);
129
inRenderer->DrawMarker(mBody2->GetCenterOfMassTransform() * mLocalSpacePosition2, Color::sGreen, 0.1f);
130
}
131
#endif // JPH_DEBUG_RENDERER
132
133
void PointConstraint::SaveState(StateRecorder &inStream) const
134
{
135
TwoBodyConstraint::SaveState(inStream);
136
137
mPointConstraintPart.SaveState(inStream);
138
}
139
140
void PointConstraint::RestoreState(StateRecorder &inStream)
141
{
142
TwoBodyConstraint::RestoreState(inStream);
143
144
mPointConstraintPart.RestoreState(inStream);
145
}
146
147
Ref<ConstraintSettings> PointConstraint::GetConstraintSettings() const
148
{
149
PointConstraintSettings *settings = new PointConstraintSettings;
150
ToConstraintSettings(*settings);
151
settings->mSpace = EConstraintSpace::LocalToBodyCOM;
152
settings->mPoint1 = RVec3(mLocalSpacePosition1);
153
settings->mPoint2 = RVec3(mLocalSpacePosition2);
154
return settings;
155
}
156
157
JPH_NAMESPACE_END
158
159