Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/patches/0002-backport-upstream-commit-bc7f1fb8c.patch
45998 views
1
diff --git a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp
2
index 7de3a4483e..972fc13583 100644
3
--- a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp
4
+++ b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.cpp
5
@@ -46,7 +46,7 @@ void ContactConstraintManager::WorldContactPoint::CalculateNonPenetrationConstra
6
}
7
8
template <EMotionType Type1, EMotionType Type2>
9
-JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, float inGravityDeltaTimeDotNormal, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution)
10
+JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, Vec3Arg inGravity, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution)
11
{
12
JPH_DET_LOG("TemplatedCalculateFrictionAndNonPenetrationConstraintProperties: p1: " << inWorldSpacePosition1 << " p2: " << inWorldSpacePosition2
13
<< " normal: " << inWorldSpaceNormal << " tangent1: " << inWorldSpaceTangent1 << " tangent2: " << inWorldSpaceTangent2
14
@@ -58,39 +58,19 @@ JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateF
15
Vec3 r1 = Vec3(p - inBody1.GetCenterOfMassPosition());
16
Vec3 r2 = Vec3(p - inBody2.GetCenterOfMassPosition());
17
18
- // The gravity is applied in the beginning of the time step. If we get here, there was a collision
19
- // at the beginning of the time step, so we've applied too much gravity. This means that our
20
- // calculated restitution can be too high, so when we apply restitution, we cancel the added
21
- // velocity due to gravity.
22
- float gravity_dt_dot_normal;
23
+ const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked();
24
+ const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked();
25
26
// Calculate velocity of collision points
27
Vec3 relative_velocity;
28
if constexpr (Type1 != EMotionType::Static && Type2 != EMotionType::Static)
29
- {
30
- const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked();
31
- const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked();
32
relative_velocity = mp2->GetPointVelocityCOM(r2) - mp1->GetPointVelocityCOM(r1);
33
- gravity_dt_dot_normal = inGravityDeltaTimeDotNormal * (mp2->GetGravityFactor() - mp1->GetGravityFactor());
34
- }
35
else if constexpr (Type1 != EMotionType::Static)
36
- {
37
- const MotionProperties *mp1 = inBody1.GetMotionPropertiesUnchecked();
38
relative_velocity = -mp1->GetPointVelocityCOM(r1);
39
- gravity_dt_dot_normal = inGravityDeltaTimeDotNormal * mp1->GetGravityFactor();
40
- }
41
else if constexpr (Type2 != EMotionType::Static)
42
- {
43
- const MotionProperties *mp2 = inBody2.GetMotionPropertiesUnchecked();
44
relative_velocity = mp2->GetPointVelocityCOM(r2);
45
- gravity_dt_dot_normal = inGravityDeltaTimeDotNormal * mp2->GetGravityFactor();
46
- }
47
else
48
- {
49
- JPH_ASSERT(false); // Static vs static makes no sense
50
- relative_velocity = Vec3::sZero();
51
- gravity_dt_dot_normal = 0.0f;
52
- }
53
+ static_assert(false, "Static vs static makes no sense");
54
float normal_velocity = relative_velocity.Dot(inWorldSpaceNormal);
55
56
// How much the shapes are penetrating (> 0 if penetrating, < 0 if separated)
57
@@ -114,11 +94,40 @@ JPH_INLINE void ContactConstraintManager::WorldContactPoint::TemplatedCalculateF
58
// position rather than from a position where it is touching the other object. This causes the object
59
// to appear to move faster for 1 frame (the opposite of time stealing).
60
if (normal_velocity < -speculative_contact_velocity_bias)
61
- normal_velocity_bias = inSettings.mCombinedRestitution * (normal_velocity - gravity_dt_dot_normal);
62
+ {
63
+ // The gravity / constant forces are applied in the beginning of the time step.
64
+ // If we get here, there was a collision at the beginning of the time step, so we've applied too much force.
65
+ // This means that our calculated restitution can be too high resulting in an increase in energy.
66
+ // So, when we apply restitution, we cancel the added velocity due to these forces.
67
+ Vec3 relative_acceleration;
68
+
69
+ // Calculate effect of gravity
70
+ if constexpr (Type1 != EMotionType::Static && Type2 != EMotionType::Static)
71
+ relative_acceleration = inGravity * (mp2->GetGravityFactor() - mp1->GetGravityFactor());
72
+ else if constexpr (Type1 != EMotionType::Static)
73
+ relative_acceleration = -inGravity * mp1->GetGravityFactor();
74
+ else if constexpr (Type2 != EMotionType::Static)
75
+ relative_acceleration = inGravity * mp2->GetGravityFactor();
76
+ else
77
+ static_assert(false, "Static vs static makes no sense");
78
+
79
+ // Calculate effect of accumulated forces
80
+ if constexpr (Type1 == EMotionType::Dynamic)
81
+ relative_acceleration -= mp1->GetAccumulatedForce() * mp1->GetInverseMass();
82
+ if constexpr (Type2 == EMotionType::Dynamic)
83
+ relative_acceleration += mp2->GetAccumulatedForce() * mp2->GetInverseMass();
84
+
85
+ // We only compensate forces towards the contact normal.
86
+ float force_delta_velocity = min(0.0f, relative_acceleration.Dot(inWorldSpaceNormal) * inDeltaTime);
87
+
88
+ normal_velocity_bias = inSettings.mCombinedRestitution * (normal_velocity - force_delta_velocity);
89
+ }
90
else
91
+ {
92
// In this case we have predicted that we don't hit the other object, but if we do (due to other constraints changing velocities)
93
// the speculative contact will prevent penetration but will not apply restitution leading to another artifact.
94
normal_velocity_bias = speculative_contact_velocity_bias;
95
+ }
96
}
97
else
98
{
99
@@ -706,7 +715,7 @@ void ContactConstraintManager::PrepareConstraintBuffer(PhysicsUpdateContext *inC
100
}
101
102
template <EMotionType Type1, EMotionType Type2>
103
-JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)
104
+JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)
105
{
106
// Calculate scaled mass and inertia
107
Mat44 inv_i1;
108
@@ -737,20 +746,17 @@ JPH_INLINE void ContactConstraintManager::TemplatedCalculateFrictionAndNonPenetr
109
110
Vec3 ws_normal = ioConstraint.GetWorldSpaceNormal();
111
112
- // Calculate value for restitution correction
113
- float gravity_dt_dot_normal = inGravityDeltaTime.Dot(ws_normal);
114
-
115
// Setup velocity constraint properties
116
float min_velocity_for_restitution = mPhysicsSettings.mMinVelocityForRestitution;
117
for (WorldContactPoint &wcp : ioConstraint.mContactPoints)
118
{
119
RVec3 p1 = inTransformBody1 * Vec3::sLoadFloat3Unsafe(wcp.mContactPoint->mPosition1);
120
RVec3 p2 = inTransformBody2 * Vec3::sLoadFloat3Unsafe(wcp.mContactPoint->mPosition2);
121
- wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(inDeltaTime, gravity_dt_dot_normal, inBody1, inBody2, ioConstraint.mInvMass1, ioConstraint.mInvMass2, inv_i1, inv_i2, p1, p2, ws_normal, t1, t2, inSettings, min_velocity_for_restitution);
122
+ wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(inDeltaTime, inGravity, inBody1, inBody2, ioConstraint.mInvMass1, ioConstraint.mInvMass2, inv_i1, inv_i2, p1, p2, ws_normal, t1, t2, inSettings, min_velocity_for_restitution);
123
}
124
}
125
126
-inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)
127
+inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2)
128
{
129
// Dispatch to the correct templated form
130
switch (inBody1.GetMotionType())
131
@@ -759,15 +765,15 @@ inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstrai
132
switch (inBody2.GetMotionType())
133
{
134
case EMotionType::Dynamic:
135
- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);
136
+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);
137
break;
138
139
case EMotionType::Kinematic:
140
- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Kinematic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);
141
+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Kinematic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);
142
break;
143
144
case EMotionType::Static:
145
- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Static>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);
146
+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Dynamic, EMotionType::Static>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);
147
break;
148
149
default:
150
@@ -778,12 +784,12 @@ inline void ContactConstraintManager::CalculateFrictionAndNonPenetrationConstrai
151
152
case EMotionType::Kinematic:
153
JPH_ASSERT(inBody2.IsDynamic());
154
- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Kinematic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);
155
+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Kinematic, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);
156
break;
157
158
case EMotionType::Static:
159
JPH_ASSERT(inBody2.IsDynamic());
160
- TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Static, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravityDeltaTime, inTransformBody1, inTransformBody2, inBody1, inBody2);
161
+ TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<EMotionType::Static, EMotionType::Dynamic>(ioConstraint, inSettings, inDeltaTime, inGravity, inTransformBody1, inTransformBody2, inBody1, inBody2);
162
break;
163
164
default:
165
@@ -863,11 +869,9 @@ void ContactConstraintManager::GetContactsFromCache(ContactAllocator &ioContactA
166
RMat44 transform_body1 = body1->GetCenterOfMassTransform();
167
RMat44 transform_body2 = body2->GetCenterOfMassTransform();
168
169
- // Get time step
170
+ // Get time step and gravity
171
float delta_time = mUpdateContext->mStepDeltaTime;
172
-
173
- // Calculate value for restitution correction
174
- Vec3 gravity_dt = mUpdateContext->mPhysicsSystem->GetGravity() * delta_time;
175
+ Vec3 gravity = mUpdateContext->mPhysicsSystem->GetGravity();
176
177
// Copy manifolds
178
uint32 output_handle = ManifoldMap::cInvalidHandle;
179
@@ -970,7 +974,7 @@ void ContactConstraintManager::GetContactsFromCache(ContactAllocator &ioContactA
180
JPH_DET_LOG("GetContactsFromCache: id1: " << constraint.mBody1->GetID() << " id2: " << constraint.mBody2->GetID() << " key: " << constraint.mSortKey);
181
182
// Calculate friction and non-penetration constraint properties for all contact points
183
- CalculateFrictionAndNonPenetrationConstraintProperties(constraint, settings, delta_time, gravity_dt, transform_body1, transform_body2, *body1, *body2);
184
+ CalculateFrictionAndNonPenetrationConstraintProperties(constraint, settings, delta_time, gravity, transform_body1, transform_body2, *body1, *body2);
185
186
// Notify island builder
187
mUpdateContext->mIslandBuilder->LinkContact(constraint_idx, body1->GetIndexInActiveBodiesInternal(), body2->GetIndexInActiveBodiesInternal());
188
@@ -1144,11 +1148,9 @@ bool ContactConstraintManager::TemplatedAddContactConstraint(ContactAllocator &i
189
// Notify island builder
190
mUpdateContext->mIslandBuilder->LinkContact(constraint_idx, inBody1.GetIndexInActiveBodiesInternal(), inBody2.GetIndexInActiveBodiesInternal());
191
192
- // Get time step
193
+ // Get time step and gravity
194
float delta_time = mUpdateContext->mStepDeltaTime;
195
-
196
- // Calculate value for restitution correction
197
- float gravity_dt_dot_normal = inManifold.mWorldSpaceNormal.Dot(mUpdateContext->mPhysicsSystem->GetGravity() * delta_time);
198
+ Vec3 gravity = mUpdateContext->mPhysicsSystem->GetGravity();
199
200
// Calculate scaled mass and inertia
201
float inv_m1;
202
@@ -1222,7 +1224,7 @@ bool ContactConstraintManager::TemplatedAddContactConstraint(ContactAllocator &i
203
wcp.mContactPoint = &cp;
204
205
// Setup velocity constraint
206
- wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(delta_time, gravity_dt_dot_normal, inBody1, inBody2, inv_m1, inv_m2, inv_i1, inv_i2, p1_ws, p2_ws, inManifold.mWorldSpaceNormal, t1, t2, settings, mPhysicsSettings.mMinVelocityForRestitution);
207
+ wcp.TemplatedCalculateFrictionAndNonPenetrationConstraintProperties<Type1, Type2>(delta_time, gravity, inBody1, inBody2, inv_m1, inv_m2, inv_i1, inv_i2, p1_ws, p2_ws, inManifold.mWorldSpaceNormal, t1, t2, settings, mPhysicsSettings.mMinVelocityForRestitution);
208
}
209
210
#ifdef JPH_DEBUG_RENDERER
211
diff --git a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h
212
index 0b5938b77e..dfe5fc8c38 100644
213
--- a/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h
214
+++ b/thirdparty/jolt_physics/Jolt/Physics/Constraints/ContactConstraintManager.h
215
@@ -427,7 +427,7 @@ private:
216
void CalculateNonPenetrationConstraintProperties(const Body &inBody1, float inInvMass1, float inInvInertiaScale1, const Body &inBody2, float inInvMass2, float inInvInertiaScale2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal);
217
218
template <EMotionType Type1, EMotionType Type2>
219
- JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, float inGravityDeltaTimeDotNormal, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution);
220
+ JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(float inDeltaTime, Vec3Arg inGravity, const Body &inBody1, const Body &inBody2, float inInvM1, float inInvM2, Mat44Arg inInvI1, Mat44Arg inInvI2, RVec3Arg inWorldSpacePosition1, RVec3Arg inWorldSpacePosition2, Vec3Arg inWorldSpaceNormal, Vec3Arg inWorldSpaceTangent1, Vec3Arg inWorldSpaceTangent2, const ContactSettings &inSettings, float inMinVelocityForRestitution);
221
222
/// The constraint parts
223
AxisConstraintPart mNonPenetrationConstraint;
224
@@ -485,10 +485,10 @@ public:
225
private:
226
/// Internal helper function to calculate the friction and non-penetration constraint properties. Templated to the motion type to reduce the amount of branches and calculations.
227
template <EMotionType Type1, EMotionType Type2>
228
- JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);
229
+ JPH_INLINE void TemplatedCalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);
230
231
/// Internal helper function to calculate the friction and non-penetration constraint properties.
232
- inline void CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravityDeltaTime, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);
233
+ inline void CalculateFrictionAndNonPenetrationConstraintProperties(ContactConstraint &ioConstraint, const ContactSettings &inSettings, float inDeltaTime, Vec3Arg inGravity, RMat44Arg inTransformBody1, RMat44Arg inTransformBody2, const Body &inBody1, const Body &inBody2);
234
235
/// Internal helper function to add a contact constraint. Templated to the motion type to reduce the amount of branches and calculations.
236
template <EMotionType Type1, EMotionType Type2>
237
238