1013 lines
39 KiB
C++
1013 lines
39 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 "DyDeformableVolumeCore.h"
|
|
#include "PxsHeapMemoryAllocator.h"
|
|
#include "PxsMemoryManager.h"
|
|
#include "foundation/PxPreprocessor.h"
|
|
|
|
#if PX_SUPPORT_GPU_PHYSX
|
|
#include "NpDeformableVolume.h"
|
|
#include "NpPBDParticleSystem.h"
|
|
#include "NpCheck.h"
|
|
#include "NpScene.h"
|
|
#include "NpShape.h"
|
|
#include "geometry/PxTetrahedronMesh.h"
|
|
#include "geometry/PxTetrahedronMeshGeometry.h"
|
|
#include "PxPhysXGpu.h"
|
|
#include "PxvGlobals.h"
|
|
#include "GuTetrahedronMesh.h"
|
|
#include "NpRigidDynamic.h"
|
|
#include "NpRigidStatic.h"
|
|
#include "NpArticulationLink.h"
|
|
#include "ScDeformableVolumeSim.h"
|
|
#include "NpDeformableVolumeMaterial.h"
|
|
|
|
using namespace physx;
|
|
|
|
class PxCudaContextManager;
|
|
|
|
namespace
|
|
{
|
|
// for deprecation
|
|
static const PxU32 sNumTwinFlags = 3;
|
|
static PxDeformableVolumeFlag::Enum sVFlags[sNumTwinFlags] = { PxDeformableVolumeFlag::eDISABLE_SELF_COLLISION, PxDeformableVolumeFlag::eENABLE_CCD, PxDeformableVolumeFlag::eKINEMATIC };
|
|
static PxDeformableBodyFlag::Enum sBFlags[sNumTwinFlags] = { PxDeformableBodyFlag::eDISABLE_SELF_COLLISION, PxDeformableBodyFlag::eENABLE_SPECULATIVE_CCD, PxDeformableBodyFlag::eKINEMATIC };
|
|
|
|
void mirrorTwinFlags(PxDeformableBodyFlags& bodyFlags, const PxDeformableVolumeFlags volumeFlags)
|
|
{
|
|
for (PxU32 f = 0; f < sNumTwinFlags; ++f)
|
|
{
|
|
bool val = volumeFlags.isSet(sVFlags[f]);
|
|
if (val)
|
|
{
|
|
bodyFlags.raise(sBFlags[f]);
|
|
}
|
|
else
|
|
{
|
|
bodyFlags.clear(sBFlags[f]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace physx
|
|
{
|
|
|
|
NpDeformableVolume::NpDeformableVolume(PxCudaContextManager& cudaContextManager) :
|
|
NpActorTemplate (PxConcreteType::eDEFORMABLE_VOLUME, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE, NpType::eDEFORMABLE_VOLUME),
|
|
mShape (NULL),
|
|
mCudaContextManager(&cudaContextManager),
|
|
mMemoryManager(NULL),
|
|
mDeviceMemoryAllocator(NULL)
|
|
{
|
|
}
|
|
|
|
NpDeformableVolume::NpDeformableVolume(PxBaseFlags baseFlags, PxCudaContextManager& cudaContextManager) :
|
|
NpActorTemplate (baseFlags),
|
|
mShape (NULL),
|
|
mCudaContextManager(&cudaContextManager),
|
|
mMemoryManager(NULL),
|
|
mDeviceMemoryAllocator(NULL)
|
|
{
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// PxActor API
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void NpDeformableVolume::release()
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
// AD why is this commented out?
|
|
// NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, PxArticulationBase::userData);
|
|
|
|
if (npScene)
|
|
{
|
|
removeAttachments(*this, true);
|
|
removeElementFilters(*this, true);
|
|
|
|
npScene->scRemoveDeformableVolume(*this);
|
|
npScene->removeFromDeformableVolumeList(*this);
|
|
}
|
|
|
|
detachSimulationMesh();
|
|
detachShape();
|
|
|
|
PX_ASSERT(!isAPIWriteForbidden());
|
|
releaseAllocator();
|
|
NpDestroyDeformableVolume(this);
|
|
}
|
|
|
|
PxBounds3 NpDeformableVolume::getWorldBounds(float inflation) const
|
|
{
|
|
NP_READ_CHECK(getNpScene());
|
|
|
|
if (!getNpScene())
|
|
{
|
|
PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Querying bounds of a PxDeformableBody which is not part of a PxScene is not supported.");
|
|
return PxBounds3::empty();
|
|
}
|
|
|
|
const Sc::DeformableVolumeSim* sim = mCore.getSim();
|
|
PX_ASSERT(sim);
|
|
|
|
PX_SIMD_GUARD;
|
|
|
|
const PxBounds3 bounds = getNpScene()->getScScene().getBoundsArray().getBounds(sim->getShapeSim().getElementID());
|
|
PX_ASSERT(bounds.isValid());
|
|
|
|
// PT: unfortunately we can't just scale the min/max vectors, we need to go through center/extents.
|
|
const PxVec3 center = bounds.getCenter();
|
|
const PxVec3 inflatedExtents = bounds.getExtents() * inflation;
|
|
return PxBounds3::centerExtents(center, inflatedExtents);
|
|
}
|
|
|
|
void NpDeformableVolume::setActorFlag(PxActorFlag::Enum flag, bool val)
|
|
{
|
|
PX_CHECK_AND_RETURN(flag == PxActorFlag::eDISABLE_GRAVITY || !val, "PxDeformableBody only supports PxActorFlag::eDISABLE_GRAVITY!");
|
|
|
|
PxActorFlags flags = mCore.getActorFlags();
|
|
if(val)
|
|
flags.raise(flag);
|
|
else
|
|
flags.clear(flag);
|
|
|
|
mCore.setActorFlags(flags);
|
|
NpActorTemplate<PxDeformableVolume>::setActorFlag(flag, val);
|
|
}
|
|
|
|
void NpDeformableVolume::setActorFlags(PxActorFlags inFlags)
|
|
{
|
|
PX_CHECK_AND_RETURN(inFlags & PxActorFlag::eVISUALIZATION, "PxDeformableBody doesn't supports PxActorFlag::eVISUALIZATION!");
|
|
PX_CHECK_AND_RETURN(inFlags & PxActorFlag::eSEND_SLEEP_NOTIFIES, "PxDeformableBody doesn't supports PxActorFlag::eSEND_SLEEP_NOTIFIES!");
|
|
PX_CHECK_AND_RETURN(inFlags & PxActorFlag::eDISABLE_SIMULATION, "PxDeformableBody doesn't supports PxActorFlag::eDISABLE_SIMULATION!");
|
|
|
|
mCore.setActorFlags(inFlags);
|
|
NpActorTemplate<PxDeformableVolume>::setActorFlags(inFlags);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// PxDeformableBody API
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void NpDeformableVolume::setDeformableBodyFlag(PxDeformableBodyFlag::Enum flag, bool val)
|
|
{
|
|
PxDeformableBodyFlags flags = mCore.getBodyFlags();
|
|
if (val)
|
|
flags.raise(flag);
|
|
else
|
|
flags.clear(flag);
|
|
|
|
mCore.setBodyFlags(flags);
|
|
}
|
|
|
|
void NpDeformableVolume::setDeformableBodyFlags(PxDeformableBodyFlags flags)
|
|
{
|
|
mCore.setBodyFlags(flags);
|
|
}
|
|
|
|
PxDeformableBodyFlags NpDeformableVolume::getDeformableBodyFlags() const
|
|
{
|
|
return mCore.getBodyFlags();
|
|
}
|
|
|
|
void NpDeformableVolume::setLinearDamping(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setLinearDamping() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setLinearDamping(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getLinearDamping() const
|
|
{
|
|
return mCore.getLinearDamping();
|
|
}
|
|
|
|
void NpDeformableVolume::setMaxLinearVelocity(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setMaxVelocity() not allowed while simulation is running. "
|
|
"Call will be ignored.");
|
|
|
|
mCore.setMaxLinearVelocity(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getMaxLinearVelocity() const
|
|
{
|
|
return mCore.getMaxLinearVelocity();
|
|
}
|
|
|
|
void NpDeformableVolume::setMaxDepenetrationVelocity(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
PX_CHECK_AND_RETURN(v > 0.0f, "PxDeformableBody::setMaxDepenetrationVelocity(): value must be greater than zero.");
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setMaxDepenetrationVelocity() not allowed while simulation is running. "
|
|
"Call will be ignored.");
|
|
|
|
mCore.setMaxPenetrationBias(-v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getMaxDepenetrationVelocity() const
|
|
{
|
|
return -mCore.getMaxPenetrationBias();
|
|
}
|
|
|
|
void NpDeformableVolume::setSelfCollisionFilterDistance(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setSelfCollisionFilterDistance() not allowed while simulation is running. "
|
|
"Call will be ignored.");
|
|
|
|
mCore.setSelfCollisionFilterDistance(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getSelfCollisionFilterDistance() const
|
|
{
|
|
return mCore.getSelfCollisionFilterDistance();
|
|
}
|
|
|
|
void NpDeformableVolume::setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
PX_CHECK_AND_RETURN(minPositionIters > 0, "PxDeformableBody::setSolverIterationCounts: minPositionIters must be more than zero!");
|
|
PX_CHECK_AND_RETURN(minPositionIters <= 255, "PxDeformableBody::setSolverIterationCounts: minPositionIters must be no greater than 255!");
|
|
PX_CHECK_AND_RETURN(minVelocityIters <= 255, "PxDeformableBody::setSolverIterationCounts: minVelocityIters must be no greater than 255!");
|
|
PX_WARN_ONCE_IF(minVelocityIters > 1, "PxDeformableBody::setSolverIterationCounts: minVelocityIters are ignored!");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setSolverIterationCounts() not allowed while simulation is running. Call will be ignored.");
|
|
|
|
mCore.setSolverIterationCounts((minVelocityIters & 0xff) << 8 | (minPositionIters & 0xff));
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
void NpDeformableVolume::getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const
|
|
{
|
|
NP_READ_CHECK(getNpScene());
|
|
|
|
PxU16 x = mCore.getSolverIterationCounts();
|
|
minVelocityIters = PxU32(x >> 8);
|
|
minPositionIters = PxU32(x & 0xff);
|
|
}
|
|
|
|
void NpDeformableVolume::setSleepThreshold(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setSleepThreshold() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setSleepThreshold(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getSleepThreshold() const
|
|
{
|
|
return mCore.getSleepThreshold();
|
|
}
|
|
|
|
void NpDeformableVolume::setSettlingThreshold(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setSettlingThreshold() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setSettlingThreshold(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getSettlingThreshold() const
|
|
{
|
|
return mCore.getSettlingThreshold();
|
|
}
|
|
|
|
void NpDeformableVolume::setSettlingDamping(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setSettlingDamping() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setSettlingDamping(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getSettlingDamping() const
|
|
{
|
|
return mCore.getSettlingDamping();
|
|
}
|
|
|
|
void NpDeformableVolume::setWakeCounter(PxReal wakeCounterValue)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setWakeCounter() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setWakeCounter(wakeCounterValue);
|
|
//UPDATE_PVD_PROPERTIES_OBJECT()
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getWakeCounter() const
|
|
{
|
|
NP_READ_CHECK(getNpScene());
|
|
return mCore.getWakeCounter();
|
|
}
|
|
|
|
bool NpDeformableVolume::isSleeping() const
|
|
{
|
|
Sc::DeformableVolumeSim* sim = mCore.getSim();
|
|
if (sim)
|
|
{
|
|
return sim->isSleeping();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
PxShape* NpDeformableVolume::getShape()
|
|
{
|
|
return mShape;
|
|
}
|
|
|
|
bool NpDeformableVolume::attachShape(PxShape& shape)
|
|
{
|
|
NpShape* npShape = static_cast<NpShape*>(&shape);
|
|
|
|
PX_CHECK_AND_RETURN_NULL(npShape->getGeometryTypeFast() == PxGeometryType::eTETRAHEDRONMESH,
|
|
"PxDeformableVolume::attachShape: Geometry type must be tetrahedron mesh geometry");
|
|
PX_CHECK_AND_RETURN_NULL(mShape == NULL,
|
|
"PxDeformableVolume::attachShape: deformable volume can just have one shape");
|
|
PX_CHECK_AND_RETURN_NULL(shape.isExclusive(),
|
|
"PxDeformableVolume::attachShape: shape must be exclusive");
|
|
|
|
const PxTetrahedronMeshGeometry& tetGeom = static_cast<const PxTetrahedronMeshGeometry&>(npShape->getGeometry());
|
|
PX_CHECK_AND_RETURN_NULL(tetGeom.tetrahedronMesh != NULL,
|
|
"PxDeformableVolume::attachShape: PxTetrahedronMeshGeometry::tetrahedronMesh is NULL");
|
|
|
|
Gu::BVTetrahedronMesh* tetMesh = static_cast<Gu::BVTetrahedronMesh*>(tetGeom.tetrahedronMesh);
|
|
PX_CHECK_AND_RETURN_NULL(tetMesh->getNbTetrahedronsFast() <= PX_MAX_NB_DEFORMABLE_VOLUME_TET,
|
|
"PxDeformableVolume::attachShape: collision mesh consists of too many tetrahedrons, see PX_MAX_NB_DEFORMABLE_VOLUME_TET");
|
|
|
|
PX_CHECK_AND_RETURN_NULL(npShape->getCore().getCore().mShapeCoreFlags & PxShapeCoreFlag::eDEFORMABLE_VOLUME_SHAPE,
|
|
"PxDeformableVolume::attachShape: shape must be a deformable volume shape!");
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
PX_CHECK_AND_RETURN_NULL(core.positionInvMass == NULL,
|
|
"PxDeformableVolume::attachShape: positionInvMass already exists, overwrite not allowed, call detachShape first");
|
|
|
|
mShape = npShape;
|
|
|
|
PX_ASSERT(shape.getActor() == NULL);
|
|
npShape->onActorAttach(*this);
|
|
|
|
createAllocator();
|
|
const PxU32 numVerts = tetMesh->getNbVerticesFast();
|
|
core.positionInvMass = reinterpret_cast<PxVec4*>(mDeviceMemoryAllocator->allocate(numVerts * sizeof(PxVec4), PxsHeapStats::eSHARED_SOFTBODY, PX_FL));
|
|
core.restPosition = reinterpret_cast<PxVec4*>(mDeviceMemoryAllocator->allocate(numVerts * sizeof(PxVec4), PxsHeapStats::eSHARED_SOFTBODY, PX_FL));
|
|
|
|
updateMaterials();
|
|
|
|
return true;
|
|
}
|
|
|
|
void NpDeformableVolume::detachShape()
|
|
{
|
|
PX_CHECK_MSG(getNpSceneFromActor(*this) == NULL,
|
|
"Detaching a shape from a PxDeformableVolume is currenly only allowed as long as it is not part of a scene. "
|
|
"Please remove the deformable volume from its scene first.");
|
|
|
|
PX_ASSERT(mDeviceMemoryAllocator);
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
if (core.restPosition)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.restPosition);
|
|
core.restPosition = NULL;
|
|
}
|
|
if (core.positionInvMass)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.positionInvMass);
|
|
core.positionInvMass = NULL;
|
|
}
|
|
|
|
if (mShape)
|
|
mShape->onActorDetach();
|
|
mShape = NULL;
|
|
}
|
|
|
|
PxCudaContextManager* NpDeformableVolume::getCudaContextManager() const
|
|
{
|
|
return mCudaContextManager;
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::setParameter(const PxFEMParameters& parameters)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setParameter() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setLinearDamping(parameters.velocityDamping);
|
|
mCore.setSettlingThreshold(parameters.settlingThreshold);
|
|
mCore.setSleepThreshold(parameters.sleepThreshold);
|
|
mCore.setSettlingDamping(parameters.sleepDamping);
|
|
mCore.setSelfCollisionFilterDistance(parameters.selfCollisionFilterDistance);
|
|
mCore.setSelfCollisionStressTolerance(parameters.selfCollisionStressTolerance);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
// deprecated
|
|
PxFEMParameters NpDeformableVolume::getParameter() const
|
|
{
|
|
NP_READ_CHECK(getNpScene());
|
|
PxFEMParameters parameters;
|
|
parameters.velocityDamping = mCore.getLinearDamping();
|
|
parameters.settlingThreshold = mCore.getSettlingThreshold();
|
|
parameters.sleepThreshold = mCore.getSleepThreshold();
|
|
parameters.sleepDamping = mCore.getSettlingDamping();
|
|
parameters.selfCollisionFilterDistance = mCore.getSelfCollisionFilterDistance();
|
|
parameters.selfCollisionStressTolerance = mCore.getSelfCollisionStressTolerance();
|
|
return parameters;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// PxDeformableVolume API
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void NpDeformableVolume::setDeformableVolumeFlag(PxDeformableVolumeFlag::Enum flag, bool val)
|
|
{
|
|
PxDeformableVolumeFlags flags = mCore.getVolumeFlags();
|
|
if (val)
|
|
flags.raise(flag);
|
|
else
|
|
flags.clear(flag);
|
|
|
|
mCore.setVolumeFlags(flags);
|
|
|
|
//deprecation functionality
|
|
PxDeformableBodyFlags bodyFlags = mCore.getBodyFlags();
|
|
mirrorTwinFlags(bodyFlags, flags);
|
|
mCore.setBodyFlags(bodyFlags);
|
|
}
|
|
|
|
void NpDeformableVolume::setDeformableVolumeFlags(PxDeformableVolumeFlags flags)
|
|
{
|
|
mCore.setVolumeFlags(flags);
|
|
|
|
//deprecation functionality
|
|
PxDeformableBodyFlags bodyFlags = mCore.getBodyFlags();
|
|
mirrorTwinFlags(bodyFlags, flags);
|
|
mCore.setBodyFlags(bodyFlags);
|
|
}
|
|
|
|
PxDeformableVolumeFlags NpDeformableVolume::getDeformableVolumeFlags() const
|
|
{
|
|
return mCore.getVolumeFlags();
|
|
}
|
|
|
|
void NpDeformableVolume::setSelfCollisionStressTolerance(const PxReal v)
|
|
{
|
|
NpScene* npScene = getNpScene();
|
|
NP_WRITE_CHECK(npScene);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxDeformableBody::setSelfCollisionStressTolerance() not allowed while simulation is running. "
|
|
"Call will be ignored.");
|
|
|
|
mCore.setSelfCollisionStressTolerance(v);
|
|
UPDATE_PVD_PROPERTY
|
|
}
|
|
|
|
PxReal NpDeformableVolume::getSelfCollisionStressTolerance() const
|
|
{
|
|
return mCore.getSelfCollisionStressTolerance();
|
|
}
|
|
|
|
PxVec4* NpDeformableVolume::getPositionInvMassBufferD()
|
|
{
|
|
PX_CHECK_AND_RETURN_NULL(mShape != NULL, "PxDeformableVolume::getPositionInvMassBufferD: Softbody does not have a shape, attach shape first.");
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
return core.positionInvMass;
|
|
}
|
|
|
|
PxVec4* NpDeformableVolume::getRestPositionBufferD()
|
|
{
|
|
PX_CHECK_AND_RETURN_NULL(mShape != NULL, "PxDeformableVolume::getRestPositionBufferD: Softbody does not have a shape, attach shape first.");
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
return core.restPosition;
|
|
}
|
|
|
|
PxVec4* NpDeformableVolume::getSimPositionInvMassBufferD()
|
|
{
|
|
PX_CHECK_AND_RETURN_NULL(mSimulationMesh != NULL, "PxDeformableVolume::getSimPositionInvMassBufferD: Softbody does not have a simulation mesh, attach simulation mesh first.");
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
return core.simPositionInvMass;
|
|
}
|
|
|
|
PxVec4* NpDeformableVolume::getSimVelocityBufferD()
|
|
{
|
|
PX_CHECK_AND_RETURN_NULL(mSimulationMesh != NULL, "PxDeformableVolume::getSimVelocityBufferD: Softbody does not have a simulation mesh, attach simulation mesh first.");
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
return core.simVelocity;
|
|
}
|
|
|
|
void NpDeformableVolume::markDirty(PxDeformableVolumeDataFlags flags)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
core.dirtyFlags |= flags;
|
|
}
|
|
|
|
void NpDeformableVolume::setKinematicTargetBufferD(const PxVec4* positions)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(),
|
|
"PxDeformableVolume::setKinematicTargetBufferD() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
mCore.setKinematicTargets(positions);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::setKinematicTargetBufferD(const PxVec4* positions, PxDeformableVolumeFlags flags)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(),
|
|
"PxDeformableVolume::setKinematicTargetBufferD() not allowed while simulation is running. Call will be ignored.")
|
|
|
|
PX_CHECK_AND_RETURN(!(positions == NULL && flags != PxDeformableVolumeFlags(0)),
|
|
"PxDeformableVolume::setKinematicTargetBufferD: targets cannot be null if flags are set to be kinematic.");
|
|
|
|
//toggling flags automatically seems SDK atypcal, hence the deprecation ...
|
|
PxDeformableVolumeFlags volumeFlags = mCore.getVolumeFlags();
|
|
if (positions != NULL)
|
|
{
|
|
if (flags.isSet(PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC))
|
|
{
|
|
volumeFlags.raise(PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC);
|
|
}
|
|
if (flags.isSet(PxDeformableVolumeFlag::eKINEMATIC))
|
|
{
|
|
volumeFlags.raise(PxDeformableVolumeFlag::eKINEMATIC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
volumeFlags.clear(PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC);
|
|
volumeFlags.clear(PxDeformableVolumeFlag::eKINEMATIC);
|
|
}
|
|
mCore.setVolumeFlags(volumeFlags);
|
|
|
|
//deprecation functionality
|
|
PxDeformableBodyFlags bodyFlags = mCore.getBodyFlags();
|
|
mirrorTwinFlags(bodyFlags, volumeFlags);
|
|
mCore.setBodyFlags(bodyFlags);
|
|
|
|
mCore.setKinematicTargets(positions);
|
|
}
|
|
|
|
bool NpDeformableVolume::attachSimulationMesh(PxTetrahedronMesh& simulationMesh, PxDeformableVolumeAuxData& deformableVolumeAuxData)
|
|
{
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
|
|
PX_CHECK_AND_RETURN_NULL(core.simPositionInvMass == NULL, "PxDeformableVolume::attachSimulationMesh: simPositionInvMass already exists, overwrite not allowed, call detachSimulationMesh first");
|
|
PX_CHECK_AND_RETURN_NULL(core.simVelocity == NULL, "PxDeformableVolume::attachSimulationMesh: simVelocity already exists, overwrite not allowed, call detachSimulationMesh first");
|
|
Gu::TetrahedronMesh& tetMesh = static_cast<Gu::TetrahedronMesh&>(simulationMesh);
|
|
PX_CHECK_AND_RETURN_NULL(tetMesh.getNbTetrahedronsFast() <= PX_MAX_NB_DEFORMABLE_VOLUME_TET, "PxDeformableVolume::attachSimulationMesh: simulation mesh contains too many tetrahedrons, see PX_MAX_NB_DEFORMABLE_VOLUME_TET");
|
|
|
|
mSimulationMesh = &tetMesh;
|
|
mAuxData = static_cast<Gu::DeformableVolumeAuxData*>(&deformableVolumeAuxData);
|
|
const PxU32 numVertsGM = tetMesh.getNbVerticesFast();
|
|
|
|
createAllocator();
|
|
|
|
core.simPositionInvMass = reinterpret_cast<PxVec4*>(mDeviceMemoryAllocator->allocate(numVertsGM * sizeof(PxVec4), PxsHeapStats::eSHARED_SOFTBODY, PX_FL));
|
|
core.simVelocity = reinterpret_cast<PxVec4*>(mDeviceMemoryAllocator->allocate(numVertsGM * sizeof(PxVec4), PxsHeapStats::eSHARED_SOFTBODY, PX_FL));
|
|
|
|
return true;
|
|
}
|
|
|
|
void NpDeformableVolume::detachSimulationMesh()
|
|
{
|
|
PX_ASSERT(mDeviceMemoryAllocator);
|
|
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
if (core.simPositionInvMass)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.simPositionInvMass);
|
|
core.simPositionInvMass = NULL;
|
|
}
|
|
|
|
if (core.simVelocity)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.simVelocity);
|
|
core.simVelocity = NULL;
|
|
}
|
|
|
|
mSimulationMesh = NULL;
|
|
mAuxData = NULL;
|
|
}
|
|
|
|
PxTetrahedronMesh* NpDeformableVolume::getCollisionMesh()
|
|
{
|
|
const PxTetrahedronMeshGeometry& tetMeshGeom = static_cast<const PxTetrahedronMeshGeometry&>(mShape->getGeometry());
|
|
return tetMeshGeom.tetrahedronMesh;
|
|
}
|
|
|
|
const PxTetrahedronMesh* NpDeformableVolume::getCollisionMesh() const
|
|
{
|
|
const PxTetrahedronMeshGeometry& tetMeshGeom = static_cast<const PxTetrahedronMeshGeometry&>(mShape->getGeometry());
|
|
return tetMeshGeom.tetrahedronMesh;
|
|
}
|
|
|
|
PxU32 NpDeformableVolume::getGpuDeformableVolumeIndex()
|
|
{
|
|
NP_READ_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN_VAL(getNpScene(), "PxDeformableVolume::getGpuDeformableVolumeIndex: Soft body must be in a scene.", 0xffffffff);
|
|
|
|
return mCore.getGpuIndex();
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::addParticleFilter(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::addParticleFilter: Soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((particlesystem == NULL || particlesystem->getScene() != NULL), "PxDeformableVolume::addParticleFilter: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::addParticleFilter: Illegal to call while simulation is running.");
|
|
|
|
NpPBDParticleSystem* npParticleSystem = static_cast<NpPBDParticleSystem*>(particlesystem);
|
|
Sc::ParticleSystemCore& core = npParticleSystem->getCore();
|
|
mCore.addParticleFilter(&core, particleId, buffer ? buffer->getUniqueId() : 0, tetId);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeParticleFilter(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeParticleFilter: Soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((particlesystem == NULL || particlesystem->getScene() != NULL), "PxDeformableVolume::removeParticleFilter: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeParticleFilter: Illegal to call while simulation is running.");
|
|
|
|
NpPBDParticleSystem* npParticleSystem = static_cast<NpPBDParticleSystem*>(particlesystem);
|
|
Sc::ParticleSystemCore& core = npParticleSystem->getCore();
|
|
mCore.removeParticleFilter(&core, particleId, buffer ? buffer->getUniqueId() : 0, tetId);
|
|
}
|
|
|
|
// deprecated
|
|
PxU32 NpDeformableVolume::addParticleAttachment(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId, const PxVec4& barycentric)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "PxDeformableVolume::addParticleAttachment: Soft body must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL((particlesystem == NULL || particlesystem->getScene() != NULL), "PxDeformableVolume::addParticleAttachment: actor must be inserted into the scene.", 0xFFFFFFFF);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "PxDeformableVolume::addParticleAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF);
|
|
|
|
NpPBDParticleSystem* npParticleSystem = static_cast<NpPBDParticleSystem*>(particlesystem);
|
|
Sc::ParticleSystemCore& core = npParticleSystem->getCore();
|
|
return mCore.addParticleAttachment(&core, particleId, buffer ? buffer->getUniqueId() : 0, tetId, barycentric);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeParticleAttachment(PxPBDParticleSystem* particlesystem, PxU32 handle)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::addParticleAttachment: Soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((particlesystem == NULL || particlesystem->getScene() != NULL), "PxDeformableVolume::addParticleAttachment: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::addParticleAttachment: Illegal to call while simulation is running.");
|
|
|
|
NpPBDParticleSystem* npParticleSystem = static_cast<NpPBDParticleSystem*>(particlesystem);
|
|
Sc::ParticleSystemCore& core = npParticleSystem->getCore();
|
|
mCore.removeParticleAttachment(&core, handle);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::addRigidFilter(PxRigidActor* actor, PxU32 vertId)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::addRigidFilter: Soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::addRigidFilter: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::addRigidFilter: Illegal to call while simulation is running.");
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
mCore.addRigidFilter(core, vertId);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeRigidFilter(PxRigidActor* actor, PxU32 vertId)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeRigidFilter: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::removeRigidFilter: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeRigidFilter: Illegal to call while simulation is running.");
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
mCore.removeRigidFilter(core, vertId);
|
|
}
|
|
|
|
// deprecated
|
|
PxU32 NpDeformableVolume::addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "PxDeformableVolume::addRigidAttachment: Soft body must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::addRigidAttachment: actor must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "PxDeformableVolume::addRigidAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "PxDeformableVolume::addRigidAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF);
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
|
|
PxVec3 aPose = actorSpacePose;
|
|
if (actor && actor->getConcreteType()==PxConcreteType::eRIGID_STATIC)
|
|
{
|
|
NpRigidStatic* stat = static_cast<NpRigidStatic*>(actor);
|
|
aPose = stat->getGlobalPose().transform(aPose);
|
|
}
|
|
|
|
return mCore.addRigidAttachment(core, vertId, aPose, constraint, true);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeRigidAttachment(PxRigidActor* actor, PxU32 handle)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeRigidAttachment: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::removeRigidAttachment: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeRigidAttachment: Illegal to call while simulation is running.");
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
mCore.removeRigidAttachment(core, handle);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::addTetRigidFilter(PxRigidActor* actor, PxU32 tetIdx)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::addTetRigidFilter: Soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::addTetRigidFilter: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::addTetRigidFilter: Illegal to call while simulation is running.");
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
return mCore.addTetRigidFilter(core, tetIdx);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeTetRigidFilter(PxRigidActor* actor, PxU32 tetIdx)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeTetRigidFilter: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::removeTetRigidFilter: actor must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeTetRigidFilter: Illegal to call while simulation is running.");
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
mCore.removeTetRigidFilter(core, tetIdx);
|
|
}
|
|
|
|
// deprecated
|
|
PxU32 NpDeformableVolume::addTetRigidAttachment(PxRigidActor* actor, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "PxDeformableVolume::addTetRigidAttachment: Soft body must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL((actor == NULL || actor->getScene() != NULL), "PxDeformableVolume::addTetRigidAttachment: actor must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "PxDeformableVolume::addTetRigidAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "PxDeformableVolume::addTetRigidAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF);
|
|
|
|
Sc::BodyCore* core = getBodyCore(actor);
|
|
|
|
PxVec3 aPose = actorSpacePose;
|
|
if (actor && actor->getConcreteType()==PxConcreteType::eRIGID_STATIC)
|
|
{
|
|
NpRigidStatic* stat = static_cast<NpRigidStatic*>(actor);
|
|
aPose = stat->getGlobalPose().transform(aPose);
|
|
}
|
|
|
|
return mCore.addTetRigidAttachment(core, tetIdx, barycentric, aPose, constraint, true);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::addSoftBodyFilter(PxDeformableVolume* softbody0, PxU32 tetIdx0, PxU32 tetIdx1)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(softbody0 != NULL, "PxDeformableVolume::addSoftBodyFilter: soft body must not be null");
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::addSoftBodyFilter: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN(softbody0->getScene() != NULL, "PxDeformableVolume::addSoftBodyFilter: soft body must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::addSoftBodyFilter: Illegal to call while simulation is running.");
|
|
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(softbody0);
|
|
Sc::DeformableVolumeCore* core = &dyn->getCore();
|
|
|
|
mCore.addSoftBodyFilter(*core, tetIdx0, tetIdx1);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeSoftBodyFilter(PxDeformableVolume* softbody0, PxU32 tetIdx0, PxU32 tetIdx1)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(softbody0 != NULL, "PxDeformableVolume::removeSoftBodyFilter: soft body must not be null");
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeSoftBodyFilter: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN(softbody0->getScene() != NULL, "PxDeformableVolume::removeSoftBodyFilter: soft body must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeSoftBodyFilter: Illegal to call while simulation is running.");
|
|
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(softbody0);
|
|
Sc::DeformableVolumeCore* core = &dyn->getCore();
|
|
|
|
mCore.removeSoftBodyFilter(*core, tetIdx0, tetIdx1);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::addSoftBodyFilters(PxDeformableVolume* softbody0, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(softbody0 != NULL, "PxDeformableVolume::addSoftBodyFilter: soft body must not be null");
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::addSoftBodyFilter: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN(softbody0->getScene() != NULL, "PxDeformableVolume::addSoftBodyFilter: soft body must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::addSoftBodyFilter: Illegal to call while simulation is running.");
|
|
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(softbody0);
|
|
Sc::DeformableVolumeCore* core = &dyn->getCore();
|
|
|
|
mCore.addSoftBodyFilters(*core, tetIndices0, tetIndices1, tetIndicesSize);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeSoftBodyFilters(PxDeformableVolume* softbody0, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(softbody0 != NULL, "PxDeformableVolume::removeSoftBodyFilter: soft body must not be null");
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeSoftBodyFilter: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN(softbody0->getScene() != NULL, "PxDeformableVolume::removeSoftBodyFilter: soft body must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeSoftBodyFilter: Illegal to call while simulation is running.");
|
|
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(softbody0);
|
|
Sc::DeformableVolumeCore* core = &dyn->getCore();
|
|
|
|
mCore.removeSoftBodyFilters(*core, tetIndices0, tetIndices1, tetIndicesSize);
|
|
}
|
|
|
|
// deprecated
|
|
PxU32 NpDeformableVolume::addSoftBodyAttachment(PxDeformableVolume* softbody0, PxU32 tetIdx0, const PxVec4& tetBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1,
|
|
PxConeLimitedConstraint* constraint, PxReal constraintOffset)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN_VAL(softbody0 != NULL, "PxDeformableVolume::addSoftBodyAttachment: soft body must not be null", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "PxDeformableVolume::addSoftBodyAttachment: soft body must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL(softbody0->getScene() != NULL, "PxDeformableVolume::addSoftBodyAttachment: soft body must be inserted into the scene.", 0xFFFFFFFF);
|
|
PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "PxDeformableVolume::addSoftBodyAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF);
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "PxDeformableVolume::addSoftBodyAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF);
|
|
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(softbody0);
|
|
Sc::DeformableVolumeCore* core = &dyn->getCore();
|
|
|
|
return mCore.addSoftBodyAttachment(*core, tetIdx0, tetBarycentric0, tetIdx1, tetBarycentric1, constraint, constraintOffset, true);
|
|
}
|
|
|
|
// deprecated
|
|
void NpDeformableVolume::removeSoftBodyAttachment(PxDeformableVolume* softbody0, PxU32 handle)
|
|
{
|
|
NP_WRITE_CHECK(getNpScene());
|
|
PX_CHECK_AND_RETURN(softbody0 != NULL, "PxDeformableVolume::removeSoftBodyAttachment: soft body must not be null");
|
|
PX_CHECK_AND_RETURN(getNpScene() != NULL, "PxDeformableVolume::removeSoftBodyAttachment: soft body must be inserted into the scene.");
|
|
PX_CHECK_AND_RETURN(softbody0->getScene() != NULL, "PxDeformableVolume::removeSoftBodyAttachment: soft body must be inserted into the scene.");
|
|
|
|
PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxDeformableVolume::removeSoftBodyAttachment: Illegal to call while simulation is running.");
|
|
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(softbody0);
|
|
Sc::DeformableVolumeCore* core = &dyn->getCore();
|
|
|
|
mCore.removeSoftBodyAttachment(*core, handle);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void NpDeformableVolume::updateMaterials()
|
|
{
|
|
mCore.clearMaterials();
|
|
for (PxU32 i = 0; i < mShape->getNbMaterials(); ++i)
|
|
{
|
|
PxDeformableVolumeMaterial* material;
|
|
mShape->getDeformableVolumeMaterials(&material, 1, i);
|
|
mCore.addMaterial(static_cast<NpDeformableVolumeMaterial*>(material)->mMaterial.mMaterialIndex);
|
|
}
|
|
}
|
|
|
|
void NpDeformableVolume::createAllocator()
|
|
{
|
|
if (!mMemoryManager)
|
|
{
|
|
PxPhysXGpu* physXGpu = PxvGetPhysXGpu(true);
|
|
PX_ASSERT(physXGpu != NULL);
|
|
|
|
mMemoryManager = physXGpu->createGpuMemoryManager(mCudaContextManager);
|
|
mDeviceMemoryAllocator = mMemoryManager->getDeviceMemoryAllocator();
|
|
}
|
|
PX_ASSERT(mMemoryManager != NULL);
|
|
PX_ASSERT(mDeviceMemoryAllocator != NULL);
|
|
}
|
|
|
|
void NpDeformableVolume::releaseAllocator()
|
|
{
|
|
// deallocate device memory if not released already.
|
|
Dy::DeformableVolumeCore& core = mCore.getCore();
|
|
if (core.simVelocity)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.simVelocity);
|
|
core.simVelocity = NULL;
|
|
}
|
|
if (core.simPositionInvMass)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.simPositionInvMass);
|
|
core.simPositionInvMass = NULL;
|
|
}
|
|
if (core.restPosition)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.restPosition);
|
|
core.restPosition = NULL;
|
|
}
|
|
if (core.positionInvMass)
|
|
{
|
|
mDeviceMemoryAllocator->deallocate(core.positionInvMass);
|
|
core.positionInvMass = NULL;
|
|
}
|
|
|
|
if (mMemoryManager != NULL)
|
|
{
|
|
mDeviceMemoryAllocator = NULL; // released by memory manager
|
|
PX_DELETE(mMemoryManager);
|
|
}
|
|
}
|
|
|
|
Sc::DeformableVolumeCore* getDeformableVolumeCore(PxActor* actor)
|
|
{
|
|
if (actor->getConcreteType() == PxConcreteType::eDEFORMABLE_VOLUME)
|
|
{
|
|
NpDeformableVolume* dyn = static_cast<NpDeformableVolume*>(actor);
|
|
return &dyn->getCore();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
} // namespace physx
|
|
|
|
#endif //PX_SUPPORT_GPU_PHYSX
|