29#ifndef GU_GJKRAYCAST_H
30#define GU_GJKRAYCAST_H
33#include "GuGJKSimplex.h"
34#include "GuConvexSupportTable.h"
35#include "GuGJKPenetration.h"
54 template<
class ConvexA,
class ConvexB>
55 bool gjkRaycast(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3VArg initialDir,
const aos::FloatVArg initialLambda,
const aos::Vec3VArg s,
const aos::Vec3VArg r, aos::FloatV& lambda, aos::Vec3V& normal, aos::Vec3V& closestA,
const PxReal _inflation)
57 PX_UNUSED(initialLambda);
61 const FloatV inflation = FLoad(_inflation);
62 const Vec3V zeroV = V3Zero();
63 const FloatV
zero = FZero();
64 const FloatV one = FOne();
65 const BoolV bTrue = BTTTT();
67 const FloatV maxDist = FLoad(PX_MAX_REAL);
69 FloatV _lambda =
zero;
70 Vec3V x = V3ScaleAdd(r, _lambda, s);
74 const Vec3V _initialSearchDir = V3Sel(FIsGrtr(V3Dot(initialDir, initialDir), FEps()), initialDir, V3UnitX());
75 const Vec3V initialSearchDir = V3Normalize(_initialSearchDir);
77 const Vec3V initialSupportA(a.ConvexA::support(V3Neg(initialSearchDir)));
78 const Vec3V initialSupportB( b.ConvexB::support(initialSearchDir));
80 Vec3V Q[4] = {V3Sub(initialSupportA, initialSupportB), zeroV, zeroV, zeroV};
81 Vec3V A[4] = {initialSupportA, zeroV, zeroV, zeroV};
82 Vec3V B[4] = {initialSupportB, zeroV, zeroV, zeroV};
84 Vec3V v = V3Neg(Q[0]);
85 Vec3V supportA = initialSupportA;
86 Vec3V supportB = initialSupportB;
89 const FloatV minMargin = FMin(a.ConvexA::getSweepMargin(), b.ConvexB::getSweepMargin());
90 const FloatV eps1 = FMul(minMargin, FLoad(0.1f));
91 const FloatV inflationPlusEps(FAdd(eps1, inflation));
92 const FloatV eps2 = FMul(eps1, eps1);
94 const FloatV inflation2 = FMul(inflationPlusEps, inflationPlusEps);
99 FloatV sDist = V3Dot(v, v);
100 FloatV minDist = sDist;
104 BoolV bNotTerminated = FIsGrtr(sDist, eps2);
105 BoolV bNotDegenerated = bTrue;
109 while(BAllEqTTTT(bNotTerminated))
114 const Vec3V vNorm = V3Normalize(v);
115 const Vec3V nvNorm = V3Neg(vNorm);
117 supportA=a.ConvexA::support(vNorm);
118 supportB=V3Add(x, b.ConvexB::support(nvNorm));
121 support = V3Sub(supportA, supportB);
122 const Vec3V w = V3Neg(support);
123 const FloatV vw = FSub(V3Dot(vNorm, w), inflationPlusEps);
124 if(FAllGrtr(vw, zero))
126 const FloatV vr = V3Dot(vNorm, r);
127 if(FAllGrtrOrEq(vr, zero))
133 const FloatV _oldLambda = _lambda;
134 _lambda = FSub(_lambda, FDiv(vw, vr));
135 if(FAllGrtr(_lambda, _oldLambda))
137 if(FAllGrtr(_lambda, one))
141 const Vec3V bPreCenter = x;
142 x = V3ScaleAdd(r, _lambda, s);
144 const Vec3V offSet =V3Sub(x, bPreCenter);
145 const Vec3V b0 = V3Add(B[0], offSet);
146 const Vec3V b1 = V3Add(B[1], offSet);
147 const Vec3V b2 = V3Add(B[2], offSet);
153 Q[0]=V3Sub(A[0], b0);
154 Q[1]=V3Sub(A[1], b1);
155 Q[2]=V3Sub(A[2], b2);
157 supportB = V3Add(x, b.ConvexB::support(nvNorm));
158 support = V3Sub(supportA, supportB);
172 clos = GJKCPairDoSimplex(Q, A, B, support, size);
174 sDist = V3Dot(clos, clos);
176 bNotDegenerated = FIsGrtr(minDist, sDist);
177 bNotTerminated = BAnd(FIsGrtr(sDist, inflation2), bNotDegenerated);
180 const BoolV aQuadratic = a.isMarginEqRadius();
184 nor = V3Sel(BAnd(FIsGrtr(sDist, eps2), bNotDegenerated), v, nor);
185 nor = V3Neg(V3NormalizeSafe(nor, V3Zero()));
189 const Vec3V closestP = V3Sel(bNotDegenerated, clos, preClos);
190 Vec3V closA = zeroV, closB = zeroV;
191 getClosestPoint(Q, A, B, closestP, closA, closB, size);
192 closestA = V3Sel(aQuadratic, V3NegScaleSub(nor, a.getMargin(), closA), closA);
210 template<
class ConvexA,
class ConvexB>
211 bool gjkRaycastPenetration(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3VArg initialDir,
const aos::FloatVArg initialLambda,
const aos::Vec3VArg s,
const aos::Vec3VArg r, aos::FloatV& lambda,
212 aos::Vec3V& normal, aos::Vec3V& closestA,
const PxReal _inflation,
const bool initialOverlap)
218 if(gjkRaycast(a, b, initialDir, initialLambda, s, r, _lambda, norm, closA, _inflation))
220 const FloatV
zero = FZero();
222 if(FAllEq(_lambda, zero) && initialOverlap)
225 const FloatV contactDist = getSweepContactEps(a.getMargin(), b.getMargin());
235#ifdef USE_VIRTUAL_GJK
236 GjkStatus status = gjkPenetration<ConvexA, ConvexB>(a, b,
238 typename ConvexA::ConvexGeomType convexA = a.getGjkConvex();
239 typename ConvexB::ConvexGeomType convexB = b.getGjkConvex();
241 GjkStatus status = gjkPenetration<typename ConvexA::ConvexGeomType, typename ConvexB::ConvexGeomType>(convexA, convexB,
243 initialDir, contactDist,
false, aIndices, bIndices, size, output);
245 if(status == GJK_CONTACT)
247 closA = output.closestA;
248 sDist = output.penDep;
249 norm = output.normal;
251 else if(status == EPA_CONTACT)
253 status = epaPenetration(a, b, aIndices, bIndices, size,
false, FLoad(1.f), output);
255 if (status == EPA_CONTACT || status == EPA_DEGENERATE)
257 closA = output.closestA;
258 sDist = output.penDep;
259 norm = output.normal;
266 norm = V3Normalize(V3Neg(r));
273 closA = output.closestA;
274 sDist = output.penDep;
275 norm = output.normal;
277 lambda = FMin(zero, sDist);
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