diff options
| author | Sheikh Dawood Abdul Ajees <[email protected]> | 2017-11-20 14:41:07 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <[email protected]> | 2017-11-20 15:22:41 -0600 |
| commit | 4bda45ce4e8b509eb0da786a6044006942ac259c (patch) | |
| tree | a51eb808016e1710a4bbd537000a493250602944 /PhysX_3.4/Source/GeomUtils/src | |
| parent | Update README.md (diff) | |
| parent | PhysX 3.4.1, APEX 1.4.1 Release @23131702 (diff) | |
| download | physx-3.4-4bda45ce4e8b509eb0da786a6044006942ac259c.tar.xz physx-3.4-4bda45ce4e8b509eb0da786a6044006942ac259c.zip | |
Merge branch 'master'
Diffstat (limited to 'PhysX_3.4/Source/GeomUtils/src')
11 files changed, 351 insertions, 215 deletions
diff --git a/PhysX_3.4/Source/GeomUtils/src/GuSweepMTD.cpp b/PhysX_3.4/Source/GeomUtils/src/GuSweepMTD.cpp index ff4acd10..178d0389 100644 --- a/PhysX_3.4/Source/GeomUtils/src/GuSweepMTD.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/GuSweepMTD.cpp @@ -49,6 +49,20 @@ using namespace physx; using namespace Gu; +// PT: TODO: refactor with GuMTD.cpp versions +static PX_FORCE_INLINE PxF32 manualNormalize(PxVec3& mtd, const PxVec3& normal, PxReal lenSq) +{ + const PxF32 len = PxSqrt(lenSq); + + // We do a *manual* normalization to check for singularity condition + if(lenSq < 1e-6f) + mtd = PxVec3(1.0f, 0.0f, 0.0f); // PT: zero normal => pick up random one + else + mtd = normal * 1.0f / len; + + return len; +} + static PX_FORCE_INLINE void getScaledTriangle(const PxTriangleMeshGeometry& triGeom, const Cm::Matrix34& vertex2worldSkew, bool flipsNormal, PxTriangle& triangle, PxTriangleID triangleIndex) { TriangleMesh* tm = static_cast<TriangleMesh*>(triGeom.triangleMesh); @@ -1087,8 +1101,7 @@ bool physx::Gu::computeSphere_SphereMTD(const Sphere& sphere0, const Sphere& sph const PxReal d2 = delta.magnitudeSquared(); const PxReal radiusSum = sphere0.radius + sphere1.radius; - const PxReal d = PxSqrt(d2); - hit.normal = delta / d; + const PxReal d = manualNormalize(hit.normal, delta, d2); hit.distance = d - radiusSum ; hit.position = sphere0.center + hit.normal * sphere0.radius; return true; @@ -1105,8 +1118,7 @@ bool physx::Gu::computeSphere_CapsuleMTD( const Sphere& sphere, const Capsule& c const PxVec3 normal = capsule.getPointAt(u) - sphere.center; const PxReal lenSq = normal.magnitudeSquared(); - const PxF32 d = PxSqrt(lenSq); - hit.normal = normal / d; + const PxF32 d = manualNormalize(hit.normal, normal, lenSq); hit.distance = d - radiusSum; hit.position = sphere.center + hit.normal * sphere.radius; return true; @@ -1115,8 +1127,6 @@ bool physx::Gu::computeSphere_CapsuleMTD( const Sphere& sphere, const Capsule& c //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool physx::Gu::computeCapsule_CapsuleMTD(const Capsule& capsule0, const Capsule& capsule1, PxSweepHit& hit) { - using namespace Ps::aos; - PxReal s,t; distanceSegmentSegmentSquared(capsule0, capsule1, &s, &t); @@ -1127,8 +1137,7 @@ bool physx::Gu::computeCapsule_CapsuleMTD(const Capsule& capsule0, const Capsule const PxVec3 normal = pointAtCapsule0 - pointAtCapsule1; const PxReal lenSq = normal.magnitudeSquared(); - const PxF32 len = PxSqrt(lenSq); - hit.normal = normal / len; + const PxF32 len = manualNormalize(hit.normal, normal, lenSq); hit.distance = len - radiusSum; hit.position = pointAtCapsule1 + hit.normal * capsule1.radius; return true; diff --git a/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp b/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp index 5d653fc6..33eb7c52 100644 --- a/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp @@ -129,6 +129,7 @@ public: mPose (pose), mDistance (distance) { + mSweepHit.faceIndex = 0xFFFFffff; } virtual PxAgain onEvent(PxU32 nb, PxU32* indices) @@ -327,6 +328,7 @@ public: { const bool hasContacts = computeConvex_HeightFieldMTD(hfGeom, pose, convexGeom, convexPose, inflation, mIsDoubleSided, GuHfQueryFlags::eWORLD_SPACE, sweepHit); + sweepHit.faceIndex = mSweepHit.faceIndex; sweepHit.flags = PxHitFlag::eDISTANCE | PxHitFlag::eNORMAL | PxHitFlag::eFACE_INDEX; if(!hasContacts) { @@ -424,6 +426,7 @@ public: mInflation (inflation) { mMinToi = FMax(); + mSweepHit.faceIndex = 0xFFFFffff; } virtual PxAgain onEvent(PxU32 nb, PxU32* indices) diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp index ea7f44b7..1136d522 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp @@ -56,21 +56,23 @@ public: PCMCapsuleVsMeshContactGeneration mGeneration; PCMCapsuleVsHeightfieldContactGenerationCallback( - const Gu::CapsuleV& capsule, - const Ps::aos::FloatVArg contactDistance, - const Ps::aos::FloatVArg replaceBreakingThreshold, + const Gu::CapsuleV& capsule, + const Ps::aos::FloatVArg contactDistance, + const Ps::aos::FloatVArg replaceBreakingThreshold, - const PsTransformV& capsuleTransform, - const PsTransformV& heightfieldTransform, - const PxTransform& heightfieldTransform1, - Gu::MultiplePersistentContactManifold& multiManifold, - Gu::ContactBuffer& contactBuffer, + const PsTransformV& capsuleTransform, + const PsTransformV& heightfieldTransform, + const PxTransform& heightfieldTransform1, + Gu::MultiplePersistentContactManifold& multiManifold, + Gu::ContactBuffer& contactBuffer, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, Gu::HeightFieldUtil& hfUtil ) : PCMHeightfieldContactGenerationCallback<PCMCapsuleVsHeightfieldContactGenerationCallback>(hfUtil, heightfieldTransform1), - mGeneration(capsule, contactDistance, replaceBreakingThreshold, capsuleTransform, heightfieldTransform, multiManifold, contactBuffer) + mGeneration(capsule, contactDistance, replaceBreakingThreshold, capsuleTransform, heightfieldTransform, multiManifold, + contactBuffer, deferredContacts) { } @@ -119,7 +121,6 @@ bool Gu::pcmContactCapsuleHeightField(GU_CONTACT_METHOD_ARGS) const PxVec3 capsuleDirInMesh = transform1.rotateInv(tmp); const Gu::CapsuleV capsule(V3LoadU(capsuleCenterInMesh), V3LoadU(capsuleDirInMesh), capsuleRadius); - PCMCapsuleVsHeightfieldContactGenerationCallback callback( capsule, contactDist, @@ -129,6 +130,7 @@ bool Gu::pcmContactCapsuleHeightField(GU_CONTACT_METHOD_ARGS) transform1, multiManifold, contactBuffer, + NULL, hfUtil ); diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleMesh.cpp index e19063ca..0d5dc68a 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleMesh.cpp @@ -59,20 +59,22 @@ public: PCMCapsuleVsMeshContactGeneration mGeneration; PCMCapsuleVsMeshContactGenerationCallback( - const CapsuleV& capsule, - const Ps::aos::FloatVArg contactDist, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const PsTransformV& sphereTransform, - const PsTransformV& meshTransform, - MultiplePersistentContactManifold& multiManifold, - ContactBuffer& contactBuffer, - const PxU8* extraTriData, - const Cm::FastVertex2ShapeScaling& meshScaling, - bool idtMeshScale, - Cm::RenderOutput* renderOutput = NULL + const CapsuleV& capsule, + const Ps::aos::FloatVArg contactDist, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const PsTransformV& sphereTransform, + const PsTransformV& meshTransform, + MultiplePersistentContactManifold& multiManifold, + ContactBuffer& contactBuffer, + const PxU8* extraTriData, + const Cm::FastVertex2ShapeScaling& meshScaling, + bool idtMeshScale, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, + Cm::RenderOutput* renderOutput = NULL ) : PCMMeshContactGenerationCallback<PCMCapsuleVsMeshContactGenerationCallback>(meshScaling, extraTriData, idtMeshScale), - mGeneration(capsule, contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, renderOutput) + mGeneration(capsule, contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, + deferredContacts, renderOutput) { } @@ -150,6 +152,7 @@ bool Gu::pcmContactCapsuleMesh(GU_CONTACT_METHOD_ARGS) extraData, meshScaling, idtMeshScale, + NULL, renderOutput); //bound the capsule in shape space by an OBB: @@ -163,7 +166,7 @@ bool Gu::pcmContactCapsuleMesh(GU_CONTACT_METHOD_ARGS) Midphase::intersectOBB(meshData, queryBox, callback, true); callback.flushCache(); - + callback.mGeneration.processContacts(GU_CAPSULE_MANIFOLD_CACHE_SIZE, false); } else diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.cpp index 66ecc724..b84d6806 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.cpp @@ -31,6 +31,7 @@ #include "GuPCMContactConvexCommon.h" #include "GuConvexEdgeFlags.h" #include "GuBarycentricCoordinates.h" +#include "PsSort.h" namespace physx { @@ -101,13 +102,13 @@ void PCMConvexVsMeshContactGeneration::generateLastContacts() { using namespace Ps::aos; // Process delayed contacts - PxU32 nbEntries = mDeferredContacts.size(); + PxU32 nbEntries = mDeferredContacts->size(); if(nbEntries) { nbEntries /= sizeof(PCMDeferredPolyData)/sizeof(PxU32); - const PCMDeferredPolyData* PX_RESTRICT cd = reinterpret_cast<const PCMDeferredPolyData*>(mDeferredContacts.begin()); + const PCMDeferredPolyData* PX_RESTRICT cd = reinterpret_cast<const PCMDeferredPolyData*>(mDeferredContacts->begin()); for(PxU32 i=0;i<nbEntries;i++) { const PCMDeferredPolyData& currentContact = cd[i]; @@ -409,10 +410,12 @@ static Ps::aos::FloatV pcmDistancePointTriangleSquared( const Ps::aos::Vec3VArg const Ps::aos::Vec3VArg c, const PxU8 triFlags, Ps::aos::Vec3V& closestP, - bool& generateContact) + bool& generateContact, + bool& faceContact) { using namespace Ps::aos; + faceContact = false; const FloatV zero = FZero(); const Vec3V ab = V3Sub(b, a); const Vec3V ac = V3Sub(c, a); @@ -535,6 +538,7 @@ static Ps::aos::FloatV pcmDistancePointTriangleSquared( const Ps::aos::Vec3VArg } generateContact = true; + faceContact = true; //P must project inside face region. Compute Q using Barycentric coordinates const FloatV nn = V3Dot(n, n); @@ -552,7 +556,6 @@ bool Gu::PCMSphereVsMeshContactGeneration::processTriangle(const PxVec3* verts, using namespace Ps::aos; const FloatV zero = FZero(); - const Vec3V zeroV = V3Zero(); const Vec3V v0 = V3LoadU(verts[0]); const Vec3V v1 = V3LoadU(verts[1]); @@ -570,74 +573,158 @@ bool Gu::PCMSphereVsMeshContactGeneration::processTriangle(const PxVec3* verts, if(FAllGrtr(zero, dist0)) return false; - const FloatV tolerance = FLoad(0.996);//around 5 degree //FloatV u, v; Vec3V closestP; - //mShereCenter will be in the local space of the triangle mesh - //const FloatV sqDist = Gu::distancePointTriangleSquared(mSphereCenter, v0, v1, v2, u, v, closestP); + //mSphereCenter will be in the local space of the triangle mesh bool generateContact = false; - const FloatV sqDist = pcmDistancePointTriangleSquared(mSphereCenter, v0, v1, v2, triFlags, closestP, generateContact); - - //sphere center is on the triangle surface, we take triangle normal as the patchNormal. Otherwise, we need to calculate the patchNormal - Vec3V patchNormal = n; - if(FAllGrtr(sqDist, FEps() )) - patchNormal = V3Normalize(V3Sub(mSphereCenter, closestP)); - - const FloatV cosTheta = V3Dot(patchNormal, n); + bool faceContact = false; + FloatV sqDist = pcmDistancePointTriangleSquared(mSphereCenter, v0, v1, v2, triFlags, closestP, generateContact, faceContact); - //sphere overlap with triangles - if(FAllGrtr(mSqInflatedSphereRadius, sqDist) && (generateContact || FAllGrtr(cosTheta, tolerance))) + //sphere overlap with triangles + if (FAllGrtr(mSqInflatedSphereRadius, sqDist)) { - const FloatV dist = FSqrt(sqDist); - - PX_ASSERT(mNumContactPatch <PCM_MAX_CONTACTPATCH_SIZE); - bool foundPatch = false; - if(mNumContactPatch > 0) + //sphere center is on the triangle surface, we take triangle normal as the patchNormal. Otherwise, we need to calculate the patchNormal + Vec3V patchNormal = n; + if (!faceContact) + patchNormal = V3Normalize(V3Sub(mSphereCenter, closestP)); + + const FloatV cosTheta = V3Dot(patchNormal, n); + + //two normal less than 5 degree, generate contacts + if (FAllGrtr(cosTheta, tolerance)) { - if(FAllGrtr(V3Dot(mContactPatch[mNumContactPatch-1].mPatchNormal, patchNormal), mAcceptanceEpsilon)) - { - PCMContactPatch& patch = mContactPatch[mNumContactPatch-1]; + const FloatV dist = FSqrt(sqDist); - PX_ASSERT((patch.mEndIndex - patch.mStartIndex) == 1); - - if(FAllGrtr(patch.mPatchMaxPen, dist)) - { - //overwrite the old contact - mManifoldContacts[patch.mStartIndex].mLocalPointA = zeroV;//in sphere's space - mManifoldContacts[patch.mStartIndex].mLocalPointB = closestP; - mManifoldContacts[patch.mStartIndex].mLocalNormalPen = V4SetW(Vec4V_From_Vec3V(patchNormal), dist); - mManifoldContacts[patch.mStartIndex].mFaceIndex = triangleIndex; - patch.mPatchMaxPen = dist; - } - - foundPatch = true; - } + mEdgeCache.addData(CachedEdge(vertInds[0], vertInds[1])); + mEdgeCache.addData(CachedEdge(vertInds[1], vertInds[2])); + mEdgeCache.addData(CachedEdge(vertInds[2], vertInds[0])); + + addToPatch(closestP, patchNormal, dist, triangleIndex); } - if(!foundPatch) + else { - mManifoldContacts[mNumContacts].mLocalPointA = zeroV;//in sphere's space - mManifoldContacts[mNumContacts].mLocalPointB = closestP; - mManifoldContacts[mNumContacts].mLocalNormalPen = V4SetW(Vec4V_From_Vec3V(patchNormal), dist); - mManifoldContacts[mNumContacts++].mFaceIndex = triangleIndex; + //ML : defer the contacts generation + const PxU32 nb = sizeof(PCMDeferredPolyData) / sizeof(PxU32); + PxU32 newSize = nb + mDeferredContacts->size(); + mDeferredContacts->reserve(newSize); + PCMDeferredPolyData* PX_RESTRICT data = reinterpret_cast<PCMDeferredPolyData*>(mDeferredContacts->end()); + mDeferredContacts->forceSize_Unsafe(newSize); + + SortedTriangle sortedTriangle; + sortedTriangle.mSquareDist = sqDist; + sortedTriangle.mIndex = mSortedTriangle.size(); + mSortedTriangle.pushBack(sortedTriangle); + + data->mTriangleIndex = triangleIndex; + data->mFeatureIndex = 0; + data->triFlags = PxU8(generateContact); + data->mInds[0] = vertInds[0]; + data->mInds[1] = vertInds[1]; + data->mInds[2] = vertInds[2]; + V3StoreU(closestP, data->mVerts[0]); + V3StoreU(patchNormal, data->mVerts[1]); + V3StoreU(V3Splat(sqDist), data->mVerts[2]); - mContactPatch[mNumContactPatch].mStartIndex = mNumContacts - 1; - mContactPatch[mNumContactPatch].mEndIndex = mNumContacts; - mContactPatch[mNumContactPatch].mPatchMaxPen = dist; - mContactPatch[mNumContactPatch++].mPatchNormal = patchNormal; } + } + return true; +} + +void Gu::PCMSphereVsMeshContactGeneration::addToPatch(const Ps::aos::Vec3VArg contactP, const Ps::aos::Vec3VArg patchNormal, const Ps::aos::FloatV dist, + const PxU32 triangleIndex) +{ + using namespace Ps::aos; + + PX_ASSERT(mNumContactPatch < PCM_MAX_CONTACTPATCH_SIZE); - PX_ASSERT(mNumContactPatch <PCM_MAX_CONTACTPATCH_SIZE); + const Vec3V sphereCenter = V3Zero(); // in sphere local space - if(mNumContacts >= 16) + bool foundPatch = false; + if (mNumContactPatch > 0) + { + if (FAllGrtr(V3Dot(mContactPatch[mNumContactPatch - 1].mPatchNormal, patchNormal), mAcceptanceEpsilon)) { - PX_ASSERT(mNumContacts <= 64); - processContacts(GU_SPHERE_MANIFOLD_CACHE_SIZE); + PCMContactPatch& patch = mContactPatch[mNumContactPatch - 1]; + + PX_ASSERT((patch.mEndIndex - patch.mStartIndex) == 1); + + if (FAllGrtr(patch.mPatchMaxPen, dist)) + { + //overwrite the old contact + mManifoldContacts[patch.mStartIndex].mLocalPointA = sphereCenter;//in sphere's space + mManifoldContacts[patch.mStartIndex].mLocalPointB = contactP; + mManifoldContacts[patch.mStartIndex].mLocalNormalPen = V4SetW(Vec4V_From_Vec3V(patchNormal), dist); + mManifoldContacts[patch.mStartIndex].mFaceIndex = triangleIndex; + patch.mPatchMaxPen = dist; + } + + foundPatch = true; } + } + if (!foundPatch) + { + mManifoldContacts[mNumContacts].mLocalPointA = sphereCenter;//in sphere's space + mManifoldContacts[mNumContacts].mLocalPointB = contactP; + mManifoldContacts[mNumContacts].mLocalNormalPen = V4SetW(Vec4V_From_Vec3V(patchNormal), dist); + mManifoldContacts[mNumContacts++].mFaceIndex = triangleIndex; + + mContactPatch[mNumContactPatch].mStartIndex = mNumContacts - 1; + mContactPatch[mNumContactPatch].mEndIndex = mNumContacts; + mContactPatch[mNumContactPatch].mPatchMaxPen = dist; + mContactPatch[mNumContactPatch++].mPatchNormal = patchNormal; + } + + PX_ASSERT(mNumContactPatch < PCM_MAX_CONTACTPATCH_SIZE); + + if (mNumContacts >= 16) + { + PX_ASSERT(mNumContacts <= 64); + processContacts(GU_SPHERE_MANIFOLD_CACHE_SIZE); + } +} + +void Gu::PCMSphereVsMeshContactGeneration::generateLastContacts() +{ + using namespace Ps::aos; + // Process delayed contacts + PxU32 nbSortedTriangle = mSortedTriangle.size(); + + if (nbSortedTriangle) + { + Ps::sort(mSortedTriangle.begin(), mSortedTriangle.size(), Ps::Less<SortedTriangle>()); + + const PCMDeferredPolyData* PX_RESTRICT cd = reinterpret_cast<const PCMDeferredPolyData*>(mDeferredContacts->begin()); + + for (PxU32 i = 0; i < nbSortedTriangle; ++i) + { + const PCMDeferredPolyData& currentContact = cd[mSortedTriangle[i].mIndex]; + const PxU32 ref0 = currentContact.mInds[0]; + const PxU32 ref1 = currentContact.mInds[1]; + const PxU32 ref2 = currentContact.mInds[2]; + + PxU8 generateContacts = currentContact.triFlags; + + //if addData sucessful, which means mEdgeCache doesn't have the edge + const bool noEdge01 = mEdgeCache.addData(CachedEdge(ref0, ref1)); + const bool noEdge12 = mEdgeCache.addData(CachedEdge(ref1, ref2)); + const bool noEdge20 = mEdgeCache.addData(CachedEdge(ref2, ref0)); + const bool needsProcessing = (noEdge01 && noEdge12 && noEdge20 && generateContacts); + + if (needsProcessing) + { + //we store the contact, patch normal and sq distance in the vertex memory in PCMDeferredPolyData + const Vec3V contactP = V3LoadU(currentContact.mVerts[0]); + const Vec3V patchNormal = V3LoadU(currentContact.mVerts[1]); + const FloatV sqDist = FLoad(currentContact.mVerts[2].x); + const FloatV dist = FSqrt(sqDist); + addToPatch(contactP, patchNormal, dist, currentContact.mTriangleIndex); + } + + } } - return true; } diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.h b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.h index 5c372914..cae46bdd 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.h +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexCommon.h @@ -44,27 +44,32 @@ namespace physx namespace Gu { +#define MAX_CACHE_SIZE 128 + class PCMMeshContactGeneration { PX_NOCOPY(PCMMeshContactGeneration) public: - PCMContactPatch mContactPatch[PCM_MAX_CONTACTPATCH_SIZE]; - PCMContactPatch* mContactPatchPtr[PCM_MAX_CONTACTPATCH_SIZE]; - const Ps::aos::FloatV mContactDist; - const Ps::aos::FloatV mReplaceBreakingThreshold; - const Ps::aos::PsTransformV& mConvexTransform; - const Ps::aos::PsTransformV& mMeshTransform; - Gu::MultiplePersistentContactManifold& mMultiManifold; - Gu::ContactBuffer& mContactBuffer; - - Ps::aos::FloatV mAcceptanceEpsilon; - Ps::aos::FloatV mSqReplaceBreakingThreshold; - Ps::aos::PsMatTransformV mMeshToConvex; - Gu::MeshPersistentContact* mManifoldContacts; - PxU32 mNumContacts; - PxU32 mNumContactPatch; - PxU32 mNumCalls; - Cm::RenderOutput* mRenderOutput; + PCMContactPatch mContactPatch[PCM_MAX_CONTACTPATCH_SIZE]; + PCMContactPatch* mContactPatchPtr[PCM_MAX_CONTACTPATCH_SIZE]; + const Ps::aos::FloatV mContactDist; + const Ps::aos::FloatV mReplaceBreakingThreshold; + const Ps::aos::PsTransformV& mConvexTransform; + const Ps::aos::PsTransformV& mMeshTransform; + Gu::MultiplePersistentContactManifold& mMultiManifold; + Gu::ContactBuffer& mContactBuffer; + + Ps::aos::FloatV mAcceptanceEpsilon; + Ps::aos::FloatV mSqReplaceBreakingThreshold; + Ps::aos::PsMatTransformV mMeshToConvex; + Gu::MeshPersistentContact* mManifoldContacts; + PxU32 mNumContacts; + PxU32 mNumContactPatch; + PxU32 mNumCalls; + Gu::CacheMap<Gu::CachedEdge, MAX_CACHE_SIZE> mEdgeCache; + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* mDeferredContacts; + Cm::RenderOutput* mRenderOutput; + PCMMeshContactGeneration( const Ps::aos::FloatVArg contactDist, @@ -73,6 +78,7 @@ public: const Ps::aos::PsTransformV& meshTransform, Gu::MultiplePersistentContactManifold& multiManifold, Gu::ContactBuffer& contactBuffer, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, Cm::RenderOutput* renderOutput ) : @@ -82,6 +88,7 @@ public: mMeshTransform(meshTransform), mMultiManifold(multiManifold), mContactBuffer(contactBuffer), + mDeferredContacts(deferredContacts), mRenderOutput(renderOutput) { @@ -257,8 +264,6 @@ public: PxU8 triFlags; //57 }; -#define MAX_CACHE_SIZE 128 - #if PX_VC #pragma warning(push) #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. @@ -269,36 +274,33 @@ class PCMConvexVsMeshContactGeneration : public PCMMeshContactGeneration PCMConvexVsMeshContactGeneration &operator=(PCMConvexVsMeshContactGeneration &); public: - - Gu::CacheMap<Gu::CachedEdge, MAX_CACHE_SIZE> mEdgeCache; - Gu::CacheMap<Gu::CachedVertex, MAX_CACHE_SIZE> mVertexCache; - Ps::aos::Vec3V mHullCenterMesh; - - Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>& mDeferredContacts; - const Gu::PolygonalData& mPolyData; - SupportLocal* mPolyMap; - const Cm::FastVertex2ShapeScaling& mConvexScaling; - bool mIdtConvexScale; - Cm::RenderOutput* mRenderOutput; + Gu::CacheMap<Gu::CachedVertex, MAX_CACHE_SIZE> mVertexCache; + Ps::aos::Vec3V mHullCenterMesh; + + const Gu::PolygonalData& mPolyData; + SupportLocal* mPolyMap; + const Cm::FastVertex2ShapeScaling& mConvexScaling; + bool mIdtConvexScale; + Cm::RenderOutput* mRenderOutput; PCMConvexVsMeshContactGeneration( - const Ps::aos::FloatVArg contactDistance, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const Ps::aos::PsTransformV& convexTransform, - const Ps::aos::PsTransformV& meshTransform, - Gu::MultiplePersistentContactManifold& multiManifold, - Gu::ContactBuffer& contactBuffer, - - const Gu::PolygonalData& polyData, - SupportLocal* polyMap, - Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>& delayedContacts, - const Cm::FastVertex2ShapeScaling& convexScaling, - bool idtConvexScale, - Cm::RenderOutput* renderOutput + const Ps::aos::FloatVArg contactDistance, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const Ps::aos::PsTransformV& convexTransform, + const Ps::aos::PsTransformV& meshTransform, + Gu::MultiplePersistentContactManifold& multiManifold, + Gu::ContactBuffer& contactBuffer, + + const Gu::PolygonalData& polyData, + SupportLocal* polyMap, + Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>* delayedContacts, + const Cm::FastVertex2ShapeScaling& convexScaling, + bool idtConvexScale, + Cm::RenderOutput* renderOutput - ) : PCMMeshContactGeneration(contactDistance, replaceBreakingThreshold, convexTransform, meshTransform, multiManifold, contactBuffer, renderOutput), - mDeferredContacts(delayedContacts), + ) : PCMMeshContactGeneration(contactDistance, replaceBreakingThreshold, convexTransform, meshTransform, multiManifold, contactBuffer, + delayedContacts, renderOutput), mPolyData(polyData), mPolyMap(polyMap), mConvexScaling(convexScaling), @@ -334,26 +336,39 @@ public: #pragma warning(pop) #endif +struct SortedTriangle +{ + Ps::aos::FloatV mSquareDist; + PxU32 mIndex; + + PX_FORCE_INLINE bool operator < (const SortedTriangle& data) const + { + return Ps::aos::FAllGrtrOrEq(mSquareDist, data.mSquareDist) ==0; + } +}; + class PCMSphereVsMeshContactGeneration : public PCMMeshContactGeneration { public: - Ps::aos::Vec3V mSphereCenter; - Ps::aos::FloatV mSphereRadius; - Ps::aos::FloatV mSqInflatedSphereRadius; + Ps::aos::Vec3V mSphereCenter; + Ps::aos::FloatV mSphereRadius; + Ps::aos::FloatV mSqInflatedSphereRadius; + Ps::InlineArray<SortedTriangle, 64> mSortedTriangle; - PCMSphereVsMeshContactGeneration( - const Ps::aos::Vec3VArg sphereCenter, - const Ps::aos::FloatVArg sphereRadius, - const Ps::aos::FloatVArg contactDist, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const Ps::aos::PsTransformV& sphereTransform, - const Ps::aos::PsTransformV& meshTransform, - Gu::MultiplePersistentContactManifold& multiManifold, - Gu::ContactBuffer& contactBuffer, + const Ps::aos::Vec3VArg sphereCenter, + const Ps::aos::FloatVArg sphereRadius, + const Ps::aos::FloatVArg contactDist, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const Ps::aos::PsTransformV& sphereTransform, + const Ps::aos::PsTransformV& meshTransform, + MultiplePersistentContactManifold& multiManifold, + ContactBuffer& contactBuffer, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, Cm::RenderOutput* renderOutput = NULL - ) : PCMMeshContactGeneration(contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, renderOutput), + ) : PCMMeshContactGeneration(contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, + contactBuffer, deferredContacts, renderOutput), mSphereCenter(sphereCenter), mSphereRadius(sphereRadius) { @@ -362,8 +377,10 @@ public: mSqInflatedSphereRadius = FMul(inflatedSphereRadius, inflatedSphereRadius); } - bool processTriangle(const PxVec3* verts, PxU32 triangleIndex, PxU8 triFlags, const PxU32* vertInds); + void generateLastContacts(); + void addToPatch(const Ps::aos::Vec3VArg contactP, const Ps::aos::Vec3VArg patchNormal, + const Ps::aos::FloatV pen, const PxU32 triangleIndex); }; class PCMCapsuleVsMeshContactGeneration : public PCMMeshContactGeneration @@ -376,16 +393,18 @@ public: PCMCapsuleVsMeshContactGeneration( - const CapsuleV& capsule, - const Ps::aos::FloatVArg contactDist, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const Ps::aos::PsTransformV& sphereTransform, - const Ps::aos::PsTransformV& meshTransform, - Gu::MultiplePersistentContactManifold& multiManifold, - Gu::ContactBuffer& contactBuffer, - Cm::RenderOutput* renderOutput = NULL - - ) : PCMMeshContactGeneration(contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, renderOutput), + const CapsuleV& capsule, + const Ps::aos::FloatVArg contactDist, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const Ps::aos::PsTransformV& sphereTransform, + const Ps::aos::PsTransformV& meshTransform, + Gu::MultiplePersistentContactManifold& multiManifold, + Gu::ContactBuffer& contactBuffer, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, + Cm::RenderOutput* renderOutput = NULL + + ) : PCMMeshContactGeneration(contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, + deferredContacts, renderOutput), mCapsule(capsule) { using namespace Ps::aos; diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp index 979d75be..6901a5c3 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp @@ -62,20 +62,20 @@ public: PCMConvexVsMeshContactGeneration mGeneration; PCMConvexVsHeightfieldContactGenerationCallback( - const Ps::aos::FloatVArg contactDistance, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const Gu::PolygonalData& polyData, - SupportLocal* polyMap, - const Cm::FastVertex2ShapeScaling& convexScaling, - bool idtConvexScale, - const PsTransformV& convexTransform, - const PsTransformV& heightfieldTransform, - const PxTransform& heightfieldTransform1, - Gu::MultiplePersistentContactManifold& multiManifold, - Gu::ContactBuffer& contactBuffer, - Gu::HeightFieldUtil& hfUtil, - Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>& delayedContacts, - Cm::RenderOutput* renderOutput = NULL + const Ps::aos::FloatVArg contactDistance, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const Gu::PolygonalData& polyData, + SupportLocal* polyMap, + const Cm::FastVertex2ShapeScaling& convexScaling, + bool idtConvexScale, + const PsTransformV& convexTransform, + const PsTransformV& heightfieldTransform, + const PxTransform& heightfieldTransform1, + Gu::MultiplePersistentContactManifold& multiManifold, + Gu::ContactBuffer& contactBuffer, + Gu::HeightFieldUtil& hfUtil, + Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>* delayedContacts, + Cm::RenderOutput* renderOutput = NULL ) : PCMHeightfieldContactGenerationCallback< PCMConvexVsHeightfieldContactGenerationCallback >(hfUtil, heightfieldTransform1), @@ -155,7 +155,7 @@ bool Gu::PCMContactConvexHeightfield( multiManifold, contactBuffer, hfUtil, - delayedContacts, + &delayedContacts, renderOutput ); diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexMesh.cpp index ea12eb4e..2bacfb87 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexMesh.cpp @@ -59,22 +59,22 @@ public: const BoxPadded& mBox; PCMConvexVsMeshContactGenerationCallback( - const Ps::aos::FloatVArg contactDistance, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const PsTransformV& convexTransform, - const PsTransformV& meshTransform, - MultiplePersistentContactManifold& multiManifold, - ContactBuffer& contactBuffer, - const PolygonalData& polyData, - SupportLocal* polyMap, - Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>& delayedContacts, - const Cm::FastVertex2ShapeScaling& convexScaling, - bool idtConvexScale, - const Cm::FastVertex2ShapeScaling& meshScaling, - const PxU8* extraTriData, - bool idtMeshScale, - const BoxPadded& box, - Cm::RenderOutput* renderOutput = NULL + const Ps::aos::FloatVArg contactDistance, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const PsTransformV& convexTransform, + const PsTransformV& meshTransform, + MultiplePersistentContactManifold& multiManifold, + ContactBuffer& contactBuffer, + const PolygonalData& polyData, + SupportLocal* polyMap, + Ps::InlineArray<PxU32,LOCAL_CONTACTS_SIZE>* delayedContacts, + const Cm::FastVertex2ShapeScaling& convexScaling, + bool idtConvexScale, + const Cm::FastVertex2ShapeScaling& meshScaling, + const PxU8* extraTriData, + bool idtMeshScale, + const BoxPadded& box, + Cm::RenderOutput* renderOutput = NULL ) : PCMMeshContactGenerationCallback<PCMConvexVsMeshContactGenerationCallback>(meshScaling, extraTriData, idtMeshScale), @@ -143,7 +143,7 @@ bool Gu::PCMContactConvexMesh(const PolygonalData& polyData, SupportLocal* polyM const PxU8* PX_RESTRICT extraData = meshData->getExtraTrigData(); PCMConvexVsMeshContactGenerationCallback blockCallback( contactDist, replaceBreakingThreshold, convexTransform, meshTransform, multiManifold, contactBuffer, - polyData, polyMap, delayedContacts, convexScaling, idtConvexScale, meshScaling, extraData, idtMeshScale, + polyData, polyMap, &delayedContacts, convexScaling, idtConvexScale, meshScaling, extraData, idtMeshScale, hullOBB, renderOutput); Midphase::intersectOBB(meshData, hullOBB, blockCallback, true); diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp index fbe0ab4a..cce99cd4 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp @@ -55,22 +55,24 @@ public: PCMSphereVsMeshContactGeneration mGeneration; PCMSphereVsHeightfieldContactGenerationCallback( - const Ps::aos::Vec3VArg sphereCenter, - const Ps::aos::FloatVArg sphereRadius, - const Ps::aos::FloatVArg contactDistance, - const Ps::aos::FloatVArg replaceBreakingThreshold, + const Ps::aos::Vec3VArg sphereCenter, + const Ps::aos::FloatVArg sphereRadius, + const Ps::aos::FloatVArg contactDistance, + const Ps::aos::FloatVArg replaceBreakingThreshold, - const PsTransformV& sphereTransform, - const PsTransformV& heightfieldTransform, - const PxTransform& heightfieldTransform1, - Gu::MultiplePersistentContactManifold& multiManifold, - Gu::ContactBuffer& contactBuffer, + const PsTransformV& sphereTransform, + const PsTransformV& heightfieldTransform, + const PxTransform& heightfieldTransform1, + Gu::MultiplePersistentContactManifold& multiManifold, + Gu::ContactBuffer& contactBuffer, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, Gu::HeightFieldUtil& hfUtil ) : PCMHeightfieldContactGenerationCallback<PCMSphereVsHeightfieldContactGenerationCallback>(hfUtil, heightfieldTransform1), - mGeneration(sphereCenter, sphereRadius, contactDistance, replaceBreakingThreshold, sphereTransform, heightfieldTransform, multiManifold, contactBuffer) + mGeneration(sphereCenter, sphereRadius, contactDistance, replaceBreakingThreshold, sphereTransform, + heightfieldTransform, multiManifold, contactBuffer, deferredContacts) { } @@ -123,6 +125,8 @@ bool Gu::pcmContactSphereHeightField(GU_CONTACT_METHOD_ARGS) PxBounds3 bounds(sphereCenterShape1Space - inflatedRadiusV, sphereCenterShape1Space + inflatedRadiusV); + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE> delayedContacts; + PCMSphereVsHeightfieldContactGenerationCallback blockCallback( sphereCenter, sphereRadius, @@ -133,10 +137,12 @@ bool Gu::pcmContactSphereHeightField(GU_CONTACT_METHOD_ARGS) transform1, multiManifold, contactBuffer, + &delayedContacts, hfUtil); hfUtil.overlapAABBTriangles(transform1, bounds, 0, &blockCallback); + blockCallback.mGeneration.generateLastContacts(); blockCallback.mGeneration.processContacts(GU_SPHERE_MANIFOLD_CACHE_SIZE, false); } else diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereMesh.cpp index 1c497a2c..9d8544df 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereMesh.cpp @@ -41,13 +41,16 @@ #include "GuPCMContactMeshCallback.h" #include "GuBox.h" + using namespace physx; using namespace Gu; using namespace physx::shdfnd::aos; + namespace physx { + struct PCMSphereVsMeshContactGenerationCallback : PCMMeshContactGenerationCallback< PCMSphereVsMeshContactGenerationCallback > { @@ -56,21 +59,22 @@ public: PCMSphereVsMeshContactGenerationCallback( - const Ps::aos::Vec3VArg sphereCenter, - const Ps::aos::FloatVArg sphereRadius, - const Ps::aos::FloatVArg contactDist, - const Ps::aos::FloatVArg replaceBreakingThreshold, - const PsTransformV& sphereTransform, - const PsTransformV& meshTransform, - MultiplePersistentContactManifold& multiManifold, - ContactBuffer& contactBuffer, - const PxU8* extraTriData, - const Cm::FastVertex2ShapeScaling& meshScaling, - bool idtMeshScale, - Cm::RenderOutput* renderOutput = NULL + const Ps::aos::Vec3VArg sphereCenter, + const Ps::aos::FloatVArg sphereRadius, + const Ps::aos::FloatVArg contactDist, + const Ps::aos::FloatVArg replaceBreakingThreshold, + const PsTransformV& sphereTransform, + const PsTransformV& meshTransform, + MultiplePersistentContactManifold& multiManifold, + ContactBuffer& contactBuffer, + const PxU8* extraTriData, + const Cm::FastVertex2ShapeScaling& meshScaling, + bool idtMeshScale, + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE>* deferredContacts, + Cm::RenderOutput* renderOutput = NULL ) : PCMMeshContactGenerationCallback<PCMSphereVsMeshContactGenerationCallback>(meshScaling, extraTriData, idtMeshScale), - mGeneration(sphereCenter, sphereRadius, contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, renderOutput) + mGeneration(sphereCenter, sphereRadius, contactDist, replaceBreakingThreshold, sphereTransform, meshTransform, multiManifold, contactBuffer, deferredContacts, renderOutput) { } @@ -94,8 +98,6 @@ bool Gu::pcmContactSphereMesh(GU_CONTACT_METHOD_ARGS) const PxSphereGeometry& shapeSphere = shape0.get<const PxSphereGeometry>(); const PxTriangleMeshGeometryLL& shapeMesh = shape1.get<const PxTriangleMeshGeometryLL>(); - //gRenderOutPut = cache.mRenderOutput; - const QuatV q0 = QuatVLoadA(&transform0.q.x); const Vec3V p0 = V3LoadA(&transform0.p.x); @@ -128,6 +130,8 @@ bool Gu::pcmContactSphereMesh(GU_CONTACT_METHOD_ARGS) multiManifold.mNumManifolds = 0; multiManifold.setRelativeTransform(curTransform); + Ps::InlineArray<PxU32, LOCAL_CONTACTS_SIZE> delayedContacts; + const PxU8* PX_RESTRICT extraData = meshData->getExtraTrigData(); // mesh scale is not baked into cached verts PCMSphereVsMeshContactGenerationCallback callback( @@ -141,7 +145,9 @@ bool Gu::pcmContactSphereMesh(GU_CONTACT_METHOD_ARGS) contactBuffer, extraData, meshScaling, - idtMeshScale); + idtMeshScale, + &delayedContacts, + renderOutput); PxVec3 obbCenter = sphereCenterShape1Space; PxVec3 obbExtents = PxVec3(inflatedRadius); @@ -154,6 +160,7 @@ bool Gu::pcmContactSphereMesh(GU_CONTACT_METHOD_ARGS) callback.flushCache(); + callback.mGeneration.generateLastContacts(); callback.mGeneration.processContacts(GU_SPHERE_MANIFOLD_CACHE_SIZE, false); } else diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMTriangleContactGen.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMTriangleContactGen.cpp index 7a0e68a2..5f0b20a2 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMTriangleContactGen.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMTriangleContactGen.cpp @@ -1154,10 +1154,10 @@ namespace physx { //ML : defer the contacts generation const PxU32 nb = sizeof(PCMDeferredPolyData)/sizeof(PxU32); - PxU32 newSize = nb + mDeferredContacts.size(); - mDeferredContacts.reserve(newSize); - PCMDeferredPolyData* PX_RESTRICT data = reinterpret_cast<PCMDeferredPolyData*>(mDeferredContacts.end()); - mDeferredContacts.forceSize_Unsafe(newSize); + PxU32 newSize = nb + mDeferredContacts->size(); + mDeferredContacts->reserve(newSize); + PCMDeferredPolyData* PX_RESTRICT data = reinterpret_cast<PCMDeferredPolyData*>(mDeferredContacts->end()); + mDeferredContacts->forceSize_Unsafe(newSize); data->mTriangleIndex = triangleIndex; data->mFeatureIndex = feature1; |