29#ifndef GU_GJK_PENETRATION_H
30#define GU_GJK_PENETRATION_H
33#include "GuConvexSupportTable.h"
34#include "GuGJKSimplex.h"
35#include "GuVecConvexHullNoScale.h"
37#include "foundation/PxUtilities.h"
57 for(PxU32 i=0; i<size; ++i)
59 aIndices[i] = PxTo8(aInd[i]);
60 bIndices[i] = PxTo8(bInd[i]);
66 PX_FORCE_INLINE void validateDuplicateVertex(
const aos::Vec3V* Q,
const aos::Vec3VArg support,
const PxU32 size)
70 const FloatV eps = FEps();
72 BoolV match = BFFFF();
73 for(PxU32 na = 0; na < size; ++na)
75 Vec3V dif = V3Sub(Q[na], support);
76 match = BOr(match, FIsGrtr(eps, V3Dot(dif, dif)));
97 template<
typename ConvexA,
typename ConvexB >
98 PX_NOINLINE GjkStatus gjkPenetration(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3VArg initialSearchDir,
const aos::FloatVArg contactDist,
const bool takeCoreShape,
105 const FloatV minMargin = FMin(a.ConvexA::getMinMargin(), b.ConvexB::getMinMargin());
106 const FloatV eps = FMul(minMargin, FLoad(0.1f));
118 const FloatV epsRel = FLoad(0.000225f);
119 const FloatV relDif = FSub(FOne(), epsRel);
121 const FloatV
zero = FZero();
124 const FloatV marginA = a.getMargin();
125 const FloatV marginB = b.getMargin();
127 const BoolV aQuadratic = a.isMarginEqRadius();
128 const BoolV bQuadratic = b.isMarginEqRadius();
129 const FloatV tMarginA = FSel(aQuadratic, marginA, zero);
130 const FloatV tMarginB = FSel(bQuadratic, marginB, zero);
132 const FloatV sumMargin = FAdd(tMarginA, tMarginB);
133 const FloatV sumExpandedMargin = FAdd(sumMargin, contactDist);
135 FloatV dist = FMax();
136 FloatV prevDist = dist;
137 const Vec3V zeroV = V3Zero();
138 Vec3V prevClos = zeroV;
140 const BoolV bTrue = BTTTT();
141 BoolV bNotTerminated = bTrue;
142 BoolV bNotDegenerated = bTrue;
150 Vec3V supportA = zeroV, supportB = zeroV, support=zeroV;
158 if(warmStartSize != 0)
160 for(PxU32 i=0; i<warmStartSize; ++i)
162 aInd[i] = aIndices[i];
163 bInd[i] = bIndices[i];
166 supportA = a.ConvexA::supportPoint(aIndices[i]);
167 supportB = b.ConvexB::supportPoint(bIndices[i]);
169 support = V3Sub(supportA, supportB);
174 validateDuplicateVertex(Q, support, size);
182 closest = GJKCPairDoSimplex(Q, A, B, aInd, bInd, support, size);
183 dist = V3Length(closest);
185 v = V3ScaleInv(closest, dist);
189 bNotTerminated = FIsGrtr(dist, eps);
194 closest = V3Sel(FIsGrtr(V3Dot(initialSearchDir, initialSearchDir), zero), initialSearchDir, V3UnitX());
195 v = V3Normalize(closest);
204 while(BAllEqTTTT(bNotTerminated))
212 supportA = a.ConvexA::support(V3Neg(closest), aInd[size]);
213 supportB = b.ConvexB::support(closest, bInd[size]);
216 support = V3Sub(supportA, supportB);
218 const FloatV vw = V3Dot(v, support);
219 if(FAllGrtr(vw, sumExpandedMargin))
221 assignWarmStartValue(aIndices, bIndices, warmStartSize, aInd, bInd, size);
222 return GJK_NON_INTERSECT;
226 if(FAllGrtr(vw, FMul(dist, relDif)))
228 assignWarmStartValue(aIndices, bIndices, warmStartSize, aInd, bInd, size);
229 PX_ASSERT(FAllGrtr(dist, FEps()));
233 getClosestPoint(Q, A, B, closest, closA, closB, size);
239 output.closestA= closA;
240 output.closestB = closB;
241 output.penDep = dist;
248 output.closestA = V3NegScaleSub(v, tMarginA, closA);
249 output.closestB = V3ScaleAdd(v, tMarginB, closB);
250 output.penDep = FSub(dist, sumMargin);
259 PX_ASSERT(size <= 4);
262 closest = GJKCPairDoSimplex(Q, A, B, aInd, bInd, support, size);
264 dist = V3Length(closest);
265 v = V3ScaleInv(closest, dist);
267 bNotDegenerated = FIsGrtr(prevDist, dist);
268 bNotTerminated = BAnd(FIsGrtr(dist, eps), bNotDegenerated);
271 if(BAllEqFFFF(bNotDegenerated))
273 assignWarmStartValue(aIndices, bIndices, warmStartSize, aInd, bInd, size-1);
279 getClosestPoint(Q, A, B, closest, closA, closB, size);
282 const Vec3V n = V3ScaleInv(prevClos, prevDist);
285 output.searchDir = v;
289 output.closestA = closA;
290 output.closestB = closB;
291 output.penDep = dist;
297 output.closestA = V3NegScaleSub(n, tMarginA, closA);
298 output.closestB = V3ScaleAdd(n, tMarginB, closB);
299 output.penDep = FSub(dist, sumMargin);
300 if (FAllGrtrOrEq(sumMargin, dist))
304 return GJK_DEGENERATE;
309 assignWarmStartValue(aIndices, bIndices, warmStartSize, aInd, bInd, size);
314 template<
typename ConvexA,
typename ConvexB >
315 PX_NOINLINE GjkStatus gjkPenetration(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3VArg initialSearchDir,
const aos::FloatVArg contactDist,
const bool takeCoreShape,
319 aos::Vec3V aPoints[4], bPoints[4];
320 return gjkPenetration(a, b, initialSearchDir, contactDist, takeCoreShape, aIndices, bIndices, aPoints, bPoints, warmStartSize, output);
322 template<
typename ConvexA,
typename ConvexB >
323 PX_NOINLINE GjkStatus gjkPenetration(
const ConvexA& a,
const ConvexB& b,
const aos::Vec3VArg initialSearchDir,
const aos::FloatVArg contactDist,
const bool takeCoreShape,
327 PxU8 aIndices[4], bIndices[4];
328 return gjkPenetration(a, b, initialSearchDir, contactDist, takeCoreShape, aIndices, bIndices, aPoints, bPoints, warmStartSize, output);
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_NOINLINE
Definition PxPreprocessor.h:346
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
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