Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/BodyCreationSettings.cpp
9912 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/Body/BodyCreationSettings.h>
8
#include <Jolt/ObjectStream/TypeDeclarations.h>
9
#include <Jolt/Core/StreamIn.h>
10
#include <Jolt/Core/StreamOut.h>
11
12
JPH_NAMESPACE_BEGIN
13
14
JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(BodyCreationSettings)
15
{
16
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mPosition)
17
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mRotation)
18
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mLinearVelocity)
19
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAngularVelocity)
20
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mUserData)
21
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mShape)
22
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mCollisionGroup)
23
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mObjectLayer)
24
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mMotionType)
25
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mAllowedDOFs)
26
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAllowDynamicOrKinematic)
27
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mIsSensor)
28
JPH_ADD_ATTRIBUTE_WITH_ALIAS(BodyCreationSettings, mCollideKinematicVsNonDynamic, "mSensorDetectsStatic") // This is the old name to keep backwards compatibility
29
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mUseManifoldReduction)
30
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mApplyGyroscopicForce)
31
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mMotionQuality)
32
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mEnhancedInternalEdgeRemoval)
33
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAllowSleeping)
34
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mFriction)
35
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mRestitution)
36
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mLinearDamping)
37
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mAngularDamping)
38
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMaxLinearVelocity)
39
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMaxAngularVelocity)
40
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mGravityFactor)
41
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mNumVelocityStepsOverride)
42
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mNumPositionStepsOverride)
43
JPH_ADD_ENUM_ATTRIBUTE(BodyCreationSettings, mOverrideMassProperties)
44
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mInertiaMultiplier)
45
JPH_ADD_ATTRIBUTE(BodyCreationSettings, mMassPropertiesOverride)
46
}
47
48
void BodyCreationSettings::SaveBinaryState(StreamOut &inStream) const
49
{
50
inStream.Write(mPosition);
51
inStream.Write(mRotation);
52
inStream.Write(mLinearVelocity);
53
inStream.Write(mAngularVelocity);
54
mCollisionGroup.SaveBinaryState(inStream);
55
inStream.Write(mObjectLayer);
56
inStream.Write(mMotionType);
57
inStream.Write(mAllowedDOFs);
58
inStream.Write(mAllowDynamicOrKinematic);
59
inStream.Write(mIsSensor);
60
inStream.Write(mCollideKinematicVsNonDynamic);
61
inStream.Write(mUseManifoldReduction);
62
inStream.Write(mApplyGyroscopicForce);
63
inStream.Write(mMotionQuality);
64
inStream.Write(mEnhancedInternalEdgeRemoval);
65
inStream.Write(mAllowSleeping);
66
inStream.Write(mFriction);
67
inStream.Write(mRestitution);
68
inStream.Write(mLinearDamping);
69
inStream.Write(mAngularDamping);
70
inStream.Write(mMaxLinearVelocity);
71
inStream.Write(mMaxAngularVelocity);
72
inStream.Write(mGravityFactor);
73
inStream.Write(mNumVelocityStepsOverride);
74
inStream.Write(mNumPositionStepsOverride);
75
inStream.Write(mOverrideMassProperties);
76
inStream.Write(mInertiaMultiplier);
77
mMassPropertiesOverride.SaveBinaryState(inStream);
78
}
79
80
void BodyCreationSettings::RestoreBinaryState(StreamIn &inStream)
81
{
82
inStream.Read(mPosition);
83
inStream.Read(mRotation);
84
inStream.Read(mLinearVelocity);
85
inStream.Read(mAngularVelocity);
86
mCollisionGroup.RestoreBinaryState(inStream);
87
inStream.Read(mObjectLayer);
88
inStream.Read(mMotionType);
89
inStream.Read(mAllowedDOFs);
90
inStream.Read(mAllowDynamicOrKinematic);
91
inStream.Read(mIsSensor);
92
inStream.Read(mCollideKinematicVsNonDynamic);
93
inStream.Read(mUseManifoldReduction);
94
inStream.Read(mApplyGyroscopicForce);
95
inStream.Read(mMotionQuality);
96
inStream.Read(mEnhancedInternalEdgeRemoval);
97
inStream.Read(mAllowSleeping);
98
inStream.Read(mFriction);
99
inStream.Read(mRestitution);
100
inStream.Read(mLinearDamping);
101
inStream.Read(mAngularDamping);
102
inStream.Read(mMaxLinearVelocity);
103
inStream.Read(mMaxAngularVelocity);
104
inStream.Read(mGravityFactor);
105
inStream.Read(mNumVelocityStepsOverride);
106
inStream.Read(mNumPositionStepsOverride);
107
inStream.Read(mOverrideMassProperties);
108
inStream.Read(mInertiaMultiplier);
109
mMassPropertiesOverride.RestoreBinaryState(inStream);
110
}
111
112
Shape::ShapeResult BodyCreationSettings::ConvertShapeSettings()
113
{
114
// If we already have a shape, return it
115
if (mShapePtr != nullptr)
116
{
117
mShape = nullptr;
118
119
Shape::ShapeResult result;
120
result.Set(const_cast<Shape *>(mShapePtr.GetPtr()));
121
return result;
122
}
123
124
// Check if we have shape settings
125
if (mShape == nullptr)
126
{
127
Shape::ShapeResult result;
128
result.SetError("No shape present!");
129
return result;
130
}
131
132
// Create the shape
133
Shape::ShapeResult result = mShape->Create();
134
if (result.IsValid())
135
mShapePtr = result.Get();
136
mShape = nullptr;
137
return result;
138
}
139
140
const Shape *BodyCreationSettings::GetShape() const
141
{
142
// If we already have a shape, return it
143
if (mShapePtr != nullptr)
144
return mShapePtr;
145
146
// Check if we have shape settings
147
if (mShape == nullptr)
148
return nullptr;
149
150
// Create the shape
151
Shape::ShapeResult result = mShape->Create();
152
if (result.IsValid())
153
return result.Get();
154
155
Trace("Error: %s", result.GetError().c_str());
156
JPH_ASSERT(false, "An error occurred during shape creation. Use ConvertShapeSettings() to convert the shape and get the error!");
157
return nullptr;
158
}
159
160
MassProperties BodyCreationSettings::GetMassProperties() const
161
{
162
// Calculate mass properties
163
MassProperties mass_properties;
164
switch (mOverrideMassProperties)
165
{
166
case EOverrideMassProperties::CalculateMassAndInertia:
167
mass_properties = GetShape()->GetMassProperties();
168
mass_properties.mInertia *= mInertiaMultiplier;
169
mass_properties.mInertia(3, 3) = 1.0f;
170
break;
171
case EOverrideMassProperties::CalculateInertia:
172
mass_properties = GetShape()->GetMassProperties();
173
mass_properties.ScaleToMass(mMassPropertiesOverride.mMass);
174
mass_properties.mInertia *= mInertiaMultiplier;
175
mass_properties.mInertia(3, 3) = 1.0f;
176
break;
177
case EOverrideMassProperties::MassAndInertiaProvided:
178
mass_properties = mMassPropertiesOverride;
179
break;
180
}
181
return mass_properties;
182
}
183
184
void BodyCreationSettings::SaveWithChildren(StreamOut &inStream, ShapeToIDMap *ioShapeMap, MaterialToIDMap *ioMaterialMap, GroupFilterToIDMap *ioGroupFilterMap) const
185
{
186
// Save creation settings
187
SaveBinaryState(inStream);
188
189
// Save shape
190
if (ioShapeMap != nullptr && ioMaterialMap != nullptr)
191
GetShape()->SaveWithChildren(inStream, *ioShapeMap, *ioMaterialMap);
192
else
193
inStream.Write(~uint32(0));
194
195
// Save group filter
196
StreamUtils::SaveObjectReference(inStream, mCollisionGroup.GetGroupFilter(), ioGroupFilterMap);
197
}
198
199
BodyCreationSettings::BCSResult BodyCreationSettings::sRestoreWithChildren(StreamIn &inStream, IDToShapeMap &ioShapeMap, IDToMaterialMap &ioMaterialMap, IDToGroupFilterMap &ioGroupFilterMap)
200
{
201
BCSResult result;
202
203
// Read creation settings
204
BodyCreationSettings settings;
205
settings.RestoreBinaryState(inStream);
206
if (inStream.IsEOF() || inStream.IsFailed())
207
{
208
result.SetError("Error reading body creation settings");
209
return result;
210
}
211
212
// Read shape
213
Shape::ShapeResult shape_result = Shape::sRestoreWithChildren(inStream, ioShapeMap, ioMaterialMap);
214
if (shape_result.HasError())
215
{
216
result.SetError(shape_result.GetError());
217
return result;
218
}
219
settings.SetShape(shape_result.Get());
220
221
// Read group filter
222
Result gfresult = StreamUtils::RestoreObjectReference(inStream, ioGroupFilterMap);
223
if (gfresult.HasError())
224
{
225
result.SetError(gfresult.GetError());
226
return result;
227
}
228
settings.mCollisionGroup.SetGroupFilter(gfresult.Get());
229
230
result.Set(settings);
231
return result;
232
}
233
234
JPH_NAMESPACE_END
235
236