154 using namespace physx::aos;
155 mRelativeTransform.Invalidate();
156 mQuatA = QuatIdentity();
157 mQuatB = QuatIdentity();
166 PX_ASSERT(index < GU_MANIFOLD_CACHE_SIZE);
167 return mContactPoints[index];
173 const Vec4V p0 = Vec4V_From_Vec3V(mRelativeTransform.p);
174 const Vec4V q0 = mRelativeTransform.q;
175 const Vec4V p1 = Vec4V_From_Vec3V(curTransform.p);
176 const Vec4V q1 = curTransform.q;
178 const Vec4V dp = V4Abs(V4Sub(p1, p0));
179 const Vec4V dq = V4Abs(V4Sub(q1, q0));
181 const Vec4V max0 = V4Max(dp, dq);
184 return V4ExtractMax(max0);
190 const Vec4V p0 = Vec4V_From_Vec3V(mRelativeTransform.p);
191 const Vec4V q0 = mRelativeTransform.q;
192 const Vec4V p1 = Vec4V_From_Vec3V(curTransform.p);
193 const Vec4V q1 = curTransform.q;
195 const Vec4V dp = V4Abs(V4Sub(p1, p0));
196 const Vec4V dq = V4Abs(V4Sub(q1, q0));
198 const Vec4V max0 = V4Max(dp, dq);
208 const Vec3V deltaP = V3Sub(curP, mRelativeTransform.p);
209 const Vec4V delta = Vec4V_From_Vec3V(V3Abs(deltaP));
211 return V4ExtractMax(delta);
218 const Vec4V deltaQ = V4Sub(curQ, mRelativeTransform.q);
219 const Vec4V delta = V4Abs(deltaQ);
221 return V4ExtractMax(delta);
226 mRelativeTransform = transform;
231 mRelativeTransform = transform;
239 const aos::FloatVArg minMargin,
const aos::FloatVArg radiusA,
const aos::FloatVArg radiusB)
242 PX_ASSERT(mNumContacts <= GU_MANIFOLD_CACHE_SIZE);
243 const FloatV ratio = FLoad(invalidateThresholds[mNumContacts]);
244 const FloatV thresholdP = FMul(minMargin, ratio);
245 const FloatV deltaP = maxTransformPositionDelta(curRTrans.p);
247 const FloatV thresholdQ = FLoad(invalidateQuatThresholds[mNumContacts]);
248 const FloatV deltaQA = QuatDot(quatA, mQuatA);
249 const FloatV deltaQB = QuatDot(quatB, mQuatB);
251 const BoolV con0 = BOr(FIsGrtr(deltaP, thresholdP), BOr(FIsGrtr(thresholdQ, deltaQA), FIsGrtr(thresholdQ, deltaQB)));
252 PxU32 generateContacts = BAllEqTTTT(con0);
253 if (!generateContacts)
257 FStore(deltaQA, &dqA);
258 FStore(deltaQB, &dqB);
260 const PxReal aRadian = dqA < 1.0f ?
PxAcos(dqA) : 0.f;
261 const FloatV travelDistA = FMul(FLoad(aRadian), radiusA);
263 const PxReal bRadian = dqB < 1.0f ?
PxAcos(dqB) : 0.f;
264 const FloatV travelDistB = FMul(FLoad(bRadian), radiusB);
267 const BoolV con = BOr(FIsGrtr(travelDistA, thresholdP), FIsGrtr(travelDistB, thresholdP));
269 generateContacts = BAllEqTTTT(con);
272 return generateContacts;
280 PX_ASSERT(mNumContacts <= 2);
281 const FloatV ratio = FLoad(invalidateThresholds2[mNumContacts]);
283 const FloatV thresholdP = FMul(minMargin, ratio);
284 const FloatV deltaP = maxTransformPositionDelta(curRTrans.p);
286 const FloatV thresholdQ = FLoad(invalidateQuatThresholds2[mNumContacts]);
287 const FloatV deltaQ = QuatDot(curRTrans.q, mRelativeTransform.q);
288 const BoolV con = BOr(FIsGrtr(deltaP, thresholdP), FIsGrtr(thresholdQ, deltaQ));
290 return BAllEqTTTT(con);
298 const FloatV thresholdP = FMul(minMargin, ratio);
299 const FloatV deltaP = maxTransformPositionDelta(curRTrans.p);
301 const FloatV thresholdQ = FLoad(0.99996f);
302 const FloatV deltaQ = QuatDot(curRTrans.q, mRelativeTransform.q);
303 const BoolV con = BOr(FIsGrtr(deltaP, thresholdP), FIsGrtr(thresholdQ, deltaQ));
305 return BAllEqTTTT(con);
311 mContactPoints[index] = mContactPoints[mNumContacts];
314 bool validContactDistance(
const PersistentContact& pt,
const aos::FloatVArg breakingThreshold)
const
317 const FloatV dist = V4GetW(pt.mLocalNormalPen);
318 return FAllGrtr(breakingThreshold, dist) != 0;
323 mNumWarmStartPoints = 0;
325 mRelativeTransform.Invalidate();
334 bool replaceManifoldPoint(
const aos::Vec3VArg localPointA,
const aos::Vec3VArg localPointB,
const aos::Vec4VArg localNormalPen,
const aos::FloatVArg replaceBreakingThreshold);
337 PxU32 addManifoldPoint(
const aos::Vec3VArg localPointA,
const aos::Vec3VArg localPointB,
const aos::Vec4VArg localNormalAPen,
const aos::FloatVArg replaceBreakingThreshold);
339 PxU32 addManifoldPoint2(
const aos::Vec3VArg localPointA,
const aos::Vec3VArg localPointB,
const aos::Vec4VArg localNormalAPen,
const aos::FloatVArg replaceBreakingThreshold);
341 void addBatchManifoldContactsCluster(
const PersistentContact* manifoldPoints,
const PxU32 numPoints);
344 void addBatchManifoldContacts2(
const PersistentContact* manifoldPoints,
const PxU32 numPoints);
347 void addBatchManifoldContacts(
const PersistentContact* manifoldPoints,
const PxU32 numPoints,
const PxReal toleranceLength);
349 void reduceBatchContactsCluster(
const PersistentContact* manifoldPoints,
const PxU32 numPoints);
351 void reduceBatchContacts2(
const PersistentContact* manifoldPoints,
const PxU32 numPoints);
353 void reduceBatchContacts(
const PersistentContact* manifoldPoints,
const PxU32 numPoints,
const PxReal toleranceLength);
357 PxU32 reduceContactsForPCM(
const aos::Vec3VArg localPointA,
const aos::Vec3VArg localPointB,
const aos::Vec4VArg localNormalPen);
359 PxU32 reduceContactSegment(
const aos::Vec3VArg localPointA,
const aos::Vec3VArg localPointB,
const aos::Vec4VArg localNormalPen);
366 void refreshContactPoints(
const aos::PxMatTransformV& relTra,
const aos::FloatVArg projectBreakingThreshold,
const aos::FloatVArg contactOffset);
370 void addManifoldContactsToContactBuffer(
PxContactBuffer& contactBuffer,
const aos::Vec3VArg normal,
const aos::PxTransformV& transf1,
const aos::FloatVArg contactOffset);
372 void addManifoldContactsToContactBuffer(
PxContactBuffer& contactBuffer,
const aos::Vec3VArg normal,
const aos::Vec3VArg projectionNormal,
const aos::PxTransformV& transf0,
const aos::FloatVArg radius,
const aos::FloatVArg contactOffset);
379 void recordWarmStart(PxU8* aIndices, PxU8* bIndices, PxU8& nbWarmStartPoints);
380 void setWarmStart(
const PxU8* aIndices,
const PxU8* bIndices,
const PxU8 nbWarmStartPoints);
384 static void drawPoint(
PxRenderOutput& out,
const aos::Vec3VArg p,
const PxF32 size,
const PxU32 color = 0x0000ff00);
385 static void drawLine(
PxRenderOutput& out,
const aos::Vec3VArg p0,
const aos::Vec3VArg p1,
const PxU32 color = 0xff00ffff);
386 static void drawTriangle(
PxRenderOutput& out,
const aos::Vec3VArg p0,
const aos::Vec3VArg p1,
const aos::Vec3VArg p2,
const PxU32 color = 0xffff0000);
387 static void drawTetrahedron(
PxRenderOutput& out,
const aos::Vec3VArg p0,
const aos::Vec3VArg p1,
const aos::Vec3VArg p2,
const aos::Vec3VArg p3,
const PxU32 color = 0xffff0000);
396 PxU8 mNumWarmStartPoints;
400} PX_ALIGN_SUFFIX(16);
439 PX_ASSERT(index < GU_SINGLE_MANIFOLD_CACHE_SIZE);
440 return mContactPoints[index];
446 mContactPoints[index] = mContactPoints[mNumContacts];
463 Vec4V nPen = mContactPoints[0].mLocalNormalPen;
464 for(PxU32 i =1; i < mNumContacts; ++i)
466 nPen = V4Add(nPen, mContactPoints[i].mLocalNormalPen);
469 const Vec3V n = Vec3V_From_Vec4V(nPen);
470 return V3Normalize(trB.rotate(n));
476 Vec4V nPen = mContactPoints[0].mLocalNormalPen;
477 for(PxU32 i =1; i < mNumContacts; ++i)
479 nPen = V4Add(nPen, mContactPoints[i].mLocalNormalPen);
481 return V3Normalize(Vec3V_From_Vec4V(nPen));
502 aos::FloatV refreshContactPoints(
const aos::PxMatTransformV& relTra,
const aos::FloatVArg projectBreakingThreshold,
const aos::FloatVArg contactOffset);
509} PX_ALIGN_SUFFIX(16);
536 mRelativeTransform.Invalidate();
541 mRelativeTransform = transform;
548 const Vec3V deltaP = V3Sub(curP, mRelativeTransform.p);
549 const Vec4V delta = Vec4V_From_Vec3V(V3Abs(deltaP));
551 return V4ExtractMax(delta);
558 const Vec4V deltaQ = V4Sub(curQ, mRelativeTransform.q);
559 const Vec4V delta = V4Abs(deltaQ);
561 return V4ExtractMax(delta);
568 const FloatV thresholdP = FMul(minMargin, ratio);
569 const FloatV deltaP = maxTransformPositionDelta(curRTrans.p);
570 const FloatV thresholdQ = FLoad(0.9998f);
571 const FloatV deltaQ = QuatDot(curRTrans.q, mRelativeTransform.q);
572 const BoolV con = BOr(FIsGrtr(deltaP, thresholdP), FIsGrtr(thresholdQ, deltaQ));
574 return BAllEqTTTT(con);
580 return invalidate(curRTrans, minMargin, FLoad(0.2f));
588 PX_UNUSED(manifoldContacts);
593 for(PxU32 i=0; i<numContactPatch; ++i)
596 patch->mRoot = patch;
597 patch->mEndPatch = patch;
598 patch->mTotalSize = patch->mEndIndex - patch->mStartIndex;
599 patch->mNextPatch = NULL;
601 for(PxU32 j=i; j>0; --j)
604 const FloatV d = V3Dot(patch->mPatchNormal, other->mRoot->mPatchNormal);
605 if(FAllGrtrOrEq(d, acceptanceEpsilon))
608 other->mNextPatch = patch;
609 other->mRoot->mEndPatch = patch;
610 patch->mRoot = other->mRoot;
611 other->mRoot->mTotalSize += patch->mEndIndex - patch->mStartIndex;
626 for(PxU32 i=0; i<numContactPatch; ++i)
630 if(currentPatch->mRoot == currentPatch)
637 for(PxU32 k = currentPatch->mStartIndex; k<currentPatch->mEndIndex; ++k)
639 for(PxU32 l = nextPatch->mStartIndex; l < nextPatch->mEndIndex; ++l)
641 Vec3V dif = V3Sub(manifoldContacts[l].mLocalPointB, manifoldContacts[k].mLocalPointB);
642 FloatV d = V3Dot(dif, dif);
643 if(FAllGrtr(sqReplaceBreaking, d))
646 manifoldContacts[l] = manifoldContacts[nextPatch->mEndIndex-1];
647 nextPatch->mEndIndex--;
654 currentPatch = nextPatch;
671 for(PxU32 i=0; i < mNumManifolds; ++i)
673 PxU8 ind = mManifoldIndices[i];
674 PX_ASSERT(mManifoldIndices[i] < GU_MAX_MANIFOLD_SIZE);
675 PxU32 nextInd =
PxMin(i, mNumManifolds-2u)+1;
679 FloatV _maxPen = mManifolds[ind].refreshContactPoints(relTra, projectBreakingThreshold, contactDist);
680 if(mManifolds[ind].isEmpty())
683 PxU8 index = mManifoldIndices[--mNumManifolds];
684 mManifoldIndices[mNumManifolds] = ind;
685 mManifoldIndices[i] = index;
690 FStore(_maxPen, &mMaxPen[ind]);
699 mNumTotalContacts = 0;
700 mRelativeTransform.Invalidate();
701 for(PxU8 i=0; i<GU_MAX_MANIFOLD_SIZE; ++i)
703 mManifolds[i].initialize();
704 mManifoldIndices[i] = i;
710 for(PxU8 i=0; i<mNumManifolds; ++i)
712 mManifolds[i].clearManifold();
715 mNumTotalContacts = 0;
716 mRelativeTransform.Invalidate();
721 PX_ASSERT(index < GU_MAX_MANIFOLD_SIZE);
722 return &mManifolds[mManifoldIndices[index]];
727 if(mNumManifolds < GU_MAX_MANIFOLD_SIZE)
728 return &mManifolds[mManifoldIndices[mNumManifolds]];
734 const aos::FloatVArg sqReplaceBreakingThreshold,
const aos::FloatVArg acceptanceEpsilon, PxU8 maxContactsPerManifold);
745 static void drawLine(
PxRenderOutput& out,
const aos::Vec3VArg p0,
const aos::Vec3VArg p1,
const PxU32 color = 0xff00ffff);
747 static void drawPoint(
PxRenderOutput& out,
const aos::Vec3VArg p,
const PxF32 size,
const PxU32 color = 0x00ff0000);
751 PxF32 mMaxPen[GU_MAX_MANIFOLD_SIZE];
752 PxU8 mManifoldIndices[GU_MAX_MANIFOLD_SIZE];
754 PxU8 mNumTotalContacts;
758} PX_ALIGN_SUFFIX(16);