29#ifndef GU_GJKSIMPLEX_H
30#define GU_GJKSIMPLEX_H
32#include "foundation/PxVecMath.h"
33#include "GuBarycentricCoordinates.h"
35#if (defined __GNUC__ && defined _DEBUG)
36#define PX_GJK_INLINE PX_INLINE
37#define PX_GJK_FORCE_INLINE PX_INLINE
39#define PX_GJK_INLINE PX_INLINE
40#define PX_GJK_FORCE_INLINE PX_FORCE_INLINE
53 PX_NOALIAS PX_FORCE_INLINE aos::BoolV PointOutsideOfPlane4(
const aos::Vec3VArg _a,
const aos::Vec3VArg _b,
const aos::Vec3VArg _c,
const aos::Vec3VArg _d)
57 const Vec4V
zero = V4Load(0.f);
59 const Vec3V ab = V3Sub(_b, _a);
60 const Vec3V ac = V3Sub(_c, _a);
61 const Vec3V ad = V3Sub(_d, _a);
62 const Vec3V bd = V3Sub(_d, _b);
63 const Vec3V bc = V3Sub(_c, _b);
65 const Vec3V v0 = V3Cross(ab, ac);
66 const Vec3V v1 = V3Cross(ac, ad);
67 const Vec3V v2 = V3Cross(ad, ab);
68 const Vec3V v3 = V3Cross(bd, bc);
70 const FloatV signa0 = V3Dot(v0, _a);
71 const FloatV signa1 = V3Dot(v1, _a);
72 const FloatV signa2 = V3Dot(v2, _a);
73 const FloatV signd3 = V3Dot(v3, _a);
75 const FloatV signd0 = V3Dot(v0, _d);
76 const FloatV signd1 = V3Dot(v1, _b);
77 const FloatV signd2 = V3Dot(v2, _c);
78 const FloatV signa3 = V3Dot(v3, _b);
80 const Vec4V signa = V4Merge(signa0, signa1, signa2, signa3);
81 const Vec4V signd = V4Merge(signd0, signd1, signd2, signd3);
82 return V4IsGrtrOrEq(V4Mul(signa, signd), zero);
92 const FloatV
zero = FZero();
93 const FloatV one = FOne();
96 const Vec3V ab = V3Sub(b, a);
97 const FloatV denom = V3Dot(ab, ab);
98 const Vec3V ap = V3Neg(a);
99 const FloatV nom = V3Dot(ap, ab);
100 const BoolV con = FIsGrtrOrEq(FEps(), denom);
111 const FloatV tValue = FClamp(FDiv(nom, denom), zero, one);
112 return V3ScaleAdd(ab, tValue, a);
130 barycentricCoordinates(closest, Q[0], Q[1], v);
131 const Vec3V av = V3Sub(A[1], A[0]);
132 const Vec3V bv = V3Sub(B[1], B[0]);
133 closestA = V3ScaleAdd(av, v, A[0]);
134 closestB = V3ScaleAdd(bv, v, B[0]);
142 barycentricCoordinates(closest, Q[0], Q[1], Q[2], v, w);
144 const Vec3V av0 = V3Sub(A[1], A[0]);
145 const Vec3V av1 = V3Sub(A[2], A[0]);
146 const Vec3V bv0 = V3Sub(B[1], B[0]);
147 const Vec3V bv1 = V3Sub(B[2], B[0]);
149 closestA = V3Add(A[0], V3Add(V3Scale(av0, v), V3Scale(av1, w)));
150 closestB = V3Add(B[0], V3Add(V3Scale(bv0, v), V3Scale(bv1, w)));
155 PX_NOALIAS PX_GJK_FORCE_INLINE aos::FloatV closestPtPointTriangleBaryCentric(
const aos::Vec3VArg a,
const aos::Vec3VArg b,
const aos::Vec3VArg c,
156 PxU32*
PX_RESTRICT indices, PxU32& size, aos::Vec3V& closestPt)
161 const FloatV
zero = FZero();
162 const FloatV eps = FEps();
164 const Vec3V ab = V3Sub(b, a);
165 const Vec3V ac = V3Sub(c, a);
167 const Vec3V n = V3Cross(ab, ac);
170 const FloatV nn = V3Dot(n, n);
171 if (FAllEq(nn, zero))
182 const VecCrossV crossA = V3PrepareCross(a);
183 const VecCrossV crossB = V3PrepareCross(b);
184 const VecCrossV crossC = V3PrepareCross(c);
185 const Vec3V bCrossC = V3Cross(crossB, crossC);
186 const Vec3V cCrossA = V3Cross(crossC, crossA);
187 const Vec3V aCrossB = V3Cross(crossA, crossB);
189 const FloatV va = V3Dot(n, bCrossC);
190 const FloatV vb = V3Dot(n, cCrossA);
191 const FloatV vc = V3Dot(n, aCrossB);
193 const BoolV isFacePoints = BAnd(FIsGrtrOrEq(va, zero), BAnd(FIsGrtrOrEq(vb, zero), FIsGrtrOrEq(vc, zero)));
196 if(BAllEqTTTT(isFacePoints))
198 const FloatV t = FDiv(V3Dot(n, a), nn);
199 const Vec3V q = V3Scale(n, t);
204 const Vec3V ap = V3Neg(a);
205 const Vec3V bp = V3Neg(b);
206 const Vec3V cp = V3Neg(c);
208 const FloatV d1 = V3Dot(ab, ap);
209 const FloatV d2 = V3Dot(ac, ap);
210 const FloatV d3 = V3Dot(ab, bp);
211 const FloatV d4 = V3Dot(ac, bp);
212 const FloatV d5 = V3Dot(ab, cp);
213 const FloatV d6 = V3Dot(ac, cp);
215 const FloatV unom = FSub(d4, d3);
216 const FloatV udenom = FSub(d5, d6);
220 const BoolV con30 = FIsGrtrOrEq(zero, vc);
221 const BoolV con31 = FIsGrtrOrEq(d1, zero);
222 const BoolV con32 = FIsGrtrOrEq(zero, d3);
223 const BoolV con3 = BAnd(con30, BAnd(con31, con32));
226 const FloatV toRecipAB = FSub(d1, d3);
227 const FloatV recipAB = FSel(FIsGrtr(FAbs(toRecipAB), eps), FRecip(toRecipAB), zero);
228 const FloatV t = FMul(d1, recipAB);
229 const Vec3V q = V3ScaleAdd(ab, t, a);
235 const BoolV con40 = FIsGrtrOrEq(zero, va);
236 const BoolV con41 = FIsGrtrOrEq(d4, d3);
237 const BoolV con42 = FIsGrtrOrEq(d5, d6);
238 const BoolV con4 = BAnd(con40, BAnd(con41, con42));
241 const Vec3V bc = V3Sub(c, b);
242 const FloatV toRecipBC = FAdd(unom, udenom);
243 const FloatV recipBC = FSel(FIsGrtr(FAbs(toRecipBC), eps), FRecip(toRecipBC), zero);
244 const FloatV t = FMul(unom, recipBC);
245 indices[0] = indices[1];
246 indices[1] = indices[2];
247 const Vec3V q = V3ScaleAdd(bc, t, b);
253 const BoolV con50 = FIsGrtrOrEq(zero, vb);
254 const BoolV con51 = FIsGrtrOrEq(d2, zero);
255 const BoolV con52 = FIsGrtrOrEq(zero, d6);
257 const BoolV con5 = BAnd(con50, BAnd(con51, con52));
260 const FloatV toRecipAC = FSub(d2, d6);
261 const FloatV recipAC = FSel(FIsGrtr(FAbs(toRecipAC), eps), FRecip(toRecipAC), zero);
262 const FloatV t = FMul(d2, recipAC);
263 indices[1]=indices[2];
264 const Vec3V q = V3ScaleAdd(ac, t, a);
271 const BoolV con00 = FIsGrtrOrEq(zero, d1);
272 const BoolV con01 = FIsGrtrOrEq(zero, d2);
273 const BoolV con0 = BAnd(con00, con01);
281 const BoolV con10 = FIsGrtrOrEq(d3, zero);
282 const BoolV con11 = FIsGrtrOrEq(d3, d4);
283 const BoolV con1 = BAnd(con10, con11);
286 indices[0] = indices[1];
292 indices[0] = indices[2];
297 PX_NOALIAS PX_GJK_FORCE_INLINE aos::Vec3V closestPtPointTriangle(aos::Vec3V*
PX_RESTRICT Q, aos::Vec3V* A, aos::Vec3V* B, PxU32& size)
303 const FloatV eps = FEps();
304 const Vec3V a = Q[0];
305 const Vec3V b = Q[1];
306 const Vec3V c = Q[2];
307 const Vec3V ab = V3Sub(b, a);
308 const Vec3V ac = V3Sub(c, a);
309 const Vec3V signArea = V3Cross(ab, ac);
310 const FloatV area = V3Dot(signArea, signArea);
311 if(FAllGrtrOrEq(eps, area))
315 return closestPtPointSegment(Q, size);
319 PxU32 indices[3]={0, 1, 2};
321 closestPtPointTriangleBaryCentric(a, b, c, indices, _size, closestPt);
325 const Vec3V q0 = Q[indices[0]];
const Vec3V q1 = Q[indices[1]];
326 const Vec3V a0 = A[indices[0]];
const Vec3V a1 = A[indices[1]];
327 const Vec3V b0 = B[indices[0]];
const Vec3V b1 = B[indices[1]];
329 Q[0] = q0; Q[1] = q1;
330 A[0] = a0; A[1] = a1;
331 B[0] = b0; B[1] = b1;
346 const FloatV eps = FEps();
348 const Vec3V a = Q[0];
349 const Vec3V b = Q[1];
350 const Vec3V c = Q[2];
351 const Vec3V ab = V3Sub(b, a);
352 const Vec3V ac = V3Sub(c, a);
353 const Vec3V signArea = V3Cross(ab, ac);
354 const FloatV area = V3Dot(signArea, signArea);
355 if(FAllGrtrOrEq(eps, area))
359 return closestPtPointSegment(Q, size);
363 PxU32 indices[3]={0, 1, 2};
365 closestPtPointTriangleBaryCentric(a, b, c, indices, _size, closestPt);
369 const Vec3V q0 = Q[indices[0]];
const Vec3V q1 = Q[indices[1]];
370 const Vec3V a0 = A[indices[0]];
const Vec3V a1 = A[indices[1]];
371 const Vec3V b0 = B[indices[0]];
const Vec3V b1 = B[indices[1]];
372 const PxI32 aInd0 = aInd[indices[0]];
const PxI32 aInd1 = aInd[indices[1]];
373 const PxI32 bInd0 = bInd[indices[0]];
const PxI32 bInd1 = bInd[indices[1]];
375 Q[0] = q0; Q[1] = q1;
376 A[0] = a0; A[1] = a1;
377 B[0] = b0; B[1] = b1;
378 aInd[0] = aInd0; aInd[1] = aInd1;
379 bInd[0] = bInd0; bInd[1] = bInd1;
402 return closestPtPointSegment(Q, size);
406 return closestPtPointTriangle(Q, A, B, size);
409 return closestPtPointTetrahedron(Q, A, B, size);
417 const aos::Vec3VArg support, PxU32& size)
431 return closestPtPointSegment(Q, size);
435 return closestPtPointTriangle(Q, A, B, aInd, bInd, size);
438 return closestPtPointTetrahedron(Q, A, B, aInd, bInd, size);
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_NOALIAS
Definition PxPreprocessor.h:364
GLM_FUNC_DECL GLM_CONSTEXPR genType zero()
Definition constants.inl:6
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39