aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/common/include/ApexTetrahedralizer.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 /APEX_1.4/common/include/ApexTetrahedralizer.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 'APEX_1.4/common/include/ApexTetrahedralizer.h')
-rw-r--r--APEX_1.4/common/include/ApexTetrahedralizer.h422
1 files changed, 422 insertions, 0 deletions
diff --git a/APEX_1.4/common/include/ApexTetrahedralizer.h b/APEX_1.4/common/include/ApexTetrahedralizer.h
new file mode 100644
index 00000000..77fc67b2
--- /dev/null
+++ b/APEX_1.4/common/include/ApexTetrahedralizer.h
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, 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.
+ */
+
+
+#ifndef APEX_TETRAHEDRALIZER_H
+#define APEX_TETRAHEDRALIZER_H
+
+#include "ApexDefs.h"
+#include "PxBounds3.h"
+
+#include "ApexUsingNamespace.h"
+#include "PsArray.h"
+#include "PsUserAllocated.h"
+
+#define TETRAHEDRALIZER_DEBUG_RENDERING 0
+
+namespace nvidia
+{
+namespace apex
+{
+
+class ApexMeshHash;
+class IProgressListener;
+
+class ApexTetrahedralizer : public UserAllocated
+{
+public:
+ ApexTetrahedralizer(uint32_t subdivision);
+ ~ApexTetrahedralizer();
+
+
+ void registerVertex(const PxVec3& v);
+ void registerTriangle(uint32_t i0, uint32_t i1, uint32_t i2);
+ void endRegistration(IProgressListener* progress);
+
+ uint32_t getNumVertices() const
+ {
+ return mVertices.size();
+ }
+ void getVertices(PxVec3* data);
+ uint32_t getNumIndices() const
+ {
+ return mTetras.size() * 4;
+ }
+ void getIndices(uint32_t* data);
+
+private:
+ struct FullTetrahedron;
+
+ void weldVertices();
+ void delaunayTetrahedralization(IProgressListener* progress);
+ int32_t findSurroundingTetra(uint32_t startTetra, const PxVec3& p) const;
+ float retriangulate(const uint32_t tetraNr, uint32_t vertexNr);
+ uint32_t swapTetrahedra(uint32_t startTet, IProgressListener* progress);
+ bool swapEdge(uint32_t v0, uint32_t v1);
+ bool removeOuterTetrahedra(IProgressListener* progress);
+
+ void updateCircumSphere(FullTetrahedron& tetra) const;
+ bool pointInCircumSphere(FullTetrahedron& tetra, const PxVec3& p) const;
+ bool pointInTetra(const FullTetrahedron& tetra, const PxVec3& p) const;
+
+ float getTetraVolume(const FullTetrahedron& tetra) const;
+ float getTetraVolume(int32_t v0, int32_t v1, int32_t v2, int32_t v3) const;
+ float getTetraQuality(const FullTetrahedron& tetra) const;
+ float getTetraLongestEdge(const FullTetrahedron& tetra) const;
+
+ bool triangleContainsVertexNr(uint32_t* triangle, uint32_t* vertexNumber, uint32_t nbVertices);
+
+ void compressTetrahedra(bool trashNeighbours);
+ void compressVertices();
+
+ inline bool isFarVertex(uint32_t vertNr) const
+ {
+ return mFirstFarVertex <= vertNr && vertNr <= mLastFarVertex;
+ }
+
+ ApexMeshHash* mMeshHash;
+
+ uint32_t mSubdivision;
+
+ PxBounds3 mBound;
+ float mBoundDiagonal;
+
+ struct TetraVertex
+ {
+ inline void init(const PxVec3& pos, uint32_t flags)
+ {
+ this->pos = pos;
+ this->flags = flags;
+ }
+ inline bool isDeleted() const
+ {
+ return flags == (uint32_t)0xdeadf00d;
+ }
+ inline void markDeleted()
+ {
+ flags = 0xdeadf00d;
+ }
+
+ PxVec3 pos;
+ uint32_t flags;
+ };
+ class LessInOneAxis
+ {
+ uint32_t mAxis;
+ public:
+ LessInOneAxis(uint32_t axis) : mAxis(axis) {}
+ bool operator()(const TetraVertex& v1, const TetraVertex& v2) const
+ {
+ return v1.pos[mAxis] < v2.pos[mAxis];
+ }
+ };
+
+ struct TetraEdge
+ {
+ void init(int32_t v0, int32_t v1, int32_t tetra, int neighborNr = -1)
+ {
+ this->tetraNr = (uint32_t)tetra;
+ this->neighborNr = neighborNr;
+ PX_ASSERT(v0 != v1);
+ vNr0 = (uint32_t)PxMin(v0, v1);
+ vNr1 = (uint32_t)PxMax(v0, v1);
+ }
+ PX_INLINE bool operator <(const TetraEdge& e) const
+ {
+ if (vNr0 < e.vNr0)
+ {
+ return true;
+ }
+ if (vNr0 > e.vNr0)
+ {
+ return false;
+ }
+ if (vNr1 < e.vNr1)
+ {
+ return true;
+ }
+ if (vNr1 > e.vNr1)
+ {
+ return false;
+ }
+ return (neighborNr < e.neighborNr);
+ }
+ PX_INLINE bool operator()(const TetraEdge& e1, const TetraEdge& e2) const
+ {
+ return e1 < e2;
+ }
+ bool operator ==(TetraEdge& e) const
+ {
+ return vNr0 == e.vNr0 && vNr1 == e.vNr1;
+ }
+
+ bool allEqual(TetraEdge& e) const
+ {
+ return (vNr0 == e.vNr0) && (vNr1 == e.vNr1) && (neighborNr == e.neighborNr);
+ }
+ uint32_t vNr0, vNr1;
+ uint32_t tetraNr;
+ int32_t neighborNr;
+ };
+
+
+ struct TetraEdgeList
+ {
+ void add(TetraEdge& edge)
+ {
+ mEdges.pushBack(edge);
+ }
+ void insert(uint32_t pos, TetraEdge& edge);
+ uint32_t numEdges()
+ {
+ return mEdges.size();
+ }
+ void sort();
+ int findEdge(int v0, int v1);
+ int findEdgeTetra(int v0, int v1, int tetraNr);
+ TetraEdge& operator[](unsigned i)
+ {
+ return mEdges[i];
+ }
+ const TetraEdge& operator[](unsigned i) const
+ {
+ return mEdges[i];
+ }
+
+ physx::Array<TetraEdge> mEdges;
+ };
+
+
+ struct FullTetrahedron
+ {
+ void init()
+ {
+ vertexNr[0] = vertexNr[1] = vertexNr[2] = vertexNr[3] = -1;
+ neighborNr[0] = neighborNr[1] = neighborNr[2] = neighborNr[3] = -1;
+ center = PxVec3(0.0f);
+ radiusSquared = 0.0f;
+ quality = 0;
+ bCircumSphereDirty = 1;
+ bDeleted = 0;
+ }
+ void set(int32_t v0, int32_t v1, int32_t v2, int32_t v3)
+ {
+ vertexNr[0] = v0;
+ vertexNr[1] = v1;
+ vertexNr[2] = v2;
+ vertexNr[3] = v3;
+ neighborNr[0] = neighborNr[1] = neighborNr[2] = neighborNr[3] = -1;
+ center = PxVec3(0.0f);
+ radiusSquared = 0.0f;
+ quality = 0;
+ bCircumSphereDirty = 1;
+ bDeleted = 0;
+ }
+ bool operator==(const FullTetrahedron& t) const
+ {
+ return
+ (vertexNr[0] == t.vertexNr[0]) &&
+ (vertexNr[1] == t.vertexNr[1]) &&
+ (vertexNr[2] == t.vertexNr[2]) &&
+ (vertexNr[3] == t.vertexNr[3]);
+ }
+
+ bool containsVertex(int32_t nr) const
+ {
+ return (vertexNr[0] == nr || vertexNr[1] == nr || vertexNr[2] == nr || vertexNr[3] == nr);
+ }
+ void replaceVertex(int nr, int newNr)
+ {
+ if (vertexNr[0] == nr)
+ {
+ vertexNr[0] = newNr;
+ }
+ else if (vertexNr[1] == nr)
+ {
+ vertexNr[1] = newNr;
+ }
+ else if (vertexNr[2] == nr)
+ {
+ vertexNr[2] = newNr;
+ }
+ else if (vertexNr[3] == nr)
+ {
+ vertexNr[3] = newNr;
+ }
+ else
+ {
+ PX_ASSERT(0);
+ }
+ }
+ void get2OppositeVertices(int vNr0, int vNr1, int& vNr2, int& vNr3)
+ {
+ int v[4], p = 0;
+ if (vertexNr[0] != vNr0 && vertexNr[0] != vNr1)
+ {
+ v[p++] = vertexNr[0];
+ }
+ if (vertexNr[1] != vNr0 && vertexNr[1] != vNr1)
+ {
+ v[p++] = vertexNr[1];
+ }
+ if (vertexNr[2] != vNr0 && vertexNr[2] != vNr1)
+ {
+ v[p++] = vertexNr[2];
+ }
+ if (vertexNr[3] != vNr0 && vertexNr[3] != vNr1)
+ {
+ v[p++] = vertexNr[3];
+ }
+ PX_ASSERT(p == 2);
+ vNr2 = v[0];
+ vNr3 = v[1];
+ }
+ void get3OppositeVertices(int vNr, int& vNr0, int& vNr1, int& vNr2)
+ {
+ if (vNr == vertexNr[0])
+ {
+ vNr0 = vertexNr[1];
+ vNr1 = vertexNr[2];
+ vNr2 = vertexNr[3];
+ }
+ else if (vNr == vertexNr[1])
+ {
+ vNr0 = vertexNr[2];
+ vNr1 = vertexNr[0];
+ vNr2 = vertexNr[3];
+ }
+ else if (vNr == vertexNr[2])
+ {
+ vNr0 = vertexNr[0];
+ vNr1 = vertexNr[1];
+ vNr2 = vertexNr[3];
+ }
+ else if (vNr == vertexNr[3])
+ {
+ vNr0 = vertexNr[2];
+ vNr1 = vertexNr[1];
+ vNr2 = vertexNr[0];
+ }
+ else
+ {
+ PX_ASSERT(0);
+ }
+ }
+ int getOppositeVertex(int vNr0, int vNr1, int vNr2)
+ {
+ if (vertexNr[0] != vNr0 && vertexNr[0] != vNr1 && vertexNr[0] != vNr2)
+ {
+ return vertexNr[0];
+ }
+ if (vertexNr[1] != vNr0 && vertexNr[1] != vNr1 && vertexNr[1] != vNr2)
+ {
+ return vertexNr[1];
+ }
+ if (vertexNr[2] != vNr0 && vertexNr[2] != vNr1 && vertexNr[2] != vNr2)
+ {
+ return vertexNr[2];
+ }
+ if (vertexNr[3] != vNr0 && vertexNr[3] != vNr1 && vertexNr[3] != vNr2)
+ {
+ return vertexNr[3];
+ }
+ PX_ASSERT(0);
+ return -1;
+ }
+ int sideOf(int vNr0, int vNr1, int vNr2)
+ {
+ if (vertexNr[0] != vNr0 && vertexNr[0] != vNr1 && vertexNr[0] != vNr2)
+ {
+ return 0;
+ }
+ if (vertexNr[1] != vNr0 && vertexNr[1] != vNr1 && vertexNr[1] != vNr2)
+ {
+ return 1;
+ }
+ if (vertexNr[2] != vNr0 && vertexNr[2] != vNr1 && vertexNr[2] != vNr2)
+ {
+ return 2;
+ }
+ if (vertexNr[3] != vNr0 && vertexNr[3] != vNr1 && vertexNr[3] != vNr2)
+ {
+ return 3;
+ }
+ PX_ASSERT(0);
+ return -1;
+ }
+ inline int neighborNrOf(int vNr0, int vNr1, int vNr2)
+ {
+ PX_ASSERT(containsVertex(vNr0));
+ PX_ASSERT(containsVertex(vNr1));
+ PX_ASSERT(containsVertex(vNr2));
+ if (vertexNr[0] != vNr0 && vertexNr[0] != vNr1 && vertexNr[0] != vNr2)
+ {
+ return 0;
+ }
+ if (vertexNr[1] != vNr0 && vertexNr[1] != vNr1 && vertexNr[1] != vNr2)
+ {
+ return 1;
+ }
+ if (vertexNr[2] != vNr0 && vertexNr[2] != vNr1 && vertexNr[2] != vNr2)
+ {
+ return 2;
+ }
+ if (vertexNr[3] != vNr0 && vertexNr[3] != vNr1 && vertexNr[3] != vNr2)
+ {
+ return 3;
+ }
+ PX_ASSERT(0);
+ return 0;
+ }
+ inline int& neighborOf(int vNr0, int vNr1, int vNr2)
+ {
+ return neighborNr[neighborNrOf(vNr0, vNr1, vNr2)];
+ }
+
+ inline bool onSurface()
+ {
+ return neighborNr[0] < 0 || neighborNr[1] < 0 || neighborNr[2] < 0 || neighborNr[3] < 0;
+ }
+ // representation
+ PxVec3 center;
+ int32_t vertexNr[4];
+ int32_t neighborNr[4];
+ float radiusSquared;
+ uint32_t quality : 10;
+ uint32_t bDeleted : 1;
+ uint32_t bCircumSphereDirty : 1;
+
+ // static
+ static const uint32_t sideIndices[4][3];
+ };
+
+ physx::Array<FullTetrahedron> mTetras;
+
+ uint32_t mFirstFarVertex;
+ uint32_t mLastFarVertex;
+
+ physx::Array<TetraVertex> mVertices;
+ physx::Array<uint32_t> mIndices;
+
+ // temporary indices, that way we don't allocate this buffer all the time
+ physx::Array<uint32_t> mTempItemIndices;
+
+#if TETRAHEDRALIZER_DEBUG_RENDERING
+public:
+ physx::Array<PxVec3> debugLines;
+ physx::Array<PxVec3> debugBounds;
+ physx::Array<PxVec3> debugTetras;
+#endif
+};
+
+}
+} // end namespace nvidia::apex
+
+#endif // APEX_TETRAHEDRALIZER_H