UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SimplexVectorized.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"
7
8namespace Chaos
9{
10
11 template <typename T, bool CalculatExtraInformation>
13 {
14 const T& X0 = Simplex[0];
15 const T& X1 = Simplex[1];
16 const T X0ToX1 = VectorSubtract(X1, X0);
17
18 //Closest Point = (-X0 dot X1-X0) / ||(X1-X0)||^2 * (X1-X0)
19
20 const T X0ToOrigin = VectorNegate(X0);
21 const T Dot = VectorDot3(X0ToOrigin, X0ToX1);
22
24
28
29 const T MinLimt = TMakeVectorRegisterConstant<T>(std::numeric_limits<FRealSingle>::min() , std::numeric_limits<FRealSingle>::min(), std::numeric_limits<FRealSingle>::min(), std::numeric_limits<FRealSingle>::min());
32
34
35 if constexpr(CalculatExtraInformation)
36 {
37 A[0] = VectorSelect(IsX1, A[1], A[0]);
38 B[0] = VectorSelect(IsX1, B[1], B[0]);
39 }
40
41 T Ratio = VectorDivide(Dot, X0ToX1Squared);
42
43 Ratio = VectorMax(Ratio, TVectorZero<T>());
44 Ratio = VectorMin(Ratio, TMakeVectorRegisterConstant<T>(1, 1, 1, 1));
45
47
50
52
55
56 if constexpr (CalculatExtraInformation)
57 {
59 }
60
61 return Closest;
62 }
63
64 // Based on an algorithm in Real Time Collision Detection - Ericson (very close to that)
65 // Using the same variable name conventions for easy reference
66 template <typename T, bool CalculatExtraInformation>
68 {
69 const T& A = Simplex[0];
70 const T& B = Simplex[1];
71 const T& C = Simplex[2];
72
73 const T AB = VectorSubtract(B, A);
74 const T AC = VectorSubtract(C, A);
75
78 const T MinDouble = TMakeVectorRegisterConstant<T>(std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min(), std::numeric_limits<float>::min());
79 const T AMin = VectorMultiply(A, MinDouble);
80 const T Eps2 = VectorDot3(AMin, AMin);
82
83
85 {
86 NumVerts = 2;
88 }
89
90 // Vertex region A
91 const T AO = VectorNegate(A);
92
93 const T d1 = VectorDot3(AB, AO);
94 const T d2 = VectorDot3(AC, AO);
95
99
100 if (VectorMaskBits(IsA))
101 {
102 NumVerts = 1;
103 if constexpr (CalculatExtraInformation)
104 {
106 }
107 return A;
108 }
109
110 //Vertex region B
111 const T BO = VectorNegate(B);
112 const T d3 = VectorDot3(AB, BO);
113 const T d4 = VectorDot3(AC, BO);
114
116 const T IsD3GED4 = VectorCompareGE(d3, d4);
118
119 if (VectorMaskBits(IsB))
120 {
121 NumVerts = 1;
122 if constexpr (CalculatExtraInformation)
123 {
125 }
126 Simplex[0] = Simplex[1];
127 if constexpr (CalculatExtraInformation)
128 {
129 As[0] = As[1];
130 Bs[0] = Bs[1];
131 }
132 return B;
133 }
134
135 // Edge AB
136 const T d1d4 = VectorMultiply(d1, d4);
137 const T vc = VectorNegateMultiplyAdd(d3, d2, d1d4);
139
145
146 if (VectorMaskBits(IsAB))
147 {
148 NumVerts = 2;
149
152 // b0 a1 a2 a3
153 if constexpr (CalculatExtraInformation)
154 {
156 }
157 return VectorMultiplyAdd(v, AB, A);
158 }
159
160 // Vertex C
161 const T CO = VectorNegate(C);
162 const T d5 = VectorDot3(AB, CO);
163 const T d6 = VectorDot3(AC, CO);
165 const T IsD6GED5 = VectorCompareGE(d6, d5);
167
168 if (VectorMaskBits(IsC))
169 {
170 NumVerts = 1;
171 if constexpr (CalculatExtraInformation)
172 {
174 }
175
176 Simplex[0] = Simplex[2];
177 if constexpr (CalculatExtraInformation)
178 {
179 As[0] = As[2];
180 Bs[0] = Bs[2];
181 }
182 return C;
183 }
184
185 // Edge AC
186 const T d5d2 = VectorMultiply(d5, d2);
187 const T vb = VectorNegateMultiplyAdd(d1, d6, d5d2);
189
195
196 if (VectorMaskBits(IsAC))
197 {
199 NumVerts = 2;
201 // b0 a1 a2 a3
202 if constexpr (CalculatExtraInformation)
203 {
205 }
206 Simplex[1] = Simplex[2];
207 if constexpr (CalculatExtraInformation)
208 {
209 As[1] = As[2];
210 Bs[1] = Bs[2];
211 }
212 return VectorMultiplyAdd(w, AC, A);
213 }
214
215 // Edge BC
216 const T d3d6 = VectorMultiply(d3, d6);
217 const T va = VectorNegateMultiplyAdd(d5, d4, d3d6);
218 const T d4MinusD3 = VectorSubtract(d4, d3);
219 const T d5MinusD6 = VectorSubtract(d5, d6);
221
227
228 if (VectorMaskBits(IsBC))
229 {
230 NumVerts = 2;
232 if constexpr (CalculatExtraInformation)
233 {
235 // b0 a1 a2 a3
237 }
238 const T CMinusB = VectorSubtract(C, B);
239 const T Result = VectorMultiplyAdd(w, CMinusB, B);
240 Simplex[0] = Simplex[1];
241 Simplex[1] = Simplex[2];
242 if constexpr (CalculatExtraInformation)
243 {
244 As[0] = As[1];
245 Bs[0] = Bs[1];
246 As[1] = As[2];
247 Bs[1] = Bs[2];
248 }
249 return Result;
250 }
251
252 // Inside triangle
254 T v = VectorMultiply(vb, denom);
255 T w = VectorMultiply(vc, denom);
256 NumVerts = 3;
257
258 if constexpr (CalculatExtraInformation)
259 {
261 // b0 a1 a2 a3
263 // a0 b0 a1 b1
265 }
266
267 // We know that we are inside the triangle so we can use the projected point we calculated above.
268 // The closest point can also be derived from the barycentric coordinates, but it will contain
269 // numerical error from the determinant calculation and can cause GJK to terminate with a poor solution.
270 // (E.g., this caused jittering when walking on box with dimensions of 100000cm or more).
271 // This fix the unit test TestSmallCapsuleLargeBoxGJKRaycast_Vertical
272 // Previously was return VectorMultiplyAdd(AC, w, VectorMultiplyAdd(AB, v, A));
274 const T SignedDistance = VectorDot3(T(A), TriNormalOverSize2);
275 return VectorMultiply(TriNormal, SignedDistance);
276 }
277
278 template<typename T>
280 {
283
284 const bool IsZero = static_cast<bool>(VectorMaskBits(OneIsZero));
285 const int32 MaskA = VectorMaskBits(A);
286 const int32 MaskB = VectorMaskBits(B);
287 return (MaskA == MaskB) && !IsZero;
288 }
289
290 template <typename T, bool CalculatExtraInformation>
292 {
293 const T& X0 = Simplex[0];
294 const T& X1 = Simplex[1];
295 const T& X2 = Simplex[2];
296 const T& X3 = Simplex[3];
297
298 //Use signed volumes to determine if origin is inside or outside
299 /*
300 M = [X0x X1x X2x X3x;
301 X0y X1y X2y X3y;
302 X0z X1z X2z X3z;
303 1 1 1 1]
304 */
305
306 T Cofactors[4];
312
313 bool bSignMatch[4];
314 // constexpr int32 SubIdxs[4][3] = { {1,2,3}, {0,2,3}, {0,1,3}, {0,1,2} };
315 int32 SubNumVerts[4] = { 3, 3, 3, 3};
316 T SubSimplices[4][3] = { {Simplex[1], Simplex[2], Simplex[3]}, {Simplex[0], Simplex[2], Simplex[3]}, {Simplex[0], Simplex[1], Simplex[3]}, {Simplex[0], Simplex[1], Simplex[2]} };
317 T SubAs[4][3];
318 T SubBs[4][3];
319 if constexpr (CalculatExtraInformation)
320 {
321 //SubAs = { {A[1], A[2], A[3]}, {A[0], A[2], A[3]}, {A[0], A[1], A[3]}, {A[0], A[1], A[2]} };
322 //SubBs = { {B[1], B[2], B[3]}, {B[0], B[2], B[3]}, {B[0], B[1], B[3]}, {B[0], B[1], B[2]} };
323 SubAs[0][0] = A[1]; SubAs[0][1] = A[2]; SubAs[0][2] = A[3];
324 SubAs[1][0] = A[0]; SubAs[1][1] = A[2]; SubAs[1][2] = A[3];
325 SubAs[2][0] = A[0]; SubAs[2][1] = A[1]; SubAs[2][2] = A[3];
326 SubAs[3][0] = A[0]; SubAs[3][1] = A[1]; SubAs[3][2] = A[2];
327
328 SubBs[0][0] = B[1]; SubBs[0][1] = B[2]; SubBs[0][2] = B[3];
329 SubBs[1][0] = B[0]; SubBs[1][1] = B[2]; SubBs[1][2] = B[3];
330 SubBs[2][0] = B[0]; SubBs[2][1] = B[1]; SubBs[2][2] = B[3];
331 SubBs[3][0] = B[0]; SubBs[3][1] = B[1]; SubBs[3][2] = B[2];
332 }
333 T ClosestPointSub[4];
334 T SubBarycentric[4];
337
338
339 constexpr int32 IdxSimd[4] = { 0, 1, 2, 3 };
340
342
343 bool bInside = true;
344 for (int Idx = 0; Idx < 4; ++Idx)
345 {
347 if (!bSignMatch[Idx])
348 {
349 bInside = false;
351
352 const T Dist2 = VectorDot3(ClosestPointSub[Idx], ClosestPointSub[Idx]);
353
355
356 const bool bFindClosest = static_cast<bool>(VectorMaskBits(MinGTDist)) || (ClosestTriangleIdx == INDEX_NONE);
357
360 }
361 }
362
363 if (bInside)
364 {
365 if constexpr (CalculatExtraInformation)
366 {
373 // a0 b0 a1 b1
376 // a0 a1 b0 b1
378 }
379
380 return TVectorZero<T>();
381 }
382
384 if constexpr (CalculatExtraInformation)
385 {
387 }
388
389 for (int i = 0; i < 3; i++)
390 {
392 if constexpr (CalculatExtraInformation)
393 {
394 A[i] = SubAs[ClosestTriangleIdx][i];
395 B[i] = SubBs[ClosestTriangleIdx][i];
396 }
397 }
398
400 }
401
402
403 // CalculatExtraHitInformation : Should we calculate the BaryCentric coordinates, As and Bs?
404 template <typename T, bool CalculatExtraInformation = true>
406 {
407 switch (NumVerts)
408 {
409 case 1:
410 if constexpr (CalculatExtraInformation)
411 {
413 }
414 return Simplex[0];
415 case 2:
416 {
418 }
419 case 3:
420 {
422 }
423 case 4:
424 {
426 break;
427 }
428 default:
429 ensure(false);
430 return TVectorZero<T>();
431 }
432 }
433}
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define ensure( InExpression)
Definition AssertionMacros.h:464
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define RESTRICT
Definition Platform.h:706
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FORCEINLINE VectorRegister4Float VectorSubtract(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:731
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 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 VectorMax(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1713
FORCEINLINE VectorRegister4Float VectorBitwiseAnd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1165
FORCEINLINE VectorRegister4Float VectorCombineLow(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1757
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
#define VectorSet1(F)
Definition UnrealMathFPU.h:2651
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 VectorNegateMultiplyAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2, const VectorRegister4Float &Vec3)
Definition UnrealMathFPU.h:815
FORCEINLINE VectorRegister4Float VectorAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:704
FORCEINLINE VectorRegister4Float VectorBitwiseOr(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1140
FORCEINLINE VectorRegister4Float VectorCompareEQ(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:923
FORCEINLINE VectorRegister4Float VectorOne(void)
Definition UnrealMathVectorCommon.h.inl:21
FORCEINLINE VectorRegister4Float VectorUnpackLo(const VectorRegister4Float &A, const VectorRegister4Float &B)
Definition VectorUtility.h:112
FORCEINLINE VectorRegister4Float VectorCrossNoFMA(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition VectorUtility.h:231
Definition SkeletalMeshComponent.h:307
FORCEINLINE bool VectorSignMatch(T A, T B)
Definition SimplexVectorized.h:279
FORCEINLINE_DEBUGGABLE T VectorLineSimplexFindOrigin(T *RESTRICT Simplex, int32 &RESTRICT NumVerts, T &RESTRICT OutBarycentric, T *RESTRICT A, T *RESTRICT B)
Definition SimplexVectorized.h:12
FORCEINLINE_DEBUGGABLE T VectorTetrahedronSimplexFindOrigin(T *RESTRICT Simplex, int32 &RESTRICT NumVerts, T &RESTRICT OutBarycentric, T *RESTRICT A, T *RESTRICT B)
Definition SimplexVectorized.h:291
FORCEINLINE_DEBUGGABLE T VectorSimplexFindClosestToOrigin(T *RESTRICT Simplex, int32 &RESTRICT NumVerts, T &RESTRICT OutBarycentric, T *RESTRICT A, T *RESTRICT B)
Definition SimplexVectorized.h:405
FORCEINLINE_DEBUGGABLE T TriangleSimplexFindOriginFast(T *RESTRICT Simplex, int32 &RESTRICT NumVerts, T &RESTRICT OutBarycentric, T *RESTRICT As, T *RESTRICT Bs)
Definition SimplexVectorized.h:67
constexpr VectorRegister4Float KindaSmallNumber
Definition UnrealMathVectorConstants.h.inl:52
float v
Definition radaudio_mdct.cpp:62