Files
XCEngine/engine/third_party/physx/source/geomutils/src/mesh/GuTetrahedronMesh.cpp

325 lines
12 KiB
C++

// 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.
#include "GuMidphaseInterface.h"
#include "GuTetrahedronMesh.h"
#include "GuBox.h"
using namespace physx;
using namespace Gu;
void TetrahedronMesh::onRefCountZero()
{
if (mMeshFactory)
{
::onRefCountZero(this, mMeshFactory, false, "PxTetrahedronMesh::release: double deletion detected!");
}
}
void DeformableVolumeMesh::onRefCountZero()
{
if (mMeshFactory)
{
::onRefCountZero(this, mMeshFactory, false, "PxDeformableVolumeMesh::release: double deletion detected!");
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DeformableVolumeAuxData::DeformableVolumeAuxData(DeformableVolumeSimulationData& d, DeformableVolumeCollisionData& c, CollisionMeshMappingData& e)
: PxDeformableVolumeAuxData(PxType(PxConcreteType::eDEFORMABLE_VOLUME_STATE), PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE)
, mGridModelInvMass(d.mGridModelInvMass)
, mGridModelTetraRestPoses(d.mGridModelTetraRestPoses)
, mGridModelOrderedTetrahedrons(d.mGridModelOrderedTetrahedrons)
, mGMNbPartitions(d.mGridModelNbPartitions)
, mGMMaxMaxTetsPerPartitions(d.mGridModelMaxTetsPerPartitions)
, mGMRemapOutputSize(d.mGMRemapOutputSize)
, mGMRemapOutputCP(d.mGMRemapOutputCP)
, mGMAccumulatedPartitionsCP(d.mGMAccumulatedPartitionsCP)
, mGMAccumulatedCopiesCP(d.mGMAccumulatedCopiesCP)
, mCollisionAccumulatedTetrahedronsRef(e.mCollisionAccumulatedTetrahedronsRef)
, mCollisionTetrahedronsReferences(e.mCollisionTetrahedronsReferences)
, mCollisionNbTetrahedronsReferences(e.mCollisionNbTetrahedronsReferences)
, mCollisionSurfaceVertsHint(e.mCollisionSurfaceVertsHint)
, mCollisionSurfaceVertToTetRemap(e.mCollisionSurfaceVertToTetRemap)
, mVertsBarycentricInGridModel(e.mVertsBarycentricInGridModel)
, mVertsRemapInGridModel(e.mVertsRemapInGridModel)
, mTetsRemapColToSim(e.mTetsRemapColToSim)
, mTetsRemapSize(e.mTetsRemapSize)
, mTetsAccumulatedRemapColToSim(e.mTetsAccumulatedRemapColToSim)
, mGMPullIndices(d.mGMPullIndices)
, mTetraRestPoses(c.mTetraRestPoses)
, mNumTetsPerElement(d.mNumTetsPerElement)
{
// this constructor takes ownership of memory from the data object
d.mGridModelInvMass = 0;
d.mGridModelTetraRestPoses = 0;
d.mGridModelOrderedTetrahedrons = 0;
d.mGMRemapOutputCP = 0;
d.mGMAccumulatedPartitionsCP = 0;
d.mGMAccumulatedCopiesCP = 0;
e.mCollisionAccumulatedTetrahedronsRef = 0;
e.mCollisionTetrahedronsReferences = 0;
e.mCollisionSurfaceVertsHint = 0;
e.mCollisionSurfaceVertToTetRemap = 0;
d.mGMPullIndices = 0;
e.mVertsBarycentricInGridModel = 0;
e.mVertsRemapInGridModel = 0;
e.mTetsRemapColToSim = 0;
e.mTetsAccumulatedRemapColToSim = 0;
c.mTetraRestPoses = 0;
}
DeformableVolumeAuxData::~DeformableVolumeAuxData()
{
PX_FREE(mGridModelInvMass);
PX_FREE(mGridModelTetraRestPoses);
PX_FREE(mGridModelOrderedTetrahedrons);
PX_FREE(mGMRemapOutputCP);
PX_FREE(mGMAccumulatedPartitionsCP);
PX_FREE(mGMAccumulatedCopiesCP);
PX_FREE(mCollisionAccumulatedTetrahedronsRef);
PX_FREE(mCollisionTetrahedronsReferences);
PX_FREE(mCollisionSurfaceVertsHint);
PX_FREE(mCollisionSurfaceVertToTetRemap);
PX_FREE(mVertsBarycentricInGridModel);
PX_FREE(mVertsRemapInGridModel);
PX_FREE(mTetsRemapColToSim);
PX_FREE(mTetsAccumulatedRemapColToSim);
PX_FREE(mGMPullIndices);
PX_FREE(mTetraRestPoses);
}
TetrahedronMesh::TetrahedronMesh(PxU32 nbVertices, PxVec3* vertices, PxU32 nbTetrahedrons, void* tetrahedrons, PxU8 flags, PxBounds3 aabb, PxReal geomEpsilon)
: PxTetrahedronMesh(PxType(PxConcreteType::eTETRAHEDRON_MESH), PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE)
, mNbVertices(nbVertices)
, mVertices(vertices)
, mNbTetrahedrons(nbTetrahedrons)
, mTetrahedrons(tetrahedrons)
, mFlags(flags)
, mMaterialIndices(NULL)
, mAABB(aabb)
, mGeomEpsilon(geomEpsilon)
{
}
TetrahedronMesh::TetrahedronMesh(TetrahedronMeshData& mesh)
: PxTetrahedronMesh(PxType(PxConcreteType::eTETRAHEDRON_MESH), PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE)
, mNbVertices(mesh.mNbVertices)
, mVertices(mesh.mVertices)
, mNbTetrahedrons(mesh.mNbTetrahedrons)
, mTetrahedrons(mesh.mTetrahedrons)
, mFlags(mesh.mFlags)
, mMaterialIndices(mesh.mMaterialIndices)
, mAABB(mesh.mAABB)
, mGeomEpsilon(mesh.mGeomEpsilon)
{
// this constructor takes ownership of memory from the data object
mesh.mVertices = 0;
mesh.mTetrahedrons = 0;
mesh.mMaterialIndices = 0;
}
TetrahedronMesh::TetrahedronMesh(MeshFactory* meshFactory, TetrahedronMeshData& mesh)
: PxTetrahedronMesh(PxType(PxConcreteType::eTETRAHEDRON_MESH), PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE)
, mNbVertices(mesh.mNbVertices)
, mVertices(mesh.mVertices)
, mNbTetrahedrons(mesh.mNbTetrahedrons)
, mTetrahedrons(mesh.mTetrahedrons)
, mFlags(mesh.mFlags)
, mMaterialIndices(mesh.mMaterialIndices)
, mAABB(mesh.mAABB)
, mGeomEpsilon(mesh.mGeomEpsilon)
, mMeshFactory(meshFactory)
{
// this constructor takes ownership of memory from the data object
mesh.mVertices = 0;
mesh.mTetrahedrons = 0;
mesh.mMaterialIndices = 0;
}
TetrahedronMesh::~TetrahedronMesh()
{
PX_FREE(mTetrahedrons);
PX_FREE(mVertices);
PX_FREE(mMaterialIndices);
}
BVTetrahedronMesh::BVTetrahedronMesh(TetrahedronMeshData& mesh, DeformableVolumeCollisionData& d, MeshFactory* factory) : TetrahedronMesh(mesh)
, mFaceRemap(d.mFaceRemap)
, mGRB_tetraIndices(d.mGRB_primIndices)
, mGRB_tetraSurfaceHint(d.mGRB_tetraSurfaceHint)
, mGRB_faceRemap(d.mGRB_faceRemap)
, mGRB_faceRemapInverse(d.mGRB_faceRemapInverse)
, mGRB_BV32Tree(d.mGRB_BV32Tree)
{
mMeshFactory = factory;
bool has16BitIndices = (mesh.mFlags & PxMeshFlag::e16_BIT_INDICES) ? true : false;
mMeshInterface4.mVerts = mVertices; // mesh.mVertices;
mMeshInterface4.mNbVerts = mesh.mNbVertices;
mMeshInterface4.mNbTetrahedrons = mesh.mNbTetrahedrons;
mMeshInterface4.mTetrahedrons16 = has16BitIndices ? reinterpret_cast<IndTetrahedron16*>(mTetrahedrons/*mesh.mTetrahedrons*/) : NULL;
mMeshInterface4.mTetrahedrons32 = has16BitIndices ? NULL : reinterpret_cast<IndTetrahedron32*>(mTetrahedrons/*mesh.mTetrahedrons*/);
mBV4Tree = d.mBV4Tree;
mBV4Tree.mMeshInterface = &mMeshInterface4;
if (mGRB_BV32Tree)
{
mMeshInterface32.mVerts = mVertices; // mesh.mVertices;
mMeshInterface32.mNbVerts = mesh.mNbVertices;
mMeshInterface32.mNbTetrahedrons = mesh.mNbTetrahedrons;
mMeshInterface32.mTetrahedrons16 = has16BitIndices ? reinterpret_cast<IndTetrahedron16*>(d.mGRB_primIndices) : NULL;
mMeshInterface32.mTetrahedrons32 = has16BitIndices ? NULL : reinterpret_cast<IndTetrahedron32*>(d.mGRB_primIndices);
mGRB_BV32Tree->mMeshInterface = &mMeshInterface32;
}
// this constructor takes ownership of memory from the data object
d.mGRB_tetraSurfaceHint = NULL;
d.mFaceRemap = NULL;
d.mGRB_primIndices = NULL;
d.mGRB_faceRemap = NULL;
d.mGRB_faceRemapInverse = NULL;
d.mGRB_BV32Tree = NULL;
mesh.mVertices = NULL;
mesh.mTetrahedrons = NULL;
}
DeformableVolumeMesh::DeformableVolumeMesh(MeshFactory* factory, DeformableVolumeMeshData& d)
: PxDeformableVolumeMesh(PxType(PxConcreteType::eDEFORMABLE_VOLUME_MESH), PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE)
, mMeshFactory(factory)
{
mDeformableVolumeAuxData = PX_NEW(DeformableVolumeAuxData)(d.mSimulationData, d.mCollisionData, d.mMappingData);
mCollisionMesh = PX_NEW(BVTetrahedronMesh)(d.mCollisionMesh, d.mCollisionData, factory);
mSimulationMesh = PX_NEW(TetrahedronMesh)(factory, d.mSimulationMesh);
}
DeformableVolumeMesh::~DeformableVolumeMesh()
{
if (getBaseFlags() & PxBaseFlag::eOWNS_MEMORY)
{
PX_DELETE(mDeformableVolumeAuxData);
PX_DELETE(mCollisionMesh);
PX_DELETE(mSimulationMesh);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// PT: used to be automatic but making it manual saves bytes in the internal mesh
void DeformableVolumeMesh::exportExtraData(PxSerializationContext& stream)
{
//PX_DEFINE_DYNAMIC_ARRAY(TriangleMesh, mVertices, PxField::eVEC3, mNbVertices, Ps::PxFieldFlag::eSERIALIZE),
if (getCollisionMeshFast()->mVertices)
{
stream.alignData(PX_SERIAL_ALIGN);
stream.writeData(getCollisionMeshFast()->mVertices, getCollisionMeshFast()->mNbVertices * sizeof(PxVec3));
}
/*if (mSurfaceTriangles)
{
stream.alignData(PX_SERIAL_ALIGN);
stream.writeData(mSurfaceTriangles, mNbTriangles * 3 * sizeof(PxU32));
}*/
if (getCollisionMeshFast()->mTetrahedrons)
{
stream.alignData(PX_SERIAL_ALIGN);
stream.writeData(getCollisionMeshFast()->mTetrahedrons, getCollisionMeshFast()->mNbTetrahedrons * 4 * sizeof(PxU32));
}
/*if (mTetSurfaceHint)
{
stream.alignData(PX_SERIAL_ALIGN);
stream.writeData(mTetSurfaceHint, mNbTetrahedrons * sizeof(PxU8));
}*/
if (getCollisionMeshFast()->mMaterialIndices)
{
stream.alignData(PX_SERIAL_ALIGN);
stream.writeData(getCollisionMeshFast()->mMaterialIndices, getCollisionMeshFast()->mNbTetrahedrons * sizeof(PxU16));
}
if (getCollisionMeshFast()->mFaceRemap)
{
stream.alignData(PX_SERIAL_ALIGN);
stream.writeData(getCollisionMeshFast()->mFaceRemap, getCollisionMeshFast()->mNbTetrahedrons * sizeof(PxU32));
}
}
void DeformableVolumeMesh::importExtraData(PxDeserializationContext& context)
{
// PT: vertices are followed by indices, so it will be safe to V4Load vertices from a deserialized binary file
if (getCollisionMeshFast()->mVertices)
getCollisionMeshFast()->mVertices = context.readExtraData<PxVec3, PX_SERIAL_ALIGN>(getCollisionMeshFast()->mNbVertices);
if (getCollisionMeshFast()->mTetrahedrons)
getCollisionMeshFast()->mTetrahedrons = context.readExtraData<PxU32, PX_SERIAL_ALIGN>(4 * getCollisionMeshFast()->mNbTetrahedrons);
if (getCollisionMeshFast()->mFaceRemap)
getCollisionMeshFast()->mFaceRemap = context.readExtraData<PxU32, PX_SERIAL_ALIGN>(getCollisionMeshFast()->mNbTetrahedrons);
getCollisionMeshFast()->mGRB_tetraIndices = NULL;
getCollisionMeshFast()->mGRB_tetraSurfaceHint = NULL;
getCollisionMeshFast()->mGRB_faceRemap = NULL;
getCollisionMeshFast()->mGRB_faceRemapInverse = NULL;
getCollisionMeshFast()->mGRB_BV32Tree = NULL;
}
void DeformableVolumeMesh::release()
{
Cm::RefCountable_decRefCount(*this);
}
//PxVec3* TetrahedronMesh::getVerticesForModification()
//{
// PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxDeformableVolumeMesh::getVerticesForModification() is not currently supported.");
//
// return NULL;
//}
//PxBounds3 BVTetrahedronMesh::refitBVH()
//{
// PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxDeformableVolumeMesh::refitBVH() is not currently supported.");
//
// return PxBounds3(mAABB.getMin(), mAABB.getMax());
//}