diff options
| author | Sheikh Dawood <[email protected]> | 2018-04-09 10:13:48 -0500 |
|---|---|---|
| committer | Sheikh Dawood <[email protected]> | 2018-04-09 10:13:48 -0500 |
| commit | 238605d8225a9135d6b60646e05d066e25424eee (patch) | |
| tree | 2b013bd4946bb3c699d7a06ef1f21be85d367f63 /PhysX_3.4/Source/GeomUtils | |
| parent | Add ParamTool.exe (diff) | |
| download | physx-3.4-238605d8225a9135d6b60646e05d066e25424eee.tar.xz physx-3.4-238605d8225a9135d6b60646e05d066e25424eee.zip | |
PhysX 3.4, APEX 1.4 patch release @23879214
Diffstat (limited to 'PhysX_3.4/Source/GeomUtils')
23 files changed, 434 insertions, 1444 deletions
diff --git a/PhysX_3.4/Source/GeomUtils/src/GuMeshFactory.cpp b/PhysX_3.4/Source/GeomUtils/src/GuMeshFactory.cpp index 7ffd5c72..33af97d6 100644 --- a/PhysX_3.4/Source/GeomUtils/src/GuMeshFactory.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/GuMeshFactory.cpp @@ -27,7 +27,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "PsIntrinsics.h" #include "GuMeshFactory.h" #include "PxHeightFieldDesc.h" @@ -52,12 +51,11 @@ using namespace Gu; // PT: TODO: refactor all this with a dedicated container -GuMeshFactory::GuMeshFactory() -: mTriangleMeshes (PX_DEBUG_EXP("mesh factory triangle mesh hash")) -, mConvexMeshes (PX_DEBUG_EXP("mesh factory convex mesh hash")) -, mHeightFields (PX_DEBUG_EXP("mesh factory height field hash")) -, mFactoryListeners(PX_DEBUG_EXP("FactoryListeners")) - +GuMeshFactory::GuMeshFactory() : + mTriangleMeshes (PX_DEBUG_EXP("mesh factory triangle mesh hash")), + mConvexMeshes (PX_DEBUG_EXP("mesh factory convex mesh hash")), + mHeightFields (PX_DEBUG_EXP("mesh factory height field hash")), + mFactoryListeners (PX_DEBUG_EXP("FactoryListeners")) { } @@ -98,29 +96,19 @@ void GuMeshFactory::release() PX_DELETE(this); } -namespace +template <typename T> +static void addToHash(Ps::CoalescedHashSet<T*>& hash, T* element, Ps::Mutex* mutex) { - template<typename TDataType> - inline void notifyReleaseFactoryItem( Ps::Array<GuMeshFactoryListener*>& listeners, const TDataType* type, PxType typeID) - { - PxU32 numListeners = listeners.size(); - for ( PxU32 idx = 0; idx < numListeners; ++idx ) - listeners[idx]->onGuMeshFactoryBufferRelease( type, typeID); - } + if(!element) + return; - template <typename T> void addToHash(Ps::CoalescedHashSet<T*>& hash, T* element, Ps::Mutex* mutex) - { - if(!element) - return; - - if(mutex) - mutex->lock(); + if(mutex) + mutex->lock(); - hash.insert(element); + hash.insert(element); - if(mutex) - mutex->unlock(); - } + if(mutex) + mutex->unlock(); } /////////////////////////////////////////////////////////////////////////////// @@ -675,7 +663,9 @@ void GuMeshFactory::removeFactoryListener( GuMeshFactoryListener& listener ) void GuMeshFactory::notifyFactoryListener(const PxBase* base, PxType typeID) { - notifyReleaseFactoryItem(mFactoryListeners, base, typeID); + const PxU32 nbListeners = mFactoryListeners.size(); + for(PxU32 i=0; i<nbListeners; i++) + mFactoryListeners[i]->onGuMeshFactoryBufferRelease(base, typeID); } /////////////////////////////////////////////////////////////////////////////// diff --git a/PhysX_3.4/Source/GeomUtils/src/GuRaycastTests.cpp b/PhysX_3.4/Source/GeomUtils/src/GuRaycastTests.cpp index 086d4ca2..3556a73c 100644 --- a/PhysX_3.4/Source/GeomUtils/src/GuRaycastTests.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/GuRaycastTests.cpp @@ -477,7 +477,7 @@ PxU32 raycast_heightField(GU_RAY_FUNC_PARAMS) const bool isDoubleSided = hfGeom.heightFieldFlags.isSet(PxMeshGeometryFlag::eDOUBLE_SIDED); const bool bothSides = isDoubleSided || (hitFlags & PxHitFlag::eMESH_BOTH_SIDES); - const HeightFieldUtil hfUtil(hfGeom); + const HeightFieldTraceUtil hfUtil(hfGeom); PxVec3 normRayDir = localRayDir; normRayDir.normalizeSafe(); // nothing will happen if length is < PX_NORMALIZATION_EPSILON diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuContactCapsuleMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuContactCapsuleMesh.cpp index 44494988..ba0f77c8 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuContactCapsuleMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuContactCapsuleMesh.cpp @@ -614,8 +614,7 @@ bool Gu::contactCapsuleHeightfield(GU_CONTACT_METHOD_ARGS) // We must be in local space to use the cache - const HeightField& hf = *static_cast<HeightField*>(shapeMesh.heightField); - HeightFieldUtil hfUtil(shapeMesh, hf); + HeightFieldUtil hfUtil(shapeMesh); CapsuleHeightfieldContactGenerationCallback callback( contactBuffer, transform1, hfUtil, meshCapsule, inflatedRadius, params.mContactDistance, shapeCapsule.radius); diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuContactConvexMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuContactConvexMesh.cpp index 091cc6f3..e8574ccc 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuContactConvexMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuContactConvexMesh.cpp @@ -1381,9 +1381,7 @@ static bool contactHullHeightfield2(const PolygonalData& polyData0, const PxBoun { //We need to create a callback that fills triangles from the HF - const HeightField& hf = *static_cast<HeightField*>(shape1.heightField); - - HeightFieldUtil hfUtil(shape1, hf); + HeightFieldUtil hfUtil(shape1); const Cm::Matrix34 world0(transform0); const Cm::Matrix34 world1(transform1); diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuContactSphereMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuContactSphereMesh.cpp index 352240ef..278dd38f 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuContactSphereMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuContactSphereMesh.cpp @@ -593,9 +593,8 @@ bool Gu::contactSphereHeightfield(GU_CONTACT_METHOD_ARGS) const PxSphereGeometry& shapeSphere = shape0.get<const PxSphereGeometry>(); const PxHeightFieldGeometryLL& shapeMesh = shape1.get<const PxHeightFieldGeometryLL>(); - const HeightField& hf = *static_cast<HeightField*>(shapeMesh.heightField); - HeightFieldUtil hfUtil(shapeMesh, hf); + HeightFieldUtil hfUtil(shapeMesh); const PxVec3 sphereCenterInMeshSpace = transform1.transformInv(transform0.p); const PxReal inflatedRadius = shapeSphere.radius + params.mContactDistance; diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactBoxHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactBoxHeightField.cpp index f5703111..f9bfa471 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactBoxHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactBoxHeightField.cpp @@ -187,8 +187,8 @@ bool legacyContactBoxHeightfield(GU_CONTACT_METHOD_ARGS) const PxBoxGeometry& shapeBox = shape0.get<const PxBoxGeometry>(); const PxHeightFieldGeometryLL& hfGeom = shape1.get<const PxHeightFieldGeometryLL>(); - const Gu::HeightField& hf = *static_cast<Gu::HeightField*>(hfGeom.heightField); - const Gu::HeightFieldUtil hfUtil(hfGeom, hf); + const Gu::HeightFieldTraceUtil hfUtil(hfGeom); + const Gu::HeightField& hf = hfUtil.getHeightField(); PX_ASSERT(contactBuffer.count==0); diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactCapsuleHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactCapsuleHeightField.cpp index a40ef577..73252b83 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactCapsuleHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactCapsuleHeightField.cpp @@ -62,8 +62,8 @@ bool legacyContactCapsuleHeightfield(GU_CONTACT_METHOD_ARGS) const PxCapsuleGeometry& shapeCapsule = shape0.get<const PxCapsuleGeometry>(); const PxHeightFieldGeometryLL& hfGeom = shape1.get<const PxHeightFieldGeometryLL>(); - const HeightField& hf = *static_cast<HeightField*>(hfGeom.heightField); - const HeightFieldUtil hfUtil(hfGeom, hf); + const HeightFieldUtil hfUtil(hfGeom); + const Gu::HeightField& hf = hfUtil.getHeightField(); const PxReal radius = shapeCapsule.radius; const PxReal inflatedRadius = shapeCapsule.radius + params.mContactDistance; diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactConvexHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactConvexHeightField.cpp index 42ffdce3..012133ef 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactConvexHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactConvexHeightField.cpp @@ -160,8 +160,8 @@ bool legacyContactConvexHeightfield(GU_CONTACT_METHOD_ARGS) PX_ASSERT(contactBuffer.count==0); - const Gu::HeightField& hf = *static_cast<Gu::HeightField*>(hfGeom.heightField); - const Gu::HeightFieldUtil hfUtil(hfGeom, hf); + const Gu::HeightFieldTraceUtil hfUtil(hfGeom); + const Gu::HeightField& hf = hfUtil.getHeightField(); const bool isConvexScaleIdentity = shapeConvex.scale.isIdentity(); Cm::FastVertex2ShapeScaling convexScaling; // PT: TODO: remove default ctor diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactSphereHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactSphereHeightField.cpp index ccb37f12..36f9930e 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactSphereHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyContactSphereHeightField.cpp @@ -55,8 +55,8 @@ bool GuContactSphereHeightFieldShared(GU_CONTACT_METHOD_ARGS, bool isCapsule) const PxSphereGeometry& shapeSphere = shape0.get<const PxSphereGeometry>(); const PxHeightFieldGeometryLL& hfGeom = shape1.get<const PxHeightFieldGeometryLL>(); - const Gu::HeightField& hf = *static_cast<Gu::HeightField*>(hfGeom.heightField); - const Gu::HeightFieldUtil hfUtil(hfGeom, hf); + const Gu::HeightFieldUtil hfUtil(hfGeom); + const Gu::HeightField& hf = hfUtil.getHeightField(); const PxReal radius = shapeSphere.radius; const PxReal eps = PxReal(0.1) * radius; diff --git a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyTraceLineCallback.h b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyTraceLineCallback.h index 1253931f..ee5072be 100644 --- a/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyTraceLineCallback.h +++ b/PhysX_3.4/Source/GeomUtils/src/contact/GuLegacyTraceLineCallback.h @@ -138,8 +138,7 @@ class GuContactHeightfieldTraceSegmentHelper { PX_NOCOPY(GuContactHeightfieldTraceSegmentHelper) public: - GuContactHeightfieldTraceSegmentHelper(const HeightFieldUtil& hfUtil) - : mHfUtil(hfUtil) + GuContactHeightfieldTraceSegmentHelper(const HeightFieldTraceUtil& hfUtil) : mHfUtil(hfUtil) { mHfUtil.computeLocalBounds(mLocalBounds); } @@ -150,8 +149,8 @@ public: } private: - const HeightFieldUtil& mHfUtil; - PxBounds3 mLocalBounds; + const HeightFieldTraceUtil& mHfUtil; + PxBounds3 mLocalBounds; }; }//Gu diff --git a/PhysX_3.4/Source/GeomUtils/src/gjk/GuGJKRaycast.h b/PhysX_3.4/Source/GeomUtils/src/gjk/GuGJKRaycast.h index d5520eb7..b93daa89 100644 --- a/PhysX_3.4/Source/GeomUtils/src/gjk/GuGJKRaycast.h +++ b/PhysX_3.4/Source/GeomUtils/src/gjk/GuGJKRaycast.h @@ -128,10 +128,9 @@ namespace Gu support = V3Sub(supportA, supportB); const Vec3V w = V3Neg(support); const FloatV vw = FSub(V3Dot(vNorm, w), inflationPlusEps); - const FloatV vr = V3Dot(vNorm, r); if(FAllGrtr(vw, zero)) { - + const FloatV vr = V3Dot(vNorm, r); if(FAllGrtrOrEq(vr, zero)) { return false; diff --git a/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightField.h b/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightField.h index a3072ba6..326aac4a 100644 --- a/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightField.h +++ b/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightField.h @@ -44,10 +44,8 @@ namespace physx { - class GuMeshFactory; class PxHeightFieldDesc; - } namespace physx @@ -298,8 +296,6 @@ private: } // namespace Gu - - PX_INLINE PxVec3 Gu::HeightField::getVertex(PxU32 vertexIndex) const { const PxU32 row = vertexIndex / mData.columns; @@ -372,7 +368,6 @@ PX_INLINE bool Gu::HeightField::isConvexVertex(PxU32 vertexIndex, PxU32 row, PxU return true; } - PX_INLINE bool Gu::HeightField::isValidEdge(PxU32 edgeIndex) const { const PxU32 cell = (edgeIndex / 3); @@ -397,7 +392,6 @@ PX_INLINE bool Gu::HeightField::isValidEdge(PxU32 edgeIndex) const return true; } - PX_INLINE PxU32 Gu::HeightField::getEdgeTriangleIndices(PxU32 edgeIndex, PxU32 triangleIndices[2]) const { const PxU32 cell = edgeIndex / 3; @@ -498,7 +492,6 @@ PX_INLINE PxU32 Gu::HeightField::getEdgeTriangleIndices(PxU32 edgeIndex, PxU32 t return count; } - PX_INLINE void Gu::HeightField::getEdgeVertexIndices(PxU32 edgeIndex, PxU32& vertexIndex0, PxU32& vertexIndex1) const { const PxU32 cell = edgeIndex / 3; @@ -533,231 +526,6 @@ PX_INLINE void Gu::HeightField::getEdgeVertexIndices(PxU32 edgeIndex, PxU32& ver } } -#ifdef REMOVED -PX_INLINE bool Gu::HeightField::isConvexEdge(PxU32 edgeIndex) const -{ - const PxU32 cell = edgeIndex / 3; - - const PxU32 row = cell / mData.columns; - if (row > mData.rows-2) return false; - - const PxU32 column = cell % mData.columns; - if (column > mData.columns-2) return false; - -// PxReal h0 = 0, h1 = 0, h2 = 0, h3 = 0; -// PxReal convexity = 0; - PxI32 h0 = 0, h1 = 0, h2 = 0, h3 = 0; - PxI32 convexity = 0; - -// switch (edgeIndex % 3) - switch (edgeIndex - cell*3) - { - case 0: - if (row < 1) return false; -/* if(isZerothVertexShared(cell - mData.columns)) - { - // <------ COL - // +----+ 0 R - // | / /# O - // | / / # W - // | / / # | - // |/ / # | - // + +====1 | - // | - // | - // | - // | - // | - // | - // V - // -// h0 = getHeight(cell - mData.columns); -// h1 = getHeight(cell); - h0 = getSample(cell - mData.columns).height; - h1 = getSample(cell).height; - } - else - { - // <------ COL - // 0 +----+ R - // #\ \ | O - // # \ \ | W - // # \ \ | | - // # \ \| | - // 1====+ + | - // | - // | - // | - // | - // | - // | - // V - // -// h0 = getHeight(cell - mData.columns + 1); -// h1 = getHeight(cell + 1); - h0 = getSample(cell - mData.columns + 1).height; - h1 = getSample(cell + 1).height; - }*/ - const bool b0 = !isZerothVertexShared(cell - mData.columns); - h0 = getSample(cell - mData.columns + b0).height; - h1 = getSample(cell + b0).height; - -/* if(isZerothVertexShared(cell)) - { - // <------ COL - // R - // O - // W - // | - // | - // | - // 2====+ 0 | - // # / /| | - // # / / | | - // # / / | | - // #/ / | | - // 3 +----+ | - // V - // -// h2 = getHeight(cell + 1); -// h3 = getHeight(cell + mData.columns + 1); - h2 = getSample(cell + 1).height; - h3 = getSample(cell + mData.columns + 1).height; - } - else - { - // <------ COL - // R - // O - // W - // | - // | - // | - // + +====2 | - // |\ \ # | - // | \ \ # | - // | \ \ # | - // | \ \# | - // +----+ 3 | - // V - // -// h2 = getHeight(cell); -// h3 = getHeight(cell + mData.columns); - h2 = getSample(cell).height; - h3 = getSample(cell + mData.columns).height; - }*/ - const bool b1 = isZerothVertexShared(cell); - h2 = getSample(cell + b1).height; - h3 = getSample(cell + mData.columns + b1).height; - - //convex = (h3-h2) < (h1-h0); - convexity = (h1-h0) - (h3-h2); - break; - case 1: -// h0 = getHeight(cell); -// h1 = getHeight(cell + 1); -// h2 = getHeight(cell + mData.columns); -// h3 = getHeight(cell + mData.columns + 1); - h0 = getSample(cell).height; - h1 = getSample(cell + 1).height; - h2 = getSample(cell + mData.columns).height; - h3 = getSample(cell + mData.columns + 1).height; - if (isZerothVertexShared(cell)) - //convex = (h0 + h3) > (h1 + h2); - convexity = (h0 + h3) - (h1 + h2); - else - //convex = (h2 + h1) > (h0 + h3); - convexity = (h2 + h1) - (h0 + h3); - break; - case 2: - if (column < 1) return false; -/* if(isZerothVertexShared(cell-1)) - { - // <-------------- COL - // 1====0 + R - // + / /| O - // + / / | W - // + / / | | - // +/ / | | - // + +----+ V - // -// h0 = getHeight(cell - 1); -// h1 = getHeight(cell); - h0 = getSample(cell - 1).height; - h1 = getSample(cell).height; - } - else - { - // <-------------- COL - // + +----+ R - // +\ \ | O - // + \ \ | W - // + \ \ | | - // + \ \| | - // 1====0 + V - // -// h0 = getHeight(cell - 1 + mData.columns); -// h1 = getHeight(cell + mData.columns); - h0 = getSample(cell - 1 + mData.columns).height; - h1 = getSample(cell + mData.columns).height; - }*/ - const PxU32 offset0 = isZerothVertexShared(cell-1) ? 0 : mData.columns; - h0 = getSample(cell - 1 + offset0).height; - h1 = getSample(cell + offset0).height; - -/* if(isZerothVertexShared(cell)) - { - // <-------------- COL - // +----+ + R - // | / /+ O - // | / / + W - // | / / + | - // |/ / + | - // + 3====2 V - // -// h2 = getHeight(cell + mData.columns); -// h3 = getHeight(cell + mData.columns + 1); - h2 = getSample(cell + mData.columns).height; - h3 = getSample(cell + mData.columns + 1).height; - } - else - { - // <-------------- COL - // + 3====2 R - // |\ \ + O - // | \ \ + W - // | \ \ + | - // | \ \+ | - // +----+ + V - // -// h2 = getHeight(cell); -// h3 = getHeight(cell + 1); - h2 = getSample(cell).height; - h3 = getSample(cell + 1).height; - }*/ - const PxU32 offset1 = isZerothVertexShared(cell) ? mData.columns : 0; - h2 = getSample(cell + offset1).height; - h3 = getSample(cell + offset1 + 1).height; - - //convex = (h3-h2) < (h1-h0); - convexity = (h1-h0) - (h3-h2); - break; - } - - const PxI32 threshold = PxI32(mData.convexEdgeThreshold); - if (mData.thickness <= 0) - { -// return convexity > mData.convexEdgeThreshold; - return convexity > threshold; - } - else - { -// return convexity < -mData.convexEdgeThreshold; - return convexity < -threshold; - } -} -#endif - PX_INLINE bool Gu::HeightField::isConvexEdge(PxU32 edgeIndex, PxU32 cell, PxU32 row, PxU32 column) const { // const PxU32 cell = edgeIndex / 3; @@ -987,34 +755,6 @@ PX_INLINE bool Gu::HeightField::isConvexEdge(PxU32 edgeIndex, PxU32 cell, PxU32 return convexity < -threshold; } } -#ifdef REMOVED -PX_INLINE void Gu::HeightField::computeCellCoordinates(PxReal x, PxReal z, PxU32& _row, PxU32& _column, PxReal& _fracX, PxReal& _fracZ) const -{ - x = physx::intrinsics::selectMax(x, 0.0f); - z = physx::intrinsics::selectMax(z, 0.0f); - - PxU32 row = (PxU32)x; - PxReal fracX = x - PxReal(row); - if (row > mData.rows - 2) - { - row = mData.rows - 2; - fracX = PxReal(1); - } - - PxU32 column = (PxU32)z; - PxReal fracZ = z - PxReal(column); - if (column > mData.columns - 2) - { - column = mData.columns - 2; - fracZ = PxReal(1); - } - - _row = row; - _column = column; - _fracX = fracX; - _fracZ = fracZ; -} -#endif PX_INLINE bool Gu::HeightField::isValidTriangle(PxU32 triangleIndex) const { @@ -1026,9 +766,6 @@ PX_INLINE bool Gu::HeightField::isValidTriangle(PxU32 triangleIndex) const return true; } - - - PX_INLINE void Gu::HeightField::getTriangleVertexIndices(PxU32 triangleIndex, PxU32& vertexIndex0, PxU32& vertexIndex1, PxU32& vertexIndex2) const { const PxU32 cell = triangleIndex >> 1; diff --git a/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.cpp b/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.cpp index 1717aac2..cbb0f175 100644 --- a/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.cpp @@ -27,7 +27,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "PsIntrinsics.h" #include "GuHeightFieldUtil.h" #include "GuSweepSharedTests.h" @@ -63,11 +62,6 @@ PxU32 Gu::HeightFieldUtil::getFaceIndexAtShapePoint(PxReal x, PxReal z) const return 0xffffffff; } -PxU32 Gu::HeightFieldUtil::getFaceIndexAtTriangleIndex(PxU32 triangleIndex) const -{ - return (mHeightField->getTriangleMaterial(triangleIndex) != PxHeightFieldMaterial::eHOLE) ? triangleIndex : 0xffffffff; -} - PxU32 Gu::HeightFieldUtil::getFaceIndexAtShapePointNoTest(PxReal x, PxReal z) const { PX_ASSERT(isShapePointOnHeightField(x, z)); @@ -82,104 +76,6 @@ PxU32 Gu::HeightFieldUtil::getFaceIndexAtShapePointNoTest2(PxU32 cell, PxReal fr return (mHeightField->getTriangleMaterial(triangleIndex) != PxHeightFieldMaterial::eHOLE) ? triangleIndex : 0xffffffff; } - -PxVec3 Gu::HeightFieldUtil::getSmoothNormalAtShapePoint(PxReal x, PxReal z) const -{ -#ifdef PX_HEIGHTFIELD_DEBUG - PX_ASSERT(getFaceIndexAtShapePoint(x, z) != 0xffffffff); -#endif - x *= mOneOverRowScale; - z *= mOneOverColumnScale; - - PxReal fracX, fracZ; - const PxU32 cell = mHeightField->computeCellCoordinates(x, z, fracX, fracZ); - - if (mHeightField->isZerothVertexShared(cell)) - { - // <----Z---+ - // +----+ | - // | /| | - // | / | X - // | / | | - // |/ | | - // +----+ | - // V - if (fracZ > fracX) - { - // <----Z---+ - // 1----0 | - // | / | - // | / X - // | / | - // |/ | - // 2 | - // V - const PxVec3 n0 = getVertexNormal(cell); - const PxVec3 n1 = getVertexNormal(cell + 1); - const PxVec3 n2 = getVertexNormal(cell + mHeightField->getNbColumnsFast() + 1); - return n0 + fracZ*(n1-n0) + fracX*(n2-n1); - } - else - { - // <----Z---+ - // 0 | - // /| | - // / | X - // / | | - // / | | - // 2----1 | - // V - const PxVec3 n0 = getVertexNormal(cell); - const PxVec3 n1 = getVertexNormal(cell + mHeightField->getNbColumnsFast()); - const PxVec3 n2 = getVertexNormal(cell + mHeightField->getNbColumnsFast() + 1); - return n0 + fracX*(n1-n0) + fracZ*(n2-n1); - } - } - else - { - // <----Z---+ - // +----+ | - // |\ | | - // | \ | X - // | \ | | - // | \| | - // +----+ | - // V - if (fracX + fracZ < 1) - { - // <----Z---+ - // 1----0 | - // \ | | - // \ | X - // \ | | - // \| | - // 2 | - // V - const PxVec3 n0 = getVertexNormal(cell); - const PxVec3 n1 = getVertexNormal(cell + 1); - const PxVec3 n2 = getVertexNormal(cell + mHeightField->getNbColumnsFast()); - return n0 + fracZ*(n1-n0) + fracX*(n2-n0); - } - else - { - // <----Z---+ - // 2 | - // |\ | - // | \ X - // | \ | - // | \ | - // 0----1 | - // V - // - // Note that we need to flip fracX and fracZ since we are moving the origin - const PxVec3 n0 = getVertexNormal(cell + mHeightField->getNbColumnsFast() + 1); - const PxVec3 n1 = getVertexNormal(cell + mHeightField->getNbColumnsFast()); - const PxVec3 n2 = getVertexNormal(cell + 1); - return n0 + (1-fracZ)*(n1-n0) + (1-fracX)*(n2 - n0); - } - } -} - PxVec3 Gu::HeightFieldUtil::getVertexNormal(PxU32 vertexIndex, PxU32 row, PxU32 column) const { #ifdef PX_HEIGHTFIELD_DEBUG @@ -711,63 +607,6 @@ bool Gu::HeightFieldUtil::findProjectionOnTriangle(PxU32 triangleIndex, PxU32 ro return false; } -bool Gu::HeightFieldUtil::isCollisionEdge(PxU32 edgeIndex) const -{ -#ifdef PX_HEIGHTFIELD_DEBUG - PX_ASSERT(mHeightField->isValidEdge(edgeIndex)); -#endif - - // This code was simple, readable but slow - // return isBoundaryEdge(edgeIndex) || (mHeightField->isConvexEdge(edgeIndex) && isSolidEdge(edgeIndex)); - - PxU32 faceIndices[2]; - const PxU32 count = mHeightField->getEdgeTriangleIndices(edgeIndex, faceIndices); - if (count > 1) - { - PxMaterialTableIndex mat0 = mHeightField->getTriangleMaterial(faceIndices[0]); - PxMaterialTableIndex mat1 = mHeightField->getTriangleMaterial(faceIndices[1]); - if (mat0 == PxHeightFieldMaterial::eHOLE) return (mat1 != PxHeightFieldMaterial::eHOLE); - if (mat1 == PxHeightFieldMaterial::eHOLE) return (mat0 != PxHeightFieldMaterial::eHOLE); - } - else - { - if (mHeightField->getFlagsFast() & PxHeightFieldFlag::eNO_BOUNDARY_EDGES) return false; - PxMaterialTableIndex mat0 = mHeightField->getTriangleMaterial(faceIndices[0]); - return (mat0 != PxHeightFieldMaterial::eHOLE); - } - - return mHeightField->isConvexEdge(edgeIndex); -} - -bool Gu::HeightFieldUtil::isCollisionEdge(PxU32 edgeIndex, PxU32 count, const PxU32* PX_RESTRICT faceIndices, PxU32 cell, PxU32 row, PxU32 column) const -{ -#ifdef PX_HEIGHTFIELD_DEBUG - PX_ASSERT(mHeightField->isValidEdge(edgeIndex)); -#endif - - // This code was simple, readable but slow - // return isBoundaryEdge(edgeIndex) || (mHeightField->isConvexEdge(edgeIndex) && isSolidEdge(edgeIndex)); - -// PxU32 faceIndices[2]; -// const PxU32 count = mHeightField->getEdgeTriangleIndices(edgeIndex, faceIndices); - if (count > 1) - { - PxMaterialTableIndex mat0 = mHeightField->getTriangleMaterial(faceIndices[0]); - PxMaterialTableIndex mat1 = mHeightField->getTriangleMaterial(faceIndices[1]); - if (mat0 == PxHeightFieldMaterial::eHOLE) return (mat1 != PxHeightFieldMaterial::eHOLE); - if (mat1 == PxHeightFieldMaterial::eHOLE) return (mat0 != PxHeightFieldMaterial::eHOLE); - } - else - { - if (mHeightField->getFlagsFast() & PxHeightFieldFlag::eNO_BOUNDARY_EDGES) return false; - PxMaterialTableIndex mat0 = mHeightField->getTriangleMaterial(faceIndices[0]); - return (mat0 != PxHeightFieldMaterial::eHOLE); - } - -// return mHeightField->isConvexEdge(edgeIndex); - return mHeightField->isConvexEdge(edgeIndex, cell, row, column); -} - void Gu::HeightFieldUtil::getEdge(PxU32 edgeIndex, PxU32 cell, PxU32 row, PxU32 column, PxVec3& origin, PxVec3& extent) const { #ifdef PX_HEIGHTFIELD_DEBUG @@ -1008,40 +847,3 @@ PxU32 Gu::HeightFieldUtil::getTriangle(const PxTransform& pose, PxTriangle& worl } return PxU32(mHeightField->getTriangleMaterial(triangleIndex) != PxHeightFieldMaterial::eHOLE); } - - -bool Gu::HeightFieldUtil::isBoundaryEdge(PxU32 edgeIndex) const -{ -#ifdef PX_HEIGHTFIELD_DEBUG - PX_ASSERT(mHeightField.isValidEdge(edgeIndex)); -#endif - PxU32 faceIndices[2]; - const PxU32 count = mHeightField->getEdgeTriangleIndices(edgeIndex, faceIndices); - if (count > 1) - { - const PxMaterialTableIndex mat0 = mHeightField->getTriangleMaterial(faceIndices[0]); - const PxMaterialTableIndex mat1 = mHeightField->getTriangleMaterial(faceIndices[1]); - if (mat0 == PxHeightFieldMaterial::eHOLE) return (mat1 != PxHeightFieldMaterial::eHOLE); - if (mat1 == PxHeightFieldMaterial::eHOLE) return (mat0 != PxHeightFieldMaterial::eHOLE); - } - else - { - const PxMaterialTableIndex mat0 = mHeightField->getTriangleMaterial(faceIndices[0]); - return (mat0 != PxHeightFieldMaterial::eHOLE); - } - return false; -} - - -/*PxReal Gu::HeightFieldUtil::getHeightAtShapePoint(PxReal x, PxReal z) const -{ - return mHfGeom.heightScale * mHeightField->getHeightInternal(x * mOneOverRowScale, z * mOneOverColumnScale); -}*/ - - -/* -PxVec3 Gu::HeightFieldUtil::getNormalAtShapePoint(PxReal x, PxReal z) const -{ - return hf2shapen(mHeightField->getNormal_(x * mOneOverRowScale, z * mOneOverColumnScale)); -} -*/ diff --git a/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.h b/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.h index a382f574..8e8dfb1c 100644 --- a/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.h +++ b/PhysX_3.4/Source/GeomUtils/src/hf/GuHeightFieldUtil.h @@ -59,8 +59,24 @@ namespace Gu class PX_PHYSX_COMMON_API HeightFieldUtil { - private: - + public: + PxReal mOneOverRowScale; + PxReal mOneOverHeightScale; + PxReal mOneOverColumnScale; + const Gu::HeightField* mHeightField; + const PxHeightFieldGeometry* mHfGeom; + + //sschirm: added empty ctor for gpu shared mem allocation + PX_FORCE_INLINE HeightFieldUtil() {} + + //sschirm: initialize with PxHeightFieldGeometry and Gu::HeightField for gpu shared mem allocation + PX_CUDA_CALLABLE PX_FORCE_INLINE void initialize(const PxHeightFieldGeometry& hfGeom, const Gu::HeightField& hf) + { + mHeightField = &hf; + mHfGeom = &hfGeom; + initialize(); + } + PX_CUDA_CALLABLE PX_FORCE_INLINE void initialize() { const PxReal absRowScale = PxAbs(mHfGeom->rowScale); @@ -79,36 +95,12 @@ namespace Gu mOneOverRowScale = 1.0f / mHfGeom->rowScale; mOneOverColumnScale = 1.0f / mHfGeom->columnScale; } - - PxReal mOneOverRowScale; - PxReal mOneOverHeightScale; - PxReal mOneOverColumnScale; - const Gu::HeightField* mHeightField; - const PxHeightFieldGeometry* mHfGeom; - public: - - //sschirm: added empty ctor for gpu shared mem allocation - PX_FORCE_INLINE HeightFieldUtil() {} - - PX_FORCE_INLINE HeightFieldUtil(const PxHeightFieldGeometry& hfGeom, const Gu::HeightField& hf) : mHeightField(&hf), mHfGeom(&hfGeom) - { - initialize(); - } - PX_FORCE_INLINE HeightFieldUtil(const PxHeightFieldGeometry& hfGeom) : mHeightField(static_cast<const Gu::HeightField*>(hfGeom.heightField)), mHfGeom(&hfGeom) { initialize(); } - //sschirm: initialize with PxHeightFieldGeometry and Gu::HeightField for gpu shared mem allocation - PX_CUDA_CALLABLE PX_FORCE_INLINE void initialize(const PxHeightFieldGeometry& hfGeom, const Gu::HeightField& hf) - { - mHeightField = &hf; - mHfGeom = &hfGeom; - initialize(); - } - PX_CUDA_CALLABLE PX_FORCE_INLINE const Gu::HeightField& getHeightField() const { return *mHeightField; } PX_CUDA_CALLABLE PX_FORCE_INLINE const PxHeightFieldGeometry& getHeightFieldGeometry() const { return *mHfGeom; } @@ -121,10 +113,6 @@ namespace Gu { return mHeightField->isCollisionVertex(vertexIndex, row, column, PxHeightFieldMaterial::eHOLE); } - PX_CUDA_CALLABLE bool isCollisionEdge(PxU32 edgeIndex) const; - bool isCollisionEdge(PxU32 edgeIndex, PxU32 count, const PxU32* PX_RESTRICT faceIndices, PxU32 cell, PxU32 row, PxU32 column) const; - bool isBoundaryEdge(PxU32 edgeIndex) const; -// PxReal getHeightAtShapePoint(PxReal x, PxReal z) const; PX_FORCE_INLINE PxReal getHeightAtShapePoint(PxReal x, PxReal z) const { return mHfGeom->heightScale * mHeightField->getHeightInternal(x * mOneOverRowScale, z * mOneOverColumnScale); @@ -134,7 +122,6 @@ namespace Gu return mHfGeom->heightScale * mHeightField->getHeightInternal2(vertexIndex, fracX, fracZ); } -// PxVec3 getNormalAtShapePoint(PxReal x, PxReal z) const; PX_FORCE_INLINE PxVec3 getNormalAtShapePoint(PxReal x, PxReal z) const { return mHeightField->getNormal_(x * mOneOverRowScale, z * mOneOverColumnScale, mOneOverRowScale, mOneOverHeightScale, mOneOverColumnScale); @@ -147,12 +134,8 @@ namespace Gu PxU32 getFaceIndexAtShapePoint(PxReal x, PxReal z) const; PxU32 getFaceIndexAtShapePointNoTest(PxReal x, PxReal z) const; PxU32 getFaceIndexAtShapePointNoTest2(PxU32 cell, PxReal fracX, PxReal fracZ) const; - PxU32 getFaceIndexAtTriangleIndex(PxU32 triangleIndex) const; - - PxVec3 getSmoothNormalAtShapePoint(PxReal x, PxReal z) const; PxVec3 getVertexNormal(PxU32 vertexIndex, PxU32 row, PxU32 column) const; -// PxVec3 getVertexNormal(PxU32 vertexIndex) const; PX_FORCE_INLINE PxVec3 getVertexNormal(PxU32 vertexIndex) const { const PxU32 nbColumns = mHeightField->getData().columns; @@ -185,7 +168,6 @@ namespace Gu bool findProjectionOnTriangle(PxU32 triangleIndex, PxU32 row, PxU32 column, const PxVec3& point, PxVec3& projection) const; -// PxReal findClosestPointOnEdge(PxU32 edgeIndex, const PxVec3& point, PxVec3& closestPoint) const; PxReal findClosestPointOnEdge(PxU32 edgeIndex, PxU32 cell, PxU32 row, PxU32 column, const PxVec3& point, PxVec3& closestPoint) const; PxU32 getTriangle(const PxTransform&, PxTriangle& worldTri, @@ -248,9 +230,118 @@ namespace Gu && (z < (mHeightField->getData().colLimit+1.0f))); } + PX_FORCE_INLINE PxVec3 hf2shapen(const PxVec3& v) const + { + return PxVec3(v.x * mOneOverRowScale, v.y * mOneOverHeightScale, v.z * mOneOverColumnScale); + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 shape2hfp(const PxVec3& v) const + { + return PxVec3(v.x * mOneOverRowScale, v.y * mOneOverHeightScale, v.z * mOneOverColumnScale); + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 hf2shapep(const PxVec3& v) const + { + return PxVec3(v.x * mHfGeom->rowScale, v.y * mHfGeom->heightScale, v.z * mHfGeom->columnScale); + } + + PX_INLINE PxVec3 hf2worldp(const PxTransform& pose, const PxVec3& v) const + { + const PxVec3 s = hf2shapep(v); + return pose.transform(s); + } + + PX_INLINE PxVec3 hf2worldn(const PxTransform& pose, const PxVec3& v) const + { + const PxVec3 s = hf2shapen(v); + return pose.q.rotate(s); + } + + // ptchernev TODO: this is wrong it only clips in x and z + bool clipShapeNormalToVertexVoronoi(PxVec3& normal, PxU32 vertexIndex, PxU32 row, PxU32 column) const + { + //PxU32 row = vertexIndex / getNbColumnsFast(); + //PxU32 column = vertexIndex % getNbColumnsFast(); +// const PxU32 row = vertexIndex / mHeightField.getNbColumnsFast(); +// const PxU32 column = vertexIndex % mHeightField.getNbColumnsFast(); + PX_ASSERT(row == vertexIndex / mHeightField->getNbColumnsFast()); + PX_ASSERT(column == vertexIndex % mHeightField->getNbColumnsFast()); + + //PxReal h0 = getHeight(vertexIndex); + const PxReal h0 = mHeightField->getHeight(vertexIndex); + + bool result = false; + + if(row > 0) + { + // - row + //PxVec3 e; + //e.set(-getRowScale(), getHeightScale() * (getHeight(vertexIndex - getNbColumnsFast()) - h0), 0); + const PxVec3 e(-mHfGeom->rowScale, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex - mHeightField->getNbColumnsFast()) - h0), 0); + const PxReal proj = e.dot(normal); + if(proj > 0) + { + normal -= e * proj / e.magnitudeSquared(); + result = true; + } + } + + //if(row < getNbRowsFast() - 1) + if(row < mHeightField->getNbRowsFast() - 1) + { + // + row + //PxVec3 e; + //e.set(getRowScale(), getHeightScale() * (getHeight(vertexIndex + getNbColumnsFast()) - h0), 0); + const PxVec3 e(mHfGeom->rowScale, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex + mHeightField->getNbColumnsFast()) - h0), 0); + const PxReal proj = e.dot(normal); + if(proj > 0) + { + normal -= e * proj / e.magnitudeSquared(); + result = true; + } + } + + if(column > 0) + { + // - column + //PxVec3 e; + //e.set(0, getHeightScale() * (getHeight(vertexIndex - 1) - h0), -getColumnScale()); + const PxVec3 e(0, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex - 1) - h0), -mHfGeom->columnScale); + const PxReal proj = e.dot(normal); + if(proj > 0) + { + normal -= e * proj / e.magnitudeSquared(); + result = true; + } + } + + //if(column < getNbColumnsFast() - 1) + if(column < mHeightField->getNbColumnsFast() - 1) + { + // + column + //PxVec3 e; + //e.set(0, getHeightScale() * (getHeight(vertexIndex + 1) - h0), getColumnScale()); + const PxVec3 e(0, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex + 1) - h0), mHfGeom->columnScale); + const PxReal proj = e.dot(normal); + if(proj > 0) + { + normal -= e * proj / e.magnitudeSquared(); + result = true; + } + } + + return result; + } + }; + + class PX_PHYSX_COMMON_API HeightFieldTraceUtil : public HeightFieldUtil + { + public: + PX_FORCE_INLINE HeightFieldTraceUtil(const PxHeightFieldGeometry& hfGeom) : HeightFieldUtil(hfGeom) {} + // floor and ceil don't clamp down exact integers but we want that - static PX_FORCE_INLINE PxF32 floorDown(PxF32 x) { PxF32 f = PxFloor(x); return (f == x) ? f-1 : f; } - static PX_FORCE_INLINE PxF32 ceilUp (PxF32 x) { PxF32 f = PxCeil (x); return (f == x) ? f+1 : f; } + static PX_FORCE_INLINE PxF32 floorDown(PxF32 x) { PxF32 f = PxFloor(x); return (f == x) ? f - 1 : f; } + static PX_FORCE_INLINE PxF32 ceilUp(PxF32 x) { PxF32 f = PxCeil(x); return (f == x) ? f + 1 : f; } // helper class for testing triangle height and reporting the overlapped triangles template<class T> @@ -292,23 +383,23 @@ namespace Gu public: void operator = (OverlapTraceSegment&) {} - OverlapTraceSegment(const HeightFieldUtil& hfUtil,const Gu::HeightField& hf) - : mInitialized(false), mHfUtil(hfUtil), mHf(hf), mNbIndices(0) {} + OverlapTraceSegment(const HeightFieldUtil& hfUtil, const Gu::HeightField& hf) + : mInitialized(false), mHfUtil(hfUtil), mHf(hf), mNbIndices(0) {} PX_FORCE_INLINE bool initialized() const { return mInitialized; } // prepare for iterations, set the expand u|v PX_INLINE void prepare(const PxVec3& aP0, const PxVec3& aP1, const PxVec3& overlapObjectExtent, PxF32& expandu, PxF32& expandv) - { + { // height test bounds - mMinY = (PxMin(aP1.y,aP0.y) - overlapObjectExtent.y) * mHfUtil.getOneOverHeightScale(); - mMaxY = (PxMax(aP1.y,aP0.y) + overlapObjectExtent.y) * mHfUtil.getOneOverHeightScale(); + mMinY = (PxMin(aP1.y, aP0.y) - overlapObjectExtent.y) * mHfUtil.getOneOverHeightScale(); + mMaxY = (PxMax(aP1.y, aP0.y) + overlapObjectExtent.y) * mHfUtil.getOneOverHeightScale(); // sets the clipping variables - mMinRow = PxI32(mHf.getMinRow((PxMin(aP1.x,aP0.x) - overlapObjectExtent.x)* mHfUtil.getOneOverRowScale())); - mMaxRow = PxI32(mHf.getMaxRow((PxMax(aP1.x,aP0.x) + overlapObjectExtent.x)* mHfUtil.getOneOverRowScale())); - mMinColumn = PxI32(mHf.getMinColumn((PxMin(aP1.z,aP0.z) - overlapObjectExtent.z)* mHfUtil.getOneOverColumnScale())); - mMaxColumn = PxI32(mHf.getMaxColumn((PxMax(aP1.z,aP0.z) + overlapObjectExtent.z)* mHfUtil.getOneOverColumnScale())); + mMinRow = PxI32(mHf.getMinRow((PxMin(aP1.x, aP0.x) - overlapObjectExtent.x)* mHfUtil.getOneOverRowScale())); + mMaxRow = PxI32(mHf.getMaxRow((PxMax(aP1.x, aP0.x) + overlapObjectExtent.x)* mHfUtil.getOneOverRowScale())); + mMinColumn = PxI32(mHf.getMinColumn((PxMin(aP1.z, aP0.z) - overlapObjectExtent.z)* mHfUtil.getOneOverColumnScale())); + mMaxColumn = PxI32(mHf.getMaxColumn((PxMax(aP1.z, aP0.z) + overlapObjectExtent.z)* mHfUtil.getOneOverColumnScale())); // sets the expanded u|v coordinates expandu = PxCeil(overlapObjectExtent.x*mHfUtil.getOneOverRowScale()); @@ -316,7 +407,7 @@ namespace Gu // sets the offset that will be overlapped in each axis mOffsetU = PxI32(expandu) + 1; - mOffsetV = PxI32(expandv) + 1; + mOffsetV = PxI32(expandv) + 1; } // sets all necessary variables and makes initial rectangle setup and overlap @@ -336,11 +427,11 @@ namespace Gu mPreviousRectangle.mMaxv = vi + mOffsetV; // visits all cells in given initial rectangle - if(!visitCells(mPreviousRectangle)) + if (!visitCells(mPreviousRectangle)) return false; // reports all overlaps - if(!reportOverlaps()) + if (!reportOverlaps()) return false; return true; @@ -355,11 +446,11 @@ namespace Gu mCurrentRectangle.mMinv = vi - mOffsetV; mCurrentRectangle.mMaxv = vi + mOffsetV; OverlapLine line; - computeRectangleDifference(mCurrentRectangle,mPreviousRectangle,line); - - if(!visitCells(line)) + computeRectangleDifference(mCurrentRectangle, mPreviousRectangle, line); + + if (!visitCells(line)) return false; - if(!reportOverlaps()) + if (!reportOverlaps()) return false; mPreviousRectangle = mCurrentRectangle; @@ -369,8 +460,8 @@ namespace Gu PX_INLINE void computeRectangleDifference(const OverlapRectangle& currentRectangle, const OverlapRectangle& previousRectangle, OverlapLine& line) { // check if u changes - add the row for visit - if(currentRectangle.mMinu != previousRectangle.mMinu) - { + if (currentRectangle.mMinu != previousRectangle.mMinu) + { line.mColumn = false; line.mLine = currentRectangle.mMinu < previousRectangle.mMinu ? currentRectangle.mMinu : currentRectangle.mMaxu; line.mMin = currentRectangle.mMinv; @@ -379,8 +470,8 @@ namespace Gu } // check if v changes - add the column for visit - if(currentRectangle.mMinv != previousRectangle.mMinv) - { + if (currentRectangle.mMinv != previousRectangle.mMinv) + { line.mColumn = true; line.mLine = currentRectangle.mMinv < previousRectangle.mMinv ? currentRectangle.mMinv : currentRectangle.mMaxv; line.mMin = currentRectangle.mMinu; @@ -391,20 +482,20 @@ namespace Gu // visits all cells in given rectangle PX_INLINE bool visitCells(const OverlapRectangle& rectangle) { - for(PxI32 ui = rectangle.mMinu + mStep_ui; ui <= rectangle.mMaxu + mStep_ui; ui++) + for (PxI32 ui = rectangle.mMinu + mStep_ui; ui <= rectangle.mMaxu + mStep_ui; ui++) { - if(ui < mMinRow) + if (ui < mMinRow) continue; - if(ui >= mMaxRow) + if (ui >= mMaxRow) break; - for(PxI32 vi = rectangle.mMinv + mStep_vi; vi <= rectangle.mMaxv + mStep_vi; vi++) + for (PxI32 vi = rectangle.mMinv + mStep_vi; vi <= rectangle.mMaxv + mStep_vi; vi++) { - if(vi < mMinColumn) + if (vi < mMinColumn) continue; - if(vi >= mMaxColumn) + if (vi >= mMaxColumn) break; const PxI32 vertexIndex = ui*mNumColumns + vi; - if(!testVertexIndex(PxU32(vertexIndex))) + if (!testVertexIndex(PxU32(vertexIndex))) return false; } } @@ -414,28 +505,28 @@ namespace Gu // visits all cells in given line - can be row or column PX_INLINE bool visitCells(const OverlapLine& line) { - if(line.mMin > line.mMax) + if (line.mMin > line.mMax) return true; - if(line.mColumn) + if (line.mColumn) { const PxI32 vi = line.mLine + mStep_vi; // early exit if column is out of hf clip area - if(vi < mMinColumn) + if (vi < mMinColumn) return true; - if(vi >= mMaxColumn) + if (vi >= mMaxColumn) return true; - for(PxI32 ui = line.mMin + mStep_ui; ui <= line.mMax + mStep_ui; ui++) + for (PxI32 ui = line.mMin + mStep_ui; ui <= line.mMax + mStep_ui; ui++) { // early exit or continue if row is out of hf clip area - if(ui >= mMaxRow) + if (ui >= mMaxRow) break; // continue if we did not reach the valid area, we can still get there - if(ui < mMinRow) + if (ui < mMinRow) continue; // if the cell has not been tested test and report - if(!testVertexIndex(PxU32(mNumColumns * ui + vi))) + if (!testVertexIndex(PxU32(mNumColumns * ui + vi))) return false; } } @@ -443,21 +534,21 @@ namespace Gu { const PxI32 ui = line.mLine + mStep_ui; // early exit if row is out of hf clip area - if(ui < mMinRow) + if (ui < mMinRow) return true; - if(ui >= mMaxRow) + if (ui >= mMaxRow) return true; - for(PxI32 vi = line.mMin + mStep_vi; vi <= line.mMax + mStep_vi; vi++) + for (PxI32 vi = line.mMin + mStep_vi; vi <= line.mMax + mStep_vi; vi++) { // early exit or continue if column is out of hf clip area - if(vi >= mMaxColumn) + if (vi >= mMaxColumn) break; // continue if we did not reach the valid area, we can still get there - if(vi < mMinColumn) + if (vi < mMinColumn) continue; // if the cell has not been tested test and report - if(!testVertexIndex(PxU32(mNumColumns * ui + vi))) + if (!testVertexIndex(PxU32(mNumColumns * ui + vi))) return false; } } @@ -474,17 +565,17 @@ namespace Gu const PxReal h2 = mHf.getHeight(vertexIndex + mNumColumns); const PxReal h3 = mHf.getHeight(vertexIndex + mNumColumns + 1); // actual height test, if some height pass we accept the cell - if(!((mMaxY < h0 && mMaxY < h1 && mMaxY < h2 && mMaxY < h3) || (mMinY > h0 && mMinY > h1 && mMinY > h2 && mMinY > h3))) + if (!((mMaxY < h0 && mMaxY < h1 && mMaxY < h2 && mMaxY < h3) || (mMinY > h0 && mMinY > h1 && mMinY > h2 && mMinY > h3))) { // check if the triangle is not a hole - if(!ISHOLE0) + if (!ISHOLE0) { - if(!addIndex(vertexIndex*2)) + if (!addIndex(vertexIndex * 2)) return false; } - if(!ISHOLE1) + if (!ISHOLE1) { - if(!addIndex(vertexIndex*2 + 1)) + if (!addIndex(vertexIndex * 2 + 1)) return false; } } @@ -496,9 +587,9 @@ namespace Gu // add triangle index, if we get out of buffer size, report them bool addIndex(PxU32 triangleIndex) { - if(mNbIndices == HF_SWEEP_REPORT_BUFFER_SIZE) + if (mNbIndices == HF_SWEEP_REPORT_BUFFER_SIZE) { - if(!reportOverlaps()) + if (!reportOverlaps()) return false; } @@ -508,9 +599,9 @@ namespace Gu PX_FORCE_INLINE bool reportOverlaps() { - if(mNbIndices) + if (mNbIndices) { - if(!mCallback->onEvent(mNbIndices, mIndexBuffer)) + if (!mCallback->onEvent(mNbIndices, mIndexBuffer)) return false; mNbIndices = 0; } @@ -553,11 +644,11 @@ namespace Gu // The localBounds can be obtained: PxBounds3 hfLocalBounds; hfUtil.computeLocalBounds(hfLocalBounds); and passed as // a parameter. template<class T, bool useUnderFaceCallback, bool overlap> - PX_INLINE void traceSegment(const PxVec3& aP0, const PxVec3& rayDir, const float rayLength , T* aCallback, const PxBounds3& hfLocalBounds, bool backfaceCull, + PX_INLINE void traceSegment(const PxVec3& aP0, const PxVec3& rayDir, const float rayLength, T* aCallback, const PxBounds3& hfLocalBounds, bool backfaceCull, const PxVec3* overlapObjectExtent = NULL) const - { + { PxF32 tnear, tfar; - if(!Gu::intersectRayAABB2(hfLocalBounds.minimum, hfLocalBounds.maximum, aP0, rayDir, rayLength, tnear, tfar)) + if (!Gu::intersectRayAABB2(hfLocalBounds.minimum, hfLocalBounds.maximum, aP0, rayDir, rayLength, tnear, tfar)) return; const PxVec3 p0 = aP0 + rayDir * tnear; @@ -572,7 +663,7 @@ namespace Gu if (overlap) { // setup overlap variables - overlapTraceSegment.prepare(aP0,aP0 + rayDir*rayLength,*overlapObjectExtent,expandu,expandv); + overlapTraceSegment.prepare(aP0, aP0 + rayDir*rayLength, *overlapObjectExtent, expandu, expandv); } // row = x|u, column = z|v @@ -584,7 +675,7 @@ namespace Gu const PxF32 clampEps = 1e-7f; // shrink u,v to within 1e-7 away from the world bounds // we now clamp uvs to [1e-7, rowLimit-1e-7] to avoid out of range uvs and eliminate related checks in the loop - const PxF32 nbUcells = PxF32(nbUi-1)*(1.0f-clampEps), nbVcells = PxF32(nbVi-1)*(1.0f-clampEps); + const PxF32 nbUcells = PxF32(nbUi - 1)*(1.0f - clampEps), nbVcells = PxF32(nbVi - 1)*(1.0f - clampEps); // if u0,v0 is near an integer, shift up or down in direction opposite to du,dv by PxMax(|u,v|*1e-7, 1e-7) // (same direction as du,dv for u1,v1) @@ -611,17 +702,17 @@ namespace Gu // clamp magnitude of du, dv to at least clampEpsilon to avoid special cases when dividing const PxF32 divEpsilon = 1e-10f; - if(PxAbs(du) < divEpsilon) + if (PxAbs(du) < divEpsilon) du = step_uif * divEpsilon; - if(PxAbs(dv) < divEpsilon) + if (PxAbs(dv) < divEpsilon) dv = step_vif * divEpsilon; - const PxVec3 auhP0(aP0.x*mOneOverRowScale, aP0.y, aP0.z*mOneOverColumnScale); + const PxVec3 auhP0(aP0.x*mOneOverRowScale, aP0.y, aP0.z*mOneOverColumnScale); const PxVec3 duhv(rayDir.x*rayLength*mOneOverRowScale, rayDir.y*rayLength, rayDir.z*rayLength*mOneOverColumnScale); const PxReal duhvLength = duhv.magnitude(); PxVec3 duhvNormalized = duhv; - if(duhvLength > PX_NORMALIZATION_EPSILON) - duhvNormalized *= 1.0f/duhvLength; + if (duhvLength > PX_NORMALIZATION_EPSILON) + duhvNormalized *= 1.0f / duhvLength; // Math derivation: // points on 2d segment are parametrized as: [u0,v0] + t [du, dv]. We solve for t_u[n], t for nth u-intercept @@ -641,27 +732,27 @@ namespace Gu // tu, tv can be > 1 but since the loop is structured as do {} while(tMin < tEnd) we still visit the first cell PxF32 last_tu = 0.0f, last_tv = 0.0f; - PxReal tu = (uhit0-u0) / du; - PxReal tv = (vhit0-v0) / dv; + PxReal tu = (uhit0 - u0) / du; + PxReal tv = (vhit0 - v0) / dv; PX_ASSERT(tu >= 0.0f && tv >= 0.0f); // compute step_tu and step_tv; t steps per grid cell in u and v direction const PxReal step_tu = 1.0f / PxAbs(du), step_tv = 1.0f / PxAbs(dv); // t advances at the same rate for u, v and h therefore we can compute h at u,v grid intercepts - #define COMPUTE_H_FROM_T(t) (h0 + (t) * dh) +#define COMPUTE_H_FROM_T(t) (h0 + (t) * dh) const PxF32 hEpsilon = 1e-4f; PxF32 uif = PxF32(ui), vif = PxF32(vi); // these are used to remap h values to correspond to u,v increasing order - PxI32 uflip = 1-step_ui; /*0 or 2*/ - PxI32 vflip = (1-step_vi)/2; /*0 or 1*/ + PxI32 uflip = 1 - step_ui; /*0 or 2*/ + PxI32 vflip = (1 - step_vi) / 2; /*0 or 1*/ // this epsilon is needed to ensure that we include the last [t, t+1] range in the do {} while(t<tEnd) loop // A.B. in case of overlap we do miss actually a line with this epsilon, should it not be +? PxF32 tEnd = 1.0f - 1e-4f; - if(overlap) + if (overlap) tEnd = 1.0f + 1e-4f; PxF32 tMinUV; @@ -677,210 +768,212 @@ namespace Gu // the operating u|v space has been extended by expandu|expandv if inflation is used PX_ASSERT(ui >= 0 - expandu && ui < nbUi + expandu && vi >= 0 - expandv && vi < nbVi + expandv); - PX_ASSERT(ui+step_ui >= 0 - expandu && ui+step_ui < nbUi + expandu && vi+step_vi >= 0 - expandv && vi+step_vi < nbVi + expandv); + PX_ASSERT(ui + step_ui >= 0 - expandu && ui + step_ui < nbUi + expandu && vi + step_vi >= 0 - expandv && vi + step_vi < nbVi + expandv); // handle overlap in overlapCallback - if(overlap) + if (overlap) { - if(!overlapTraceSegment.initialized()) + if (!overlapTraceSegment.initialized()) { // initial overlap and setup - if(!overlapTraceSegment.init(ui,vi,nbVi,step_ui,step_vi,aCallback)) + if (!overlapTraceSegment.init(ui, vi, nbVi, step_ui, step_vi, aCallback)) return; } else { // overlap step - if(!overlapTraceSegment.step(ui,vi)) + if (!overlapTraceSegment.step(ui, vi)) return; } } else { - const PxU32 colIndex0 = PxU32(nbVi * ui + vi); - const PxU32 colIndex1 = PxU32(nbVi * (ui + step_ui) + vi); - const PxReal h[4] = { // h[0]=h00, h[1]=h01, h[2]=h10, h[3]=h11 - oriented relative to step_uv - hf.getHeight(colIndex0) * heightScale, hf.getHeight(colIndex0 + step_vi) * heightScale, - hf.getHeight(colIndex1) * heightScale, hf.getHeight(colIndex1 + step_vi) * heightScale }; - - PxF32 minH = PxMin(PxMin(h[0], h[1]), PxMin(h[2], h[3])); - PxF32 maxH = PxMax(PxMax(h[0], h[1]), PxMax(h[2], h[3])); - - // how much space in h have we covered from previous to current u or v intercept - PxF32 hLineCellRangeMin = PxMin(hLinePrev, hLineNext); - PxF32 hLineCellRangeMax = PxMax(hLinePrev, hLineNext); - - // do a quick overlap test in h, this should be rejecting the vast majority of tests - if(!(hLineCellRangeMin-hEpsilon > maxH || hLineCellRangeMax+hEpsilon < minH) || - (useUnderFaceCallback && hLineCellRangeMax < maxH)) - { - // arrange h so that h00 corresponds to min(uif, uif+step_uif) h10 to max et c. - // this is only needed for backface culling to work so we know the proper winding order without branches - // uflip is 0 or 2, vflip is 0 or 1 (corresponding to positive and negative ui_step and vi_step) - PxF32 h00 = h[0+uflip+vflip]; - PxF32 h01 = h[1+uflip-vflip]; - PxF32 h10 = h[2-uflip+vflip]; - PxF32 h11 = h[3-uflip-vflip]; - - PxF32 minuif = PxMin(uif, uif+step_uif); - PxF32 maxuif = PxMax(uif, uif+step_uif); - PxF32 minvif = PxMin(vif, vif+step_vif); - PxF32 maxvif = PxMax(vif, vif+step_vif); - PxVec3 p00(minuif, h00, minvif); - PxVec3 p01(minuif, h01, maxvif); - PxVec3 p10(maxuif, h10, minvif); - PxVec3 p11(maxuif, h11, maxvif); - - const PxF32 enlargeEpsilon = 0.0001f; - const PxVec3* p00a = &p00, *p01a = &p01, *p10a = &p10, *p11a = &p11; - PxU32 minui = PxU32(PxMin(ui+step_ui, ui)), minvi = PxU32(PxMin(vi+step_vi, vi)); - - // row = x|u, column = z|v - const PxU32 vertIndex = nbVi * minui + minvi; - const PxU32 cellIndex = vertIndex; // this adds a dummy unused cell in the end of each row; was -minui - bool isZVS = hf.isZerothVertexShared(vertIndex); - if(!isZVS) - { - // rotate the pointers for flipped edge cells - p10a = &p00; - p00a = &p01; - p01a = &p11; - p11a = &p10; - } - - // For triangle index computation, see illustration in Gu::HeightField::getTriangleNormal() - // Since row = u, column = v - // for zeroth vert shared the 10 index is the corner of the 0-index triangle, and 01 is 1-index - // if zeroth vertex is not shared, the 00 index is the corner of 0-index triangle - if(!useUnderFaceCallback) + const PxU32 colIndex0 = PxU32(nbVi * ui + vi); + const PxU32 colIndex1 = PxU32(nbVi * (ui + step_ui) + vi); + const PxReal h[4] = { // h[0]=h00, h[1]=h01, h[2]=h10, h[3]=h11 - oriented relative to step_uv + hf.getHeight(colIndex0) * heightScale, hf.getHeight(colIndex0 + step_vi) * heightScale, + hf.getHeight(colIndex1) * heightScale, hf.getHeight(colIndex1 + step_vi) * heightScale }; + + PxF32 minH = PxMin(PxMin(h[0], h[1]), PxMin(h[2], h[3])); + PxF32 maxH = PxMax(PxMax(h[0], h[1]), PxMax(h[2], h[3])); + + // how much space in h have we covered from previous to current u or v intercept + PxF32 hLineCellRangeMin = PxMin(hLinePrev, hLineNext); + PxF32 hLineCellRangeMax = PxMax(hLinePrev, hLineNext); + + // do a quick overlap test in h, this should be rejecting the vast majority of tests + if (!(hLineCellRangeMin - hEpsilon > maxH || hLineCellRangeMax + hEpsilon < minH) || + (useUnderFaceCallback && hLineCellRangeMax < maxH)) { - if(mHeightField->getThicknessFast() > 0.0f) // new in 3.4: flip triangle winding if thickness is positive - Ps::swap<const PxVec3*>(p00a, p11a); - - #define ISHOLE0 (hf.getMaterialIndex0(vertIndex) == PxHeightFieldMaterial::eHOLE) - #define ISHOLE1 (hf.getMaterialIndex1(vertIndex) == PxHeightFieldMaterial::eHOLE) - PxReal triT0 = PX_MAX_REAL, triT1 = PX_MAX_REAL; - bool hit0 = false, hit1 = false; - PxF32 triU0, triV0, triU1, triV1; - if(Gu::intersectRayTriangle(auhP0, duhvNormalized, *p10a, *p00a, *p11a, triT0, triU0, triV0, backfaceCull, enlargeEpsilon) && - triT0 >= 0.0f && triT0 <= duhvLength && !ISHOLE0) - { - hit0 = true; - } else - triT0 = PX_MAX_REAL; - if(Gu::intersectRayTriangle(auhP0, duhvNormalized, *p01a, *p11a, *p00a, triT1, triU1, triV1, backfaceCull, enlargeEpsilon) - && triT1 >= 0.0f && triT1 <= duhvLength && !ISHOLE1) + // arrange h so that h00 corresponds to min(uif, uif+step_uif) h10 to max et c. + // this is only needed for backface culling to work so we know the proper winding order without branches + // uflip is 0 or 2, vflip is 0 or 1 (corresponding to positive and negative ui_step and vi_step) + PxF32 h00 = h[0 + uflip + vflip]; + PxF32 h01 = h[1 + uflip - vflip]; + PxF32 h10 = h[2 - uflip + vflip]; + PxF32 h11 = h[3 - uflip - vflip]; + + PxF32 minuif = PxMin(uif, uif + step_uif); + PxF32 maxuif = PxMax(uif, uif + step_uif); + PxF32 minvif = PxMin(vif, vif + step_vif); + PxF32 maxvif = PxMax(vif, vif + step_vif); + PxVec3 p00(minuif, h00, minvif); + PxVec3 p01(minuif, h01, maxvif); + PxVec3 p10(maxuif, h10, minvif); + PxVec3 p11(maxuif, h11, maxvif); + + const PxF32 enlargeEpsilon = 0.0001f; + const PxVec3* p00a = &p00, *p01a = &p01, *p10a = &p10, *p11a = &p11; + PxU32 minui = PxU32(PxMin(ui + step_ui, ui)), minvi = PxU32(PxMin(vi + step_vi, vi)); + + // row = x|u, column = z|v + const PxU32 vertIndex = nbVi * minui + minvi; + const PxU32 cellIndex = vertIndex; // this adds a dummy unused cell in the end of each row; was -minui + bool isZVS = hf.isZerothVertexShared(vertIndex); + if (!isZVS) { - hit1 = true; - } else - triT1 = PX_MAX_REAL; + // rotate the pointers for flipped edge cells + p10a = &p00; + p00a = &p01; + p01a = &p11; + p11a = &p10; + } - if(hit0 && triT0 <= triT1) + // For triangle index computation, see illustration in Gu::HeightField::getTriangleNormal() + // Since row = u, column = v + // for zeroth vert shared the 10 index is the corner of the 0-index triangle, and 01 is 1-index + // if zeroth vertex is not shared, the 00 index is the corner of 0-index triangle + if (!useUnderFaceCallback) { - const PxVec3 hitPoint((auhP0.x + duhvNormalized.x*triT0) * rowScale, auhP0.y + duhvNormalized.y * triT0, (auhP0.z + duhvNormalized.z*triT0) * columnScale); - if(!aCallback->faceHit(*this, hitPoint, cellIndex*2, triU0, triV0)) - return; - if(hit1) // possible to hit both triangles in a cell with eMESH_MULTIPLE + if (mHeightField->getThicknessFast() > 0.0f) // new in 3.4: flip triangle winding if thickness is positive + Ps::swap<const PxVec3*>(p00a, p11a); + +#define ISHOLE0 (hf.getMaterialIndex0(vertIndex) == PxHeightFieldMaterial::eHOLE) +#define ISHOLE1 (hf.getMaterialIndex1(vertIndex) == PxHeightFieldMaterial::eHOLE) + PxReal triT0 = PX_MAX_REAL, triT1 = PX_MAX_REAL; + bool hit0 = false, hit1 = false; + PxF32 triU0, triV0, triU1, triV1; + if (Gu::intersectRayTriangle(auhP0, duhvNormalized, *p10a, *p00a, *p11a, triT0, triU0, triV0, backfaceCull, enlargeEpsilon) && + triT0 >= 0.0f && triT0 <= duhvLength && !ISHOLE0) + { + hit0 = true; + } + else + triT0 = PX_MAX_REAL; + if (Gu::intersectRayTriangle(auhP0, duhvNormalized, *p01a, *p11a, *p00a, triT1, triU1, triV1, backfaceCull, enlargeEpsilon) + && triT1 >= 0.0f && triT1 <= duhvLength && !ISHOLE1) + { + hit1 = true; + } + else + triT1 = PX_MAX_REAL; + + if (hit0 && triT0 <= triT1) { - PxVec3 hitPoint1((auhP0.x + duhvNormalized.x*triT1) * rowScale, auhP0.y + duhvNormalized.y * triT1, (auhP0.z + duhvNormalized.z*triT1) * columnScale); - if(!aCallback->faceHit(*this, hitPoint1, cellIndex*2 + 1, triU1, triV1)) + const PxVec3 hitPoint((auhP0.x + duhvNormalized.x*triT0) * rowScale, auhP0.y + duhvNormalized.y * triT0, (auhP0.z + duhvNormalized.z*triT0) * columnScale); + if (!aCallback->faceHit(*this, hitPoint, cellIndex * 2, triU0, triV0)) return; + if (hit1) // possible to hit both triangles in a cell with eMESH_MULTIPLE + { + PxVec3 hitPoint1((auhP0.x + duhvNormalized.x*triT1) * rowScale, auhP0.y + duhvNormalized.y * triT1, (auhP0.z + duhvNormalized.z*triT1) * columnScale); + if (!aCallback->faceHit(*this, hitPoint1, cellIndex * 2 + 1, triU1, triV1)) + return; + } } - } - else if(hit1 && triT1 <= triT0) - { - PxVec3 hitPoint((auhP0.x + duhvNormalized.x*triT1) * rowScale, auhP0.y + duhvNormalized.y * triT1, (auhP0.z + duhvNormalized.z*triT1) * columnScale); - if(!aCallback->faceHit(*this, hitPoint, cellIndex*2 + 1, triU1, triV1)) - return; - if(hit0) // possible to hit both triangles in a cell with eMESH_MULTIPLE + else if (hit1 && triT1 <= triT0) { - PxVec3 hitPoint1((auhP0.x + duhvNormalized.x*triT0) * rowScale, auhP0.y + duhvNormalized.y * triT0, (auhP0.z + duhvNormalized.z*triT0) * columnScale); - if(!aCallback->faceHit(*this, hitPoint1, cellIndex*2, triU0, triV0)) + PxVec3 hitPoint((auhP0.x + duhvNormalized.x*triT1) * rowScale, auhP0.y + duhvNormalized.y * triT1, (auhP0.z + duhvNormalized.z*triT1) * columnScale); + if (!aCallback->faceHit(*this, hitPoint, cellIndex * 2 + 1, triU1, triV1)) return; + if (hit0) // possible to hit both triangles in a cell with eMESH_MULTIPLE + { + PxVec3 hitPoint1((auhP0.x + duhvNormalized.x*triT0) * rowScale, auhP0.y + duhvNormalized.y * triT0, (auhP0.z + duhvNormalized.z*triT0) * columnScale); + if (!aCallback->faceHit(*this, hitPoint1, cellIndex * 2, triU0, triV0)) + return; + } } +#undef ISHOLE0 +#undef ISHOLE1 } - #undef ISHOLE0 - #undef ISHOLE1 - } - else - { - // TODO: quite a few optimizations are possible here. edges can be shared, intersectRayTriangle inlined etc - // Go to shape space. Height is already in shape space so we only scale x and z - PxVec3 p00s(p00a->x * rowScale, p00a->y, p00a->z * columnScale); - PxVec3 p01s(p01a->x * rowScale, p01a->y, p01a->z * columnScale); - PxVec3 p10s(p10a->x * rowScale, p10a->y, p10a->z * columnScale); - PxVec3 p11s(p11a->x * rowScale, p11a->y, p11a->z * columnScale); - - PxVec3 triNormals[2] = { (p00s - p10s).cross(p11s - p10s), (p11s - p01s).cross(p00s-p01s) }; - triNormals[0] *= PxRecipSqrt(triNormals[0].magnitudeSquared()); - triNormals[1] *= PxRecipSqrt(triNormals[1].magnitudeSquared()); - // since the heightfield can be mirrored with negative rowScale or columnScale, this assert doesn't hold - //PX_ASSERT(triNormals[0].y >= 0.0f && triNormals[1].y >= 0.0f); - - // at this point we need to compute the edge direction that we crossed - // also since we don't DDA the w we need to find u,v for w-intercept (w refers to diagonal adjusted with isZVS) - PxF32 wnu = isZVS ? -1.0f : 1.0f, wnv = 1.0f; // uv-normal to triangle edge that splits the cell - PxF32 wpu = uif + 0.5f * step_uif, wpv = vif + 0.5f * step_vif; // a point on triangle edge that splits the cell - // note that (wpu, wpv) is on both edges (for isZVS and non-ZVS cases) which is nice - - // we clamp tNext to 1 because we still want to issue callbacks even if we stay in one cell - // note that tNext can potentially be arbitrarily large for a segment contained within a cell - PxF32 tNext = PxMin(PxMin(tu, tv), 1.0f), tPrev = PxMax(last_tu, last_tv); - - // compute uvs corresponding to tPrev, tNext - PxF32 unext = u0 + tNext*du, vnext = v0 + tNext*dv; - PxF32 uprev = u0 + tPrev*du, vprev = v0 + tPrev*dv; - - const PxReal& h00_ = h[0], &h01_ = h[1], &h10_ = h[2]/*, h11_ = h[3]*/; // aliases for step-oriented h - - // (wpu, wpv) is a point on the diagonal - // we compute a dot of ((unext, vnext) - (wpu, wpv), wn) to see on which side of triangle edge we are - // if the dot is positive we need to add 1 to triangle index - PxU32 dotPrevGtz = PxU32(((uprev - wpu) * wnu + (vprev - wpv) * wnv) > 0); - PxU32 dotNextGtz = PxU32(((unext - wpu) * wnu + (vnext - wpv) * wnv) > 0); - PxU32 triIndex0 = cellIndex*2 + dotPrevGtz; - PxU32 triIndex1 = cellIndex*2 + dotNextGtz; - PxU32 isHole0 = PxU32(hf.getMaterialIndex0(vertIndex) == PxHeightFieldMaterial::eHOLE); - PxU32 isHole1 = PxU32(hf.getMaterialIndex1(vertIndex) == PxHeightFieldMaterial::eHOLE); - if(triIndex0 > triIndex1) - shdfnd::swap<PxU32>(isHole0, isHole1); - - // TODO: compute height at u,v inside here, change callback param to PxVec3 - PxVec3 crossedEdge; - if(last_tu > last_tv) // previous intercept was at u, so we use u=const edge - crossedEdge = PxVec3(0.0f, h01_-h00_, step_vif * columnScale); - else // previous intercept at v, use v=const edge - crossedEdge = PxVec3(step_uif * rowScale, h10_-h00_, 0.0f); - - if(!isHole0 && !aCallback->underFaceHit(*this, triNormals[dotPrevGtz], crossedEdge, + else + { + // TODO: quite a few optimizations are possible here. edges can be shared, intersectRayTriangle inlined etc + // Go to shape space. Height is already in shape space so we only scale x and z + PxVec3 p00s(p00a->x * rowScale, p00a->y, p00a->z * columnScale); + PxVec3 p01s(p01a->x * rowScale, p01a->y, p01a->z * columnScale); + PxVec3 p10s(p10a->x * rowScale, p10a->y, p10a->z * columnScale); + PxVec3 p11s(p11a->x * rowScale, p11a->y, p11a->z * columnScale); + + PxVec3 triNormals[2] = { (p00s - p10s).cross(p11s - p10s), (p11s - p01s).cross(p00s - p01s) }; + triNormals[0] *= PxRecipSqrt(triNormals[0].magnitudeSquared()); + triNormals[1] *= PxRecipSqrt(triNormals[1].magnitudeSquared()); + // since the heightfield can be mirrored with negative rowScale or columnScale, this assert doesn't hold + //PX_ASSERT(triNormals[0].y >= 0.0f && triNormals[1].y >= 0.0f); + + // at this point we need to compute the edge direction that we crossed + // also since we don't DDA the w we need to find u,v for w-intercept (w refers to diagonal adjusted with isZVS) + PxF32 wnu = isZVS ? -1.0f : 1.0f, wnv = 1.0f; // uv-normal to triangle edge that splits the cell + PxF32 wpu = uif + 0.5f * step_uif, wpv = vif + 0.5f * step_vif; // a point on triangle edge that splits the cell + // note that (wpu, wpv) is on both edges (for isZVS and non-ZVS cases) which is nice + + // we clamp tNext to 1 because we still want to issue callbacks even if we stay in one cell + // note that tNext can potentially be arbitrarily large for a segment contained within a cell + PxF32 tNext = PxMin(PxMin(tu, tv), 1.0f), tPrev = PxMax(last_tu, last_tv); + + // compute uvs corresponding to tPrev, tNext + PxF32 unext = u0 + tNext*du, vnext = v0 + tNext*dv; + PxF32 uprev = u0 + tPrev*du, vprev = v0 + tPrev*dv; + + const PxReal& h00_ = h[0], &h01_ = h[1], &h10_ = h[2]/*, h11_ = h[3]*/; // aliases for step-oriented h + + // (wpu, wpv) is a point on the diagonal + // we compute a dot of ((unext, vnext) - (wpu, wpv), wn) to see on which side of triangle edge we are + // if the dot is positive we need to add 1 to triangle index + PxU32 dotPrevGtz = PxU32(((uprev - wpu) * wnu + (vprev - wpv) * wnv) > 0); + PxU32 dotNextGtz = PxU32(((unext - wpu) * wnu + (vnext - wpv) * wnv) > 0); + PxU32 triIndex0 = cellIndex * 2 + dotPrevGtz; + PxU32 triIndex1 = cellIndex * 2 + dotNextGtz; + PxU32 isHole0 = PxU32(hf.getMaterialIndex0(vertIndex) == PxHeightFieldMaterial::eHOLE); + PxU32 isHole1 = PxU32(hf.getMaterialIndex1(vertIndex) == PxHeightFieldMaterial::eHOLE); + if (triIndex0 > triIndex1) + shdfnd::swap<PxU32>(isHole0, isHole1); + + // TODO: compute height at u,v inside here, change callback param to PxVec3 + PxVec3 crossedEdge; + if (last_tu > last_tv) // previous intercept was at u, so we use u=const edge + crossedEdge = PxVec3(0.0f, h01_ - h00_, step_vif * columnScale); + else // previous intercept at v, use v=const edge + crossedEdge = PxVec3(step_uif * rowScale, h10_ - h00_, 0.0f); + + if (!isHole0 && !aCallback->underFaceHit(*this, triNormals[dotPrevGtz], crossedEdge, uprev * rowScale, vprev * columnScale, COMPUTE_H_FROM_T(tPrev), triIndex0)) - return; + return; - if(triIndex1 != triIndex0 && !isHole1) // if triIndex0 != triIndex1 that means we cross the triangle edge - { - // Need to compute tw, the t for ray intersecting the diagonal within the current cell - // dot((wnu, wnv), (u0+tw*du, v0+tw*dv)-(wpu, wpv)) = 0 - // wnu*(u0+tw*du-wpu) + wnv*(v0+tw*dv-wpv) = 0 - // wnu*u0+wnv*v0-wnu*wpu-wnv*wpv + tw*(du*wnu + dv*wnv) = 0 - const PxF32 denom = du*wnu + dv*wnv; - if(PxAbs(denom) > 1e-6f) + if (triIndex1 != triIndex0 && !isHole1) // if triIndex0 != triIndex1 that means we cross the triangle edge { - const PxF32 tw = (wnu*(wpu-u0)+wnv*(wpv-v0)) / denom; - if(!aCallback->underFaceHit(*this, triNormals[dotNextGtz], p10s-p01s, - (u0+tw*du) * rowScale, (v0+tw*dv) * columnScale, COMPUTE_H_FROM_T(tw), triIndex1)) - return; + // Need to compute tw, the t for ray intersecting the diagonal within the current cell + // dot((wnu, wnv), (u0+tw*du, v0+tw*dv)-(wpu, wpv)) = 0 + // wnu*(u0+tw*du-wpu) + wnv*(v0+tw*dv-wpv) = 0 + // wnu*u0+wnv*v0-wnu*wpu-wnv*wpv + tw*(du*wnu + dv*wnv) = 0 + const PxF32 denom = du*wnu + dv*wnv; + if (PxAbs(denom) > 1e-6f) + { + const PxF32 tw = (wnu*(wpu - u0) + wnv*(wpv - v0)) / denom; + if (!aCallback->underFaceHit(*this, triNormals[dotNextGtz], p10s - p01s, + (u0 + tw*du) * rowScale, (v0 + tw*dv) * columnScale, COMPUTE_H_FROM_T(tw), triIndex1)) + return; + } } } } } - } - if(tu < tv) + if (tu < tv) { last_tu = tu; ui += step_ui; // AP: very rare condition, wasn't able to repro but we need this if anyway (DE6565) - if(ui+step_ui< (0 - expandu) || ui+step_ui>=(nbUi + expandu)) // should hold true for ui without step from previous iteration + if (ui + step_ui< (0 - expandu) || ui + step_ui >= (nbUi + expandu)) // should hold true for ui without step from previous iteration break; uif += step_uif; tu += step_tu; @@ -890,7 +983,7 @@ namespace Gu last_tv = tv; vi += step_vi; // AP: very rare condition, wasn't able to repro but we need this if anyway (DE6565) - if(vi+step_vi< (0 - expandv) || vi+step_vi>=(nbVi + expandv)) // should hold true for vi without step from previous iteration + if (vi + step_vi< (0 - expandv) || vi + step_vi >= (nbVi + expandv)) // should hold true for vi without step from previous iteration break; vif += step_vif; tv += step_tv; @@ -900,631 +993,10 @@ namespace Gu // since min(tu,tv) is the END of the active interval we need to check if PREVIOUS min(tu,tv) was past interval end // since we update tMinUV in the beginning of the loop, at this point it stores the min(last tu,last tv) while (tMinUV < tEnd); - #undef COMPUTE_H_FROM_T - } - - PX_FORCE_INLINE PxVec3 hf2shapen(const PxVec3& v) const - { - return PxVec3(v.x * mOneOverRowScale, v.y * mOneOverHeightScale, v.z * mOneOverColumnScale); - } - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 shape2hfp(const PxVec3& v) const - { - return PxVec3(v.x * mOneOverRowScale, v.y * mOneOverHeightScale, v.z * mOneOverColumnScale); +#undef COMPUTE_H_FROM_T } - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 hf2shapep(const PxVec3& v) const - { - return PxVec3(v.x * mHfGeom->rowScale, v.y * mHfGeom->heightScale, v.z * mHfGeom->columnScale); - } - - PX_INLINE PxVec3 hf2worldp(const PxTransform& pose, const PxVec3& v) const - { - const PxVec3 s = hf2shapep(v); - return pose.transform(s); - } - - PX_INLINE PxVec3 hf2worldn(const PxTransform& pose, const PxVec3& v) const - { - const PxVec3 s = hf2shapen(v); - return pose.q.rotate(s); - } - -#ifdef REMOVED -bool clipShapeNormalToEdgeVoronoi(PxVec3& normal, PxU32 edgeIndex, PxU32 cell, PxU32 row, PxU32 column) const -{ -// const PxU32 cell = edgeIndex / 3; - PX_ASSERT(cell == edgeIndex / 3); -// const PxU32 row = cell / mHeightField.getNbColumnsFast(); -// const PxU32 column = cell % mHeightField.getNbColumnsFast(); - PX_ASSERT(row == cell / mHeightField.getNbColumnsFast()); - PX_ASSERT(column == cell % mHeightField.getNbColumnsFast()); - - //PxcHeightFieldFormat format = getFormatFast(); -// PxHeightFieldFormat::Enum format = mHeightField.getFormatFast(); - - bool result = false; - -// switch (edgeIndex % 3) - switch (edgeIndex - cell*3) - { - case 0: - if (row > 0) - { - //const PxcHeightFieldSample& sample = getSample(cell - getNbColumnsFast()); - //if(isZerothVertexShared(cell - getNbColumnsFast())) - if(mHeightField.isZerothVertexShared(cell - mHeightField.getNbColumnsFast())) - { - //if (getMaterialIndex0(cell - getNbColumnsFast()) != getHoleMaterial()) - if (mHeightField.getMaterialIndex0(cell - mHeightField.getNbColumnsFast()) != PxHeightFieldMaterial::eHOLE) - { - // <------ COL - // +----+ 0 R - // |1 / /^ O - // | / / # W - // | / / # | - // |/ / 0 # | - // + 2<===1 | - // | - // | - // | - // | - // | - // | - // V - // - //PxReal h0 = getHeightScale() * getHeight(cell - getNbColumnsFast()); - //PxReal h1 = getHeightScale() * getHeight(cell); - //PxReal h2 = getHeightScale() * getHeight(cell + 1); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell - mHeightField.getNbColumnsFast()); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell + 1); - //PxVec3 eC; - //eC.set(0, h2-h1, getColumnScale()); - const PxVec3 eC(0, h2-h1, mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(-getRowScale(), h0-h1, 0); - const PxVec3 eR(-mHfGeom.rowScale, h0-h1, 0); - const PxVec3 e = eR - eC * eC.dot(eR) / eC.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - else - { - //if (getMaterialIndex1(cell - getNbColumnsFast()) != getHoleMaterial()) - if (mHeightField.getMaterialIndex1(cell - mHeightField.getNbColumnsFast()) != PxHeightFieldMaterial::eHOLE) - { - // <------ COL - // 0 +----+ R - // ^\ \ 0 | O - // # \ \ | W - // # \ \ | | - // # 1 \ \| | - // 1===>2 + | - // | - // | - // | - // | - // | - // | - // V - // - //PxReal h0 = getHeightScale() * getHeight(cell - getNbColumnsFast() + 1); - //PxReal h1 = getHeightScale() * getHeight(cell + 1); - //PxReal h2 = getHeightScale() * getHeight(cell); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell - mHeightField.getNbColumnsFast() + 1); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + 1); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell); - //PxVec3 eC; - //eC.set(0, h2-h1, -getColumnScale()); - const PxVec3 eC(0, h2-h1, -mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(-getRowScale(), h0-h1, 0); - const PxVec3 eR(-mHfGeom.rowScale, h0-h1, 0); - const PxVec3 e = eR - eC * eC.dot(eR) / eC.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - } - //if (row < getNbRowsFast() - 1) - if (row < mHeightField.getNbRowsFast() - 1) - { - //const PxcHeightFieldSample& sample = getSample(cell); - //if(isZerothVertexShared(cell)) - if(mHeightField.isZerothVertexShared(cell)) - { - //if (getMaterialIndex1(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex1(cell) != PxHeightFieldMaterial::eHOLE) - { - // <------ COL - // R - // O - // W - // | - // | - // | - // 0===>2 0 | - // # 1 / /| | - // # / / | | - // # / / | | - // V/ / 0 | | - // 1 +----+ | - // V - // - //PxReal h0 = getHeightScale() * getHeight(cell + 1); - //PxReal h1 = getHeightScale() * getHeight(cell + getNbColumnsFast() + 1); - //PxReal h2 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell + 1); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast() + 1); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - //PxVec3 eC; - //eC.set(0, h2-h0, -getColumnScale()); - const PxVec3 eC(0, h2-h0, -mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(getRowScale(), h1-h0, 0); - const PxVec3 eR(mHfGeom.rowScale, h1-h0, 0); - const PxVec3 e = eR - eC * eC.dot(eR) / eC.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - else - { - //if (getMaterialIndex0(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex0(cell) != PxHeightFieldMaterial::eHOLE) - { - // <------ COL - // R - // O - // W - // | - // | - // | - // + 2<===0 | - // |\ \ 0 # | - // | \ \ # | - // | \ \ # | - // |1 \ \V | - // +----+ 1 | - // V - // - //PxReal h0 = getHeightScale() * getHeight(cell); - //PxReal h1 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - //PxReal h2 = getHeightScale() * getHeight(cell + 1); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell + 1); - //PxVec3 eC; - //eC.set(0, h2-h0, getColumnScale()); - const PxVec3 eC(0, h2-h0, mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(getRowScale(), h1-h0, 0); - const PxVec3 eR(mHfGeom.rowScale, h1-h0, 0); - const PxVec3 e = eR - eC * eC.dot(eR) / eC.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } } - } - } - break; - case 1: - //if ((row < getNbRowsFast() - 1) && (column < getNbColumnsFast() - 1)) - if ((row < mHeightField.getNbRowsFast() - 1) && (column < mHeightField.getNbColumnsFast() - 1)) - { - //const PxcHeightFieldSample& sample = getSample(cell); - - //PxReal h0 = getHeightScale() * getHeight(cell); - //PxReal h1 = getHeightScale() * getHeight(cell + 1); - //PxReal h2 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - //PxReal h3 = getHeightScale() * getHeight(cell + getNbColumnsFast() + 1); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + 1); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - const PxReal h3 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast() + 1); - - //if (isZerothVertexShared(cell)) - if (mHeightField.isZerothVertexShared(cell)) - { - // <------ COL - // 1<---0 R - // |1 /| O - // | / | W - // | / | | - // |V 0 V | - // 3----2 | - // V - // - //PxVec3 eD; - //eD.set(getRowScale(), h3-h0, getColumnScale()); - const PxVec3 eD(mHfGeom.rowScale, h3-h0, mHfGeom.columnScale); - const PxReal DD = eD.magnitudeSquared(); - - //if (getMaterialIndex0(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex0(cell) != PxHeightFieldMaterial::eHOLE) - { - //PxVec3 eR; - //eR.set(getRowScale(), h2-h0, 0); - const PxVec3 eR(mHfGeom.rowScale, h2-h0, 0); - const PxVec3 e = eR - eD * eD.dot(eR) / DD; - const PxReal proj = e.dot(normal); - if (proj > 0) { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - - //if (getMaterialIndex1(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex1(cell) != PxHeightFieldMaterial::eHOLE) - { - //PxVec3 eC; - //eC.set(0, h1-h0, getColumnScale()); - const PxVec3 eC(0, h1-h0, mHfGeom.columnScale); - const PxVec3 e = eC - eD * eD.dot(eC) / DD; - const PxReal proj = e.dot(normal); - if (proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - } - else - { - // <------ COL - // 1--->0 R - // |\ 0 | O - // | \ | W - // | \ | | - // V 1 V| | - // 3----2 | - // V - // - //PxVec3 eD; - //eD.set(getRowScale(), h2-h1, -getColumnScale()); - const PxVec3 eD(mHfGeom.rowScale, h2-h1, -mHfGeom.columnScale); - const PxReal DD = eD.magnitudeSquared(); - - //if (getMaterialIndex0(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex0(cell) != PxHeightFieldMaterial::eHOLE) - { - //PxVec3 eC; - //eC.set(0, h0-h1, -getColumnScale()); - const PxVec3 eC(0, h0-h1, -mHfGeom.columnScale); - const PxVec3 e = eC - eD * eD.dot(eC) / DD; - const PxReal proj = e.dot(normal); - if (proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - - //if (getMaterialIndex1(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex1(cell) != PxHeightFieldMaterial::eHOLE) - { - //PxVec3 eR; - //eR.set(getRowScale(), h3-h1, 0); - const PxVec3 eR(mHfGeom.rowScale, h3-h1, 0); - const PxVec3 e = eR - eD * eD.dot(eR) / DD; - const PxReal proj = e.dot(normal); - if (proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - } - } - break; - case 2: - if (column > 0) - { - //const PxcHeightFieldSample& sample = getSample(cell - 1); - - //if(isZerothVertexShared(cell - 1)) - if(mHeightField.isZerothVertexShared(cell - 1)) - { - //if (getMaterialIndex1(cell - 1) != getHoleMaterial()) - if (mHeightField.getMaterialIndex1(cell - 1) != PxHeightFieldMaterial::eHOLE) - { - // <-------------- COL - // 1===>0 + R - // + 1 / /| O - // + / / | W - // + / / | | - // V/ / 0 | | - // 2 +----+ V - // - //PxReal h0 = getHeightScale() * getHeight(cell - 1); - //PxReal h1 = getHeightScale() * getHeight(cell); - //PxReal h2 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell - 1); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - //PxVec3 eC; - //eC.set(0,h0-h1,-getColumnScale()); - const PxVec3 eC(0,h0-h1,-mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(getRowScale(),h2-h1,0); - const PxVec3 eR(mHfGeom.rowScale,h2-h1,0); - const PxVec3 e = eC - eR * eR.dot(eC) / eR.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - else - { - //if (getMaterialIndex1(cell - 1) != getHoleMaterial()) - if (mHeightField.getMaterialIndex1(cell - 1) != PxHeightFieldMaterial::eHOLE) - { - // <-------------- COL - // 2 +----+ R - // ^\ \ 0 | O - // + \ \ | W - // + \ \ | | - // + 1 \ \| | - // 1===>0 + V - // - //PxReal h0 = getHeightScale() * getHeight(cell - 1 + getNbColumnsFast()); - //PxReal h1 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - //PxReal h2 = getHeightScale() * getHeight(cell); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell - 1 + mHeightField.getNbColumnsFast()); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell); - //PxVec3 eC; - //eC.set(0,h0-h1,-getColumnScale()); - const PxVec3 eC(0,h0-h1,-mHfGeom.columnScale); - //PxVec3 eR; - //eC.set(-getRowScale(),h2-h1,0); - //eC.set(-mHfGeom.rowScale,h2-h1,0); - const PxVec3 eR(-mHfGeom.rowScale,h2-h1,0); // PT: I assume this was eR, not eC !!!!! - const PxVec3 e = eC - eR * eR.dot(eC) / eR.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - } - //if (column < getNbColumnsFast() - 1) - if (column < mHeightField.getNbColumnsFast() - 1) - { - //const PxcHeightFieldSample& sample = getSample(cell); - - //if (isZerothVertexShared(cell)) - if (mHeightField.isZerothVertexShared(cell)) - { - //if (getMaterialIndex0(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex0(cell) != PxHeightFieldMaterial::eHOLE) - { - // <-------------- COL - // +----+ 2 R - // | 1 / /^ O - // | / / + W - // | / / + | - // |/ / 0 + | - // + 1<===0 V - // - //PxReal h0 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - //PxReal h1 = getHeightScale() * getHeight(cell + getNbColumnsFast() + 1); - //PxReal h2 = getHeightScale() * getHeight(cell); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast() + 1); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell); - //PxVec3 eC; - //eC.set(0,h1-h0,getColumnScale()); - const PxVec3 eC(0,h1-h0,mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(-getRowScale(),h2-h0,0); - const PxVec3 eR(-mHfGeom.rowScale,h2-h0,0); - const PxVec3 e = eC - eR * eR.dot(eC) / eR.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) - { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - else - { - //if (getMaterialIndex0(cell) != getHoleMaterial()) - if (mHeightField.getMaterialIndex0(cell) != PxHeightFieldMaterial::eHOLE) - { - // <-------------- COL - // + 1<===0 R - // |\ \ 0 + O - // | \ \ + W - // | \ \ + | - // | 1 \ \V | - // +----+ 2 V - // - //PxReal h0 = getHeightScale() * getHeight(cell); - //PxReal h1 = getHeightScale() * getHeight(cell + 1); - //PxReal h2 = getHeightScale() * getHeight(cell + getNbColumnsFast()); - const PxReal h0 = mHfGeom.heightScale * mHeightField.getHeight(cell); - const PxReal h1 = mHfGeom.heightScale * mHeightField.getHeight(cell + 1); - const PxReal h2 = mHfGeom.heightScale * mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); - //PxVec3 eC; - //eC.set(0,h1-h0,getColumnScale()); - const PxVec3 eC(0,h1-h0,mHfGeom.columnScale); - //PxVec3 eR; - //eR.set(getRowScale(),h2-h0,0); - const PxVec3 eR(mHfGeom.rowScale,h2-h0,0); - const PxVec3 e = eC - eR * eR.dot(eC) / eR.magnitudeSquared(); - const PxReal s = normal.dot(e); - if (s > 0) { - normal -= e * s / e.magnitudeSquared(); - result = true; - } - } - } - } - break; - } - return result; -} -#endif - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ptchernev TODO: this is wrong it only clips in x and z - bool clipShapeNormalToVertexVoronoi(PxVec3& normal, PxU32 vertexIndex, PxU32 row, PxU32 column) const - { - //PxU32 row = vertexIndex / getNbColumnsFast(); - //PxU32 column = vertexIndex % getNbColumnsFast(); -// const PxU32 row = vertexIndex / mHeightField.getNbColumnsFast(); -// const PxU32 column = vertexIndex % mHeightField.getNbColumnsFast(); - PX_ASSERT(row == vertexIndex / mHeightField->getNbColumnsFast()); - PX_ASSERT(column == vertexIndex % mHeightField->getNbColumnsFast()); - - //PxReal h0 = getHeight(vertexIndex); - const PxReal h0 = mHeightField->getHeight(vertexIndex); - - bool result = false; - - if(row > 0) - { - // - row - //PxVec3 e; - //e.set(-getRowScale(), getHeightScale() * (getHeight(vertexIndex - getNbColumnsFast()) - h0), 0); - const PxVec3 e(-mHfGeom->rowScale, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex - mHeightField->getNbColumnsFast()) - h0), 0); - const PxReal proj = e.dot(normal); - if(proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - - //if(row < getNbRowsFast() - 1) - if(row < mHeightField->getNbRowsFast() - 1) - { - // + row - //PxVec3 e; - //e.set(getRowScale(), getHeightScale() * (getHeight(vertexIndex + getNbColumnsFast()) - h0), 0); - const PxVec3 e(mHfGeom->rowScale, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex + mHeightField->getNbColumnsFast()) - h0), 0); - const PxReal proj = e.dot(normal); - if(proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - - if(column > 0) - { - // - column - //PxVec3 e; - //e.set(0, getHeightScale() * (getHeight(vertexIndex - 1) - h0), -getColumnScale()); - const PxVec3 e(0, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex - 1) - h0), -mHfGeom->columnScale); - const PxReal proj = e.dot(normal); - if(proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - - //if(column < getNbColumnsFast() - 1) - if(column < mHeightField->getNbColumnsFast() - 1) - { - // + column - //PxVec3 e; - //e.set(0, getHeightScale() * (getHeight(vertexIndex + 1) - h0), getColumnScale()); - const PxVec3 e(0, mHfGeom->heightScale * (mHeightField->getHeight(vertexIndex + 1) - h0), mHfGeom->columnScale); - const PxReal proj = e.dot(normal); - if(proj > 0) - { - normal -= e * proj / e.magnitudeSquared(); - result = true; - } - } - - return result; - } - -PxVec3 getEdgeDirection(PxU32 edgeIndex, PxU32 cell) const -{ -// const PxU32 cell = edgeIndex / 3; - PX_ASSERT(cell == edgeIndex / 3); -// switch (edgeIndex % 3) - switch (edgeIndex - cell*3) - { - case 0: - { -// const PxReal y0 = mHeightField.getHeight(cell); -// const PxReal y1 = mHeightField.getHeight(cell + 1); -// return PxVec3(0.0f, mHfGeom.heightScale * (y1 - y0), mHfGeom.columnScale); - const PxI32 y0 = mHeightField->getSample(cell).height; - const PxI32 y1 = mHeightField->getSample(cell + 1).height; - return PxVec3(0.0f, mHfGeom->heightScale * PxReal(y1 - y0), mHfGeom->columnScale); - } - case 1: - if(mHeightField->isZerothVertexShared(cell)) - { -// const PxReal y0 = mHeightField.getHeight(cell); -// const PxReal y3 = mHeightField.getHeight(cell + mHeightField.getNbColumnsFast() + 1); -// return PxVec3(mHfGeom.rowScale, mHfGeom.heightScale * (y3 - y0), mHfGeom.columnScale); - const PxI32 y0 = mHeightField->getSample(cell).height; - const PxI32 y3 = mHeightField->getSample(cell + mHeightField->getNbColumnsFast() + 1).height; - return PxVec3(mHfGeom->rowScale, mHfGeom->heightScale * PxReal(y3 - y0), mHfGeom->columnScale); - } - else - { -// const PxReal y1 = mHeightField.getHeight(cell + 1); -// const PxReal y2 = mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); -// return PxVec3(mHfGeom.rowScale, mHfGeom.heightScale * (y2 - y1), -mHfGeom.columnScale); - const PxI32 y1 = mHeightField->getSample(cell + 1).height; - const PxI32 y2 = mHeightField->getSample(cell + mHeightField->getNbColumnsFast()).height; - return PxVec3(mHfGeom->rowScale, mHfGeom->heightScale * PxReal(y2 - y1), -mHfGeom->columnScale); - } - case 2: - { -// const PxReal y0 = mHeightField.getHeight(cell); -// const PxReal y2 = mHeightField.getHeight(cell + mHeightField.getNbColumnsFast()); -// return PxVec3(mHfGeom.rowScale, mHfGeom.heightScale * (y2 - y0), 0.0f); - const PxI32 y0 = mHeightField->getSample(cell).height; - const PxI32 y2 = mHeightField->getSample(cell + mHeightField->getNbColumnsFast()).height; - return PxVec3(mHfGeom->rowScale, mHfGeom->heightScale * PxReal(y2 - y0), 0.0f); - } - } - return PxVec3(0); -} - -/*PX_FORCE_INLINE PxVec3 getEdgeDirection(PxU32 edgeIndex) const -{ - const PxU32 cell = edgeIndex / 3; - return getEdgeDirection(edgeIndex, cell); -}*/ - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - }; - } // namespace Gu } diff --git a/PhysX_3.4/Source/GeomUtils/src/hf/GuOverlapTestsHF.cpp b/PhysX_3.4/Source/GeomUtils/src/hf/GuOverlapTestsHF.cpp index 8c3acfce..14360ca7 100644 --- a/PhysX_3.4/Source/GeomUtils/src/hf/GuOverlapTestsHF.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/hf/GuOverlapTestsHF.cpp @@ -345,8 +345,7 @@ namespace Gu { PX_NOCOPY(OverlapHeightfieldTraceSegmentHelper) public: - OverlapHeightfieldTraceSegmentHelper(const HeightFieldUtil& hfUtil) - : mHfUtil(hfUtil) + OverlapHeightfieldTraceSegmentHelper(const HeightFieldTraceUtil& hfUtil) : mHfUtil(hfUtil) { mHfUtil.computeLocalBounds(mLocalBounds); } @@ -357,14 +356,14 @@ namespace Gu } private: - const HeightFieldUtil& mHfUtil; - PxBounds3 mLocalBounds; + const HeightFieldTraceUtil& mHfUtil; + PxBounds3 mLocalBounds; }; } // namespace } -static bool intersectHeightFieldBox(const HeightFieldUtil& hfUtil, const Box& boxInHfShape) +static bool intersectHeightFieldBox(const HeightFieldTraceUtil& hfUtil, const Box& boxInHfShape) { const HeightField& hf = hfUtil.getHeightField(); @@ -489,7 +488,7 @@ static Matrix34 multiplyInverseRTLeft(const Matrix34& left, const Matrix34& righ } static bool intersectHeightFieldConvex( - const HeightFieldUtil& hfUtil, const PxTransform& _hfAbsPose, const ConvexMesh& convexMesh, + const HeightFieldTraceUtil& hfUtil, const PxTransform& _hfAbsPose, const ConvexMesh& convexMesh, const PxTransform& _convexAbsPose, const PxMeshScale& convexMeshScaling) { const Matrix34 hfAbsPose34(_hfAbsPose); @@ -699,7 +698,7 @@ bool Gu::checkOverlapAABB_heightFieldGeom(const PxGeometry& geom, const PxTransf box.getExtents(), invAbsPose.m); - HeightFieldUtil hfUtil(hfGeom); + HeightFieldTraceUtil hfUtil(hfGeom); return intersectHeightFieldBox(hfUtil, boxInHfShape); } @@ -747,7 +746,7 @@ bool GeomOverlapCallback_BoxHeightfield(GU_OVERLAP_FUNC_PARAMS) Box box; buildFrom(box, boxShape2HfShape.p, boxGeom.halfExtents, boxShape2HfShape.q); - HeightFieldUtil hfUtil(hfGeom); + HeightFieldTraceUtil hfUtil(hfGeom); return intersectHeightFieldBox(hfUtil, box); } @@ -763,6 +762,6 @@ bool GeomOverlapCallback_ConvexHeightfield(GU_OVERLAP_FUNC_PARAMS) ConvexMesh* cm = static_cast<ConvexMesh*>(convexGeom.convexMesh); - HeightFieldUtil hfUtil(hfGeom); + HeightFieldTraceUtil hfUtil(hfGeom); return intersectHeightFieldConvex(hfUtil, pose1, *cm, pose0, convexGeom.scale); } diff --git a/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp b/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp index 33eb7c52..ccaa0d4c 100644 --- a/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/hf/GuSweepsHF.cpp @@ -56,7 +56,7 @@ class HeightFieldTraceSegmentSweepHelper { PX_NOCOPY(HeightFieldTraceSegmentSweepHelper) public: - HeightFieldTraceSegmentSweepHelper(const HeightFieldUtil& hfUtil, const PxVec3& aabbExtentHfLocalSpace) + HeightFieldTraceSegmentSweepHelper(const HeightFieldTraceUtil& hfUtil, const PxVec3& aabbExtentHfLocalSpace) : mHfUtil(hfUtil), mOverlapObjectExtent(aabbExtentHfLocalSpace) { mHfUtil.computeLocalBounds(mLocalBounds); @@ -72,9 +72,9 @@ public: } private: - const HeightFieldUtil& mHfUtil; - const PxVec3& mOverlapObjectExtent; - PxBounds3 mLocalBounds; + const HeightFieldTraceUtil& mHfUtil; + const PxVec3& mOverlapObjectExtent; + PxBounds3 mLocalBounds; }; /////////////////////////////////////////////////////////////////////////////// @@ -237,7 +237,7 @@ bool sweepCapsule_HeightFieldGeom(GU_CAPSULE_SWEEP_FUNC_PARAMS) const PxVec3 capsuleAABBExtents = capsuleBox.computeAABBExtent(); - const HeightFieldUtil hfUtil(hfGeom); + const HeightFieldTraceUtil hfUtil(hfGeom); CapsuleTraceSegmentReport myReport(hfUtil, hitFlags, inflatedCapsule, unitDir, sweepHit, pose, distance); sweepHit.distance = PX_MAX_F32; @@ -385,7 +385,7 @@ bool sweepConvex_HeightFieldGeom(GU_CONVEX_SWEEP_FUNC_PARAMS) PX_ASSERT(!convexMesh->getLocalBoundsFast().isEmpty()); const PxBounds3 hullAABBLocalSpace = convexMesh->getLocalBoundsFast().transformFast(convexScaling.getVertex2ShapeSkew()); - const HeightFieldUtil hfUtil(hfGeom); + const HeightFieldTraceUtil hfUtil(hfGeom); ConvexTraceSegmentReport entityReport( hfUtil, convexMesh->getHull(), convexGeom.scale, convexPose, pose, -unitDir, distance, hitFlags, inflation); @@ -589,7 +589,7 @@ bool sweepBox_HeightFieldGeom(GU_BOX_SWEEP_FUNC_PARAMS) sweepHit.distance = PX_MAX_F32; - const HeightFieldUtil hfUtil(hfGeom); + const HeightFieldTraceUtil hfUtil(hfGeom); BoxTraceSegmentReport myReport(hfUtil, hitFlags, WorldToBoxV, pose, boxV, localMotion, sweepHit, inflation); // need hf local space stuff diff --git a/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.cpp index 59775508..26b1fe1f 100644 --- a/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.cpp @@ -214,16 +214,16 @@ void Gu::TriangleMesh::release() } #if PX_ENABLE_DYNAMIC_MESH_RTREE -PxVec3 * Gu::TriangleMesh::getVerticesForModification() +PxVec3* Gu::TriangleMesh::getVerticesForModification() { - Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxTriangleMesh::getVerticesForModification() is only supported for meshes with PxMeshMidPhase::eBVHDynamic."); + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxTriangleMesh::getVerticesForModification() is only supported for meshes with PxMeshMidPhase::eBVH33."); return NULL; } PxBounds3 Gu::TriangleMesh::refitBVH() { - Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxTriangleMesh::refitBVH() is only supported for meshes with PxMeshMidPhase::eBVHDynamic."); + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxTriangleMesh::refitBVH() is only supported for meshes with PxMeshMidPhase::eBVH33."); return PxBounds3(mAABB.getMin(), mAABB.getMax()); } diff --git a/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMeshRTree.cpp b/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMeshRTree.cpp index 61a900d5..d5787c24 100644 --- a/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMeshRTree.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMeshRTree.cpp @@ -135,9 +135,12 @@ PxBounds3 Gu::RTreeTriangleMesh::refitBVH() if ((mRTree.mFlags & RTree::IS_EDGE_SET) == 0) { mRTree.mFlags |= RTree::IS_EDGE_SET; - const PxU32 nbTris = getNbTriangles(); - for (PxU32 i = 0; i < nbTris; i++) - mExtraTrigData[i] |= (Gu::ETD_CONVEX_EDGE_01 | Gu::ETD_CONVEX_EDGE_12 | Gu::ETD_CONVEX_EDGE_20); + if(mExtraTrigData) + { + const PxU32 nbTris = getNbTriangles(); + for (PxU32 i = 0; i < nbTris; i++) + mExtraTrigData[i] |= ETD_CONVEX_EDGE_ALL; + } } mAABB = meshBounds; diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp index 1136d522..8c83b145 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactCapsuleHeightField.cpp @@ -109,9 +109,7 @@ bool Gu::pcmContactCapsuleHeightField(GU_CONTACT_METHOD_ARGS) multiManifold.mNumManifolds = 0; multiManifold.setRelativeTransform(curTransform); - const Gu::HeightField& hf = *static_cast<Gu::HeightField*>(shapeHeight.heightField); - - Gu::HeightFieldUtil hfUtil(shapeHeight, hf); + Gu::HeightFieldUtil hfUtil(shapeHeight); const PxVec3 tmp = getCapsuleHalfHeightVector(transform0, shapeCapsule); diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp index 45bec74c..d7a58bdb 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactConvexHeightField.cpp @@ -129,10 +129,8 @@ bool Gu::PCMContactConvexHeightfield( const PxTransform t0to1 = transform1.transformInv(transform0); - const Gu::HeightField& hf = *static_cast<Gu::HeightField*>(shapeHeightfield.heightField); - Gu::HeightFieldUtil hfUtil(shapeHeightfield, hf); - - //Gu::HeightFieldUtil hfUtil(shapeHeightfield); + Gu::HeightFieldUtil hfUtil(shapeHeightfield); + const Gu::HeightField& hf = hfUtil.getHeightField(); //////////////////// diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereBox.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereBox.cpp index 30fda7de..213833f7 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereBox.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereBox.cpp @@ -115,10 +115,9 @@ bool pcmContactSphereBox(GU_CONTACT_METHOD_ARGS) const FloatV dist = FNeg(FSel(con0, z, FSel(con1, x, y))); //separation so far is just the embedding of the center point; we still have to push out all of the radius. - const Vec3V point = sphereOrigin; const Vec3V normal = transf1.rotate(locNorm); const FloatV penetration = FSub(dist, radius); - + const Vec3V point = V3Sub(sphereOrigin, V3Scale(normal, dist)); Gu::ContactPoint& contact = contactBuffer.contacts[contactBuffer.count++]; V4StoreA(Vec4V_From_Vec3V(normal), &contact.normal.x); diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp index cce99cd4..f642a751 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereHeightField.cpp @@ -116,8 +116,7 @@ bool Gu::pcmContactSphereHeightField(GU_CONTACT_METHOD_ARGS) multiManifold.setRelativeTransform(curTransform); const FloatV replaceBreakingThreshold = FMul(sphereRadius, FLoad(0.001f)); - const Gu::HeightField& hf = *static_cast<Gu::HeightField*>(shapeHeight.heightField); - Gu::HeightFieldUtil hfUtil(shapeHeight, hf); + Gu::HeightFieldUtil hfUtil(shapeHeight); const PxVec3 sphereCenterShape1Space = transform1.transformInv(transform0.p); const Vec3V sphereCenter = V3LoadU(sphereCenterShape1Space); PxReal inflatedRadius = shapeSphere.radius + params.mContactDistance; diff --git a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereSphere.cpp b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereSphere.cpp index c56f4df5..0a18286b 100644 --- a/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereSphere.cpp +++ b/PhysX_3.4/Source/GeomUtils/src/pcm/GuPCMContactSphereSphere.cpp @@ -62,19 +62,18 @@ bool pcmContactSphereSphere(GU_CONTACT_METHOD_ARGS) if(FAllGrtr(FMul(inflatedSum, inflatedSum), distanceSq)) { const FloatV eps = FLoad(0.00001f); - const FloatV nhalf = FLoad(-0.5f); - const FloatV magn = FSqrt(distanceSq); - const BoolV bCon = FIsGrtrOrEq(eps, magn); - const Vec3V normal = V3Sel(bCon, V3UnitX(), V3ScaleInv(_delta, magn)); - const FloatV scale = FMul(FSub(FAdd(r0, magn), r1), nhalf); - const Vec3V point = V3ScaleAdd(normal, scale, p0); - const FloatV dist = FSub(magn, radiusSum); + const FloatV dist = FSqrt(distanceSq); + const BoolV bCon = FIsGrtrOrEq(eps, dist); + const Vec3V normal = V3Sel(bCon, V3UnitX(), V3ScaleInv(_delta, dist)); + + const Vec3V point = V3ScaleAdd(normal, r1, p1); + const FloatV pen = FSub(dist, radiusSum); PX_ASSERT(contactBuffer.count < ContactBuffer::MAX_CONTACTS); Gu::ContactPoint& contact = contactBuffer.contacts[contactBuffer.count++]; V4StoreA(Vec4V_From_Vec3V(normal), &contact.normal.x); V4StoreA(Vec4V_From_Vec3V(point), &contact.point.x); - FStore(dist, &contact.separation); + FStore(pen, &contact.separation); contact.internalFaceIndex1 = PXC_CONTACT_NO_FACE_INDEX; |