Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Body/MotionProperties.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/Body/MotionProperties.h>
8
#include <Jolt/Physics/StateRecorder.h>
9
10
JPH_NAMESPACE_BEGIN
11
12
void MotionProperties::SetMassProperties(EAllowedDOFs inAllowedDOFs, const MassProperties &inMassProperties)
13
{
14
// Store allowed DOFs
15
mAllowedDOFs = inAllowedDOFs;
16
17
// Decompose DOFs
18
uint allowed_translation_axis = uint(inAllowedDOFs) & 0b111;
19
uint allowed_rotation_axis = (uint(inAllowedDOFs) >> 3) & 0b111;
20
21
// Set inverse mass
22
if (allowed_translation_axis == 0)
23
{
24
// No translation possible
25
mInvMass = 0.0f;
26
}
27
else
28
{
29
JPH_ASSERT(inMassProperties.mMass > 0.0f, "Invalid mass. "
30
"Some shapes like MeshShape or TriangleShape cannot calculate mass automatically, "
31
"in this case you need to provide it by setting BodyCreationSettings::mOverrideMassProperties and mMassPropertiesOverride.");
32
mInvMass = 1.0f / inMassProperties.mMass;
33
}
34
35
if (allowed_rotation_axis == 0)
36
{
37
// No rotation possible
38
mInvInertiaDiagonal = Vec3::sZero();
39
mInertiaRotation = Quat::sIdentity();
40
}
41
else
42
{
43
// Set inverse inertia
44
Mat44 rotation;
45
Vec3 diagonal;
46
if (inMassProperties.DecomposePrincipalMomentsOfInertia(rotation, diagonal)
47
&& !diagonal.IsNearZero())
48
{
49
mInvInertiaDiagonal = diagonal.Reciprocal();
50
mInertiaRotation = rotation.GetQuaternion();
51
}
52
else
53
{
54
// Failed! Fall back to inertia tensor of sphere with radius 1.
55
mInvInertiaDiagonal = Vec3::sReplicate(2.5f * mInvMass);
56
mInertiaRotation = Quat::sIdentity();
57
}
58
}
59
60
JPH_ASSERT(mInvMass != 0.0f || mInvInertiaDiagonal != Vec3::sZero(), "Can't lock all axes, use a static body for this. This will crash with a division by zero later!");
61
}
62
63
void MotionProperties::SaveState(StateRecorder &inStream) const
64
{
65
// Only write properties that can change at runtime
66
inStream.Write(mLinearVelocity);
67
inStream.Write(mAngularVelocity);
68
inStream.Write(mForce);
69
inStream.Write(mTorque);
70
#ifdef JPH_DOUBLE_PRECISION
71
inStream.Write(mSleepTestOffset);
72
#endif // JPH_DOUBLE_PRECISION
73
inStream.Write(mSleepTestSpheres);
74
inStream.Write(mSleepTestTimer);
75
inStream.Write(mAllowSleeping);
76
}
77
78
void MotionProperties::RestoreState(StateRecorder &inStream)
79
{
80
inStream.Read(mLinearVelocity);
81
inStream.Read(mAngularVelocity);
82
inStream.Read(mForce);
83
inStream.Read(mTorque);
84
#ifdef JPH_DOUBLE_PRECISION
85
inStream.Read(mSleepTestOffset);
86
#endif // JPH_DOUBLE_PRECISION
87
inStream.Read(mSleepTestSpheres);
88
inStream.Read(mSleepTestTimer);
89
inStream.Read(mAllowSleeping);
90
}
91
92
JPH_NAMESPACE_END
93
94