aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.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/GeomUtils/src/mesh/GuTriangleMesh.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/GeomUtils/src/mesh/GuTriangleMesh.h')
-rw-r--r--PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.h302
1 files changed, 302 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.h b/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.h
new file mode 100644
index 00000000..854f43b5
--- /dev/null
+++ b/PhysX_3.4/Source/GeomUtils/src/mesh/GuTriangleMesh.h
@@ -0,0 +1,302 @@
+// 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 GU_TRIANGLEMESH_H
+#define GU_TRIANGLEMESH_H
+
+#include "foundation/PxIO.h"
+#include "PxSimpleTriangleMesh.h"
+#include "PxTriangleMeshGeometry.h"
+#include "CmScaling.h"
+#include "GuTriangleMesh.h"
+#include "GuTriangle32.h"
+#include "CmRefCountable.h"
+#include "PxTriangle.h"
+#include "PxTriangleMesh.h"
+#include "CmRenderOutput.h"
+#include "GuMeshData.h"
+#include "GuCenterExtents.h"
+
+namespace physx
+{
+
+class GuMeshFactory;
+class PxMeshScale;
+
+namespace Gu
+{
+
+#if PX_VC
+#pragma warning(push)
+#pragma warning(disable: 4324) // Padding was added at the end of a structure because of a __declspec(align) value.
+#endif
+
+// Possible optimization: align the whole struct to cache line
+class TriangleMesh : public PxTriangleMesh, public Ps::UserAllocated, public Cm::RefCountable
+{
+//= ATTENTION! =====================================================================================
+// Changing the data layout of this class breaks the binary serialization format. See comments for
+// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
+// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
+// accordingly.
+//==================================================================================================
+public:
+
+// PX_SERIALIZATION
+ TriangleMesh(PxBaseFlags baseFlags) : PxTriangleMesh(baseFlags), Cm::RefCountable(PxEmpty) {}
+ virtual void exportExtraData(PxSerializationContext& ctx);
+ void importExtraData(PxDeserializationContext&);
+ PX_PHYSX_COMMON_API static void getBinaryMetaData(PxOutputStream& stream);
+ virtual void release();
+
+ void resolveReferences(PxDeserializationContext& ) {}
+ virtual void requires(PxProcessPxBaseCallback&){}
+//~PX_SERIALIZATION
+
+// Cm::RefCountable
+ virtual void onRefCountZero();
+//~Cm::RefCountable
+
+ TriangleMesh(GuMeshFactory& factory, TriangleMeshData& data);
+ virtual ~TriangleMesh();
+
+// PxTriangleMesh
+ virtual PxU32 getNbVertices() const { return mNbVertices; }
+ virtual const PxVec3* getVertices() const { return mVertices; }
+ virtual const PxU32* getTrianglesRemap() const { return mFaceRemap; }
+ virtual PxU32 getNbTriangles() const { return mNbTriangles; }
+ virtual const void* getTriangles() const { return mTriangles; }
+ virtual PxTriangleMeshFlags getTriangleMeshFlags() const { return PxTriangleMeshFlags(mFlags); }
+ virtual PxMaterialTableIndex getTriangleMaterialIndex(PxTriangleID triangleIndex) const {
+ return hasPerTriangleMaterials() ? getMaterials()[triangleIndex] : PxMaterialTableIndex(0xffff); }
+
+#if PX_ENABLE_DYNAMIC_MESH_RTREE
+ virtual PxVec3* getVerticesForModification();
+ virtual PxBounds3 refitBVH();
+#endif
+
+ virtual PxBounds3 getLocalBounds() const
+ {
+ PX_ASSERT(mAABB.isValid());
+ return PxBounds3::centerExtents(mAABB.mCenter, mAABB.mExtents);
+ }
+
+ virtual void acquireReference() { incRefCount(); }
+ virtual PxU32 getReferenceCount() const { return getRefCount(); }
+//~PxTriangleMesh
+ // PT: this one is just to prevent instancing Gu::TriangleMesh.
+ // But you should use PxBase::getConcreteType() instead to avoid the virtual call.
+ virtual PxMeshMidPhase::Enum getMidphaseID() const = 0;
+
+ PX_FORCE_INLINE const PxU32* getFaceRemap() const { return mFaceRemap; }
+ PX_FORCE_INLINE bool has16BitIndices() const { return (mFlags & PxMeshFlag::e16_BIT_INDICES) ? true : false; }
+ PX_FORCE_INLINE bool hasPerTriangleMaterials() const { return mMaterialIndices != NULL; }
+ PX_FORCE_INLINE PxU32 getNbVerticesFast() const { return mNbVertices; }
+ PX_FORCE_INLINE PxU32 getNbTrianglesFast() const { return mNbTriangles; }
+ PX_FORCE_INLINE const void* getTrianglesFast() const { return mTriangles; }
+ PX_FORCE_INLINE const PxVec3* getVerticesFast() const { return mVertices; }
+ PX_FORCE_INLINE const PxU32* getAdjacencies() const { return mAdjacencies; }
+ PX_FORCE_INLINE PxReal getGeomEpsilon() const { return mGeomEpsilon; }
+ PX_FORCE_INLINE const CenterExtents& getLocalBoundsFast() const { return mAABB; }
+ PX_FORCE_INLINE const PxU16* getMaterials() const { return mMaterialIndices; }
+ PX_FORCE_INLINE const PxU8* getExtraTrigData() const { return mExtraTrigData; }
+
+ PX_FORCE_INLINE const CenterExtentsPadded& getPaddedBounds() const
+ {
+ // PT: see compile-time assert in cpp
+ return static_cast<const CenterExtentsPadded&>(mAABB);
+ }
+
+ PX_FORCE_INLINE void computeWorldTriangle(
+ PxTriangle& worldTri, PxTriangleID triangleIndex, const Cm::Matrix34& worldMatrix, bool flipNormal = false,
+ PxU32* PX_RESTRICT vertexIndices=NULL, PxU32* PX_RESTRICT adjacencyIndices=NULL) const;
+ PX_FORCE_INLINE void getLocalTriangle(PxTriangle& localTri, PxTriangleID triangleIndex, bool flipNormal = false) const;
+
+ void setMeshFactory(GuMeshFactory* factory) { mMeshFactory = factory; }
+
+protected:
+ PxU32 mNbVertices;
+ PxU32 mNbTriangles;
+ PxVec3* mVertices;
+ void* mTriangles; //!< 16 (<= 0xffff #vertices) or 32 bit trig indices (mNbTriangles * 3)
+ // 16 bytes block
+
+ // PT: WARNING: bounds must be followed by at least 32bits of data for safe SIMD loading
+ CenterExtents mAABB;
+ PxU8* mExtraTrigData; //one per trig
+ PxReal mGeomEpsilon; //!< see comments in cooking code referencing this variable
+ // 16 bytes block
+ /*
+ low 3 bits (mask: 7) are the edge flags:
+ b001 = 1 = ignore edge 0 = edge v0-->v1
+ b010 = 2 = ignore edge 1 = edge v0-->v2
+ b100 = 4 = ignore edge 2 = edge v1-->v2
+ */
+ PxU8 mFlags; //!< Flag whether indices are 16 or 32 bits wide
+ //!< Flag whether triangle adajacencies are build
+ PxU16* mMaterialIndices; //!< the size of the array is numTriangles.
+ PxU32* mFaceRemap; //!< new faces to old faces mapping (after cleaning, etc). Usage: old = faceRemap[new]
+ PxU32* mAdjacencies; //!< Adjacency information for each face - 3 adjacent faces
+ //!< Set to 0xFFFFffff if no adjacent face
+
+ GuMeshFactory* mMeshFactory; // PT: changed to pointer for serialization
+
+#if PX_ENABLE_DEBUG_VISUALIZATION
+public:
+ /**
+ \brief Perform triangle mesh geometry debug visualization
+
+ \param out Debug renderer.
+ \param pose World position.
+ */
+ void debugVisualize( Cm::RenderOutput& out, const PxTransform& pose, const PxMeshScale& scaling, const PxBounds3& cullbox,
+ const PxU64 mask, const PxReal fscale, const PxU32 numMaterials) const;
+#endif
+
+public:
+
+ // GRB data -------------------------
+ void * mGRB_triIndices; //!< GRB: GPU-friendly tri indices [uint4]
+
+ // TODO avoroshilov: cooking - adjacency info - duplicated, remove it and use 'mAdjacencies' and 'mExtraTrigData' see GuTriangleMesh.cpp:325
+ void * mGRB_triAdjacencies; //!< GRB: adjacency data, with BOUNDARY and NONCONVEX flags (flags replace adj indices where applicable)
+ PxU32 * mGRB_vertValency; //!< GRB: number of adjacent vertices to a vertex
+ PxU32 * mGRB_adjVertStart; //!< GRB: offset for each vertex in the adjacency list
+ PxU32 * mGRB_adjVertices; //!< GRB: list of adjacent vertices
+
+ PxU32 mGRB_meshAdjVerticiesTotal; //!< GRB: total number of indices in the 'mGRB_adjVertices'
+ PxU32* mGRB_faceRemap; //!< GRB : gpu to cpu triangle indice remap
+ void* mGRB_BV32Tree; //!< GRB: BV32 tree
+ // End of GRB data ------------------
+
+};
+
+#if PX_VC
+#pragma warning(pop)
+#endif
+
+} // namespace Gu
+
+PX_FORCE_INLINE void Gu::TriangleMesh::computeWorldTriangle(PxTriangle& worldTri, PxTriangleID triangleIndex, const Cm::Matrix34& worldMatrix, bool flipNormal,
+ PxU32* PX_RESTRICT vertexIndices, PxU32* PX_RESTRICT adjacencyIndices) const
+{
+ PxU32 vref0, vref1, vref2;
+ if(has16BitIndices())
+ {
+ const Gu::TriangleT<PxU16>& T = (reinterpret_cast<const Gu::TriangleT<PxU16>*>(getTrianglesFast()))[triangleIndex];
+ vref0 = T.v[0];
+ vref1 = T.v[1];
+ vref2 = T.v[2];
+ }
+ else
+ {
+ const Gu::TriangleT<PxU32>& T = (reinterpret_cast<const Gu::TriangleT<PxU32>*>(getTrianglesFast()))[triangleIndex];
+ vref0 = T.v[0];
+ vref1 = T.v[1];
+ vref2 = T.v[2];
+ }
+ if (flipNormal)
+ Ps::swap<PxU32>(vref1, vref2);
+ const PxVec3* PX_RESTRICT vertices = getVerticesFast();
+ worldTri.verts[0] = worldMatrix.transform(vertices[vref0]);
+ worldTri.verts[1] = worldMatrix.transform(vertices[vref1]);
+ worldTri.verts[2] = worldMatrix.transform(vertices[vref2]);
+
+ if(vertexIndices)
+ {
+ vertexIndices[0] = vref0;
+ vertexIndices[1] = vref1;
+ vertexIndices[2] = vref2;
+ }
+
+ if(adjacencyIndices)
+ {
+ if(getAdjacencies())
+ {
+ adjacencyIndices[0] = flipNormal ? getAdjacencies()[triangleIndex*3 + 2] : getAdjacencies()[triangleIndex*3 + 0];
+ adjacencyIndices[1] = getAdjacencies()[triangleIndex*3 + 1];
+ adjacencyIndices[2] = flipNormal ? getAdjacencies()[triangleIndex*3 + 0] : getAdjacencies()[triangleIndex*3 + 2];
+ }
+ else
+ {
+ adjacencyIndices[0] = 0xffffffff;
+ adjacencyIndices[1] = 0xffffffff;
+ adjacencyIndices[2] = 0xffffffff;
+ }
+ }
+}
+
+PX_FORCE_INLINE void Gu::TriangleMesh::getLocalTriangle(PxTriangle& localTri, PxTriangleID triangleIndex, bool flipNormal) const
+{
+ PxU32 vref0, vref1, vref2;
+ if(has16BitIndices())
+ {
+ const Gu::TriangleT<PxU16>& T = (reinterpret_cast<const Gu::TriangleT<PxU16>*>(getTrianglesFast()))[triangleIndex];
+ vref0 = T.v[0];
+ vref1 = T.v[1];
+ vref2 = T.v[2];
+ }
+ else
+ {
+ const Gu::TriangleT<PxU32>& T = (reinterpret_cast<const Gu::TriangleT<PxU32>*>(getTrianglesFast()))[triangleIndex];
+ vref0 = T.v[0];
+ vref1 = T.v[1];
+ vref2 = T.v[2];
+ }
+ if (flipNormal)
+ Ps::swap<PxU32>(vref1, vref2);
+ const PxVec3* PX_RESTRICT vertices = getVerticesFast();
+ localTri.verts[0] = vertices[vref0];
+ localTri.verts[1] = vertices[vref1];
+ localTri.verts[2] = vertices[vref2];
+}
+
+PX_INLINE float computeSweepData(const PxTriangleMeshGeometry& triMeshGeom, /*const Cm::FastVertex2ShapeScaling& scaling,*/ PxVec3& sweepOrigin, PxVec3& sweepExtents, PxVec3& sweepDir, float distance)
+{
+ PX_ASSERT(!Cm::isEmpty(sweepOrigin, sweepExtents));
+
+ const PxVec3 endPt = sweepOrigin + sweepDir*distance;
+ PX_ASSERT(!Cm::isEmpty(endPt, sweepExtents));
+
+ const Cm::FastVertex2ShapeScaling meshScaling(triMeshGeom.scale.getInverse()); // shape to vertex transform
+
+ const PxMat33& vertex2ShapeSkew = meshScaling.getVertex2ShapeSkew();
+
+ const PxVec3 originBoundsCenter = vertex2ShapeSkew * sweepOrigin;
+ const PxVec3 originBoundsExtents = Cm::basisExtent(vertex2ShapeSkew.column0, vertex2ShapeSkew.column1, vertex2ShapeSkew.column2, sweepExtents);
+
+ sweepOrigin = originBoundsCenter;
+ sweepExtents = originBoundsExtents;
+ sweepDir = (vertex2ShapeSkew * endPt) - originBoundsCenter;
+ return sweepDir.normalizeSafe();
+}
+
+}
+
+#endif