Revision control

+ // 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-2026 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 NP_PBD_PARTICLE_SYSTEM_H
+ #define NP_PBD_PARTICLE_SYSTEM_H
+
+ #if PX_SUPPORT_GPU_PHYSX
+
+ #include "PxPBDParticleSystem.h"
+ #include "PxParticleMaterial.h"
+ #include "PxSparseGridParams.h"
+ #include "NpActorTemplate.h"
+ #include "ScParticleSystemSim.h"
+
+ namespace physx
+ {
+ class PxCudaContextManager;
+ class PxRigidActor;
+ class PxSerializationContext;
+ class PxParticleBuffer;
+ class NpScene;
+ class NpParticleBuffer;
+ class NpParticleAndDiffuseBuffer;
+ class NpPBDParticleSystem : public NpActorTemplate<PxPBDParticleSystem>
+ {
+ public:
+ NpPBDParticleSystem(PxU32 maxNeighborhood, PxReal neighborhoodScale, PxCudaContextManager& contextManager);
+ NpPBDParticleSystem(PxBaseFlags baseFlags);
+
+ virtual ~NpPBDParticleSystem(){}
+
+ void exportData(PxSerializationContext& /*context*/) const {}
+
+ // PxBase
+ virtual void release() PX_OVERRIDE;
+ //~PxBase
+
+ // PxActor
+ virtual PxActorType::Enum getType() const PX_OVERRIDE { return PxActorType::ePBD_PARTICLESYSTEM; }
+ //~PxActor
+
+ // PxPBDParticleSystem
+ virtual PxCudaContextManager* getCudaContextManager() const PX_OVERRIDE { return mCudaContextManager; }
+
+ virtual PxBounds3 getWorldBounds(PxReal inflation = 1.01f) const PX_OVERRIDE;
+
+ virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) PX_OVERRIDE;
+ virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const PX_OVERRIDE;
+
+ virtual void setRestOffset(PxReal restOffset) PX_OVERRIDE { scSetRestOffset(restOffset); }
+ virtual PxReal getRestOffset() const PX_OVERRIDE { return mCore.getRestOffset(); }
+
+ virtual void setContactOffset(PxReal contactOffset) PX_OVERRIDE { scSetContactOffset(contactOffset); }
+ virtual PxReal getContactOffset() const PX_OVERRIDE { return mCore.getContactOffset(); }
+
+ virtual void setParticleContactOffset(PxReal particleContactOffset) PX_OVERRIDE { scSetParticleContactOffset(particleContactOffset); }
+ virtual PxReal getParticleContactOffset() const PX_OVERRIDE { return mCore.getParticleContactOffset(); }
+
+ virtual void setSolidRestOffset(PxReal solidRestOffset) PX_OVERRIDE { scSetSolidRestOffset(solidRestOffset); }
+ virtual PxReal getSolidRestOffset() const PX_OVERRIDE { return mCore.getSolidRestOffset(); }
+
+ virtual void setMaxDepenetrationVelocity(PxReal v) PX_OVERRIDE { scSetMaxDepenetrationVelocity(v); }
+ virtual PxReal getMaxDepenetrationVelocity() const PX_OVERRIDE { return mCore.getMaxDepenetrationVelocity(); }
+
+ virtual void setMaxLinearVelocity(PxReal v) PX_OVERRIDE { scSetMaxVelocity(v); }
+ virtual PxReal getMaxLinearVelocity() const PX_OVERRIDE { return mCore.getMaxVelocity(); }
+
+ virtual void setParticleSystemCallback(PxParticleSystemCallback* callback) PX_OVERRIDE { mCore.setParticleSystemCallback(callback); }
+ virtual PxParticleSystemCallback* getParticleSystemCallback() const PX_OVERRIDE { return mCore.getParticleSystemCallback(); }
+
+ virtual PxParticleLockFlags getParticleLockFlags() const PX_OVERRIDE { return mCore.getLockFlags(); }
+ virtual void setParticleLockFlag(PxParticleLockFlag::Enum flag, bool value) PX_OVERRIDE { scSetParticleLockFlag(flag, value); }
+ virtual void setParticleLockFlags(PxParticleLockFlags flags) PX_OVERRIDE { scSetParticleLockFlags(flags); }
+
+ virtual PxFilterData getSimulationFilterData() const PX_OVERRIDE { return mCore.getShapeCore().getSimulationFilterData(); }
+ virtual void setSimulationFilterData(const PxFilterData& data) PX_OVERRIDE { scSetSimulationFilterData(data); }
+
+ virtual void setParticleFlag(PxParticleFlag::Enum flag, bool val) PX_OVERRIDE { scSetParticleFlag(flag, val); }
+ virtual void setParticleFlags(PxParticleFlags flags) PX_OVERRIDE { scSetParticleFlags(flags); }
+ virtual PxParticleFlags getParticleFlags() const PX_OVERRIDE { return mCore.getFlags(); }
+
+ virtual PxU32 createPhase(PxParticleMaterial* material, PxParticlePhaseFlags flags) PX_OVERRIDE;
+
+ virtual void setWind(const PxVec3& wind) PX_OVERRIDE { scSetWind(wind); }
+ virtual PxVec3 getWind() const PX_OVERRIDE { return mCore.getWind(); }
+
+ virtual void setFluidBoundaryDensityScale(PxReal fluidBoundaryDensityScale) PX_OVERRIDE { scSetFluidBoundaryDensityScale(fluidBoundaryDensityScale); }
+ virtual PxReal getFluidBoundaryDensityScale() const PX_OVERRIDE { return mCore.getFluidBoundaryDensityScale(); }
+
+ virtual void setFluidRestOffset(PxReal fluidRestOffset) PX_OVERRIDE { scSetFluidRestOffset(fluidRestOffset); }
+ virtual PxReal getFluidRestOffset() const PX_OVERRIDE { return mCore.getFluidRestOffset(); }
+
+ virtual void setGridSizeX(PxU32 gridSizeX) PX_OVERRIDE { scSetGridSizeX(gridSizeX); }
+ virtual PxU32 getGridSizeX() const PX_OVERRIDE { return mCore.getGridSizeX(); }
+
+ virtual void setGridSizeY(PxU32 gridSizeY) PX_OVERRIDE { scSetGridSizeY(gridSizeY); }
+ virtual PxU32 getGridSizeY() const PX_OVERRIDE { return mCore.getGridSizeY(); }
+
+ virtual void setGridSizeZ(PxU32 gridSizeZ) PX_OVERRIDE { scSetGridSizeZ(gridSizeZ); }
+ virtual PxU32 getGridSizeZ() const PX_OVERRIDE { return mCore.getGridSizeZ(); }
+
+ virtual PxU32 getParticleMaterials(PxParticleMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const PX_OVERRIDE;
+ virtual PxU32 getNbParticleMaterials() const PX_OVERRIDE { return mCore.getShapeCore().getLLCore().mUniqueMaterialHandles.size(); }
+
+ virtual void addParticleBuffer(PxParticleBuffer* particleBuffer) PX_OVERRIDE;
+ virtual void removeParticleBuffer(PxParticleBuffer* particleBuffer) PX_OVERRIDE;
+
+ virtual PxU32 getGpuParticleSystemIndex() PX_OVERRIDE;
+ //~PxPBDParticleSystem
+
+ public:
+ PX_FORCE_INLINE const Sc::ParticleSystemCore& getCore() const { return mCore; }
+ PX_FORCE_INLINE Sc::ParticleSystemCore& getCore() { return mCore; }
+ static PX_FORCE_INLINE size_t getCoreOffset() { return PX_OFFSET_OF_RT(NpPBDParticleSystem, mCore); }
+
+ #if PX_ENABLE_DEBUG_VISUALIZATION
+ void visualize(PxRenderOutput& out, NpScene& npScene) const;
+ #else
+ PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION
+ #endif
+
+ private:
+
+ PX_INLINE void scSetDirtyFlag()
+ {
+ NP_READ_CHECK(NpBase::getNpScene());
+ NpScene* scene = NpBase::getNpScene();
+ if (scene)
+ {
+ mCore.getSim()->getLowLevelParticleSystem()->mFlag |= Dy::ParticleSystemFlag::eUPDATE_PARAMS;
+ }
+ }
+
+ PX_INLINE void scSetSleepThreshold(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setSleepThreshold(v);
+ //UPDATE_PVD_PROPERTY
+ }
+
+ PX_INLINE void scSetRestOffset(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setRestOffset(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, restOffset, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetContactOffset(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setContactOffset(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, contactOffset, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetParticleContactOffset(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setParticleContactOffset(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, particleContactOffset, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetSolidRestOffset(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setSolidRestOffset(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, solidRestOffset, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetFluidRestOffset(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setFluidRestOffset(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, fluidRestOffset, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetParticleLockFlag(const PxParticleLockFlag::Enum flag, bool value)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ PxParticleLockFlags flags = mCore.getLockFlags();
+ if (value)
+ flags = flags | flag;
+ else
+ flags = flags & (~flag);
+
+ scSetParticleLockFlags(flags);
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, particleLockFlags, static_cast<PxPBDParticleSystem&>(*this), flags);
+ }
+
+ PX_INLINE void scSetParticleLockFlags(const PxParticleLockFlags flags)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setLockFlags(flags);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, particleLockFlags, static_cast<PxPBDParticleSystem&>(*this), flags);
+ }
+
+ PX_INLINE void scSetSimulationFilterData(const PxFilterData& data)
+ {
+ mCore.getShapeCore().setSimulationFilterData(data);
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, simulationFilterData, static_cast<PxPBDParticleSystem&>(*this), data);
+ }
+
+ PX_INLINE void scSetParticleFlag(PxParticleFlag::Enum flag, bool val)
+ {
+ PxParticleFlags flags = mCore.getFlags();
+ if (val)
+ flags.raise(flag);
+ else
+ flags.clear(flag);
+
+ mCore.setFlags(flags);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, particleFlags, static_cast<PxPBDParticleSystem&>(*this), flags);
+ }
+
+ PX_INLINE void scSetParticleFlags(PxParticleFlags flags)
+ {
+ mCore.setFlags(flags);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, particleFlags, static_cast<PxPBDParticleSystem&>(*this), flags);
+ }
+
+ PX_INLINE void scSetWind(const PxVec3& v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setWind(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, wind, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetMaxDepenetrationVelocity(const PxReal v)
+ {
+ PX_CHECK_AND_RETURN(v > 0.f, "PxParticleSystem::setMaxDepenetrationVelocity: Max Depenetration Velocity must be > 0!");
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setMaxDepenetrationVelocity(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, maxDepenetrationVelocity, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetMaxVelocity(const PxReal v)
+ {
+ PX_CHECK_AND_RETURN(v > 0.f, "PxPBDParticleSystem::setMaxLinearVelocity: maxLinearVelocity must be > 0!");
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setMaxVelocity(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, maxVelocity, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_FORCE_INLINE void scSetFluidBoundaryDensityScale(const PxReal v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setFluidBoundaryDensityScale(v);
+ scSetDirtyFlag();
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, fluidBoundaryDensityScale, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetGridSizeX(const PxU32 v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setGridSizeX(v);
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, gridSizeX, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetGridSizeY(const PxU32 v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setGridSizeY(v);
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, gridSizeY, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ PX_INLINE void scSetGridSizeZ(const PxU32 v)
+ {
+ PX_ASSERT(!NpBase::isAPIWriteForbidden());
+ mCore.setGridSizeZ(v);
+ OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxPBDParticleSystem, gridSizeZ, static_cast<PxPBDParticleSystem&>(*this), v);
+ }
+
+ public:
+ PxArray<NpParticleBuffer*> mParticleBuffers;
+ PxArray<NpParticleAndDiffuseBuffer*> mParticleDiffuseBuffers;
+
+ private:
+ Sc::ParticleSystemCore mCore;
+ PxCudaContextManager* mCudaContextManager;
+ PxU32 mNextPhaseGroupID;
+ };
+
+ }
+ #endif
+ #endif