UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDCollisionSolverJacobi.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Core.h"
6#include "Chaos/Defines.h"
9
10namespace Chaos
11{
12 class FManifoldPoint;
13 class FPBDCollisionConstraint;
14
15 namespace Private
16 {
17 class FPBDCollisionSolverJacobi;
18 }
19
20 namespace CVars
21 {
27 }
28
29 namespace Private
30 {
32 {
36 };
37
39 {
41 };
42
47 {
48 public:
49 static const int32 MaxManifoldPoints = 4;
50
51 void Reset()
52 {
53 ManifoldPoints.Reset();
54 }
55
60
62 {
63 return ManifoldPoints.AddUninitialized();
64 }
65
67 const int32 ManifoldPointIndex,
77 {
78 ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0 = InRelativeContactPosition0;
79 ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1 = InRelativeContactPosition1;
80 ManifoldPoints[ManifoldPointIndex].ContactNormal = InWorldContactNormal;
81 ManifoldPoints[ManifoldPointIndex].ContactTangentU = InWorldContactTangentU;
82 ManifoldPoints[ManifoldPointIndex].ContactTangentV = InWorldContactTangentV;
83 ManifoldPoints[ManifoldPointIndex].ContactDeltaNormal = InWorldContactDeltaNormal;
84 ManifoldPoints[ManifoldPointIndex].ContactDeltaTangentU = InWorldContactDeltaTangentU;
85 ManifoldPoints[ManifoldPointIndex].ContactDeltaTangentV = InWorldContactDeltaTangentV;
86 ManifoldPoints[ManifoldPointIndex].ContactTargetVelocityNormal = InWorldContactVelocityTargetNormal;
87 }
88
93 const int32 ManifoldPointIndex,
94 const FConstraintSolverBody& Body0,
95 const FConstraintSolverBody& Body1)
96 {
97 ManifoldPoints[ManifoldPointIndex].NetPushOutNormal = FSolverReal(0);
98 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU = FSolverReal(0);
99 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV = FSolverReal(0);
100 ManifoldPoints[ManifoldPointIndex].NetImpulseNormal = FSolverReal(0);
101 ManifoldPoints[ManifoldPointIndex].NetImpulseTangentU = FSolverReal(0);
102 ManifoldPoints[ManifoldPointIndex].NetImpulseTangentV = FSolverReal(0);
103 ManifoldPoints[ManifoldPointIndex].StaticFrictionRatio = FSolverReal(0);
104
105 UpdateMass(ManifoldPointIndex, Body0, Body1);
106 }
107
112 const int32 ManifoldPointIndex,
113 const FConstraintSolverBody& Body0,
114 const FConstraintSolverBody& Body1)
115 {
119
120 if (Body0.IsDynamic())
121 {
122 const FSolverVec3 R0xN = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0, ManifoldPoints[ManifoldPointIndex].ContactNormal);
123 const FSolverVec3 R0xU = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0, ManifoldPoints[ManifoldPointIndex].ContactTangentU);
124 const FSolverVec3 R0xV = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0, ManifoldPoints[ManifoldPointIndex].ContactTangentV);
125
126 const FSolverMatrix33 InvI0 = Body0.InvI();
127
128 ManifoldPoints[ManifoldPointIndex].ContactNormalAngular0 = InvI0 * R0xN;
129 ManifoldPoints[ManifoldPointIndex].ContactTangentUAngular0 = InvI0 * R0xU;
130 ManifoldPoints[ManifoldPointIndex].ContactTangentVAngular0 = InvI0 * R0xV;
131
132 ContactMassInvNormal += FSolverVec3::DotProduct(R0xN, ManifoldPoints[ManifoldPointIndex].ContactNormalAngular0) + Body0.InvM();
133 ContactMassInvTangentU += FSolverVec3::DotProduct(R0xU, ManifoldPoints[ManifoldPointIndex].ContactTangentUAngular0) + Body0.InvM();
134 ContactMassInvTangentV += FSolverVec3::DotProduct(R0xV, ManifoldPoints[ManifoldPointIndex].ContactTangentVAngular0) + Body0.InvM();
135 }
136 if (Body1.IsDynamic())
137 {
138 const FSolverVec3 R1xN = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1, ManifoldPoints[ManifoldPointIndex].ContactNormal);
139 const FSolverVec3 R1xU = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1, ManifoldPoints[ManifoldPointIndex].ContactTangentU);
140 const FSolverVec3 R1xV = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1, ManifoldPoints[ManifoldPointIndex].ContactTangentV);
141
142 const FSolverMatrix33 InvI1 = Body1.InvI();
143
144 ManifoldPoints[ManifoldPointIndex].ContactNormalAngular1 = InvI1 * R1xN;
145 ManifoldPoints[ManifoldPointIndex].ContactTangentUAngular1 = InvI1 * R1xU;
146 ManifoldPoints[ManifoldPointIndex].ContactTangentVAngular1 = InvI1 * R1xV;
147
148 ContactMassInvNormal += FSolverVec3::DotProduct(R1xN, ManifoldPoints[ManifoldPointIndex].ContactNormalAngular1) + Body1.InvM();
149 ContactMassInvTangentU += FSolverVec3::DotProduct(R1xU, ManifoldPoints[ManifoldPointIndex].ContactTangentUAngular1) + Body1.InvM();
150 ContactMassInvTangentV += FSolverVec3::DotProduct(R1xV, ManifoldPoints[ManifoldPointIndex].ContactTangentVAngular1) + Body1.InvM();
151 }
152
153 ManifoldPoints[ManifoldPointIndex].ContactMassNormal = (ContactMassInvNormal > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvNormal : FSolverReal(0);
154 ManifoldPoints[ManifoldPointIndex].ContactMassTangentU = (ContactMassInvTangentU > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvTangentU : FSolverReal(0);
155 ManifoldPoints[ManifoldPointIndex].ContactMassTangentV = (ContactMassInvTangentV > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvTangentV : FSolverReal(0);
156 }
157
163 const int32 ManifoldPointIndex,
164 const FConstraintSolverBody& Body0,
165 const FConstraintSolverBody& Body1)
166 {
168 if (Body0.IsDynamic())
169 {
170 const FSolverVec3 R0xN = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0, ManifoldPoints[ManifoldPointIndex].ContactNormal);
171 const FSolverMatrix33 InvI0 = Body0.InvI();
172 ManifoldPoints[ManifoldPointIndex].ContactNormalAngular0 = InvI0 * R0xN;
173 ContactMassInvNormal += FSolverVec3::DotProduct(R0xN, ManifoldPoints[ManifoldPointIndex].ContactNormalAngular0) + Body0.InvM();
174 }
175 if (Body1.IsDynamic())
176 {
177 const FSolverVec3 R1xN = FSolverVec3::CrossProduct(ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1, ManifoldPoints[ManifoldPointIndex].ContactNormal);
178 const FSolverMatrix33 InvI1 = Body1.InvI();
179 ManifoldPoints[ManifoldPointIndex].ContactNormalAngular1 = InvI1 * R1xN;
180 ContactMassInvNormal += FSolverVec3::DotProduct(R1xN, ManifoldPoints[ManifoldPointIndex].ContactNormalAngular1) + Body1.InvM();
181 }
182 ManifoldPoints[ManifoldPointIndex].ContactMassNormal = (ContactMassInvNormal > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvNormal : FSolverReal(0);
183 }
184
186 {
187 return ManifoldPoints[ManifoldPointIndex].NetPushOutNormal* ManifoldPoints[ManifoldPointIndex].ContactNormal +
188 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU * ManifoldPoints[ManifoldPointIndex].ContactTangentU +
189 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV * ManifoldPoints[ManifoldPointIndex].ContactTangentV;
190 }
191
193 {
194 return ManifoldPoints[ManifoldPointIndex].NetImpulseNormal* ManifoldPoints[ManifoldPointIndex].ContactNormal +
195 ManifoldPoints[ManifoldPointIndex].NetImpulseTangentU * ManifoldPoints[ManifoldPointIndex].ContactTangentU +
196 ManifoldPoints[ManifoldPointIndex].NetImpulseTangentV * ManifoldPoints[ManifoldPointIndex].ContactTangentV;
197 }
198
200 {
201 return ManifoldPoints[ManifoldPointIndex].StaticFrictionRatio;
202 }
203
209 const int32 ManifoldPointIndex,
210 const FConstraintSolverBody& Body0,
211 const FConstraintSolverBody& Body1,
212 const FSolverReal MaxPushOut,
214 {
215 // Linear version: calculate the contact delta assuming linear motion after applying a positional impulse at the contact point. There will be an error that depends on the size of the rotation.
216 const FSolverVec3 ContactDelta0 = Body0.DP() + FSolverVec3::CrossProduct(Body0.DQ(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0);
217 const FSolverVec3 ContactDelta1 = Body1.DP() + FSolverVec3::CrossProduct(Body1.DQ(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1);
219 OutContactDeltaNormal = ManifoldPoints[ManifoldPointIndex].ContactDeltaNormal + FSolverVec3::DotProduct(ContactDelta, ManifoldPoints[ManifoldPointIndex].ContactNormal);
220
221 // NOTE: OutContactDeltaNormal is negative for penetration
222 // NOTE: MaxPushOut == 0 disables the pushout limits
224 {
226 }
227 }
228
230 const int32 ManifoldPointIndex,
231 const FConstraintSolverBody& Body0,
232 const FConstraintSolverBody& Body1,
235 {
236 // Linear version: calculate the contact delta assuming linear motion after applying a positional impulse at the contact point. There will be an error that depends on the size of the rotation.
237 const FSolverVec3 ContactDelta0 = Body0.DP() + FSolverVec3::CrossProduct(Body0.DQ(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0);
238 const FSolverVec3 ContactDelta1 = Body1.DP() + FSolverVec3::CrossProduct(Body1.DQ(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1);
240 OutContactDeltaTangentU = ManifoldPoints[ManifoldPointIndex].ContactDeltaTangentU + FSolverVec3::DotProduct(ContactDelta, ManifoldPoints[ManifoldPointIndex].ContactTangentU);
241 OutContactDeltaTangentV = ManifoldPoints[ManifoldPointIndex].ContactDeltaTangentV + FSolverVec3::DotProduct(ContactDelta, ManifoldPoints[ManifoldPointIndex].ContactTangentV);
242 }
243
245 const int32 ManifoldPointIndex,
247 FSolverReal ContactDeltaNormal,
254 {
255 FSolverReal PushOutNormal = -Stiffness * ContactDeltaNormal * ManifoldPoints[ManifoldPointIndex].ContactMassNormal;
256
257 // The total pushout so far this sub-step
258 // Unilateral constraint: Net-negative impulses not allowed (negative incremental impulses are allowed as long as the net is positive)
259 if ((ManifoldPoints[ManifoldPointIndex].NetPushOutNormal + PushOutNormal) > FSolverReal(0))
260 {
261 ManifoldPoints[ManifoldPointIndex].NetPushOutNormal += PushOutNormal;
262 }
263 else
264 {
265 PushOutNormal = -ManifoldPoints[ManifoldPointIndex].NetPushOutNormal;
266 ManifoldPoints[ManifoldPointIndex].NetPushOutNormal = 0;
267 }
268
269 // Update the particle state based on the pushout
270 if (Body0.IsDynamic())
271 {
272 InOutDX0 += (Body0.InvM() * PushOutNormal) * ManifoldPoints[ManifoldPointIndex].ContactNormal;
273 InOutDR0 += ManifoldPoints[ManifoldPointIndex].ContactNormalAngular0 * PushOutNormal;
274 }
275 if (Body1.IsDynamic())
276 {
277 InOutDX1 -= (Body1.InvM() * PushOutNormal) * ManifoldPoints[ManifoldPointIndex].ContactNormal;
278 InOutDR1 -= ManifoldPoints[ManifoldPointIndex].ContactNormalAngular1 * PushOutNormal;
279 }
280 }
281
283 const int32 ManifoldPointIndex,
284 const FSolverReal StaticFriction,
285 const FSolverReal DynamicFriction,
289 {
290 // Assume we stay in the friction cone...
291 ManifoldPoints[ManifoldPointIndex].StaticFrictionRatio = FSolverReal(1);
292
294 {
295 // Note: we have already added the current iteration's PushOut to the NetPushOut but it has not been applied to the body
296 // so we must subtract it again to calculate the actual pushout we want to undo (i.e., the net pushout that has been applied
297 // to the body so far from previous iterations)
298 InOutPushOutTangentU = -(ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU - InOutPushOutTangentU);
299 InOutPushOutTangentV = -(ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV - InOutPushOutTangentV);
300 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU = FSolverReal(0);
301 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV = FSolverReal(0);
302 ManifoldPoints[ManifoldPointIndex].StaticFrictionRatio = FSolverReal(0);
303 }
304 else
305 {
306 // If we exceed the static friction cone, clip to the dynamic friction cone
308 const FSolverReal NetPushOutTangentSq = FMath::Square(ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU) + FMath::Square(ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV);
310 {
312 const FSolverReal FrictionMultiplier = MaxDynamicPushOutTangent * FMath::InvSqrt(NetPushOutTangentSq);
313 const FSolverReal NetPushOutTangentU = FrictionMultiplier * ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU;
314 const FSolverReal NetPushOutTangentV = FrictionMultiplier * ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV;
315 InOutPushOutTangentU = NetPushOutTangentU - (ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU - InOutPushOutTangentU);
316 InOutPushOutTangentV = NetPushOutTangentV - (ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV - InOutPushOutTangentV);
317 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU = NetPushOutTangentU;
318 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV = NetPushOutTangentV;
319 ManifoldPoints[ManifoldPointIndex].StaticFrictionRatio = FrictionMultiplier;
320 }
321 }
322 }
323
329 {
330 // Apply the position correction so that all contacts have zero separation
335
336 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < NumManifoldPoints(); ++ManifoldPointIndex)
337 {
338 FSolverReal ContactDeltaNormal;
339 CalculateContactPositionErrorNormal(ManifoldPointIndex, Body0.SolverBody(), Body1.SolverBody(), MaxPushOut, ContactDeltaNormal);
340
341 const bool bProcessManifoldPoint = (ContactDeltaNormal < FSolverReal(0)) || (ManifoldPoints[ManifoldPointIndex].NetPushOutNormal > FSolverReal(UE_SMALL_NUMBER));
343 {
345 ManifoldPointIndex,
346 Stiffness,
347 ContactDeltaNormal,
348 Body0,
349 Body1,
350 DX0, DR0, DX1, DR1);
351 }
352 }
353
354 if (Body0.IsDynamic())
355 {
356 Body0.ApplyPositionDelta(DX0);
357 Body0.ApplyRotationDelta(DR0);
358 }
359 if (Body1.IsDynamic())
360 {
361 Body1.ApplyPositionDelta(DX1);
362 Body1.ApplyRotationDelta(DR1);
363 }
364 }
365
368 const FSolverReal Dt,
369 const FSolverReal StaticFriction,
370 const FSolverReal DynamicFriction,
374 {
375 // Accumulate net pushout for friction limits below
376 bool bApplyFriction[MaxManifoldPoints] = { false, };
379
384
385 // Apply the position correction along the normal and determine if we want to run friction on each point
386 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < NumManifoldPoints(); ++ManifoldPointIndex)
387 {
388 FSolverReal ContactDeltaNormal;
389 CalculateContactPositionErrorNormal(ManifoldPointIndex, Body0.SolverBody(), Body1.SolverBody(), MaxPushOut, ContactDeltaNormal);
390
391 // Apply a normal correction if we still have penetration or if we are now separated but have previously applied a correction that we may want to undo
392 const bool bProcessManifoldPoint = (ContactDeltaNormal < FSolverReal(0)) || (ManifoldPoints[ManifoldPointIndex].NetPushOutNormal > FSolverReal(UE_SMALL_NUMBER));
394 {
396 ManifoldPointIndex,
397 Stiffness,
398 ContactDeltaNormal,
399 Body0,
400 Body1,
401 DX0, DR0, DX1, DR1);
402
403 TotalPushOutNormal += ManifoldPoints[ManifoldPointIndex].NetPushOutNormal;
404 }
405
406 // Friction gets updated for any point with a net normal correction or where we have previously had a normal correction and
407 // already applied friction (in which case we may need to zero it)
408 if ((ManifoldPoints[ManifoldPointIndex].NetPushOutNormal != 0) || (ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU != 0) || (ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV != 0))
409 {
410 bApplyFriction[ManifoldPointIndex] = true;
412 }
413 }
414
415 // Apply the tangential position correction if required
416 if (NumFrictionContacts > 0)
417 {
418 // We clip the tangential correction at each contact to the friction cone, but we use to average impulse
419 // among all contacts as the clipping limit. This is not really correct but it is much more stable to
420 // differences in contacts from tick to tick
423
424 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < NumManifoldPoints(); ++ManifoldPointIndex)
425 {
426 if (bApplyFriction[ManifoldPointIndex])
427 {
428 FSolverReal ContactDeltaTangentU, ContactDeltaTangentV;
429 CalculateContactPositionErrorTangential(ManifoldPointIndex, Body0.SolverBody(), Body1.SolverBody(), ContactDeltaTangentU, ContactDeltaTangentV);
430
431 // Bilateral constraint - negative values allowed (unlike the normal correction)
432 FSolverReal PushOutTangentU = -Stiffness * ManifoldPoints[ManifoldPointIndex].ContactMassTangentU * ContactDeltaTangentU;
433 FSolverReal PushOutTangentV = -Stiffness * ManifoldPoints[ManifoldPointIndex].ContactMassTangentV * ContactDeltaTangentV;
434
435 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentU += PushOutTangentU;
436 ManifoldPoints[ManifoldPointIndex].NetPushOutTangentV += PushOutTangentV;
437
439 ManifoldPointIndex,
440 StaticFriction,
441 DynamicFriction,
443 PushOutTangentU, // InOut
444 PushOutTangentV); // InOut
445
446 // Update the particle state based on the pushout
447 const FSolverVec3 PushOut = PushOutTangentU * ManifoldPoints[ManifoldPointIndex].ContactTangentU + PushOutTangentV * ManifoldPoints[ManifoldPointIndex].ContactTangentV;
448 if (Body0.IsDynamic())
449 {
450 DX0 += Body0.InvM() * PushOut;
451 DR0 += ManifoldPoints[ManifoldPointIndex].ContactTangentUAngular0 * PushOutTangentU + ManifoldPoints[ManifoldPointIndex].ContactTangentVAngular0 * PushOutTangentV;
452 }
453 if (Body1.IsDynamic())
454 {
455 DX1 -= Body1.InvM() * PushOut;
456 DR1 -= ManifoldPoints[ManifoldPointIndex].ContactTangentUAngular1 * PushOutTangentU + ManifoldPoints[ManifoldPointIndex].ContactTangentVAngular1 * PushOutTangentV;
457 }
458 }
459 }
460
461 if (Body0.IsDynamic())
462 {
463 Body0.ApplyPositionDelta(DX0);
464 Body0.ApplyRotationDelta(DR0);
465 }
466 if (Body1.IsDynamic())
467 {
468 Body1.ApplyPositionDelta(DX1);
469 Body1.ApplyRotationDelta(DR1);
470 }
471 }
472
473 return false;
474 }
475
480 const int32 ManifoldPointIndex,
481 const FConstraintSolverBody& Body0,
482 const FConstraintSolverBody& Body1,
484 {
485 const FSolverVec3 ContactVelocity0 = Body0.V() + FSolverVec3::CrossProduct(Body0.W(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0);
486 const FSolverVec3 ContactVelocity1 = Body1.V() + FSolverVec3::CrossProduct(Body1.W(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1);
488 const FSolverReal ContactVelocityNormal = FSolverVec3::DotProduct(ContactVelocity, ManifoldPoints[ManifoldPointIndex].ContactNormal);
489
490 // Add up the errors in the velocity (current velocity - desired velocity)
491 OutContactVelocityDeltaNormal = (ContactVelocityNormal - ManifoldPoints[ManifoldPointIndex].ContactTargetVelocityNormal);
492 }
493
495 const int32 ManifoldPointIndex,
496 const FConstraintSolverBody& Body0,
497 const FConstraintSolverBody& Body1,
498 const FSolverReal DynamicFriction,
499 const FSolverReal Dt,
503 {
504 const FSolverVec3 ContactVelocity0 = Body0.V() + FSolverVec3::CrossProduct(Body0.W(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition0);
505 const FSolverVec3 ContactVelocity1 = Body1.V() + FSolverVec3::CrossProduct(Body1.W(), ManifoldPoints[ManifoldPointIndex].RelativeContactPosition1);
507 const FSolverReal ContactVelocityNormal = FSolverVec3::DotProduct(ContactVelocity, ManifoldPoints[ManifoldPointIndex].ContactNormal);
508 const FSolverReal ContactVelocityTangent0 = FSolverVec3::DotProduct(ContactVelocity, ManifoldPoints[ManifoldPointIndex].ContactTangentU);
509 const FSolverReal ContactVelocityTangent1 = FSolverVec3::DotProduct(ContactVelocity, ManifoldPoints[ManifoldPointIndex].ContactTangentV);
510
511 OutContactVelocityDeltaNormal = (ContactVelocityNormal - ManifoldPoints[ManifoldPointIndex].ContactTargetVelocityNormal);
514 }
515
516 // @todo(chaos): dynamic friction
519 const FSolverReal Dt,
520 const bool bApplyDynamicFriction,
523 {
528
529 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < NumManifoldPoints(); ++ManifoldPointIndex)
530 {
531 if (ShouldSolveVelocity(ManifoldPointIndex))
532 {
533 const FSolverReal MinImpulseNormal = FMath::Min(FSolverReal(0), -ManifoldPoints[ManifoldPointIndex].NetPushOutNormal / Dt);
534
536 CalculateContactVelocityErrorNormal(ManifoldPointIndex, Body0, Body1, ContactVelocityDeltaNormal);
537
538 FSolverReal ImpulseNormal = -(Stiffness * ManifoldPoints[ManifoldPointIndex].ContactMassNormal) * ContactVelocityDeltaNormal;
539
540 const FSolverReal NetImpulseNormal = ManifoldPoints[ManifoldPointIndex].NetImpulseNormal + ImpulseNormal;
541 if (NetImpulseNormal < MinImpulseNormal)
542 {
543 ImpulseNormal = ImpulseNormal - NetImpulseNormal + MinImpulseNormal;
544 }
545
546 ManifoldPoints[ManifoldPointIndex].NetImpulseNormal += ImpulseNormal;
547
548 FSolverVec3 Impulse = ImpulseNormal * ManifoldPoints[ManifoldPointIndex].ContactNormal;
549 if (Body0.IsDynamic())
550 {
551 DV0 += Body0.InvM() * Impulse;
552 DW0 += ManifoldPoints[ManifoldPointIndex].ContactNormalAngular0 * ImpulseNormal;
553 }
554 if (Body1.IsDynamic())
555 {
556 DV1 -= Body1.InvM() * Impulse;
557 DW1 -= ManifoldPoints[ManifoldPointIndex].ContactNormalAngular1 * ImpulseNormal;
558 }
559 }
560 }
561
562 if (Body0.IsDynamic())
563 {
564 Body0.ApplyVelocityDelta(DV0, DW0);
565 }
566 if (Body1.IsDynamic())
567 {
568 Body1.ApplyVelocityDelta(DV1, DW1);
569 }
570 }
571
572 // @todo(chaos): make private
573 public:
575
579 FORCEINLINE_DEBUGGABLE bool ShouldSolveVelocity(const int32 ManifoldPointIndex) const
580 {
581 // We ensure positive separating velocity for close contacts even if they didn't receive a pushout
582 return (ManifoldPoints[ManifoldPointIndex].NetPushOutNormal > FSolverReal(0)) || (ManifoldPoints[ManifoldPointIndex].ContactDeltaNormal < FSolverReal(0));
583 }
584
586 {
587 // World-space contact point relative to each particle's center of mass
590
591 // World-space contact normal and tangents
595
596 // Errors to correct along each of the contact axes
600
601 // Target velocity along the normal direction
603
604 // I^-1.(R x A) for each body where A is each axis (Normal, TangentU, TangentV)
611
612 // Contact mass (for non-friction)
616
617 // Solver outputs
624
625 // A measure of how much we exceeded the static friction threshold.
626 // Equal to (NormalPushOut / TangentialPushOut) before clamping to the friction cone.
627 // Used to move the static friction anchors to the edge of the cone in Scatter.
629 };
630
632 };
633
651 {
652 public:
653 static const int32 MaxConstrainedBodies = 2;
655
656 // Create a solver that is initialized to safe defaults
658 {
660 Solver.State.Init();
661 return Solver;
662 }
663
664 // Create a solver with no initialization
669
670 // NOTE: Does not initialize any properties. See MakeInitialized
672
675 {
676 State.SolverBodies[0].Reset();
677 State.SolverBodies[1].Reset();
679 }
680
682 {
683 State.ManifoldPoints.Reset();
684 }
685
687 {
688 return State.ManifoldPoints.AddManifoldPoint();
689 }
690
692 {
693 return State.StaticFriction;
694 }
695
697 {
698 return State.DynamicFriction;
699 }
700
702 {
703 return State.VelocityFriction;
704 }
705
707 {
708 State.StaticFriction = InStaticFriction;
709 State.DynamicFriction = InDynamicFriction;
710 State.VelocityFriction = InVelocityFriction;
711 }
712
714 {
715 State.Stiffness = InStiffness;
716 }
717
719 {
720 State.SolverBodies[0].SetSolverBody(SolverBody0);
721 State.SolverBodies[1].SetSolverBody(SolverBody1);
722 }
723
725 {
726 return State.ManifoldPoints.NumManifoldPoints();
727 }
728
730 {
731 return State.ManifoldPoints.GetNetPushOut(ManifoldPointIndex);
732 }
733
735 {
736 return State.ManifoldPoints.GetNetImpulse(ManifoldPointIndex);
737 }
738
740 {
741 return State.ManifoldPoints.GetStaticFrictionRatio(ManifoldPointIndex);
742 }
743
773
799
805 {
806 State.ManifoldPoints.InitContact(
807 ManifoldPointIndex,
808 State.SolverBodies[0],
809 State.SolverBodies[1]);
810 }
811
816 FORCEINLINE_DEBUGGABLE FConstraintSolverBody& SolverBody0() { return State.SolverBodies[0]; }
817 FORCEINLINE_DEBUGGABLE const FConstraintSolverBody& SolverBody0() const { return State.SolverBodies[0]; }
818
823 FORCEINLINE_DEBUGGABLE FConstraintSolverBody& SolverBody1() { return State.SolverBodies[1]; }
824 FORCEINLINE_DEBUGGABLE const FConstraintSolverBody& SolverBody1() const { return State.SolverBodies[1]; }
825
830
835
840
846 {
847 // SolverBody decorator used to add mass scaling
850
852
853 State.ManifoldPoints.SolvePositionNoFriction(
854 Stiffness,
856 Body0,
857 Body1);
858
859 return false;
860 }
861
863 {
864 // SolverBody decorator used to add mass scaling
867
869
870 State.ManifoldPoints.SolvePositionWithFriction(
871 Stiffness,
872 Dt,
873 State.StaticFriction,
874 State.DynamicFriction,
876 Body0,
877 Body1);
878
879 return false;
880 }
881
882
888 {
891
893
894 State.ManifoldPoints.SolveVelocity(
895 Stiffness,
896 Dt,
898 Body0,
899 Body1);
900
901 return false;
902 }
903
904 private:
909 void SetShockPropagationInvMassScale(const FSolverReal InvMassScale);
910
911 struct FState
912 {
913 FState()
914 {
915 }
916
917 void Init()
918 {
919 SolverBodies[0].Init();
920 SolverBodies[1].Init();
921 StaticFriction = 0;
922 DynamicFriction = 0;
923 VelocityFriction = 0;
924 Stiffness = 1;
925 ManifoldPoints.Reset();
926 }
927
928 // Static Friction in the position-solve phase
929 FSolverReal StaticFriction;
930
931 // Dynamic Friction in the position-solve phase
932 FSolverReal DynamicFriction;
933
934 // Dynamic Friction in the velocity-solve phase
935 FSolverReal VelocityFriction;
936
937 // Solver stiffness (scales all pushout and impulses)
938 FSolverReal Stiffness;
939
940 // Bodies and contacts
941 FConstraintSolverBody SolverBodies[MaxConstrainedBodies];
942 FPBDCollisionSolverJacobiManifoldPoints ManifoldPoints;
943 };
944
945 FState State;
946 };
947
948
953
954
959 {
960 public:
961 static void SolvePositionNoFriction(const TArrayView<FPBDCollisionSolverJacobi>& CollisionSolvers, const FSolverReal Dt, const FSolverReal MaxPushOut);
962 static void SolvePositionWithFriction(const TArrayView<FPBDCollisionSolverJacobi>& CollisionSolvers, const FSolverReal Dt, const FSolverReal MaxPushOut);
963 static void SolveVelocity(const TArrayView<FPBDCollisionSolverJacobi>& CollisionSolvers, const FSolverReal Dt, const bool bApplyDynamicFriction);
964
965 static void CheckISPC();
966 };
967
968 } // namespace Private
969} // namespace Chaos
970
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
Definition SolverBody.h:543
bool IsDynamic() const
Whether the body is dynamic (i.e., has a finite mass) after scaling is applied.
Definition SolverBody.h:622
void ApplyPositionDelta(const FSolverVec3 &DP)
Definition SolverBody.h:649
const FSolverVec3 & DP() const
Definition SolverBody.h:641
FSolverBody & SolverBody()
The decorated SolverBody.
Definition SolverBody.h:582
FSolverReal InvM() const
The net scaled inverse mass.
Definition SolverBody.h:607
void ApplyVelocityDelta(const FSolverVec3 &DV, const FSolverVec3 &DW)
Definition SolverBody.h:653
FSolverMatrix33 InvI() const
The net scaled inverse inertia.
Definition SolverBody.h:612
const FSolverVec3 & DQ() const
Definition SolverBody.h:642
void ApplyRotationDelta(const FSolverVec3 &DR)
Definition SolverBody.h:650
const FSolverVec3 & V() const
Definition SolverBody.h:638
const FSolverVec3 & W() const
Definition SolverBody.h:639
Definition SolverBody.h:99
Definition Matrix.h:21
Definition PBDCollisionSolverJacobi.h:959
static void SolveVelocity(const TArrayView< FPBDCollisionSolverJacobi > &CollisionSolvers, const FSolverReal Dt, const bool bApplyDynamicFriction)
Definition PBDCollisionSolverJacobi.cpp:112
static void SolvePositionNoFriction(const TArrayView< FPBDCollisionSolverJacobi > &CollisionSolvers, const FSolverReal Dt, const FSolverReal MaxPushOut)
Definition PBDCollisionSolverJacobi.cpp:94
static void SolvePositionWithFriction(const TArrayView< FPBDCollisionSolverJacobi > &CollisionSolvers, const FSolverReal Dt, const FSolverReal MaxPushOut)
Definition PBDCollisionSolverJacobi.cpp:104
static void CheckISPC()
Definition PBDCollisionSolverJacobi.cpp:120
A set of 4 manifold points in a FPBDCollisionSolver.
Definition PBDCollisionSolverJacobi.h:47
FORCEINLINE_DEBUGGABLE void CalculateContactVelocityErrorNormal(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1, FSolverReal &OutContactVelocityDeltaNormal) const
Calculate the velocity error at the current transforms.
Definition PBDCollisionSolverJacobi.h:479
FORCEINLINE_DEBUGGABLE void SolvePositionNoFriction(const FSolverReal Stiffness, const FSolverReal MaxPushOut, FConstraintSolverBody &Body0, FConstraintSolverBody &Body1)
Definition PBDCollisionSolverJacobi.h:324
FORCEINLINE_DEBUGGABLE void SolveVelocity(const FSolverReal Stiffness, const FSolverReal Dt, const bool bApplyDynamicFriction, FConstraintSolverBody &Body0, FConstraintSolverBody &Body1)
Definition PBDCollisionSolverJacobi.h:517
static const int32 MaxManifoldPoints
Definition PBDCollisionSolverJacobi.h:49
FORCEINLINE_DEBUGGABLE bool SolvePositionWithFriction(const FSolverReal Stiffness, const FSolverReal Dt, const FSolverReal StaticFriction, const FSolverReal DynamicFriction, const FSolverReal MaxPushOut, FConstraintSolverBody &Body0, FConstraintSolverBody &Body1)
Definition PBDCollisionSolverJacobi.h:366
FORCEINLINE_DEBUGGABLE void CalculatePositionCorrectionNormal(const int32 ManifoldPointIndex, const FSolverReal Stiffness, FSolverReal ContactDeltaNormal, FConstraintSolverBody &Body0, FConstraintSolverBody &Body1, FSolverVec3 &InOutDX0, FSolverVec3 &InOutDR0, FSolverVec3 &InOutDX1, FSolverVec3 &InOutDR1)
Definition PBDCollisionSolverJacobi.h:244
FORCEINLINE_DEBUGGABLE void InitContact(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1)
Initialize the geometric data for the contact.
Definition PBDCollisionSolverJacobi.h:92
void UpdateMassNormal(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1)
Update the contact mass for the normal correction This is used by shock propagation.
Definition PBDCollisionSolverJacobi.h:162
FORCEINLINE_DEBUGGABLE bool ShouldSolveVelocity(const int32 ManifoldPointIndex) const
Whether we need to solve velocity for this manifold point (only if we were penetrating or applied a p...
Definition PBDCollisionSolverJacobi.h:579
void Reset()
Definition PBDCollisionSolverJacobi.h:51
FORCEINLINE_DEBUGGABLE FSolverVec3 GetNetPushOut(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverJacobi.h:185
FORCEINLINE_DEBUGGABLE void ApplyFrictionCone(const int32 ManifoldPointIndex, const FSolverReal StaticFriction, const FSolverReal DynamicFriction, const FSolverReal MaxFrictionPushOut, FSolverReal &InOutPushOutTangentU, FSolverReal &InOutPushOutTangentV)
Definition PBDCollisionSolverJacobi.h:282
void UpdateMass(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1)
Update the cached mass properties based on the current body transforms.
Definition PBDCollisionSolverJacobi.h:111
FORCEINLINE_DEBUGGABLE int32 AddManifoldPoint()
Definition PBDCollisionSolverJacobi.h:61
FORCEINLINE_DEBUGGABLE void SetWorldContact(const int32 ManifoldPointIndex, const FSolverVec3 &InRelativeContactPosition0, const FSolverVec3 &InRelativeContactPosition1, const FSolverVec3 &InWorldContactNormal, const FSolverVec3 &InWorldContactTangentU, const FSolverVec3 &InWorldContactTangentV, const FSolverReal InWorldContactDeltaNormal, const FSolverReal InWorldContactDeltaTangentU, const FSolverReal InWorldContactDeltaTangentV, const FSolverReal InWorldContactVelocityTargetNormal)
Definition PBDCollisionSolverJacobi.h:66
FORCEINLINE_DEBUGGABLE int32 NumManifoldPoints() const
Definition PBDCollisionSolverJacobi.h:56
TCArray< FManifoldPoint, MaxManifoldPoints > ManifoldPoints
Definition PBDCollisionSolverJacobi.h:631
FORCEINLINE_DEBUGGABLE void CalculateContactVelocityError(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1, const FSolverReal DynamicFriction, const FSolverReal Dt, FSolverReal &OutContactVelocityDeltaNormal, FSolverReal &OutContactVelocityDeltaTangent0, FSolverReal &OutContactVelocityDeltaTangent1) const
Definition PBDCollisionSolverJacobi.h:494
FORCEINLINE_DEBUGGABLE void CalculateContactPositionErrorTangential(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1, FSolverReal &OutContactDeltaTangentU, FSolverReal &OutContactDeltaTangentV) const
Definition PBDCollisionSolverJacobi.h:229
FORCEINLINE_DEBUGGABLE void CalculateContactPositionErrorNormal(const int32 ManifoldPointIndex, const FConstraintSolverBody &Body0, const FConstraintSolverBody &Body1, const FSolverReal MaxPushOut, FSolverReal &OutContactDeltaNormal) const
Calculate the position error at the current transforms.
Definition PBDCollisionSolverJacobi.h:208
FORCEINLINE_DEBUGGABLE FSolverReal GetStaticFrictionRatio(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverJacobi.h:199
FORCEINLINE_DEBUGGABLE FSolverVec3 GetNetImpulse(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverJacobi.h:192
Definition PBDCollisionSolverJacobi.h:651
FORCEINLINE_DEBUGGABLE const FConstraintSolverBody & SolverBody0() const
Definition PBDCollisionSolverJacobi.h:817
FORCEINLINE_DEBUGGABLE FConstraintSolverBody & SolverBody1()
Get the second (decorated) solver body The decorator add a possible mass scale.
Definition PBDCollisionSolverJacobi.h:823
FORCEINLINE_DEBUGGABLE FSolverReal GetStaticFrictionRatio(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverJacobi.h:739
FORCEINLINE_DEBUGGABLE FConstraintSolverBody & SolverBody0()
Get the first (decorated) solver body The decorator add a possible mass scale.
Definition PBDCollisionSolverJacobi.h:816
FORCEINLINE_DEBUGGABLE void ResetManifold()
Definition PBDCollisionSolverJacobi.h:681
FORCEINLINE_DEBUGGABLE FSolverVec3 GetNetImpulse(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverJacobi.h:734
FORCEINLINE_DEBUGGABLE int32 NumManifoldPoints() const
Definition PBDCollisionSolverJacobi.h:724
FORCEINLINE_DEBUGGABLE FSolverVec3 GetNetPushOut(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverJacobi.h:729
FORCEINLINE_DEBUGGABLE const FConstraintSolverBody & SolverBody1() const
Definition PBDCollisionSolverJacobi.h:824
void EnablePositionShockPropagation()
Set up the mass scaling for shock propagation, using the position-phase mass scale.
Definition PBDCollisionSolverJacobi.cpp:33
FORCEINLINE_DEBUGGABLE bool SolveVelocity(const FSolverReal Dt, const bool bApplyDynamicFriction)
Calculate and apply the velocity correction for this iteration.
Definition PBDCollisionSolverJacobi.h:887
static FPBDCollisionSolverJacobi MakeUninitialized()
Definition PBDCollisionSolverJacobi.h:665
static const int32 MaxPointsPerConstraint
Definition PBDCollisionSolverJacobi.h:654
FORCEINLINE_DEBUGGABLE void SetStiffness(const FSolverReal InStiffness)
Definition PBDCollisionSolverJacobi.h:713
void DisableShockPropagation()
Disable mass scaling.
Definition PBDCollisionSolverJacobi.cpp:43
FORCEINLINE_DEBUGGABLE void SetFriction(const FSolverReal InStaticFriction, const FSolverReal InDynamicFriction, const FSolverReal InVelocityFriction)
Definition PBDCollisionSolverJacobi.h:706
FPBDCollisionSolverJacobi()
Definition PBDCollisionSolverJacobi.h:671
FORCEINLINE_DEBUGGABLE void SetSolverBodies(FSolverBody &SolverBody0, FSolverBody &SolverBody1)
Definition PBDCollisionSolverJacobi.h:718
static const int32 MaxConstrainedBodies
Definition PBDCollisionSolverJacobi.h:653
FORCEINLINE_DEBUGGABLE bool SolvePositionNoFriction(const FSolverReal Dt, const FSolverReal MaxPushOut)
Calculate and apply the position correction for this iteration.
Definition PBDCollisionSolverJacobi.h:845
FORCEINLINE_DEBUGGABLE void FinalizeManifoldPoint(const int32 ManifoldPointIndex)
Definition PBDCollisionSolverJacobi.h:804
static FPBDCollisionSolverJacobi MakeInitialized()
Definition PBDCollisionSolverJacobi.h:657
FORCEINLINE_DEBUGGABLE void SetManifoldPoint(const int32 ManifoldPointIndex, const FSolverVec3 &InRelativeContactPosition0, const FSolverVec3 &InRelativeContactPosition1, const FSolverVec3 &InWorldContactNormal, const FSolverVec3 &InWorldContactTangentU, const FSolverVec3 &InWorldContactTangentV, const FSolverReal InWorldContactDeltaNormal, const FSolverReal InWorldContactDeltaTangentU, const FSolverReal InWorldContactDeltaTangentV, const FSolverReal InWorldContactVelocityTargetNormal)
Definition PBDCollisionSolverJacobi.h:747
FORCEINLINE_DEBUGGABLE void Reset()
Definition PBDCollisionSolverJacobi.h:674
void EnableVelocityShockPropagation()
Set up the mass scaling for shock propagation, using the velocity-phase mass scale.
Definition PBDCollisionSolverJacobi.cpp:38
FORCEINLINE_DEBUGGABLE FSolverReal DynamicFriction() const
Definition PBDCollisionSolverJacobi.h:696
FORCEINLINE_DEBUGGABLE bool SolvePositionWithFriction(const FSolverReal Dt, const FSolverReal MaxPushOut)
Definition PBDCollisionSolverJacobi.h:862
FORCEINLINE_DEBUGGABLE int32 AddManifoldPoint()
Definition PBDCollisionSolverJacobi.h:686
FORCEINLINE_DEBUGGABLE FSolverReal StaticFriction() const
Definition PBDCollisionSolverJacobi.h:691
FORCEINLINE_DEBUGGABLE void InitManifoldPoint(const int32 ManifoldPointIndex, const FSolverVec3 &InRelativeContactPosition0, const FSolverVec3 &InRelativeContactPosition1, const FSolverVec3 &InWorldContactNormal, const FSolverVec3 &InWorldContactTangentU, const FSolverVec3 &InWorldContactTangentV, const FSolverReal InWorldContactDeltaNormal, const FSolverReal InWorldContactDeltaTangentU, const FSolverReal InWorldContactDeltaTangentV, const FSolverReal InWorldContactVelocityTargetNormal)
Definition PBDCollisionSolverJacobi.h:774
FORCEINLINE_DEBUGGABLE FSolverReal VelocityFriction() const
Definition PBDCollisionSolverJacobi.h:701
Definition PBDCollisionSolverJacobi.h:39
Definition PBDCollisionSolverJacobi.h:32
A c-style array of objects with non-shipping bounds checking.
Definition UncheckedArray.h:47
Definition Vector.h:1000
Definition ArrayView.h:139
bool bChaos_PBDCollisionSolver_Velocity_FrictionEnabled
Definition PBDCollisionSolver.cpp:47
FRealSingle Chaos_PBDCollisionSolver_JacobiStiffness
Definition PBDCollisionContainerSolver.cpp:40
float Chaos_PBDCollisionSolver_Position_StaticFrictionStiffness
Definition PBDCollisionSolver.cpp:34
FRealSingle Chaos_PBDCollisionSolver_JacobiRotationTolerance
Definition PBDCollisionContainerSolver.cpp:50
FRealSingle Chaos_PBDCollisionSolver_JacobiPositionTolerance
Definition PBDCollisionContainerSolver.cpp:45
Definition SkeletalMeshComponent.h:307
TVec3< FSolverReal > FSolverVec3
Definition SolverBody.h:44
FRealSingle FSolverReal
Definition SolverBody.h:38
Definition OverriddenPropertySet.cpp:45
FAutoConsoleVariableRef CVars[]
Definition MassProcessingPhaseManager.cpp:29
Definition UnrealMathFPU.h:113
FSolverVec3 ContactTangentUAngular1
Definition PBDCollisionSolverJacobi.h:609
FSolverVec3 ContactTangentVAngular0
Definition PBDCollisionSolverJacobi.h:607
FSolverReal NetImpulseNormal
Definition PBDCollisionSolverJacobi.h:621
FSolverReal ContactMassTangentV
Definition PBDCollisionSolverJacobi.h:615
FSolverReal NetPushOutTangentV
Definition PBDCollisionSolverJacobi.h:620
FSolverReal ContactMassTangentU
Definition PBDCollisionSolverJacobi.h:614
FSolverVec3 ContactNormal
Definition PBDCollisionSolverJacobi.h:592
FSolverReal ContactDeltaTangentU
Definition PBDCollisionSolverJacobi.h:598
FSolverVec3 ContactNormalAngular0
Definition PBDCollisionSolverJacobi.h:605
FSolverReal NetPushOutNormal
Definition PBDCollisionSolverJacobi.h:618
FSolverReal ContactTargetVelocityNormal
Definition PBDCollisionSolverJacobi.h:602
FSolverVec3 ContactTangentUAngular0
Definition PBDCollisionSolverJacobi.h:606
FSolverReal NetPushOutTangentU
Definition PBDCollisionSolverJacobi.h:619
FSolverReal NetImpulseTangentU
Definition PBDCollisionSolverJacobi.h:622
FSolverReal ContactDeltaTangentV
Definition PBDCollisionSolverJacobi.h:599
FSolverReal NetImpulseTangentV
Definition PBDCollisionSolverJacobi.h:623
FSolverVec3 ContactTangentV
Definition PBDCollisionSolverJacobi.h:594
FSolverReal StaticFrictionRatio
Definition PBDCollisionSolverJacobi.h:628
FSolverVec3 ContactNormalAngular1
Definition PBDCollisionSolverJacobi.h:608
FSolverVec3 ContactTangentVAngular1
Definition PBDCollisionSolverJacobi.h:610
FSolverVec3 RelativeContactPosition1
Definition PBDCollisionSolverJacobi.h:589
FSolverVec3 RelativeContactPosition0
Definition PBDCollisionSolverJacobi.h:588
FSolverVec3 ContactTangentU
Definition PBDCollisionSolverJacobi.h:593
FSolverReal ContactDeltaNormal
Definition PBDCollisionSolverJacobi.h:597
FSolverReal ContactMassNormal
Definition PBDCollisionSolverJacobi.h:613
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578