aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h')
-rw-r--r--PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h337
1 files changed, 337 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h b/PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h
new file mode 100644
index 00000000..a41889ed
--- /dev/null
+++ b/PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h
@@ -0,0 +1,337 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+
+#ifndef PX_COLLISION_GRBTRIANGLEMESHCOOKING
+#define PX_COLLISION_GRBTRIANGLEMESHCOOKING
+
+#include "GuMeshData.h"
+#include "cooking/PxCooking.h"
+
+namespace physx
+{
+ namespace Gu
+ {
+
+ }
+
+// TODO avoroshilov: remove duplicate definitions
+static const PxU32 BOUNDARY = 0xffffffff;
+static const PxU32 NONCONVEX_FLAG = 0x80000000;
+
+struct EdgeTriLookup
+{
+ PxU32 edgeId0, edgeId1;
+ PxU32 triId;
+
+ bool operator < (const EdgeTriLookup& edge1) const
+ {
+ return edgeId0 < edge1.edgeId0 || (edgeId0 == edge1.edgeId0 && edgeId1 < edge1.edgeId1);
+ }
+
+ bool operator <=(const EdgeTriLookup& edge1) const
+ {
+ return edgeId0 < edge1.edgeId0 || (edgeId0 == edge1.edgeId0 && edgeId1 <= edge1.edgeId1);
+ }
+};
+
+
+static PxU32 binarySearch(const EdgeTriLookup* __restrict data, const PxU32 numElements, const EdgeTriLookup& value)
+{
+ PxU32 left = 0;
+ PxU32 right = numElements;
+
+ while ((right - left) > 1)
+ {
+ PxU32 pos = (left + right) / 2;
+ const EdgeTriLookup& element = data[pos];
+ if (element <= value)
+ {
+ left = pos;
+ }
+ else
+ {
+ right = pos;
+ }
+ }
+
+ return left;
+}
+
+// slightly different behavior from collide2: boundary edges are filtered out
+
+static PxU32 findAdjacent(const PxVec3* triVertices, const PxVec3* triNormals, const uint3* triIndices,
+ PxU32 nbTris, PxU32 i0, PxU32 i1, const PxPlane& plane,
+ EdgeTriLookup* triLookups, PxU32 triangleIndex)
+{
+ PxU32 result = BOUNDARY;
+ PxReal bestCos = -FLT_MAX;
+
+ EdgeTriLookup lookup;
+ lookup.edgeId0 = PxMin(i0, i1);
+ lookup.edgeId1 = PxMax(i0, i1);
+
+ PxU32 startIndex = binarySearch(triLookups, nbTris * 3, lookup);
+
+ for (PxU32 a = startIndex; a > 0; --a)
+ {
+ if (triLookups[a - 1].edgeId0 == lookup.edgeId0 && triLookups[a - 1].edgeId1 == lookup.edgeId1)
+ startIndex = a - 1;
+ else
+ break;
+ }
+
+ for (PxU32 a = startIndex; a < nbTris * 3; ++a)
+ {
+ EdgeTriLookup& edgeTri = triLookups[a];
+
+ if (edgeTri.edgeId0 != lookup.edgeId0 || edgeTri.edgeId1 != lookup.edgeId1)
+ break;
+
+ if (edgeTri.triId == triangleIndex)
+ continue;
+
+ const uint3& triIdx = triIndices[edgeTri.triId];
+ PxU32 vIdx0 = triIdx.x;
+ PxU32 vIdx1 = triIdx.y;
+ PxU32 vIdx2 = triIdx.z;
+
+ PxU32 other = vIdx0 + vIdx1 + vIdx2 - (i0 + i1);
+
+ if (plane.distance(triVertices[other]) >= 0)
+ return NONCONVEX_FLAG | edgeTri.triId;
+
+ PxReal c = plane.n.dot(triNormals[edgeTri.triId]);
+ if (c>bestCos)
+ {
+ bestCos = c;
+ result = edgeTri.triId;
+ }
+
+ }
+
+ return result;
+}
+
+
+static void buildAdjacencies(uint4* triAdjacencies, PxVec3* tempNormalsPerTri_prealloc, const PxVec3* triVertices, const uint3* triIndices, PxU32 nbTris)
+{
+ //PxVec3 * triNormals = new PxVec3[nbTris];
+
+ EdgeTriLookup* edgeLookups = reinterpret_cast<EdgeTriLookup*>(PX_ALLOC(sizeof(EdgeTriLookup) * nbTris * 3, PX_DEBUG_EXP("edgeLookups")));
+
+
+ for (PxU32 i = 0; i < nbTris; i++)
+ {
+ const uint3& triIdx = triIndices[i];
+ PxU32 vIdx0 = triIdx.x;
+ PxU32 vIdx1 = triIdx.y;
+ PxU32 vIdx2 = triIdx.z;
+
+ tempNormalsPerTri_prealloc[i] = (triVertices[vIdx1] - triVertices[vIdx0]).cross(triVertices[vIdx2] - triVertices[vIdx0]).getNormalized();
+
+ edgeLookups[i * 3].edgeId0 = PxMin(vIdx0, vIdx1);
+ edgeLookups[i * 3].edgeId1 = PxMax(vIdx0, vIdx1);
+ edgeLookups[i * 3].triId = i;
+
+ edgeLookups[i * 3 + 1].edgeId0 = PxMin(vIdx1, vIdx2);
+ edgeLookups[i * 3 + 1].edgeId1 = PxMax(vIdx1, vIdx2);
+ edgeLookups[i * 3 + 1].triId = i;
+
+ edgeLookups[i * 3 + 2].edgeId0 = PxMin(vIdx0, vIdx2);
+ edgeLookups[i * 3 + 2].edgeId1 = PxMax(vIdx0, vIdx2);
+ edgeLookups[i * 3 + 2].triId = i;
+ }
+
+ Ps::sort<EdgeTriLookup>(edgeLookups, PxU32(nbTris * 3));
+
+ for (PxU32 i = 0; i < nbTris; i++)
+ {
+ const uint3& triIdx = triIndices[i];
+ PxU32 vIdx0 = triIdx.x;
+ PxU32 vIdx1 = triIdx.y;
+ PxU32 vIdx2 = triIdx.z;
+
+ PxPlane triPlane(triVertices[vIdx0], tempNormalsPerTri_prealloc[i]);
+ uint4 triAdjIdx;
+
+ triAdjIdx.x = findAdjacent(triVertices, tempNormalsPerTri_prealloc, triIndices, nbTris, vIdx0, vIdx1, triPlane, edgeLookups, i);
+ triAdjIdx.y = findAdjacent(triVertices, tempNormalsPerTri_prealloc, triIndices, nbTris, vIdx1, vIdx2, triPlane, edgeLookups, i);
+ triAdjIdx.z = findAdjacent(triVertices, tempNormalsPerTri_prealloc, triIndices, nbTris, vIdx2, vIdx0, triPlane, edgeLookups, i);
+ triAdjIdx.w = 0;
+
+ triAdjacencies[i] = triAdjIdx;
+ }
+
+
+ PX_FREE(edgeLookups);
+}
+
+static bool isEdgeNonconvex(PxU32 adjEdgeIndex)
+{
+ return (adjEdgeIndex != BOUNDARY) && (adjEdgeIndex & NONCONVEX_FLAG);
+}
+
+PX_INLINE void buildVertexConnection_p1(PxU32 * vertValency, PxU32 * vertNeighborStart, PxU32 & tempNumAdjVertices, const float4 * /*triVertices*/, const uint4 * triIndices, const uint4 * triAdjacencies, PxU32 nbVerts, PxU32 nbTris)
+{
+ tempNumAdjVertices = 0;
+ memset(vertValency, 0, nbVerts*sizeof(PxU32));
+
+ // Calculate max num of adjVerts
+ for (PxU32 i = 0; i < nbTris; i++)
+ {
+ uint4 triIdx = triIndices[i];
+ PxU32 vi0 = triIdx.x;
+ PxU32 vi1 = triIdx.y;
+ PxU32 vi2 = triIdx.z;
+
+ uint4 triAdjIdx = triAdjacencies[i];
+
+ PxU32 totalVertsAdded = 0;
+ if (!isEdgeNonconvex(triAdjIdx.x))
+ {
+ ++vertValency[vi0];
+ ++vertValency[vi1];
+ totalVertsAdded += 2;
+ }
+ if (!isEdgeNonconvex(triAdjIdx.y))
+ {
+ ++vertValency[vi1];
+ ++vertValency[vi2];
+ totalVertsAdded += 2;
+ }
+ if (!isEdgeNonconvex(triAdjIdx.z))
+ {
+ ++vertValency[vi2];
+ ++vertValency[vi0];
+ totalVertsAdded += 2;
+ }
+ tempNumAdjVertices += totalVertsAdded;
+ }
+ PxU32 offset = 0;
+ for (PxU32 i = 0; i < nbVerts; i++)
+ {
+ vertNeighborStart[i] = offset;
+ offset += vertValency[i];
+ }
+
+ memset(vertValency, 0, nbVerts*sizeof(PxU32));
+}
+
+PX_INLINE PxU32 buildVertexConnection_p2(PxU32 * vertValency, PxU32 * vertNeighborStart, PxU32 * vertNeighboringPairs_prealloc, PxU32 tempNumAdjVertices, const float4 * /*triVertices*/, const uint4 * triIndices, const uint4 * triAdjacencies, PxU32 /*nbVerts*/, PxU32 nbTris)
+{
+ memset(vertNeighboringPairs_prealloc, 0xff, tempNumAdjVertices*2*sizeof(PxU32));
+
+ PxU32 newAdjVertsNum = 0;
+ for (PxU32 i = 0; i < nbTris; i++)
+ {
+ uint4 triIdx = triIndices[i];
+ PxU32 vi[3] =
+ {
+ triIdx.x,
+ triIdx.y,
+ triIdx.z
+ };
+ uint4 triAdjIdx = triAdjacencies[i];
+ PxU32 ta[3] =
+ {
+ triAdjIdx.x,
+ triAdjIdx.y,
+ triAdjIdx.z
+ };
+
+ for (int tvi = 0; tvi < 3; ++tvi)
+ {
+ PxU32 curIdx = vi[tvi];
+ PxU32 nextIdx = vi[(tvi+1)%3];
+ if (!isEdgeNonconvex(ta[tvi]))
+ {
+ bool matchFound = false;
+ for (PxU32 valIdx = vertNeighborStart[curIdx], valIdxEnd = vertNeighborStart[curIdx] + vertValency[curIdx]; valIdx < valIdxEnd; ++valIdx)
+ {
+ if (vertNeighboringPairs_prealloc[valIdx*2+1] == nextIdx)
+ {
+ matchFound = true;
+ break;
+ }
+ }
+
+ if (!matchFound)
+ {
+ PxU32 curPairIdx;
+
+ curPairIdx = vertNeighborStart[curIdx] + vertValency[curIdx];
+ vertNeighboringPairs_prealloc[curPairIdx*2+0] = curIdx;
+ vertNeighboringPairs_prealloc[curPairIdx*2+1] = nextIdx;
+ ++vertValency[curIdx];
+
+ curPairIdx = vertNeighborStart[nextIdx] + vertValency[nextIdx];
+ vertNeighboringPairs_prealloc[curPairIdx*2+0] = nextIdx;
+ vertNeighboringPairs_prealloc[curPairIdx*2+1] = curIdx;
+ ++vertValency[nextIdx];
+
+ newAdjVertsNum += 2;
+ }
+ }
+ }
+ }
+
+ return newAdjVertsNum;
+}
+
+PX_INLINE void buildVertexConnection_p3(PxU32 * vertNeighbors, PxU32 * /*vertValency*/, PxU32 * vertNeighborStart, PxU32 * vertNeighboringPairs_prealloc, PxU32 tempNumAdjVertices, PxU32 newNumAdjVertices, const float4 * /*triVertices*/, const uint4 * /*triIndices*/, const uint4 * /*triAdjacencies*/, PxU32 /*nbVerts*/, PxU32 /*nbTris*/)
+{
+ PX_UNUSED(newNumAdjVertices);
+ PxU32 prevVertex = 0xFFffFFff;
+ PxU32 writingIndex = 0;
+ for (PxU32 i = 0; i < tempNumAdjVertices; ++i)
+ {
+ PxU32 curPairIdx0 = vertNeighboringPairs_prealloc[i*2+0];
+ if (curPairIdx0 == 0xFFffFFff)
+ {
+ continue;
+ }
+
+ PxU32 curPairIdx1 = vertNeighboringPairs_prealloc[i*2+1];
+ vertNeighbors[writingIndex] = curPairIdx1;
+ if (curPairIdx0 != prevVertex)
+ {
+ vertNeighborStart[curPairIdx0] = writingIndex;
+ }
+ prevVertex = curPairIdx0;
+
+ ++writingIndex;
+ }
+
+ PX_ASSERT(writingIndex == newNumAdjVertices);
+}
+
+} // namespace physx
+
+#endif