UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
EPAVectorized.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/EPA.h"
7
8#include <queue>
9#include "ChaosCheck.h"
10#include "ChaosLog.h"
11#include "Templates/Function.h"
12
13#include "Math/VectorRegister.h"
14
15namespace Chaos
16{
17
18
23
24
26{
28 VectorRegister4Float Distance; //Triangle distance from origin
30 TVector<int32, 3> AdjFaces; //Adjacent triangles
31 TVector<int32, 3> AdjEdges; //Adjacent edges (idx in adjacent face)
32 bool bObsolete; //indicates that an entry can be skipped (became part of bigger polytope)
33
35 {
36 return static_cast<bool>(VectorMaskBits(VectorCompareGT(Distance, Other.Distance)));
37 }
38
69
71 {
72 //change vertex order
73 std::swap(IdxBuffer[0], IdxBuffer[1]);
74
75 //edges went from 0,1,2 to 1,0,2
76 //0th edge/face is the same (0,1 becomes 1,0)
77 //1th edge/face is now (0,2 instead of 1,2)
78 //2nd edge/face is now (2,1 instead of 2,0)
79
80 //update the adjacent face's adjacent edge first
81 auto UpdateAdjEdge = [Entries, this](int32 Old, int32 New)
82 {
83 VectorTEPAEntry& AdjFace = Entries[AdjFaces[Old]];
85 check(StaleAdjIdx == Old);
87 };
88
89 UpdateAdjEdge(1, 2);
90 UpdateAdjEdge(2, 1);
91
92 //now swap the actual edges and faces
93 std::swap(AdjFaces[1], AdjFaces[2]);
94 std::swap(AdjEdges[1], AdjEdges[2]);
95
98 }
99
104
106 {
107 //Compare the projected point (PlaneNormal) to the triangle in the plane
112
117
118
124
128
129
130 // (PACSign < -Epsilon && PCBSign > Epsilon) || (PACSign > Epsilon && PCBSign < -Epsilon)
131
134
137
141
143
144 return !static_cast<bool>(VectorMaskBits(IsFalse));
145 }
146};
147template <typename SupportALambda, typename SupportBLambda >
149{
150 const int32 NumVerts = VertsA.Num();
151 check(VertsB.Num() == NumVerts);
152
153 auto AddFartherPoint = [&](const VectorRegister4Float& Dir)
154 {
156 const VectorRegister4Float A0 = SupportA(Dir); //should we have a function that does both directions at once?
159 const VectorRegister4Float B1 = SupportB(Dir);
160
162 const VectorRegister4Float W1 = VectorSubtract(A1, B1);
163
166
168
170 {
171 VertsA.Add(A1);
172 VertsB.Add(B1);
173 }
174 else
175 {
176 VertsA.Add(A0);
177 VertsB.Add(B0);
178 }
179 };
180
181 OutEntries.AddUninitialized(4);
182 OutTouchNormal = MakeVectorRegisterFloat(0.0f, 0.0f, 1.0f, 0.0f);
183
184 bool bValid = false;
185
186 switch (NumVerts)
187 {
188 case 1:
189 {
190 //assuming it's a touching hit at origin, but we still need to calculate a separating normal
191 AddFartherPoint(OutTouchNormal); // Use an arbitrary direction
192
193 // Now we might have a line! So fall trough to the next case
194 }
195 case 2:
196 {
197 //line, add farthest point along most orthogonal axes
198 const VectorRegister4Float Dir = VectorSubtract(VectorMinkowskiVert(VertsA.GetData(), VertsB.GetData(), 1), VectorMinkowskiVert(VertsA.GetData(), VertsB.GetData(), 0));
199
200 constexpr VectorRegister4Float Eps = MakeVectorRegisterFloatConstant(1e-4f, 1e-4f, 1e-4f, 1e-4f);
202 if (VectorMaskBits(Valid)) //two verts given are distinct
203 {
204 // return MakeVectorRegisterFloatFromDouble(LoadFloat3(Center));
209
213
214 constexpr VectorRegister4Float Axis1 = MakeVectorRegisterFloatConstant(0.0f, 1.0f, 0.0f, 0.0f);
215 constexpr VectorRegister4Float Axis2 = MakeVectorRegisterFloatConstant(0.0f, 0.0f, 1.0f, 0.0f);
216
220
223
226
227 bValid = OutEntries[0].Initialize(VertsA.GetData(), VertsB.GetData(), 1, 2, 3, { 3,1,2 }, { 1,1,1 });
228 bValid &= OutEntries[1].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 3, 2, { 2,0,3 }, { 2,1,0 });
229 bValid &= OutEntries[2].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 1, 3, { 3,0,1 }, { 2,2,0 });
230 bValid &= OutEntries[3].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 2, 1, { 1,0,2 }, { 2,0,0 });
231
232 if (!bValid)
233 {
235 return false;
236 }
237 }
238 else
239 {
240 // The two vertices are not distinct that may happen when the single vertex case above was hit and our CSO is very thin in that direction
241 CHAOS_ENSURE(NumVerts == 1); // If this ensure fires we were given 2 vertices that are not distinct to start with
242 return false;
243 }
244 break;
245 }
246 case 3:
247 {
248 //triangle, add farthest point along normal
249 bValid = OutEntries[3].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 2, 1, { 1,0,2 }, { 2,0,0 });
250 if (CHAOS_ENSURE(bValid)) //input verts must form a valid triangle
251 {
252 const VectorTEPAEntry& Base = OutEntries[3];
253
254 AddFartherPoint(Base.PlaneNormal);
255
256 bValid = OutEntries[0].Initialize(VertsA.GetData(), VertsB.GetData(), 1, 2, 3, { 3,1,2 }, { 1,1,1 });
257 bValid &= OutEntries[1].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 3, 2, { 2,0,3 }, { 2,1,0 });
258 bValid &= OutEntries[2].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 1, 3, { 3,0,1 }, { 2,2,0 });
259
260 if (!bValid)
261 {
262 OutTouchNormal = Base.PlaneNormal;
263 return false;
264 }
265 }
266 break;
267 }
268 case 4:
269 {
270 bValid = OutEntries[0].Initialize(VertsA.GetData(), VertsB.GetData(), 1, 2, 3, { 3,1,2 }, { 1,1,1 });
271 bValid &= OutEntries[1].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 3, 2, { 2,0,3 }, { 2,1,0 });
272 bValid &= OutEntries[2].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 1, 3, { 3,0,1 }, { 2,2,0 });
273 bValid &= OutEntries[3].Initialize(VertsA.GetData(), VertsB.GetData(), 0, 2, 1, { 1,0,2 }, { 2,0,0 });
274
275 if (!bValid)
276 {
277 CHAOS_ENSURE(false); //expect user to give us valid tetrahedron
278 UE_LOG(LogChaos, Log, TEXT("Invalid tetrahedron encountered in VectorInitializeEPA"));
279 }
280
281 break;
282 }
283
284 default:
285 {
286 CHAOS_ENSURE(false);
287 break;
288 }
289 }
290
291 if (bValid)
292 {
293 //make sure normals are pointing out of tetrahedron
294 // In the usual case the distances will either all be positive or negative,
295 // but the tetrahedron can be very close to (or touching) the origin
296 // Look for farthest plane to decide
298 for (VectorTEPAEntry& Entry : OutEntries)
299 {
300 const VectorRegister4Float AbsDistance = VectorAbs(Entry.Distance);
304 }
307 {
308 for (VectorTEPAEntry& Entry : OutEntries)
309 {
310 Entry.SwapWinding(OutEntries.GetData());
311 }
312 }
313 }
314
315 return bValid;
316}
317
318
320{
321 constexpr VectorRegister4Float Eps = MakeVectorRegisterFloatConstant(1.e-4f, 1.e-4f, 1.e-4f, 1.e-4f);
322 {
323 VectorTEPAEntry& Entry = Entries[EntryIdx];
324 for (int i = 0; i < 3; ++i)
325 {
326 ToVisitStack.Add({ Entry.AdjFaces[i], Entry.AdjEdges[i] });
327 }
328 }
329
330 int32 Iteration = 0;
331 const int32 MaxIteration = 10000;
332
333 while (ToVisitStack.Num() && Iteration++ < MaxIteration)
334 {
336 VectorTEPAEntry& Entry = Entries[FloodEntry.EntryIdx];
337 if (!Entry.bObsolete)
338 {
340 {
341 //W can't see this triangle so mark the edge as a border
343 }
344 else
345 {
346 //W can see this triangle so continue flood fill
347 Entry.bObsolete = true; //no longer needed
348 const int32 Idx0 = FloodEntry.EdgeIdx;
349 const int32 Idx1 = (Idx0 + 1) % 3;
350 const int32 Idx2 = (Idx0 + 2) % 3;
351 ToVisitStack.Add({ Entry.AdjFaces[Idx1], Entry.AdjEdges[Idx1] });
352 ToVisitStack.Add({ Entry.AdjFaces[Idx2], Entry.AdjEdges[Idx2] });
353 }
354 }
355 }
356
357 if (Iteration >= MaxIteration)
358 {
359 UE_LOG(LogChaos, Warning, TEXT("VectorEPAComputeVisibilityBorder reached max iteration - something is wrong"));
360 }
361}
362
364{
365 //NOTE: We use this function as fallback when robustness breaks. So - do not assume adjacency is valid as these may be new uninitialized traingles that failed
366
367 VectorRegister4Float As[4] = { VertsA[Entry.IdxBuffer[0]], VertsA[Entry.IdxBuffer[1]], VertsA[Entry.IdxBuffer[2]] };
368 VectorRegister4Float Bs[4] = { VertsB[Entry.IdxBuffer[0]], VertsB[Entry.IdxBuffer[1]], VertsB[Entry.IdxBuffer[2]] };
369 VectorRegister4Float Simplex[4] = { VectorSubtract(As[0], Bs[0]), VectorSubtract(As[1], Bs[1]), VectorSubtract(As[2], Bs[2]) };
370 VectorRegister4Float Barycentric;
371 int32 NumVerts = 3;
373
375
377 {
380 }
381
383
384 constexpr float EpsFloat = 1e-4f;
386
387 // @todo(chaos): pass in epsilon? Does it need to match anything in GJK?
388 if (VectorMaskBits(VectorCompareGT(Eps, OutPenetration))) //if closest point is on the origin (edge case when surface is right on the origin)
389 {
390 OutDir = Entry.PlaneNormal; //just fall back on plane normal
392 {
393 OutPenetration = VectorNegate(OutPenetration); // We are a bit outside of the shape so penetration is negative
394 }
395 }
396 else
397 {
400 {
401 //The origin is on the outside, so the direction is reversed
403 OutPenetration = VectorNegate(OutPenetration); // We are a bit outside of the shape so penetration is negative
404 }
405 }
406
407 OutA = VectorZero();
408 OutB = VectorZero();
409
410
412 Barycentrics[0] = VectorSwizzle(Barycentric, 0, 0, 0, 0);
413 Barycentrics[1] = VectorSwizzle(Barycentric, 1, 1, 1, 1);
414 Barycentrics[2] = VectorSwizzle(Barycentric, 2, 2, 2, 2);
415 Barycentrics[3] = VectorSwizzle(Barycentric, 3, 3, 3, 3);
416
417 for (int i = 0; i < NumVerts; ++i)
418 {
421 }
422}
423
424template <typename TSupportA, typename TSupportB>
426{
428
430
432 {
433 //either degenerate or a touching hit. Either way return penetration 0
438 }
439
440#if DEBUG_EPA
442 for (int32 Idx = 0; Idx < 4; ++Idx)
443 {
445 }
446#endif
447
449 for(int32 Idx = 0; Idx < Entries.Num(); ++Idx)
450 {
451 const bool bIsZeroGTDist = static_cast<bool>(VectorMaskBits(VectorCompareGE(VectorZero(), Entries[Idx].Distance)));
452 //ensure(Entries[Idx].Distance > -Eps);
453 // Entries[Idx].Distance <= 0.0f is true if the origin is a bit out of the polytope (we need to support this case for robustness)
454 if(bIsZeroGTDist || Entries[Idx].IsOriginProjectedInside(VertsABuffer.GetData(), VertsBBuffer.GetData(), OriginInsideEps))
455 {
456 Queue.Add(Idx);
457 }
458 }
459
462
463 VectorTEPAEntry LastEntry = Queue.Num() > 0 ? Entries[Queue.Last()] : Entries[0];
464
467
468 VectorRegister4Float UpperBound = MaxLimit;
469 VectorRegister4Float LowerBound = MinLimit;
470 bool bQueueDirty = true;
471 int32 Iteration = 0;
472 int32 constexpr MaxIterations = 128;
474 while (Queue.Num() && (Iteration++ < MaxIterations))
475 {
476 if (bQueueDirty)
477 {
478 // Avoiding UE's Sort here because it has a call to FMath::Loge. The std version calls insertion sort when possible
479 std::sort(Queue.GetData(), Queue.GetData() + Queue.Num(), [&Entries](const int32 L, const int32 R) { return Entries[L] > Entries[R]; });
480 bQueueDirty = false;
481 }
482
483 int32 EntryIdx = Queue.Pop(EAllowShrinking::No);
484 VectorTEPAEntry& Entry = Entries[EntryIdx];
485 //bool bBadFace = Entry.IsOriginProjectedInside(VertsABuffer.GetData(), VertsBBuffer.GetData());
486 {
487 //UE_LOG(LogChaos, Warning, TEXT("%d BestW:%f, Distance:%f, bObsolete:%d, InTriangle:%d"),
488 // Iteration, BestW.Size(), Entry.Distance, Entry.bObsolete, bBadFace);
489 }
490 if (Entry.bObsolete)
491 {
492 // @todo(chaos): should this count as an iteration? Currently it does...
493 continue;
494 }
495
496 if (VectorMaskBits(VectorCompareGT(Entry.Distance, UpperBound)))
497 {
499 break;
500 }
501
506
507 //Remember the entry that gave us the lowest upper bound and use it in case we have to terminate early
508 //This can result in very deep planes. Ideally we'd just use the plane formed at W, but it's not clear how you get back points in A, B for that
509 //BestEntry = Entry;
510 UpperBound = VectorMin(DistanceToSupportPlane, UpperBound);
511 LowerBound = Entry.Distance;
512
513 // Add one absolute epsilon to be more robust with small values, fixed some issue with small UpperBound
514 constexpr VectorRegister4Float SmallFloatEps = MakeVectorRegisterFloatConstant(1.e-5f, 1.e-5f, 1.e-5f, 1.e-5f);
515 // Use a relative epsilon to have a robust check in the main case
516 constexpr VectorRegister4Float OnePlusRelativeEps = MakeVectorRegisterFloatConstant(1.01f, 1.01f, 1.01f, 1.01f);
517 // It's possible the origin is not contained by the CSO, probably because of numerical error.
518 // In this case the upper bound will be negative, at which point we should just exit.
522 {
524 LastEntry = Entry;
525 break;
526 }
527
528 const VectorRegister4Float LowGTUp = VectorCompareGT(LowerBound, UpperBound);
530 {
531 //we cannot get any better than what we saw, so just return previous face
533 break;
534 }
535
536 LastEntry = Entry;
537
540
541#if DEBUG_EPA
543#endif
544
545 Entry.bObsolete = true;
546 VisibilityBorder.Reset();
550 const int32 FirstIdxInBatch = Entries.Num();
553 if (NumBorderEdges >= 3)
554 {
555 bool bTerminate = false;
557 {
558 //create new entries and update adjacencies
560 VectorTEPAEntry& NewEntry = Entries[NewIdx];
561 const int32 BorderEntryIdx = BorderInfo.EntryIdx;
563 const int32 BorderEdgeIdx0 = BorderInfo.EdgeIdx;
564 const int32 BorderEdgeIdx1 = (BorderEdgeIdx0 + 1) % 3;
567 const bool bValidTri = NewEntry.Initialize(VertsABuffer.GetData(), VertsBBuffer.GetData(), BorderEntry.IdxBuffer[BorderEdgeIdx1], BorderEntry.IdxBuffer[BorderEdgeIdx0], NewVertIdx,
569 { BorderEdgeIdx0, 2, 1 });
571 BorderEntry.AdjEdges[BorderEdgeIdx0] = 0;
572
573 if (!bValidTri)
574 {
575 //couldn't properly expand polytope, so just stop
577 bTerminate = true;
578 break;
579 }
580
581 // Due to numerical inaccuracies NewEntry.Distance >= LowerBound may be false!
582 // However these Entries still have good normals, and needs to be included to prevent
583 // this exiting with very deep penetration results
584
585 if (bValidTri && VectorMaskBits(VectorCompareGE(UpperBound, NewEntry.Distance)))
586 {
587 // NewEntry.Distance <= 0.0f is if the origin is a bit out of the polytope
589 {
590 Queue.Add(NewIdx);
591 bQueueDirty = true;
592 }
593 }
594
595 ++NewIdx;
596 }
597
598 if (bTerminate)
599 {
600 break;
601 }
602 }
603 else
604 {
605 //couldn't properly expand polytope, just stop now
607 break;
608 }
609 }
610
612
613 return ResultStatus;
614}
615}
@ Valid
Definition AndroidInputInterface.h:103
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
#define CHAOS_ENSURE(Condition)
Definition ChaosCheck.h:22
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
#define TEXT(x)
Definition Platform.h:1272
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_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
#define W1
T * New(FMemStackBase &Mem, int32 Count=1, int32 Align=DEFAULT_ALIGNMENT)
Definition MemStack.h:259
FORCEINLINE VectorRegister4Float VectorSubtract(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:731
FORCEINLINE VectorRegister4Float VectorSqrt(const VectorRegister4Float &Vec)
Definition UnrealMathFPU.h:1263
FORCEINLINE VectorRegister4Float VectorReciprocalSqrt(const VectorRegister4Float &Vec)
Definition UnrealMathFPU.h:1279
FORCEINLINE VectorRegister4Float VectorDot3(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:880
FORCEINLINE VectorRegister4Float VectorMin(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1686
FORCEINLINE VectorRegister4Float VectorDot4(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:901
FORCEINLINE VectorRegister4Float VectorDivide(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:834
FORCEINLINE VectorRegister4Float VectorMultiply(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:758
FORCEINLINE VectorRegister4Float VectorBitwiseAnd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1165
FORCEINLINE constexpr VectorRegister4Float MakeVectorRegisterFloatConstant(float X, float Y, float Z, float W)
Definition UnrealMathFPU.h:297
FORCEINLINE VectorRegister4Float VectorMultiplyAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2, const VectorRegister4Float &Vec3)
Definition UnrealMathFPU.h:786
FORCEINLINE VectorRegister4Float VectorSelect(const VectorRegister4Float &Mask, const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1105
FORCEINLINE VectorRegister4Float VectorCompareGT(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:974
FORCEINLINE VectorRegister4Float VectorCompareGE(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1000
FORCEINLINE int32 VectorMaskBits(const VectorRegister4Float &Vec1)
Definition UnrealMathFPU.h:1075
FORCEINLINE VectorRegister4Float VectorNegate(const VectorRegister4Float &Vec)
Definition UnrealMathFPU.h:687
FORCEINLINE VectorRegister4Float VectorAbs(const VectorRegister4Float &Vec)
Definition UnrealMathFPU.h:661
FORCEINLINE VectorRegister4Float VectorAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:704
#define VectorSwizzle(Vec, X, Y, Z, W)
Definition UnrealMathFPU.h:639
FORCEINLINE VectorRegister4Float VectorCross(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1216
FORCEINLINE VectorRegister4Float VectorBitwiseOr(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1140
bool VectorContainsNaNOrInfinite(const VectorRegister4Float &Vec)
Definition UnrealMathFPU.h:1960
FORCEINLINE VectorRegister4Float VectorCompareLE(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1050
FORCEINLINE VectorRegister4Float MakeVectorRegisterFloat(uint32 X, uint32 Y, uint32 Z, uint32 W)
Definition UnrealMathFPU.h:175
FORCEINLINE TVectorRegisterType VectorNormalizeAccurate(TVectorRegisterType Vector)
Definition UnrealMathVectorCommon.h.inl:412
FORCEINLINE VectorRegister4Float VectorZero(void)
Definition UnrealMathVectorCommon.h.inl:16
Definition Vector.h:41
Definition Array.h:670
UE_FORCEINLINE_HINT SizeType AddUninitialized()
Definition Array.h:1664
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT ElementType & Last(SizeType IndexFromTheEnd=0) UE_LIFETIMEBOUND
Definition Array.h:1263
UE_NODEBUG UE_FORCEINLINE_HINT ElementType * GetData() UE_LIFETIMEBOUND
Definition Array.h:1027
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
ElementType Pop(EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:1196
Definition SkeletalMeshComponent.h:307
FORCEINLINE_DEBUGGABLE void VectorComputeEPAResults(const VectorRegister4Float *VertsA, const VectorRegister4Float *VertsB, const VectorTEPAEntry &Entry, VectorRegister4Float &OutPenetration, VectorRegister4Float &OutDir, VectorRegister4Float &OutA, VectorRegister4Float &OutB, EEPAResult &ResultStatus)
Definition EPAVectorized.h:363
FORCEINLINE const VectorRegister4Float VectorMinkowskiVert(const VectorRegister4Float *VertsABuffer, const VectorRegister4Float *VertsBBuffer, const int32 Idx)
Definition EPAVectorized.h:19
EEPAResult VectorEPA(TArray< VectorRegister4Float > &VertsABuffer, TArray< VectorRegister4Float > &VertsBBuffer, const TSupportA &SupportA, const TSupportB &SupportB, VectorRegister4Float &OutPenetration, VectorRegister4Float &OutDir, VectorRegister4Float &WitnessA, VectorRegister4Float &WitnessB)
Definition EPAVectorized.h:425
@ X
Definition SimulationModuleBase.h:152
FORCEINLINE_DEBUGGABLE void VectorEPAComputeVisibilityBorder(TEPAWorkingArray< VectorTEPAEntry > &Entries, int32 EntryIdx, const VectorRegister4Float &W, TEPAWorkingArray< FEPAFloodEntry > &OutBorderEdges, TEPAWorkingArray< FEPAFloodEntry > &ToVisitStack)
Definition EPAVectorized.h:319
EEPAResult
Definition EPA.h:421
FORCEINLINE_DEBUGGABLE T VectorSimplexFindClosestToOrigin(T *RESTRICT Simplex, int32 &RESTRICT NumVerts, T &RESTRICT OutBarycentric, T *RESTRICT A, T *RESTRICT B)
Definition SimplexVectorized.h:405
bool VectorInitializeEPA(TArray< VectorRegister4Float > &VertsA, TArray< VectorRegister4Float > &VertsB, const SupportALambda &SupportA, const SupportBLambda &SupportB, TEPAWorkingArray< VectorTEPAEntry > &OutEntries, VectorRegister4Float &OutTouchNormal)
Definition EPAVectorized.h:148
constexpr VectorRegister4Float Float1000
Definition UnrealMathVectorConstants.h.inl:44
Definition EPA.h:328
Definition EPAVectorized.h:26
VectorRegister4Float Distance
Definition EPAVectorized.h:28
FORCEINLINE_DEBUGGABLE bool Initialize(const VectorRegister4Float *VerticesA, const VectorRegister4Float *VerticesB, int32 InIdx0, int32 InIdx1, int32 InIdx2, const TVector< int32, 3 > &InAdjFaces, const TVector< int32, 3 > &InAdjEdges)
Definition EPAVectorized.h:39
FORCEINLINE_DEBUGGABLE VectorRegister4Float DistanceToPlane(const VectorRegister4Float &X) const
Definition EPAVectorized.h:100
void SwapWinding(VectorTEPAEntry *Entries)
Definition EPAVectorized.h:70
int32 IdxBuffer[3]
Definition EPAVectorized.h:29
FORCEINLINE bool operator>(const VectorTEPAEntry &Other) const
Definition EPAVectorized.h:34
FORCEINLINE_DEBUGGABLE bool IsOriginProjectedInside(const VectorRegister4Float *VertsABuffer, const VectorRegister4Float *VertsBBuffer, const VectorRegister4Float Epsilon) const
Definition EPAVectorized.h:105
VectorRegister4Float PlaneNormal
Definition EPAVectorized.h:27
bool bObsolete
Definition EPAVectorized.h:32
TVector< int32, 3 > AdjFaces
Definition EPAVectorized.h:30
TVector< int32, 3 > AdjEdges
Definition EPAVectorized.h:31
Definition NumericLimits.h:41
Definition UnrealMathFPU.h:20