feat(physics): wire physx sdk into build
This commit is contained in:
346
engine/third_party/physx/source/geomutils/src/mesh/GuTriangleMesh.h
vendored
Normal file
346
engine/third_party/physx/source/geomutils/src/mesh/GuTriangleMesh.h
vendored
Normal file
@@ -0,0 +1,346 @@
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2025 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 "geometry/PxTriangle.h"
|
||||
#include "geometry/PxTriangleMeshGeometry.h"
|
||||
#include "geometry/PxSimpleTriangleMesh.h"
|
||||
#include "geometry/PxTriangleMesh.h"
|
||||
|
||||
#include "GuMeshData.h"
|
||||
#include "GuCenterExtents.h"
|
||||
#include "CmScaling.h"
|
||||
#include "CmRefCountable.h"
|
||||
#include "common/PxRenderOutput.h"
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxMeshScale;
|
||||
struct PxTriangleMeshInternalData;
|
||||
|
||||
namespace Gu
|
||||
{
|
||||
PX_FORCE_INLINE void getVertexRefs(PxU32 triangleIndex, PxU32& vref0, PxU32& vref1, PxU32& vref2, const void* indices, bool has16BitIndices)
|
||||
{
|
||||
if(has16BitIndices)
|
||||
{
|
||||
const PxU16* inds = reinterpret_cast<const PxU16*>(indices) + triangleIndex*3;
|
||||
vref0 = inds[0];
|
||||
vref1 = inds[1];
|
||||
vref2 = inds[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
const PxU32* inds = reinterpret_cast<const PxU32*>(indices) + triangleIndex*3;
|
||||
vref0 = inds[0];
|
||||
vref1 = inds[1];
|
||||
vref2 = inds[2];
|
||||
}
|
||||
}
|
||||
|
||||
class MeshFactory;
|
||||
#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
|
||||
|
||||
class EdgeList;
|
||||
|
||||
class TriangleMesh : public PxTriangleMesh, public PxUserAllocated
|
||||
{
|
||||
public:
|
||||
|
||||
// PX_SERIALIZATION
|
||||
TriangleMesh(PxBaseFlags baseFlags) : PxTriangleMesh(baseFlags), mSdfData(PxEmpty) {}
|
||||
|
||||
void preExportDataReset() { Cm::RefCountable_preExportDataReset(*this); }
|
||||
virtual void exportExtraData(PxSerializationContext& context);
|
||||
void importExtraData(PxDeserializationContext& context);
|
||||
virtual void release();
|
||||
virtual void requiresObjects(PxProcessPxBaseCallback&){}
|
||||
//~PX_SERIALIZATION
|
||||
TriangleMesh(MeshFactory* factory, TriangleMeshData& data);
|
||||
TriangleMesh(const PxTriangleMeshInternalData& data);
|
||||
virtual ~TriangleMesh();
|
||||
|
||||
// PxBase
|
||||
virtual void onRefCountZero();
|
||||
//~PxBase
|
||||
|
||||
// PxRefCounted
|
||||
virtual void acquireReference() { Cm::RefCountable_incRefCount(*this); }
|
||||
virtual PxU32 getReferenceCount() const { return Cm::RefCountable_getRefCount(*this); }
|
||||
//~PxRefCounted
|
||||
|
||||
// PxTriangleMesh
|
||||
virtual PxU32 getNbVertices() const { return mNbVertices;}
|
||||
virtual const PxVec3* getVertices() const { return mVertices; }
|
||||
|
||||
virtual PxVec3* getVerticesForModification();
|
||||
virtual PxBounds3 refitBVH();
|
||||
virtual PxU32 getNbTriangles() const { return mNbTriangles; }
|
||||
virtual const void* getTriangles() const { return mTriangles; }
|
||||
virtual PxTriangleMeshFlags getTriangleMeshFlags() const { return PxTriangleMeshFlags(mFlags); }
|
||||
virtual const PxU32* getTrianglesRemap() const { return mFaceRemap; }
|
||||
virtual void setPreferSDFProjection(bool preferProjection)
|
||||
{
|
||||
if (preferProjection)
|
||||
mFlags &= PxU8(~PxTriangleMeshFlag::ePREFER_NO_SDF_PROJ);
|
||||
else
|
||||
mFlags |= PxTriangleMeshFlag::ePREFER_NO_SDF_PROJ;
|
||||
}
|
||||
|
||||
virtual bool getPreferSDFProjection() const { return !(mFlags & PxTriangleMeshFlag::ePREFER_NO_SDF_PROJ); }
|
||||
|
||||
virtual PxMaterialTableIndex getTriangleMaterialIndex(PxTriangleID triangleIndex) const
|
||||
{
|
||||
return hasPerTriangleMaterials() ? getMaterials()[triangleIndex] : PxMaterialTableIndex(0xffff);
|
||||
}
|
||||
|
||||
virtual PxBounds3 getLocalBounds() const
|
||||
{
|
||||
PX_ASSERT(mAABB.isValid());
|
||||
return PxBounds3::centerExtents(mAABB.mCenter, mAABB.mExtents);
|
||||
}
|
||||
|
||||
virtual const PxReal* getSDF() const
|
||||
{
|
||||
return mSdfData.mSdf;
|
||||
}
|
||||
|
||||
virtual void getSDFDimensions(PxU32& numX, PxU32& numY, PxU32& numZ) const
|
||||
{
|
||||
if(mSdfData.mSdf)
|
||||
{
|
||||
numX = mSdfData.mDims.x;
|
||||
numY = mSdfData.mDims.y;
|
||||
numZ = mSdfData.mDims.z;
|
||||
}
|
||||
else
|
||||
numX = numY = numZ = 0;
|
||||
}
|
||||
|
||||
virtual void getMassInformation(PxReal& mass, PxMat33& localInertia, PxVec3& localCenterOfMass) const
|
||||
{
|
||||
mass = mMass; localInertia = mInertia; localCenterOfMass = mLocalCenterOfMass;
|
||||
}
|
||||
|
||||
//~PxTriangleMesh
|
||||
|
||||
virtual bool getInternalData(PxTriangleMeshInternalData&, bool) const { return false; }
|
||||
|
||||
// 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 PxU32* getAccumulatedTriangleRef() const { return mAccumulatedTrianglesRef; }
|
||||
PX_FORCE_INLINE const PxU32* getTriangleReferences() const { return mTrianglesReferences; }
|
||||
PX_FORCE_INLINE PxU32 getNbTriangleReferences() const { return mNbTrianglesReferences; }
|
||||
|
||||
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 PxMat34& 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(MeshFactory* factory) { mMeshFactory = factory; }
|
||||
|
||||
// SDF methods
|
||||
PX_FORCE_INLINE const SDF& getSdfDataFast() const { return mSdfData; }
|
||||
//~SDF methods
|
||||
|
||||
PX_FORCE_INLINE PxReal getMass() const { return mMass; }
|
||||
|
||||
// PT: for debug viz
|
||||
PX_PHYSX_COMMON_API const Gu::EdgeList* requestEdgeList() const;
|
||||
|
||||
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
|
||||
|
||||
MeshFactory* mMeshFactory; // PT: changed to pointer for serialization
|
||||
mutable Gu::EdgeList* mEdgeList; // PT: for debug viz
|
||||
|
||||
|
||||
PxReal mMass; //this is mass assuming a unit density that can be scaled by instances!
|
||||
PxMat33 mInertia; //in local space of mesh!
|
||||
PxVec3 mLocalCenterOfMass; //local space com
|
||||
public:
|
||||
|
||||
// GRB data -------------------------
|
||||
void* mGRB_triIndices; //!< GRB: GPU-friendly tri indices
|
||||
|
||||
// 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_faceRemap; //!< GRB : gpu to cpu triangle indice remap
|
||||
PxU32* mGRB_faceRemapInverse;
|
||||
Gu::BV32Tree* mGRB_BV32Tree; //!< GRB: BV32 tree
|
||||
// End of GRB data ------------------
|
||||
|
||||
// SDF data -------------------------
|
||||
SDF mSdfData;
|
||||
// End of SDF data ------------------
|
||||
|
||||
void setAllEdgesActive();
|
||||
//Vertex mapping data
|
||||
PxU32* mAccumulatedTrianglesRef;//runsum
|
||||
PxU32* mTrianglesReferences;
|
||||
PxU32 mNbTrianglesReferences;
|
||||
//End of vertex mapping data
|
||||
};
|
||||
|
||||
#if PX_VC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace Gu
|
||||
|
||||
PX_FORCE_INLINE void Gu::TriangleMesh::computeWorldTriangle(PxTriangle& worldTri, PxTriangleID triangleIndex, const PxMat34& worldMatrix, bool flipNormal,
|
||||
PxU32* PX_RESTRICT vertexIndices, PxU32* PX_RESTRICT adjacencyIndices) const
|
||||
{
|
||||
PxU32 vref0, vref1, vref2;
|
||||
getVertexRefs(triangleIndex, vref0, vref1, vref2, mTriangles, has16BitIndices());
|
||||
|
||||
if(flipNormal)
|
||||
PxSwap<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(mAdjacencies)
|
||||
{
|
||||
// PT: TODO: is this correct?
|
||||
adjacencyIndices[0] = flipNormal ? mAdjacencies[triangleIndex*3 + 2] : mAdjacencies[triangleIndex*3 + 0];
|
||||
adjacencyIndices[1] = mAdjacencies[triangleIndex*3 + 1];
|
||||
adjacencyIndices[2] = flipNormal ? mAdjacencies[triangleIndex*3 + 0] : mAdjacencies[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;
|
||||
getVertexRefs(triangleIndex, vref0, vref1, vref2, mTriangles, has16BitIndices());
|
||||
|
||||
if(flipNormal)
|
||||
PxSwap<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();
|
||||
}
|
||||
|
||||
PX_FORCE_INLINE const Gu::TriangleMesh* _getMeshData(const PxTriangleMeshGeometry& meshGeom)
|
||||
{
|
||||
return static_cast<const Gu::TriangleMesh*>(meshGeom.triangleMesh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user