200 lines
6.6 KiB
C++
200 lines
6.6 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.
|
||
|
|
|
||
|
|
#include "foundation/PxPreprocessor.h"
|
||
|
|
|
||
|
|
#if PX_SUPPORT_GPU_PHYSX
|
||
|
|
|
||
|
|
#include "ScDeformableVolumeSim.h"
|
||
|
|
#include "geometry/PxTetrahedronMesh.h"
|
||
|
|
|
||
|
|
using namespace physx;
|
||
|
|
using namespace Dy;
|
||
|
|
|
||
|
|
Sc::DeformableVolumeSim::DeformableVolumeSim(DeformableVolumeCore& core, Scene& scene) :
|
||
|
|
GPUActorSim(scene, core, NULL)
|
||
|
|
{
|
||
|
|
mLLDeformableVolume = scene.createLLDeformableVolume(this);
|
||
|
|
|
||
|
|
mNodeIndex = scene.getSimpleIslandManager()->addNode(false, false, IG::Node::eDEFORMABLE_VOLUME_TYPE, mLLDeformableVolume);
|
||
|
|
|
||
|
|
scene.getSimpleIslandManager()->activateNode(mNodeIndex);
|
||
|
|
|
||
|
|
mLLDeformableVolume->setElementId(mShapeSim.getElementID());
|
||
|
|
}
|
||
|
|
|
||
|
|
Sc::DeformableVolumeSim::~DeformableVolumeSim()
|
||
|
|
{
|
||
|
|
if (!mLLDeformableVolume)
|
||
|
|
return;
|
||
|
|
|
||
|
|
mScene.destroyLLDeformableVolume(*mLLDeformableVolume);
|
||
|
|
|
||
|
|
mScene.getSimpleIslandManager()->removeNode(mNodeIndex);
|
||
|
|
|
||
|
|
mCore.setSim(NULL);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool Sc::DeformableVolumeSim::isSleeping() const
|
||
|
|
{
|
||
|
|
IG::IslandSim& sim = mScene.getSimpleIslandManager()->getAccurateIslandSim();
|
||
|
|
return sim.getActiveNodeIndex(mNodeIndex) == PX_INVALID_NODE;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sc::DeformableVolumeSim::onSetWakeCounter()
|
||
|
|
{
|
||
|
|
mScene.getSimulationController()->setSoftBodyWakeCounter(mLLDeformableVolume);
|
||
|
|
if (mLLDeformableVolume->getCore().wakeCounter > 0.f)
|
||
|
|
mScene.getSimpleIslandManager()->activateNode(mNodeIndex);
|
||
|
|
else
|
||
|
|
mScene.getSimpleIslandManager()->deactivateNode(mNodeIndex);
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sc::DeformableVolumeSim::attachShapeCore(ShapeCore* core)
|
||
|
|
{
|
||
|
|
mShapeSim.setCore(core);
|
||
|
|
{
|
||
|
|
PX_ASSERT(getWorldBounds().isFinite());
|
||
|
|
|
||
|
|
const PxU32 index = mShapeSim.getElementID();
|
||
|
|
|
||
|
|
mScene.getBoundsArray().setBounds(getWorldBounds(), index);
|
||
|
|
|
||
|
|
addToAABBMgr(Bp::FilterType::DEFORMABLE_VOLUME);
|
||
|
|
}
|
||
|
|
|
||
|
|
PxsShapeCore* shapeCore = const_cast<PxsShapeCore*>(&core->getCore());
|
||
|
|
mLLDeformableVolume->setShapeCore(shapeCore);
|
||
|
|
}
|
||
|
|
|
||
|
|
PxBounds3 Sc::DeformableVolumeSim::getWorldBounds() const
|
||
|
|
{
|
||
|
|
const PxTetrahedronMeshGeometry& tetGeom = static_cast<const PxTetrahedronMeshGeometry&>(mShapeSim.getCore().getGeometry());
|
||
|
|
|
||
|
|
return tetGeom.tetrahedronMesh->getLocalBounds();
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sc::DeformableVolumeSim::attachSimulationMesh(PxTetrahedronMesh* simulationMesh, PxDeformableVolumeAuxData* simulationState)
|
||
|
|
{
|
||
|
|
mLLDeformableVolume->setSimShapeCore(simulationMesh, simulationState);
|
||
|
|
}
|
||
|
|
|
||
|
|
PxTetrahedronMesh* Sc::DeformableVolumeSim::getSimulationMesh()
|
||
|
|
{
|
||
|
|
return mLLDeformableVolume->getSimulationMesh();
|
||
|
|
}
|
||
|
|
|
||
|
|
PxDeformableVolumeAuxData* Sc::DeformableVolumeSim::getAuxData()
|
||
|
|
{
|
||
|
|
return mLLDeformableVolume->getAuxData();
|
||
|
|
}
|
||
|
|
|
||
|
|
PxTetrahedronMesh* Sc::DeformableVolumeSim::getCollisionMesh()
|
||
|
|
{
|
||
|
|
return mLLDeformableVolume->getCollisionMesh();
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sc::DeformableVolumeSim::enableSelfCollision()
|
||
|
|
{
|
||
|
|
if (isActive())
|
||
|
|
{
|
||
|
|
mScene.getSimulationController()->activateSoftbodySelfCollision(mLLDeformableVolume);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sc::DeformableVolumeSim::disableSelfCollision()
|
||
|
|
{
|
||
|
|
if (isActive())
|
||
|
|
{
|
||
|
|
mScene.getSimulationController()->deactivateSoftbodySelfCollision(mLLDeformableVolume);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*void Sc::DeformableVolumeSim::activate()
|
||
|
|
{
|
||
|
|
// Activate body
|
||
|
|
//{
|
||
|
|
// PX_ASSERT((!isKinematic()) || notInScene() || readInternalFlag(InternalFlags(BF_KINEMATIC_MOVED | BF_KINEMATIC_SURFACE_VELOCITY))); // kinematics should only get activated when a target is set.
|
||
|
|
// // exception: object gets newly added, then the state change will happen later
|
||
|
|
// if (!isArticulationLink())
|
||
|
|
// {
|
||
|
|
// mLLBody.mInternalFlags &= (~PxsRigidBody::eFROZEN);
|
||
|
|
// // Put in list of activated bodies. The list gets cleared at the end of a sim step after the sleep callbacks have been fired.
|
||
|
|
// getScene().onBodyWakeUp(this);
|
||
|
|
// }
|
||
|
|
|
||
|
|
// BodyCore& core = getBodyCore();
|
||
|
|
// if (core.getFlags() & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW)
|
||
|
|
// {
|
||
|
|
// PX_ASSERT(!getScene().isInPosePreviewList(*this));
|
||
|
|
// getScene().addToPosePreviewList(*this);
|
||
|
|
// }
|
||
|
|
// createSqBounds();
|
||
|
|
//}
|
||
|
|
|
||
|
|
activateInteractions(*this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void Sc::DeformableVolumeSim::deactivate()
|
||
|
|
{
|
||
|
|
deactivateInteractions(*this);
|
||
|
|
|
||
|
|
// Deactivate body
|
||
|
|
//{
|
||
|
|
// PX_ASSERT((!isKinematic()) || notInScene() || !readInternalFlag(BF_KINEMATIC_MOVED)); // kinematics should only get deactivated when no target is set.
|
||
|
|
// // exception: object gets newly added, then the state change will happen later
|
||
|
|
// BodyCore& core = getBodyCore();
|
||
|
|
// if (!readInternalFlag(BF_ON_DEATHROW))
|
||
|
|
// {
|
||
|
|
// // Set velocity to 0.
|
||
|
|
// // Note: this is also fine if the method gets called because the user puts something to sleep (this behavior is documented in the API)
|
||
|
|
// PX_ASSERT(core.getWakeCounter() == 0.0f);
|
||
|
|
// const PxVec3 zero(0.0f);
|
||
|
|
// core.setLinearVelocityInternal(zero);
|
||
|
|
// core.setAngularVelocityInternal(zero);
|
||
|
|
|
||
|
|
// setForcesToDefaults(!(mLLBody.mInternalFlags & PxsRigidBody::eDISABLE_GRAVITY));
|
||
|
|
// }
|
||
|
|
|
||
|
|
// if (!isArticulationLink()) // Articulations have their own sleep logic.
|
||
|
|
// getScene().onBodySleep(this);
|
||
|
|
|
||
|
|
// if (core.getFlags() & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW)
|
||
|
|
// {
|
||
|
|
// PX_ASSERT(getScene().isInPosePreviewList(*this));
|
||
|
|
// getScene().removeFromPosePreviewList(*this);
|
||
|
|
// }
|
||
|
|
// destroySqBounds();
|
||
|
|
//}
|
||
|
|
}*/
|
||
|
|
|
||
|
|
PxU32 Sc::DeformableVolumeSim::getGpuIndex() const
|
||
|
|
{
|
||
|
|
return mLLDeformableVolume->getGpuIndex();
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif //PX_SUPPORT_GPU_PHYSX
|