35#include "GuConvexSupportTable.h"
36#include "GuGJKSimplex.h"
37#include "foundation/PxFPU.h"
39#define GJK_SEPERATING_AXIS_VALIDATE 0
48#if GJK_SEPERATING_AXIS_VALIDATE
49 template<
typename ConvexA,
typename ConvexB>
50 static void validateSeparatingAxis(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3VArg separatingAxis)
53 const Vec3V minV0 = a.ConvexA::support(V3Neg(separatingAxis));
54 const Vec3V maxV0 = a.ConvexA::support(separatingAxis);
56 const Vec3V minV1 = b.ConvexB::support(V3Neg(separatingAxis));
57 const Vec3V maxV1 = b.ConvexB::support(separatingAxis);
59 const FloatV min0 = V3Dot(minV0, separatingAxis);
60 const FloatV max0 = V3Dot(maxV0, separatingAxis);
62 const FloatV min1 = V3Dot(minV1, separatingAxis);
63 const FloatV max1 = V3Dot(maxV1, separatingAxis);
65 PX_ASSERT(FAllGrtr(min1, max0) || FAllGrtr(min0, max1));
89 template<
typename ConvexA,
typename ConvexB>
90 GjkStatus gjk(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3V& initialSearchDir,
const aos::FloatV& contactDist, aos::Vec3V& closestA, aos::Vec3V& closestB, aos::Vec3V& normal,
91 aos::FloatV& distance)
98 const FloatV
zero = FZero();
102 Vec3V closest = V3Sel(FIsGrtr(V3Dot(initialSearchDir, initialSearchDir), zero), initialSearchDir, V3UnitX());
103 Vec3V v = V3Normalize(closest);
108 const FloatV tenPerc = FLoad(0.1f);
109 const FloatV minMargin = FMin(a.getMinMargin(), b.getMinMargin());
110 const FloatV eps = FMax(FLoad(1e-6f), FMul(minMargin, tenPerc));
117 const FloatV epsRel = FLoad(0.000225f);
119 FloatV dist = FMax();
121 Vec3V prevClos, prevDir;
123 const BoolV bTrue = BTTTT();
124 BoolV bNotTerminated = bTrue;
125 BoolV bNotDegenerated = bTrue;
128 const BoolV aQuadratic = a.isMarginEqRadius();
129 const BoolV bQuadratic = b.isMarginEqRadius();
131 const FloatV sumMargin = FAdd(FSel(aQuadratic, a.getMargin(), zero), FSel(bQuadratic, b.getMargin(), zero));
132 const FloatV separatingDist = FAdd(sumMargin, contactDist);
133 const FloatV relDif = FSub(FOne(), epsRel);
144 const Vec3V supportA=a.ConvexA::support(V3Neg(closest));
145 const Vec3V supportB=b.ConvexB::support(closest);
148 const Vec3V support = V3Sub(supportA, supportB);
150 const FloatV signDist = V3Dot(v, support);
152 if(FAllGrtr(signDist, separatingDist))
156#if GJK_SEPERATING_AXIS_VALIDATE
157 validateSeparatingAxis(a, b, v);
159 return GJK_NON_INTERSECT;
162 const BoolV con = BAnd(FIsGrtr(signDist, sumMargin), FIsGrtr(signDist, FMul(relDif, dist)));
169 const Vec3V n = V3Neg(v);
170 getClosestPoint(Q, A, B, closest, closA, closB, size);
171 closestA = V3Sel(aQuadratic, V3ScaleAdd(n, a.getMargin(), closA), closA);
172 closestB = V3Sel(bQuadratic, V3NegScaleSub(n, b.getMargin(), closB), closB);
173 distance = FMax(zero, FSub(dist, sumMargin));
184 closest = GJKCPairDoSimplex(Q, A, B, support, size);
186 dist = V3Length(closest);
187 v = V3ScaleInv(closest, dist);
188 bNotDegenerated = FIsGrtr(prevDist, dist);
189 bNotTerminated = BAnd(FIsGrtr(dist, eps), bNotDegenerated);
190 }
while(BAllEqTTTT(bNotTerminated));
192 if(BAllEqTTTT(bNotDegenerated))
200 const FloatV acceptancePerc = FLoad(0.2f);
201 const FloatV acceptanceMargin = FMul(acceptancePerc, FMin(a.getMargin(), b.getMargin()));
202 const FloatV acceptanceDist = FSel(FIsGrtr(sumMargin, zero), sumMargin, acceptanceMargin);
204 const Vec3V n = V3Neg(prevDir);
205 getClosestPoint(Q, A, B, prevClos, closA, closB, size);
206 closestA = V3Sel(aQuadratic, V3ScaleAdd(n, a.getMargin(), closA), closA);
207 closestB = V3Sel(bQuadratic, V3NegScaleSub(n, b.getMargin(), closB), closB);
209 dist = FMax(zero, FSub(prevDist, sumMargin));
212 return FAllGrtr(dist, acceptanceDist) ? GJK_CLOSE: GJK_CONTACT;
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