diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysXCooking/src/mesh/GrbTriangleMeshCooking.h | |
| download | physx-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.h | 337 |
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 |