UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PBDCollisionSolverSimd.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"
8#include "Chaos/Simd4.h"
9
10// Set to 1 to use a dummy solver body instead of a nullptr in unused lanes, and an aligned Simd gather operation
11// Currently this is slower, but once the object sizes are reduced may be better
12#ifndef CHAOS_SIMDCOLLISIONSOLVER_USEDUMMYSOLVERBODY
13#define CHAOS_SIMDCOLLISIONSOLVER_USEDUMMYSOLVERBODY 0
14#endif
15
16namespace Chaos
17{
18 class FManifoldPoint;
19 class FPBDCollisionConstraint;
20
21 namespace CVars
22 {
25 }
26
27 namespace Private
28 {
29 template<int TNumLanes>
30 class TPBDCollisionSolverSimd;
31
32 template<int TNumLanes>
34
36 const TSolverBodyPtrSimd<4>& Body0,
37 const TSolverBodyPtrSimd<4>& Body1,
42 {
43#if !CHAOS_SIMDCOLLISIONSOLVER_USEDUMMYSOLVERBODY
44 // Non-SIMD gather
45 for (int32 LaneIndex = 0; LaneIndex < 4; ++LaneIndex)
46 {
47 const FSolverBody* LaneBody0 = Body0.GetValue(LaneIndex);
48 const FSolverBody* LaneBody1 = Body1.GetValue(LaneIndex);
49 if (LaneBody0 != nullptr)
50 {
51 DP0.SetValue(LaneIndex, LaneBody0->DP());
52 DQ0.SetValue(LaneIndex, LaneBody0->DQ());
53 }
54 if (LaneBody1 != nullptr)
55 {
56 DP1.SetValue(LaneIndex, LaneBody1->DP());
57 DQ1.SetValue(LaneIndex, LaneBody1->DQ());
58 }
59 }
60#else
61 // SIMD gather (valid ptrs to dummy object for unused lanes)
62 const FSolverBody* Body00 = Body0.GetValue(0);
63 const FSolverBody* Body01 = Body0.GetValue(1);
64 const FSolverBody* Body02 = Body0.GetValue(2);
65 const FSolverBody* Body03 = Body0.GetValue(3);
67 Body00->DP(),
68 Body01->DP(),
69 Body02->DP(),
70 Body03->DP());
72 Body00->DQ(),
73 Body01->DQ(),
74 Body02->DQ(),
75 Body03->DQ());
76
77 const FSolverBody* Body10 = Body1.GetValue(0);
78 const FSolverBody* Body11 = Body1.GetValue(1);
79 const FSolverBody* Body12 = Body1.GetValue(2);
80 const FSolverBody* Body13 = Body1.GetValue(3);
82 Body10->DP(),
83 Body11->DP(),
84 Body12->DP(),
85 Body13->DP());
87 Body10->DQ(),
88 Body11->DQ(),
89 Body12->DQ(),
90 Body13->DQ());
91#endif
92 }
93
95 const TSimdVec3f<4>& DP0,
96 const TSimdVec3f<4>& DQ0,
97 const TSimdVec3f<4>& DP1,
98 const TSimdVec3f<4>& DQ1,
99 const TSolverBodyPtrSimd<4>& Body0,
100 const TSolverBodyPtrSimd<4>& Body1)
101 {
102 for (int32 LaneIndex = 0; LaneIndex < 4; ++LaneIndex)
103 {
104 FSolverBody* LaneBody0 = Body0.GetValue(LaneIndex);
105 FSolverBody* LaneBody1 = Body1.GetValue(LaneIndex);
106 if (LaneBody0 != nullptr)
107 {
108 LaneBody0->SetDP(DP0.GetValue(LaneIndex));
109 LaneBody0->SetDQ(DQ0.GetValue(LaneIndex));
110 }
111 if (LaneBody1 != nullptr)
112 {
113 LaneBody1->SetDP(DP1.GetValue(LaneIndex));
114 LaneBody1->SetDQ(DQ1.GetValue(LaneIndex));
115 }
116 }
117 }
118
119
121 const TSolverBodyPtrSimd<4>& Body0,
122 const TSolverBodyPtrSimd<4>& Body1,
123 TSimdVec3f<4>& V0,
125 TSimdVec3f<4>& V1,
127 {
128 for (int32 LaneIndex = 0; LaneIndex < 4; ++LaneIndex)
129 {
130 const FSolverBody* LaneBody0 = Body0.GetValue(LaneIndex);
131 const FSolverBody* LaneBody1 = Body1.GetValue(LaneIndex);
132 if (LaneBody0 != nullptr)
133 {
134 V0.SetValue(LaneIndex, LaneBody0->V());
135 W0.SetValue(LaneIndex, LaneBody0->W());
136 }
137 if (LaneBody1 != nullptr)
138 {
139 V1.SetValue(LaneIndex, LaneBody1->V());
140 W1.SetValue(LaneIndex, LaneBody1->W());
141 }
142 }
143 }
144
146 const TSimdVec3f<4>& V0,
147 const TSimdVec3f<4>& W0,
148 const TSimdVec3f<4>& V1,
149 const TSimdVec3f<4>& W1,
150 const TSolverBodyPtrSimd<4>& Body0,
151 const TSolverBodyPtrSimd<4>& Body1)
152 {
153 for (int32 LaneIndex = 0; LaneIndex < 4; ++LaneIndex)
154 {
155 FSolverBody* LaneBody0 = Body0.GetValue(LaneIndex);
156 FSolverBody* LaneBody1 = Body1.GetValue(LaneIndex);
157 if (LaneBody0 != nullptr)
158 {
159 LaneBody0->SetV(V0.GetValue(LaneIndex));
160 LaneBody0->SetW(W0.GetValue(LaneIndex));
161 }
162 if (LaneBody0 != nullptr)
163 {
164 LaneBody1->SetV(V1.GetValue(LaneIndex));
165 LaneBody1->SetW(W1.GetValue(LaneIndex));
166 }
167 }
168 }
169
170 template<int TNumLanes>
176
180 template<int TNumLanes>
182 {
183 public:
189
190 // Whether the manifold point in each lane is set up for solving
192
193 // World-space contact point relative to each particle's center of mass
196
197 // Normal PushOut
204
205 // Tangential PushOut
219
220 // Normal Impulse
225 };
226
230 template<int TNumLanes>
232 {
233 public:
240
241 static const int32 MaxConstrainedBodies = 2;
243
244 // Create a solver that is initialized to safe defaults
246 {
248 Solver.Init();
249 return Solver;
250 }
251
252 // Create a solver with no initialization
257
258 // NOTE: Does not initialize any properties. See MakeInitialized
260
262 {
264 }
265
270
277
279 {
280 return MaxManifoldPoints;
281 }
282
284 const int32 ManifoldPointIndex,
286 {
287 return ManifoldPointsBuffer[GetBufferIndex(ManifoldPointIndex)];
288 }
289
297
302
309
314
316 {
317 // Not required as long as we are zeroing the full points array on resize
318 // Otherwise we need to reset all outputs and some properties here as not all lanes will be used by all points
319 }
320
325 const int32 ManifoldPointIndex,
326 const int32 LaneIndex,
337 const FSolverBody& Body0,
338 const FSolverBody& Body1,
343 {
344 const int32 BufferIndex = GetBufferIndex(ManifoldPointIndex);
346
347 ManifoldPoint.IsValid.SetValue(LaneIndex, true);
348
349 ManifoldPoint.SimdRelativeContactPoint0.SetValue(LaneIndex, InRelativeContactPosition0);
350 ManifoldPoint.SimdRelativeContactPoint1.SetValue(LaneIndex, InRelativeContactPosition1);
351 ManifoldPoint.SimdContactNormal.SetValue(LaneIndex, InWorldContactNormal);
352 ManifoldPoint.SimdContactTangentU.SetValue(LaneIndex, InWorldContactTangentU);
353 ManifoldPoint.SimdContactTangentV.SetValue(LaneIndex, InWorldContactTangentV);
354 ManifoldPoint.SimdContactDeltaNormal.SetValue(LaneIndex, InWorldContactDeltaNormal);
355 ManifoldPoint.SimdContactDeltaTangentU.SetValue(LaneIndex, InWorldContactDeltaTangentU);
356 ManifoldPoint.SimdContactDeltaTangentV.SetValue(LaneIndex, InWorldContactDeltaTangentV);
357 ManifoldPoint.SimdContactTargetVelocityNormal.SetValue(LaneIndex, InWorldContactVelocityTargetNormal);
358
360 ManifoldPointIndex,
361 LaneIndex,
363 Body0,
364 Body1,
368 InvIScale1);
369 }
370
375 const int32 ManifoldPointIndex,
376 const int32 LaneIndex,
378 const FSolverBody& Body0,
379 const FSolverBody& Body1,
384 {
385 const int32 BufferIndex = GetBufferIndex(ManifoldPointIndex);
387
388 if (!ManifoldPoint.IsValid.GetValue(LaneIndex))
389 {
390 return;
391 }
392
396
397 SimdInvM0.SetValue(LaneIndex, 0);
398 SimdInvM1.SetValue(LaneIndex, 0);
399 ManifoldPoint.SimdContactNormalAngular0.SetValue(LaneIndex, FVec3f(0));
400 ManifoldPoint.SimdContactTangentUAngular0.SetValue(LaneIndex, FVec3f(0));
401 ManifoldPoint.SimdContactTangentVAngular0.SetValue(LaneIndex, FVec3f(0));
402 ManifoldPoint.SimdContactNormalAngular1.SetValue(LaneIndex, FVec3f(0));
403 ManifoldPoint.SimdContactTangentUAngular1.SetValue(LaneIndex, FVec3f(0));
404 ManifoldPoint.SimdContactTangentVAngular1.SetValue(LaneIndex, FVec3f(0));
405
406 const FVec3f ContactNormal = ManifoldPoint.SimdContactNormal.GetValue(LaneIndex);
407 const FVec3f ContactTangentU = ManifoldPoint.SimdContactTangentU.GetValue(LaneIndex);
408 const FVec3f ContactTangentV = ManifoldPoint.SimdContactTangentV.GetValue(LaneIndex);
409
410 const FSolverReal InvM0 = InvMScale0 * Body0.InvM();
411 const FSolverReal InvM1 = InvMScale1 * Body1.InvM();
412 if (InvM0 > 0)
413 {
414 const FSolverMatrix33 InvI0 = InvIScale0 * Body0.InvI();
415
416 const FVec3f RelativeContactPoint0 = ManifoldPoint.SimdRelativeContactPoint0.GetValue(LaneIndex);
417 const FSolverVec3 R0xN = FSolverVec3::CrossProduct(RelativeContactPoint0, ContactNormal);
418 const FSolverVec3 R0xU = FSolverVec3::CrossProduct(RelativeContactPoint0, ContactTangentU);
419 const FSolverVec3 R0xV = FSolverVec3::CrossProduct(RelativeContactPoint0, ContactTangentV);
420 const FSolverVec3 IR0xN = InvI0 * R0xN;
421 const FSolverVec3 IR0xU = InvI0 * R0xU;
422 const FSolverVec3 IR0xV = InvI0 * R0xV;
423
424 SimdInvM0.SetValue(LaneIndex, InvM0);
425
426 ManifoldPoint.SimdContactNormalAngular0.SetValue(LaneIndex, IR0xN);
427 ManifoldPoint.SimdContactTangentUAngular0.SetValue(LaneIndex, IR0xU);
428 ManifoldPoint.SimdContactTangentVAngular0.SetValue(LaneIndex, IR0xV);
429
430 ContactMassInvNormal += FSolverVec3::DotProduct(R0xN, IR0xN) + InvM0;
431 ContactMassInvTangentU += FSolverVec3::DotProduct(R0xU, IR0xU) + InvM0;
432 ContactMassInvTangentV += FSolverVec3::DotProduct(R0xV, IR0xV) + InvM0;
433 }
434 if (InvM1 > 0)
435 {
436 const FSolverMatrix33 InvI1 = InvIScale1 * Body1.InvI();
437
438 const FVec3f RelativeContactPoint1 = ManifoldPoint.SimdRelativeContactPoint1.GetValue(LaneIndex);
439 const FSolverVec3 R1xN = FSolverVec3::CrossProduct(RelativeContactPoint1, ContactNormal);
440 const FSolverVec3 R1xU = FSolverVec3::CrossProduct(RelativeContactPoint1, ContactTangentU);
441 const FSolverVec3 R1xV = FSolverVec3::CrossProduct(RelativeContactPoint1, ContactTangentV);
442 const FSolverVec3 IR1xN = InvI1 * R1xN;
443 const FSolverVec3 IR1xU = InvI1 * R1xU;
444 const FSolverVec3 IR1xV = InvI1 * R1xV;
445
446 SimdInvM1.SetValue(LaneIndex, InvM1);
447
448 ManifoldPoint.SimdContactNormalAngular1.SetValue(LaneIndex, IR1xN);
449 ManifoldPoint.SimdContactTangentUAngular1.SetValue(LaneIndex, IR1xU);
450 ManifoldPoint.SimdContactTangentVAngular1.SetValue(LaneIndex, IR1xV);
451
452 ContactMassInvNormal += FSolverVec3::DotProduct(R1xN, IR1xN) + InvM1;
453 ContactMassInvTangentU += FSolverVec3::DotProduct(R1xU, IR1xU) + InvM1;
454 ContactMassInvTangentV += FSolverVec3::DotProduct(R1xV, IR1xV) + InvM1;
455 }
456
457 ManifoldPoint.SimdContactMassNormal.SetValue(LaneIndex, (ContactMassInvNormal > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvNormal : FSolverReal(0));
458 ManifoldPoint.SimdContactMassTangentU.SetValue(LaneIndex, (ContactMassInvTangentU > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvTangentU : FSolverReal(0));
459 ManifoldPoint.SimdContactMassTangentV.SetValue(LaneIndex, (ContactMassInvTangentV > FSolverReal(UE_SMALL_NUMBER)) ? FSolverReal(1) / ContactMassInvTangentV : FSolverReal(0));
460 }
461
463 const int32 ManifoldPointIndex,
464 const int32 LaneIndex,
466 const FSolverBody& Body0,
467 const FSolverBody& Body1,
472 {
473 const int32 BufferIndex = GetBufferIndex(ManifoldPointIndex);
475
476 if (!ManifoldPoint.IsValid.GetValue(LaneIndex))
477 {
478 return;
479 }
480
482
483 SimdInvM0.SetValue(LaneIndex, 0);
484 SimdInvM1.SetValue(LaneIndex, 0);
485 ManifoldPoint.SimdContactNormalAngular0.SetValue(LaneIndex, FVec3f(0));
486 ManifoldPoint.SimdContactNormalAngular1.SetValue(LaneIndex, FVec3f(0));
487
488 const FVec3f ContactNormal = ManifoldPoint.SimdContactNormal.GetValue(LaneIndex);
489
490 const FSolverReal InvM0 = InvMScale0 * Body0.InvM();
491 const FSolverReal InvM1 = InvMScale1 * Body1.InvM();
492 if (InvM0 > 0)
493 {
494 const FSolverMatrix33 InvI0 = InvIScale0 * Body0.InvI();
495
496 const FVec3f RelativeContactPoint0 = ManifoldPoint.SimdRelativeContactPoint0.GetValue(LaneIndex);
497 const FSolverVec3 R0xN = FSolverVec3::CrossProduct(RelativeContactPoint0, ContactNormal);
498 const FSolverVec3 IR0xN = InvI0 * R0xN;
499
500 SimdInvM0.SetValue(LaneIndex, InvM0);
501
502 ManifoldPoint.SimdContactNormalAngular0.SetValue(LaneIndex, IR0xN);
503
504 ContactMassInvNormal += FSolverVec3::DotProduct(R0xN, IR0xN) + InvM0;
505 }
506 if (InvM1 > 0)
507 {
508 const FSolverMatrix33 InvI1 = InvIScale1 * Body1.InvI();
509
510 const FVec3f RelativeContactPoint1 = ManifoldPoint.SimdRelativeContactPoint1.GetValue(LaneIndex);
511 const FSolverVec3 R1xN = FSolverVec3::CrossProduct(RelativeContactPoint1, ContactNormal);
512 const FSolverVec3 IR1xN = InvI1 * R1xN;
513
514 SimdInvM1.SetValue(LaneIndex, InvM1);
515
516 ManifoldPoint.SimdContactNormalAngular1.SetValue(LaneIndex, IR1xN);
517
518 ContactMassInvNormal += FSolverVec3::DotProduct(R1xN, IR1xN) + InvM1;
519 }
520
522 ManifoldPoint.SimdContactMassNormal.SetValue(LaneIndex, ContactMassNormal);
523 }
524
526 const int32 LaneIndex,
528 const FSolverBody& Body0,
529 const FSolverBody& Body1,
534 {
536 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < NumManifoldPoints; ++ManifoldPointIndex)
537 {
539 ManifoldPointIndex,
540 LaneIndex,
542 Body0,
543 Body1,
547 InvIScale1);
548 }
549 }
550
553 const FSimdSolverBodyPtr& Body0,
554 const FSimdSolverBodyPtr& Body1,
555 const FSimdRealf& MaxPushOut)
556 {
557 // Get the current corrections for each body.
558 // NOTE: This is a gather operation
560 GatherBodyPositionCorrections(Body0, Body1, DP0, DQ0, DP1, DQ1);
561
562 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < MaxManifoldPoints; ++ManifoldPointIndex)
563 {
565
566 // Which lanes require this point be simulated?
567 //if (!SimdAnyTrue(ManifoldPoint.IsValid))
568 //{
569 // continue;
570 //}
571
572 // Calculate the contact error
573 const FSimdVec3f DQ0xR0 = SimdCrossProduct(DQ0, ManifoldPoint.SimdRelativeContactPoint0);
574 const FSimdVec3f DQ1xR1 = SimdCrossProduct(DQ1, ManifoldPoint.SimdRelativeContactPoint1);
578 FSimdRealf ContactErrorNormal = SimdAdd(ManifoldPoint.SimdContactDeltaNormal, SimdDotProduct(ContactDelta, ManifoldPoint.SimdContactNormal));
579
580 // Apply MaxPushOut clamping if required
581 //if ((MaxPushOut > 0) && (ContactErrorNormal < -MaxPushOut)) { ContactErrorNormal = -MaxPushOut; }
585
586 // Determine which lanes to process: only those with an overlap or that applied a pushout on a prior iteration
590
591 // If all lanes are to be skipped, early-out
592 //if (!SimdAnyTrue(ShouldProcess))
593 //{
594 // continue;
595 //}
596
597 // Zero out the error for points we should not process so we don't apply a correction for them
599
601
602 // Unilateral constraint: Net-negative pushout is not allowed, but
603 // PushOutNormal may be negative on any iteration as long as the net is positive
604 // If the net goes negative, apply a pushout to make it zero
607
608 // New net pushout
609 ManifoldPoint.SimdNetPushOutNormal = SimdAdd(PushOutNormal, ManifoldPoint.SimdNetPushOutNormal);
610
611 // Convert the positional impulse into position and rotation corrections for each body
612 // NOTE: order of operations matches FPBDCollisionSolver::ApplyPositionCorrectionNormal so we can AB test
614 const FSimdVec3f DDQ0 = SimdMultiply(ManifoldPoint.SimdContactNormalAngular0, PushOutNormal);
616 const FSimdVec3f DDQ1 = SimdMultiply(ManifoldPoint.SimdContactNormalAngular1, PushOutNormal);
617 DP0 = SimdAdd(DP0, DDP0);
618 DQ0 = SimdAdd(DQ0, DDQ0);
621 }
622
623 // Update the corrections on the bodies.
624 // NOTE: This is a scatter operation
625 ScatterBodyPositionCorrections(DP0, DQ0, DP1, DQ1, Body0, Body1);
626 }
627
630 const FSimdSolverBodyPtr& Body0,
631 const FSimdSolverBodyPtr& Body1,
632 const FSimd4Realf& MaxPushOut,
634 {
635 // Get the current corrections for each body.
636 // NOTE: This is a gather operation
638 GatherBodyPositionCorrections(Body0, Body1, DP0, DQ0, DP1, DQ1);
639
642
645
646 // @todo(chaos): can these be zero (and make non-simd version match)?
649
650 // Apply the normal pushout and calculate the net normal pushout for the friction limit
651 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < MaxManifoldPoints; ++ManifoldPointIndex)
652 {
654
655 // Which lanes require this point be simulated?
656 //if (!SimdAnyTrue(ManifoldPoint.IsValid))
657 //{
658 // continue;
659 //}
660
661 // Calculate the contact error
662 const FSimdVec3f DQ0xR0 = SimdCrossProduct(DQ0, ManifoldPoint.SimdRelativeContactPoint0);
663 const FSimdVec3f DQ1xR1 = SimdCrossProduct(DQ1, ManifoldPoint.SimdRelativeContactPoint1);
667 FSimdRealf ContactErrorNormal = SimdAdd(ManifoldPoint.SimdContactDeltaNormal, SimdDotProduct(ContactDelta, ManifoldPoint.SimdContactNormal));
668
669 // Apply MaxPushOut clamping if required
670 //if ((MaxPushOut > 0) && (ContactErrorNormal < -MaxPushOut)) { ContactErrorNormal = -MaxPushOut; }
674
675 // Determine which lanes to process: only those with an overlap or that applied a pushout on a prior iteration
679
680 // If all lanes are to be skipped, early-out
681 //if (!SimdAnyTrue(ProcessManifoldPoint))
682 //{
683 // continue;
684 //}
685
686 // Zero out the error for points we should not process so we don't apply a correction for them
688
690
691 // Unilateral constraint: Net-negative pushout is not allowed, but
692 // PushOutNormal may be negative on any iteration as long as the net is positive
693 // If the net goes negative, apply a pushout to make it zero
696
697 // New net pushout
698 ManifoldPoint.SimdNetPushOutNormal = SimdAdd(PushOutNormal, ManifoldPoint.SimdNetPushOutNormal);
699
700 // Convert the positional impulse into position and rotation corrections for each body
701 // NOTE: order of operations matches FPBDCollisionSolver::ApplyPositionCorrectionNormal so we can AB test
703 const FSimdVec3f DDQ0 = SimdMultiply(ManifoldPoint.SimdContactNormalAngular0, PushOutNormal);
705 const FSimdVec3f DDQ1 = SimdMultiply(ManifoldPoint.SimdContactNormalAngular1, PushOutNormal);
706 DP0 = SimdAdd(DP0, DDP0);
707 DQ0 = SimdAdd(DQ0, DDQ0);
710
713 }
714
716
717 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < MaxManifoldPoints; ++ManifoldPointIndex)
718 {
720
721 // Which lanes require this point be simulated?
722 //if (!SimdAnyTrue(ManifoldPoint.IsValid))
723 //{
724 // continue;
725 //}
726
727 // Calculate the contact error
728 const FSimdVec3f DQ0xR0 = SimdCrossProduct(DQ0, ManifoldPoint.SimdRelativeContactPoint0);
729 const FSimdVec3f DQ1xR1 = SimdCrossProduct(DQ1, ManifoldPoint.SimdRelativeContactPoint1);
733
734 // Should we apply tangential corrections for friction?
735 // bUpdateFriction = ((TotalPushOutNormal > 0) || (NetPushOutTangentU != 0) || (NetPushOutTangentV != 0))
737 const FSimdSelector HasNormalPushout = SimdGreater(ManifoldPoint.SimdNetPushOutNormal, Zero);
738 const FSimdSelector HasTangentUPushout = SimdNotEqual(ManifoldPoint.SimdNetPushOutTangentU, Zero);
739 const FSimdSelector HasTangentVPushout = SimdNotEqual(ManifoldPoint.SimdNetPushOutTangentV, Zero);
741 //if (SimdAnyTrue(ApplyPointFriction))
742 {
743 // Calculate tangential errors
744 const FSimdRealf ContactErrorTangentU = SimdAdd(ManifoldPoint.SimdContactDeltaTangentU, SimdDotProduct(ContactDelta, ManifoldPoint.SimdContactTangentU));
745 const FSimdRealf ContactErrorTangentV = SimdAdd(ManifoldPoint.SimdContactDeltaTangentV, SimdDotProduct(ContactDelta, ManifoldPoint.SimdContactTangentV));
746
747 // A stiffness multiplier on the impulses
749
750 // Calculate tangential correction
753
754 // New net tangential pushouts
755 FSimdRealf NetPushOutTangentU = SimdAdd(ManifoldPoint.SimdNetPushOutTangentU, PushOutTangentU);
756 FSimdRealf NetPushOutTangentV = SimdAdd(ManifoldPoint.SimdNetPushOutTangentV, PushOutTangentV);
757 FSimdRealf StaticFrictionRatio = One;
758
759 // Should we clamp to the friction cone or reset the friction?
761
762 // Apply cone limits to tangential pushouts on lanes that exceed the limit
763 // NOTE: if HasNormalPushout is false in any lane, we have already zeroed the net pushout and don't need to do anything here
764 //if (SimdAnyTrue(ApplyFrictionCone))
765 {
767 const FSimdRealf NetPushOutTangentSq = SimdAdd(SimdSquare(NetPushOutTangentU), SimdSquare(NetPushOutTangentV));
769 //if (SimdAnyTrue(ExceededFrictionCone))
770 {
773 const FSimdRealf ClampedNetPushOutTangentU = SimdMultiply(FrictionMultiplier, NetPushOutTangentU);
774 const FSimdRealf ClampedNetPushOutTangentV = SimdMultiply(FrictionMultiplier, NetPushOutTangentV);
777
780 NetPushOutTangentU = SimdSelect(ExceededFrictionCone, ClampedNetPushOutTangentU, NetPushOutTangentU);
781 NetPushOutTangentV = SimdSelect(ExceededFrictionCone, ClampedNetPushOutTangentV, NetPushOutTangentV);
782 StaticFrictionRatio = SimdSelect(ExceededFrictionCone, FrictionMultiplier, StaticFrictionRatio);
783 }
784 }
785
786 // If we did not apply the friction cone because we have no normal impulse, apply a pushout to cancel previously applied friction
787 //if (!SimdAllTrue(ApplyFrictionCone))
788 {
789 PushOutTangentU = SimdSelect(ApplyFrictionCone, PushOutTangentU, SimdNegate(ManifoldPoint.SimdNetPushOutTangentU));
790 PushOutTangentV = SimdSelect(ApplyFrictionCone, PushOutTangentV, SimdNegate(ManifoldPoint.SimdNetPushOutTangentV));
791 NetPushOutTangentU = SimdSelect(ApplyFrictionCone, NetPushOutTangentU, Zero);
792 NetPushOutTangentV = SimdSelect(ApplyFrictionCone, NetPushOutTangentV, Zero);
793 StaticFrictionRatio = SimdSelect(ApplyFrictionCone, StaticFrictionRatio, Zero);
794 }
795
796 // Undo all our good work for lanes that should not apply friction at all
797 //if (!SimdAllTrue(ApplyPointFriction))
798 {
801 NetPushOutTangentU = SimdSelect(ApplyPointFriction, NetPushOutTangentU, ManifoldPoint.SimdNetPushOutTangentU);
802 NetPushOutTangentV = SimdSelect(ApplyPointFriction, NetPushOutTangentV, ManifoldPoint.SimdNetPushOutTangentV);
803 StaticFrictionRatio = SimdSelect(ApplyPointFriction, StaticFrictionRatio, One);
804 }
805
806 ManifoldPoint.SimdNetPushOutTangentU = NetPushOutTangentU;
807 ManifoldPoint.SimdNetPushOutTangentV = NetPushOutTangentV;
808 ManifoldPoint.SimdStaticFrictionRatio = StaticFrictionRatio;
809
810 // Add the tangential corrections to the applied correction
811 // NOTE: The order of operations here matches FPBDCollisionSolver::ApplyPositionCorrectionTangential
812 // so that we can do an AB test of the SIMD solver versus the standard solver
816 const FSimdVec3f DDQ0 = SimdAdd(SimdMultiply(ManifoldPoint.SimdContactTangentUAngular0, PushOutTangentU), SimdMultiply(ManifoldPoint.SimdContactTangentVAngular0, PushOutTangentV));
817 const FSimdVec3f DDQ1 = SimdAdd(SimdMultiply(ManifoldPoint.SimdContactTangentUAngular1, PushOutTangentU), SimdMultiply(ManifoldPoint.SimdContactTangentVAngular1, PushOutTangentV));
818 DP0 = SimdAdd(DP0, DDP0);
819 DQ0 = SimdAdd(DQ0, DDQ0);
822 }
823 }
824
825 // Update the corrections on the bodies.
826 // NOTE: This is a scatter operation
827 ScatterBodyPositionCorrections(DP0, DQ0, DP1, DQ1, Body0, Body1);
828 }
829
832 const FSimdSolverBodyPtr& Body0,
833 const FSimdSolverBodyPtr& Body1,
834 const FSimdRealf& Dt)
835 {
836 // Gather the body data we need
837 FSimdVec3f V0, W0, V1, W1;
838 GatherBodyVelocities(Body0, Body1, V0, W0, V1, W1);
839
840 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < MaxManifoldPoints; ++ManifoldPointIndex)
841 {
843
844 // Which lanes require this point be simulated?
845 //if (!SimdAnyTrue(ManifoldPoint.IsValid))
846 //{
847 // continue;
848 //}
849
850 // Only lanes that applied a position correction or that started with an overlap require a velocity correction
851 FSimdSelector ShouldSolveVelocity = SimdOr(SimdGreater(ManifoldPoint.SimdNetPushOutNormal, FSimdRealf::Zero()), SimdLess(ManifoldPoint.SimdContactDeltaNormal, FSimdRealf::Zero()));
852 ShouldSolveVelocity = SimdAnd(ManifoldPoint.IsValid, ShouldSolveVelocity);
853 //if (!SimdAnyTrue(ShouldSolveVelocity))
854 //{
855 // continue;
856 //}
857
858 // Calculate the velocity error we need to correct
859 const FSimdVec3f ContactVelocity0 = SimdAdd(V0, SimdCrossProduct(W0, ManifoldPoint.SimdRelativeContactPoint0));
860 const FSimdVec3f ContactVelocity1 = SimdAdd(V1, SimdCrossProduct(W1, ManifoldPoint.SimdRelativeContactPoint1));
864
865 // Calculate the velocity correction for the error
867
868 // The minimum normal impulse we can apply. We are allowed to apply a negative impulse
869 // up to an amount that would conteract the implciit velocity applied by the pushout
870 // MinImpulseNormal = FMath::Min(0, -NetPushOutNormal / Dt)
871 // if (NetImpulseNormal + ImpulseNormal < MinImpulseNormal) {...}
876
877 // Clear the impulse for lanes that should not be solving for velocity
878 ImpulseNormal = SimdSelect(ShouldSolveVelocity, ImpulseNormal, FSimdRealf::Zero());
879
880 ManifoldPoint.SimdNetImpulseNormal = SimdAdd(ManifoldPoint.SimdNetImpulseNormal, ImpulseNormal);
881
882 // NOTE: order of operations matches FPBDCollisionSolver::ApplyVelocityCorrectionNormal for AB Testing
883 const FSimdVec3f Impulse = SimdMultiply(ImpulseNormal, ManifoldPoint.SimdContactNormal);
886 const FSimdVec3f DW0 = SimdMultiply(ImpulseNormal, ManifoldPoint.SimdContactNormalAngular0);
887 const FSimdVec3f DW1 = SimdMultiply(ImpulseNormal, ManifoldPoint.SimdContactNormalAngular1);
888 V0 = SimdAdd(V0, DV0);
889 W0 = SimdAdd(W0, DW0);
890 V1 = SimdSubtract(V1, DV1);
891 W1 = SimdSubtract(W1, DW1);
892 }
893
894 ScatterBodyVelocities(V0, W0, V1, W1, Body0, Body1);
895 }
896
899 const FSimdSolverBodyPtr& Body0,
900 const FSimdSolverBodyPtr& Body1,
901 const FSimdRealf& Dt,
903 {
904 // Gather the body data we need
905 FSimdVec3f V0, W0, V1, W1;
906 GatherBodyVelocities(Body0, Body1, V0, W0, V1, W1);
907
908 for (int32 ManifoldPointIndex = 0; ManifoldPointIndex < MaxManifoldPoints; ++ManifoldPointIndex)
909 {
911
912 // Which lanes require this point be simulated?
913 //if (!SimdAnyTrue(ManifoldPoint.IsValid))
914 //{
915 // continue;
916 //}
917
918 // Only lanes that applied a position correction or that started with an overlap require a velocity correction
919 FSimdSelector ShouldSolveVelocity = SimdOr(SimdGreater(ManifoldPoint.SimdNetPushOutNormal, FSimdRealf::Zero()), SimdLess(ManifoldPoint.SimdContactDeltaNormal, FSimdRealf::Zero()));
920 ShouldSolveVelocity = SimdAnd(ManifoldPoint.IsValid, ShouldSolveVelocity);
921 //if (!SimdAnyTrue(ShouldSolveVelocity))
922 //{
923 // continue;
924 //}
925
926 // Calculate the velocity error we need to correct
927 const FSimdVec3f ContactVelocity0 = SimdAdd(V0, SimdCrossProduct(W0, ManifoldPoint.SimdRelativeContactPoint0));
928 const FSimdVec3f ContactVelocity1 = SimdAdd(V1, SimdCrossProduct(W1, ManifoldPoint.SimdRelativeContactPoint1));
933
934 // A stiffness multiplier on the impulses (zeroed if we have no friction in a lane)
936
937 // Calculate the impulses
941
942 // Zero out friction for lanes with no friction
946
947 // The minimum normal impulse we can apply. We are allowed to apply a negative impulse
948 // up to an amount that would conteract the implciit velocity applied by the pushout
949 // MinImpulseNormal = FMath::Min(0, -NetPushOutNormal / Dt)
950 // if (NetImpulseNormal + ImpulseNormal < MinImpulseNormal) {...}
955
956 // Calculate the impulse multipler if clamped to the dynamic friction cone
957 const FSimdRealf MaxNetImpulseAndPushOutTangent = SimdAdd(ManifoldPoint.SimdNetImpulseNormal, SimdAdd(ImpulseNormal, SimdDivide(ManifoldPoint.SimdNetPushOutNormal, Dt)));
962
963 // Apply the multiplier to lanes that exceeded the friction limit
967
968 // Clear the impulse for lanes that should not be solving for velocity
969 ImpulseNormal = SimdSelect(ShouldSolveVelocity, ImpulseNormal, FSimdRealf::Zero());
972
973 ManifoldPoint.SimdNetImpulseNormal = SimdAdd(ManifoldPoint.SimdNetImpulseNormal, ImpulseNormal);
974 ManifoldPoint.SimdNetImpulseTangentU = SimdAdd(ManifoldPoint.SimdNetImpulseTangentU, ImpulseTangentU);
975 ManifoldPoint.SimdNetImpulseTangentV = SimdAdd(ManifoldPoint.SimdNetImpulseTangentU, ImpulseTangentV);
976
977 // NOTE: order of operations matches FPBDCollisionSolver::ApplyVelocityCorrection for AB Testing
981 const FSimdVec3f DW0 = SimdAdd(SimdMultiply(ImpulseNormal, ManifoldPoint.SimdContactNormalAngular0), SimdAdd(SimdMultiply(ImpulseTangentU, ManifoldPoint.SimdContactTangentUAngular0), SimdMultiply(ImpulseTangentV, ManifoldPoint.SimdContactTangentVAngular0)));
982 const FSimdVec3f DW1 = SimdAdd(SimdMultiply(ImpulseNormal, ManifoldPoint.SimdContactNormalAngular1), SimdAdd(SimdMultiply(ImpulseTangentU, ManifoldPoint.SimdContactTangentUAngular1), SimdMultiply(ImpulseTangentV, ManifoldPoint.SimdContactTangentVAngular1)));
983 V0 = SimdAdd(V0, DV0);
984 W0 = SimdAdd(W0, DW0);
985 V1 = SimdSubtract(V1, DV1);
986 W1 = SimdSubtract(W1, DW1);
987 }
988
989 ScatterBodyVelocities(V0, W0, V1, W1, Body0, Body1);
990 }
991
994 const FSimdSolverBodyPtr& Body0,
995 const FSimdSolverBodyPtr& Body1,
996 const FSimdRealf& Dt,
998 {
999 // If all the lanes have zero velocity friction, run the zero-friction path
1000 // (only spheres and capsules use the velocity-based dynamic friction path)
1003 {
1005 return;
1006 }
1007
1009 }
1010
1012 const int32 ManifoldPointIndex,
1013 const int32 LaneIndex,
1015 {
1016 const int32 BufferIndex = GetBufferIndex(ManifoldPointIndex);
1018
1019 return ManifoldPoint.SimdNetPushOutNormal.GetValue(LaneIndex) * ManifoldPoint.SimdContactNormal.GetValue(LaneIndex) +
1020 ManifoldPoint.SimdNetPushOutTangentU.GetValue(LaneIndex) * ManifoldPoint.SimdContactTangentU.GetValue(LaneIndex) +
1021 ManifoldPoint.SimdNetPushOutTangentV.GetValue(LaneIndex) * ManifoldPoint.SimdContactTangentV.GetValue(LaneIndex);
1022 }
1023
1025 const int32 ManifoldPointIndex,
1026 const int32 LaneIndex,
1028 {
1029 const int32 BufferIndex = GetBufferIndex(ManifoldPointIndex);
1031
1032 return ManifoldPoint.SimdNetImpulseNormal.GetValue(LaneIndex) * ManifoldPoint.SimdContactNormal.GetValue(LaneIndex) +
1033 ManifoldPoint.SimdNetImpulseTangentU.GetValue(LaneIndex) * ManifoldPoint.SimdContactTangentU.GetValue(LaneIndex) +
1034 ManifoldPoint.SimdNetImpulseTangentV.GetValue(LaneIndex) * ManifoldPoint.SimdContactTangentV.GetValue(LaneIndex);
1035 }
1036
1038 const int32 ManifoldPointIndex,
1039 const int32 LaneIndex,
1041 {
1042 const int32 BufferIndex = GetBufferIndex(ManifoldPointIndex);
1044
1046 }
1047
1048 public:
1049 int32 GetBufferIndex(const int32 ManifoldPointIndex) const
1050 {
1051 return ManifoldPointBeginIndex + ManifoldPointIndex;
1052 }
1053
1066
1067 // Each lane has space for MaxManifoldPoints, but not all will be used
1068 // Unused manifold points may be in the middle of the list (if disabled for example)
1072
1079 };
1080
1085
1086
1092 {
1093 public:
1094 template<int TNumLanes>
1098 const TArrayView<TSolverBodyPtrPairSimd<TNumLanes>>& SolverBodies,
1099 const FSolverReal Dt,
1100 const FSolverReal MaxPushOut);
1101
1102 template<int TNumLanes>
1106 const TArrayView<TSolverBodyPtrPairSimd<TNumLanes>>& SolverBodies,
1107 const FSolverReal Dt,
1108 const FSolverReal MaxPushOut);
1109
1110 template<int TNumLanes>
1114 const TArrayView<TSolverBodyPtrPairSimd<TNumLanes>>& SolverBodies,
1115 const FSolverReal Dt);
1116
1117 template<int TNumLanes>
1121 const TArrayView<TSolverBodyPtrPairSimd<TNumLanes>>& SolverBodies,
1122 const FSolverReal Dt);
1123
1124 static CHAOS_API void CheckISPC();
1125 };
1126
1127 template<>
1129 const TArrayView<TPBDCollisionSolverSimd<4>>& Solvers,
1131 const TArrayView<TSolverBodyPtrPairSimd<4>>& SolverBodies,
1132 const FSolverReal Dt,
1133 const FSolverReal MaxPushOut);
1134
1135 template<>
1137 const TArrayView<TPBDCollisionSolverSimd<4>>& Solvers,
1139 const TArrayView<TSolverBodyPtrPairSimd<4>>& SolverBodies,
1140 const FSolverReal Dt,
1141 const FSolverReal MaxPushOut);
1142
1143 template<>
1145 const TArrayView<TPBDCollisionSolverSimd<4>>& Solvers,
1147 const TArrayView<TSolverBodyPtrPairSimd<4>>& SolverBodies,
1148 const FSolverReal Dt);
1149
1150 template<>
1152 const TArrayView<TPBDCollisionSolverSimd<4>>& Solvers,
1154 const TArrayView<TSolverBodyPtrPairSimd<4>>& SolverBodies,
1155 const FSolverReal Dt);
1156
1157 } // namespace Private
1158} // namespace Chaos
1159
@ INDEX_NONE
Definition CoreMiscDefines.h:150
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 W1
@ One
Definition PropertyPathHelpersTest.h:16
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
Definition SolverBody.h:99
const FSolverMatrix33 & InvI() const
Get the world-space inverse inertia.
Definition SolverBody.h:166
FSolverReal InvM() const
Get the inverse mass.
Definition SolverBody.h:156
Definition Matrix.h:21
Definition PBDCollisionSolverSimd.h:1092
static void SolveVelocityWithFriction(const TArrayView< TPBDCollisionSolverSimd< TNumLanes > > &Solvers, const TArrayView< TPBDCollisionSolverManifoldPointsSimd< TNumLanes > > &ManifoldPoints, const TArrayView< TSolverBodyPtrPairSimd< TNumLanes > > &SolverBodies, const FSolverReal Dt)
static void SolvePositionWithFriction(const TArrayView< TPBDCollisionSolverSimd< TNumLanes > > &Solvers, const TArrayView< TPBDCollisionSolverManifoldPointsSimd< TNumLanes > > &ManifoldPoints, const TArrayView< TSolverBodyPtrPairSimd< TNumLanes > > &SolverBodies, const FSolverReal Dt, const FSolverReal MaxPushOut)
static void SolvePositionNoFriction(const TArrayView< TPBDCollisionSolverSimd< TNumLanes > > &Solvers, const TArrayView< TPBDCollisionSolverManifoldPointsSimd< TNumLanes > > &ManifoldPoints, const TArrayView< TSolverBodyPtrPairSimd< TNumLanes > > &SolverBodies, const FSolverReal Dt, const FSolverReal MaxPushOut)
static void SolveVelocityNoFriction(const TArrayView< TPBDCollisionSolverSimd< TNumLanes > > &Solvers, const TArrayView< TPBDCollisionSolverManifoldPointsSimd< TNumLanes > > &ManifoldPoints, const TArrayView< TSolverBodyPtrPairSimd< TNumLanes > > &SolverBodies, const FSolverReal Dt)
static CHAOS_API void CheckISPC()
Definition PBDCollisionSolverSimd.cpp:194
A SIMD row of contact points from a set of FPBDCollisionSolverSimd.
Definition PBDCollisionSolverSimd.h:182
FSimdRealf SimdNetImpulseNormal
Definition PBDCollisionSolverSimd.h:222
FSimdRealf SimdContactDeltaNormal
Definition PBDCollisionSolverSimd.h:199
FSimdVec3f SimdContactNormal
Definition PBDCollisionSolverSimd.h:198
FSimdRealf SimdContactMassNormal
Definition PBDCollisionSolverSimd.h:201
FSimdRealf SimdContactDeltaTangentU
Definition PBDCollisionSolverSimd.h:208
FSimdVec3f SimdContactNormalAngular1
Definition PBDCollisionSolverSimd.h:203
FSimdRealf SimdNetPushOutNormal
Definition PBDCollisionSolverSimd.h:200
FSimdSelector IsValid
Definition PBDCollisionSolverSimd.h:191
FSimdVec3f SimdContactTangentVAngular1
Definition PBDCollisionSolverSimd.h:218
FSimdRealf SimdNetImpulseTangentU
Definition PBDCollisionSolverSimd.h:223
FSimdRealf SimdContactMassTangentV
Definition PBDCollisionSolverSimd.h:214
FSimdVec3f SimdContactTangentU
Definition PBDCollisionSolverSimd.h:206
FSimdRealf SimdNetPushOutTangentV
Definition PBDCollisionSolverSimd.h:211
FSimdVec3f SimdContactTangentVAngular0
Definition PBDCollisionSolverSimd.h:216
FSimdVec3f SimdContactNormalAngular0
Definition PBDCollisionSolverSimd.h:202
FSimdRealf SimdNetPushOutTangentU
Definition PBDCollisionSolverSimd.h:210
FSimdRealf SimdNetImpulseTangentV
Definition PBDCollisionSolverSimd.h:224
FSimdVec3f SimdContactTangentV
Definition PBDCollisionSolverSimd.h:207
FSimdRealf SimdContactDeltaTangentV
Definition PBDCollisionSolverSimd.h:209
FSimdVec3f SimdContactTangentUAngular1
Definition PBDCollisionSolverSimd.h:217
FSimdRealf SimdContactMassTangentU
Definition PBDCollisionSolverSimd.h:213
FSimdVec3f SimdRelativeContactPoint0
Definition PBDCollisionSolverSimd.h:194
FSimdVec3f SimdContactTangentUAngular0
Definition PBDCollisionSolverSimd.h:215
FSimdRealf SimdContactTargetVelocityNormal
Definition PBDCollisionSolverSimd.h:221
FSimdRealf SimdStaticFrictionRatio
Definition PBDCollisionSolverSimd.h:212
FSimdVec3f SimdRelativeContactPoint1
Definition PBDCollisionSolverSimd.h:195
Definition PBDCollisionSolverSimd.h:232
int32 MaxManifoldPoints
Definition PBDCollisionSolverSimd.h:1069
FSolverVec3 GetNetPushOut(const int32 ManifoldPointIndex, const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer) const
Definition PBDCollisionSolverSimd.h:1011
void ResetManifold()
Definition PBDCollisionSolverSimd.h:298
FSolverVec3 GetNetImpulse(const int32 ManifoldPointIndex, const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer) const
Definition PBDCollisionSolverSimd.h:1024
void Init()
Definition PBDCollisionSolverSimd.h:1054
static TPBDCollisionSolverSimd< TNumLanes > MakeInitialized()
Definition PBDCollisionSolverSimd.h:245
TPBDCollisionSolverSimd()
Definition PBDCollisionSolverSimd.h:259
void SetManifoldPoint(const int32 ManifoldPointIndex, const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, 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, const FSolverBody &Body0, const FSolverBody &Body1, const FSolverReal InvMScale0, const FSolverReal InvIScale0, const FSolverReal InvMScale1, const FSolverReal InvIScale1)
Definition PBDCollisionSolverSimd.h:324
int32 ManifoldPointBeginIndex
Definition PBDCollisionSolverSimd.h:1070
FSimdRealf SimdInvM0
Definition PBDCollisionSolverSimd.h:1077
FSolverReal GetStaticFrictionRatio(const int32 ManifoldPointIndex, const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer) const
Definition PBDCollisionSolverSimd.h:1037
FSimdInt32 NumManifoldPoints() const
Definition PBDCollisionSolverSimd.h:261
void SetManifoldPointsBuffer(const int32 InBeginIndex, const int32 InMax)
Definition PBDCollisionSolverSimd.h:271
int32 GetMaxManifoldPoints() const
Definition PBDCollisionSolverSimd.h:278
void SetStiffness(const FSimdRealf InStiffness)
Definition PBDCollisionSolverSimd.h:310
const FSimdManifoldPoint & GetManifoldPoint(const int32 ManifoldPointIndex, const TArrayView< const FSimdManifoldPoint > &ManifoldPointsBuffer) const
Definition PBDCollisionSolverSimd.h:283
void SolvePositionNoFriction(const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSimdSolverBodyPtr &Body0, const FSimdSolverBodyPtr &Body1, const FSimdRealf &MaxPushOut)
Definition PBDCollisionSolverSimd.h:551
void SetNumManifoldPoints(const FSimdInt32 &InNum)
Definition PBDCollisionSolverSimd.h:266
static const int32 MaxConstrainedBodies
Definition PBDCollisionSolverSimd.h:241
static const int32 MaxPointsPerConstraint
Definition PBDCollisionSolverSimd.h:242
void SolvePositionWithFriction(const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSimdSolverBodyPtr &Body0, const FSimdSolverBodyPtr &Body1, const FSimd4Realf &MaxPushOut, const FSimd4Realf &FrictionStiffnessScale)
Definition PBDCollisionSolverSimd.h:628
int32 GetBufferIndex(const int32 ManifoldPointIndex) const
Definition PBDCollisionSolverSimd.h:1049
FSimdRealf SimdStaticFriction
Definition PBDCollisionSolverSimd.h:1073
FSimdRealf SimdStiffness
Definition PBDCollisionSolverSimd.h:1076
void InitManifoldPoints(const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer)
Definition PBDCollisionSolverSimd.h:315
void UpdateManifoldPointMass(const int32 ManifoldPointIndex, const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSolverBody &Body0, const FSolverBody &Body1, const FSolverReal InvMScale0, const FSolverReal InvIScale0, const FSolverReal InvMScale1, const FSolverReal InvIScale1)
Update the cached mass properties based on the current body transforms.
Definition PBDCollisionSolverSimd.h:374
void UpdateMassNormal(const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSolverBody &Body0, const FSolverBody &Body1, const FSolverReal InvMScale0, const FSolverReal InvIScale0, const FSolverReal InvMScale1, const FSolverReal InvIScale1)
Definition PBDCollisionSolverSimd.h:525
void SetFriction(const FSimdRealf InStaticFriction, const FSimdRealf InDynamicFriction, const FSimdRealf InVelocityFriction)
Definition PBDCollisionSolverSimd.h:303
void SolveVelocityNoFriction(const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSimdSolverBodyPtr &Body0, const FSimdSolverBodyPtr &Body1, const FSimdRealf &Dt)
Definition PBDCollisionSolverSimd.h:830
FSimdInt32 SimdNumManifoldPoints
Definition PBDCollisionSolverSimd.h:1071
void SolveVelocityWithFriction(const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSimdSolverBodyPtr &Body0, const FSimdSolverBodyPtr &Body1, const FSimdRealf &Dt, const FSimd4Realf &FrictionStiffnessScale)
Definition PBDCollisionSolverSimd.h:992
FSimdRealf SimdDynamicFriction
Definition PBDCollisionSolverSimd.h:1074
FSimdRealf SimdVelocityFriction
Definition PBDCollisionSolverSimd.h:1075
void Reset()
Definition PBDCollisionSolverSimd.h:291
FSimdRealf SimdInvM1
Definition PBDCollisionSolverSimd.h:1078
void UpdateManifoldPointMassNormal(const int32 ManifoldPointIndex, const int32 LaneIndex, const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSolverBody &Body0, const FSolverBody &Body1, const FSolverReal InvMScale0, const FSolverReal InvIScale0, const FSolverReal InvMScale1, const FSolverReal InvIScale1)
Definition PBDCollisionSolverSimd.h:462
static TPBDCollisionSolverSimd< TNumLanes > MakeUninitialized()
Definition PBDCollisionSolverSimd.h:253
void SolveVelocityWithFrictionImpl(const TArrayView< FSimdManifoldPoint > &ManifoldPointsBuffer, const FSimdSolverBodyPtr &Body0, const FSimdSolverBodyPtr &Body1, const FSimdRealf &Dt, const FSimd4Realf &FrictionStiffnessScale)
Definition PBDCollisionSolverSimd.h:897
Definition Vector.h:407
Definition Vector.h:1000
Definition ArrayView.h:139
float Chaos_PBDCollisionSolver_Position_MinInvMassScale
Definition PBDCollisionSolver.cpp:33
float Chaos_PBDCollisionSolver_Velocity_MinInvMassScale
Definition PBDCollisionSolver.cpp:46
FORCEINLINE FSimd4Realf SimdMax(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:524
FORCEINLINE FSimd4Realf SimdSquare(const FSimd4Realf &InV)
Definition Simd4.h:479
void ScatterBodyPositionCorrections(const TSimdVec3f< 4 > &DP0, const TSimdVec3f< 4 > &DQ0, const TSimdVec3f< 4 > &DP1, const TSimdVec3f< 4 > &DQ1, const TSolverBodyPtrSimd< 4 > &Body0, const TSolverBodyPtrSimd< 4 > &Body1)
Definition PBDCollisionSolverSimd.h:94
FORCEINLINE FSimd4Realf SimdMultiply(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:362
void GatherBodyVelocities(const TSolverBodyPtrSimd< 4 > &Body0, const TSolverBodyPtrSimd< 4 > &Body1, TSimdVec3f< 4 > &V0, TSimdVec3f< 4 > &W0, TSimdVec3f< 4 > &V1, TSimdVec3f< 4 > &W1)
Definition PBDCollisionSolverSimd.h:120
FORCEINLINE FSimd4Selector SimdLess(const FSimd4Int32 &InL, const FSimd4Int32 &InR)
Definition Simd4.h:250
FORCEINLINE FSimd4Realf SimdDivide(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:431
FORCEINLINE FSimd4Realf SimdMin(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:512
FORCEINLINE FSimd4Realf SimdDotProduct(const FSimd4Vec3f &L, const FSimd4Vec3f &R)
Definition Simd4.h:460
void GatherBodyPositionCorrections(const TSolverBodyPtrSimd< 4 > &Body0, const TSolverBodyPtrSimd< 4 > &Body1, TSimdVec3f< 4 > &DP0, TSimdVec3f< 4 > &DQ0, TSimdVec3f< 4 > &DP1, TSimdVec3f< 4 > &DQ1)
Definition PBDCollisionSolverSimd.h:35
FORCEINLINE FSimd4Selector SimdNotEqual(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:188
FORCEINLINE FSimd4Selector SimdAnd(const FSimd4Selector &InL, const FSimd4Selector &InR)
Definition Simd4.h:164
FORCEINLINE FSimd4Realf SimdSubtract(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:333
FORCEINLINE FSimd4Realf SimdAdd(const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:304
FORCEINLINE FSimd4Selector SimdOr(const FSimd4Selector &InL, const FSimd4Selector &InR)
Definition Simd4.h:152
void ScatterBodyVelocities(const TSimdVec3f< 4 > &V0, const TSimdVec3f< 4 > &W0, const TSimdVec3f< 4 > &V1, const TSimdVec3f< 4 > &W1, const TSolverBodyPtrSimd< 4 > &Body0, const TSolverBodyPtrSimd< 4 > &Body1)
Definition PBDCollisionSolverSimd.h:145
FORCEINLINE FSimd4Selector SimdGreaterEqual(const FSimd4Int32 &InL, const FSimd4Int32 &InR)
Definition Simd4.h:200
FORCEINLINE FSimd4Realf SimdSelect(const FSimd4Selector &InSelector, const FSimd4Realf &InL, const FSimd4Realf &InR)
Definition Simd4.h:274
FORCEINLINE bool SimdAnyTrue(const FSimd4Selector &InL)
Definition Simd4.h:129
FORCEINLINE FSimd4Selector SimdGreater(const FSimd4Int32 &InL, const FSimd4Int32 &InR)
Definition Simd4.h:225
FORCEINLINE FSimd4Realf SimdInvSqrt(const FSimd4Realf &InV)
Definition Simd4.h:501
FORCEINLINE FSimd4Realf SimdNegate(const FSimd4Realf &InL)
Definition Simd4.h:293
FORCEINLINE FSimd4Vec3f SimdCrossProduct(const FSimd4Vec3f &L, const FSimd4Vec3f &R)
Definition Simd4.h:443
FORCEINLINE FSimd4Vec3f SimdGatherAligned(const FVec3f &InA, const FVec3f &InB, const FVec3f &InC, const FVec3f &InD)
Definition Simd4.h:544
Definition SkeletalMeshComponent.h:307
TVector< FRealSingle, 3 > FVec3f
Definition Core.h:27
FRealSingle FSolverReal
Definition SolverBody.h:38
Definition OverriddenPropertySet.cpp:45
Definition SimdTypes.h:127
FORCEINLINE void SetValues(const int32 I)
Definition SimdTypes.h:144
FORCEINLINE int32 GetValue(const int32 LaneIndex) const
Definition SimdTypes.h:139
static TSimdInt32< TNumLanes > Zero()
Definition SimdTypes.h:168
FORCEINLINE float GetValue(const int32 LaneIndex) const
Definition SimdTypes.h:180
static TSimdRealf Make(const float F)
FORCEINLINE void SetValue(const int32 LaneIndex, const float F)
Definition SimdTypes.h:175
static TSimdRealf Zero()
FORCEINLINE void SetValues(const float F)
Definition SimdTypes.h:185
static TSimdRealf One()
Definition SimdTypes.h:75
FORCEINLINE void SetValue(const int LaneIndex, bool B)
Definition SimdTypes.h:78
Definition SimdTypes.h:99
FORCEINLINE ValueType GetValue(const int32 LaneIndex) const
Definition SimdTypes.h:108
Definition SimdTypes.h:204
Definition PBDCollisionSolverSimd.h:172
TSolverBodyPtrSimd< TNumLanes > Body1
Definition PBDCollisionSolverSimd.h:174
TSolverBodyPtrSimd< TNumLanes > Body0
Definition PBDCollisionSolverSimd.h:173