feat(physics): wire physx sdk into build

This commit is contained in:
2026-04-15 12:22:15 +08:00
parent 5bf258df6d
commit 31f40e2cbb
2044 changed files with 752623 additions and 1 deletions

View File

@@ -0,0 +1,383 @@
// 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 PX_ACTOR_H
#define PX_ACTOR_H
#include "PxPhysXConfig.h"
#include "foundation/PxBounds3.h"
#include "PxClient.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxRigidActor;
class PxRigidBody;
class PxRigidStatic;
class PxRigidDynamic;
class PxArticulationLink;
class PxScene;
/**
\brief Group index which allows to specify 1- or 2-way interaction
*/
typedef PxU8 PxDominanceGroup; // Must be < 32, PxU8.
/**
\brief Flags which control the behavior of an actor.
\see PxActorFlags PxActor PxActor.setActorFlag() PxActor.getActorFlags()
*/
struct PxActorFlag
{
enum Enum
{
/**
\brief Enable debug renderer for this actor
\see PxScene.getRenderBuffer() PxRenderBuffer PxVisualizationParameter
*/
eVISUALIZATION = (1<<0),
/**
\brief Disables scene gravity for this actor
*/
eDISABLE_GRAVITY = (1<<1),
/**
\brief Enables the sending of PxSimulationEventCallback::onWake() and PxSimulationEventCallback::onSleep() notify events
\see PxSimulationEventCallback::onWake() PxSimulationEventCallback::onSleep()
*/
eSEND_SLEEP_NOTIFIES = (1<<2),
/**
\brief Disables simulation for the actor.
\note This is only supported by PxRigidStatic and PxRigidDynamic actors and can be used to reduce the memory footprint when rigid actors are
used for scene queries only.
\note Setting this flag will remove all constraints attached to the actor from the scene.
\note If this flag is set, the following calls are forbidden:
\li PxRigidBody: setLinearVelocity(), setAngularVelocity(), addForce(), addTorque(), clearForce(), clearTorque(), setForceAndTorque()
\li PxRigidDynamic: setKinematicTarget(), setWakeCounter(), wakeUp(), putToSleep()
\par <b>Sleeping:</b>
Raising this flag will set all velocities and the wake counter to 0, clear all forces, clear the kinematic target, put the actor
to sleep and wake up all touching actors from the previous frame.
*/
eDISABLE_SIMULATION = (1<<3)
};
};
/**
\brief collection of set bits defined in PxActorFlag.
\see PxActorFlag
*/
typedef PxFlags<PxActorFlag::Enum,PxU8> PxActorFlags;
PX_FLAGS_OPERATORS(PxActorFlag::Enum,PxU8)
/**
\brief Identifies each type of actor.
\see PxActor
*/
struct PxActorType
{
enum Enum
{
/**
\brief A static rigid body
\see PxRigidStatic
*/
eRIGID_STATIC,
/**
\brief A dynamic rigid body
\see PxRigidDynamic
*/
eRIGID_DYNAMIC,
/**
\brief An articulation link
\see PxArticulationLink
*/
eARTICULATION_LINK,
/**
\brief A deformable surface
\see PxDeformableSurface
*/
eDEFORMABLE_SURFACE,
/**
\brief A deformable volume
\see PxDeformableVolume
*/
eDEFORMABLE_VOLUME,
/**
\brief Deprecated
\see eDEFORMABLE_VOLUME
*/
eSOFTBODY PX_DEPRECATED = eDEFORMABLE_VOLUME,
/**
\brief A PBD ParticleSystem
\see PxPBDParticleSystem
*/
ePBD_PARTICLESYSTEM,
//! \brief internal use only!
eACTOR_COUNT,
//! \brief internal use only!
eACTOR_FORCE_DWORD = 0x7fffffff
};
};
/**
\brief PxActor is the base class for the main simulation objects in the physics SDK.
The actor is owned by and contained in a PxScene.
*/
class PxActor : public PxBase
{
public:
/**
\brief Deletes the actor.
Do not keep a reference to the deleted instance.
If the actor belongs to a #PxAggregate object, it is automatically removed from the aggregate.
\see PxBase.release(), PxAggregate
*/
virtual void release() = 0;
/**
\brief Retrieves the type of actor.
\return The actor type of the actor.
\see PxActorType
*/
virtual PxActorType::Enum getType() const = 0;
/**
\brief Retrieves the scene which this actor belongs to.
\return Owner Scene. NULL if not part of a scene.
\see PxScene
*/
virtual PxScene* getScene() const = 0;
// Runtime modifications
/**
\brief Sets a name string for the object that can be retrieved with getName().
This is for debugging and is not used by the SDK. The string is not copied by the SDK,
only the pointer is stored.
\param[in] name String to set the objects name to.
<b>Default:</b> NULL
\see getName()
*/
virtual void setName(const char* name) = 0;
/**
\brief Retrieves the name string set with setName().
\return Name string associated with object.
\see setName()
*/
virtual const char* getName() const = 0;
/**
\brief Retrieves the axis aligned bounding box enclosing the actor.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value.
\return The actor's bounding box.
\see PxBounds3
*/
virtual PxBounds3 getWorldBounds(float inflation=1.01f) const = 0;
/**
\brief Raises or clears a particular actor flag.
See the list of flags #PxActorFlag
<b>Sleeping:</b> Does <b>NOT</b> wake the actor up automatically.
\param[in] flag The PxActor flag to raise(set) or clear. See #PxActorFlag.
\param[in] value The boolean value to assign to the flag.
\see PxActorFlag getActorFlags()
*/
virtual void setActorFlag(PxActorFlag::Enum flag, bool value) = 0;
/**
\brief Sets the actor flags.
See the list of flags #PxActorFlag
\see PxActorFlag setActorFlag()
*/
virtual void setActorFlags( PxActorFlags inFlags ) = 0;
/**
\brief Reads the PxActor flags.
See the list of flags #PxActorFlag
\return The values of the PxActor flags.
\see PxActorFlag setActorFlag()
*/
virtual PxActorFlags getActorFlags() const = 0;
/**
\brief Assigns dynamic actors a dominance group identifier.
PxDominanceGroup is a 5 bit group identifier (legal range from 0 to 31).
The PxScene::setDominanceGroupPair() lets you set certain behaviors for pairs of dominance groups.
By default every dynamic actor is created in group 0.
<b>Default:</b> 0
<b>Sleeping:</b> Changing the dominance group does <b>NOT</b> wake the actor up automatically.
\param[in] dominanceGroup The dominance group identifier. <b>Range:</b> [0..31]
\see getDominanceGroup() PxDominanceGroup PxScene::setDominanceGroupPair()
*/
virtual void setDominanceGroup(PxDominanceGroup dominanceGroup) = 0;
/**
\brief Retrieves the value set with setDominanceGroup().
\return The dominance group of this actor.
\see setDominanceGroup() PxDominanceGroup PxScene::setDominanceGroupPair()
*/
virtual PxDominanceGroup getDominanceGroup() const = 0;
/**
\brief Sets the owner client of an actor.
This cannot be done once the actor has been placed into a scene.
<b>Default:</b> PX_DEFAULT_CLIENT
\see PxClientID PxScene::createClient()
*/
virtual void setOwnerClient( PxClientID inClient ) = 0;
/**
\brief Returns the owner client that was specified at creation time.
This value cannot be changed once the object is placed into the scene.
\see PxClientID PxScene::createClient()
*/
virtual PxClientID getOwnerClient() const = 0;
/**
\brief Retrieves the aggregate the actor might be a part of.
\return The aggregate the actor is a part of, or NULL if the actor does not belong to an aggregate.
\see PxAggregate
*/
virtual PxAggregate* getAggregate() const = 0;
/************************************************************************************************/
/** \name Environment ID
*/
/**
\brief Sets the environment ID for this actor.
The environment ID is an extra built-in filter group for the GPU broadphase. Actors will only collide with each-other if they have the
same environment ID.
The default value is PX_INVALID_U32. Actors with this ID will collide with other actors, regardless of which environment they are a part of.
The environment ID must be set before adding the actor to a scene, and cannot change while the actor is in the scene.
If it is not PX_INVALID_U32, the environment ID must be smaller than 1<<24, i.e. the system does not support more than 1<<24 environments.
<b>Default:</b> PX_INVALID_U32
\note This is not available for CPU broadphases.
\param[in] envID Environment ID for this actor.
\return True if success.
\see getEnvironmentID()
*/
virtual bool setEnvironmentID(PxU32 envID) = 0;
/**
\brief Returns the environment ID for this actor.
\return Environment ID for this actor.
\see setEnvironmentID()
*/
virtual PxU32 getEnvironmentID() const = 0;
//public variables:
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
PX_INLINE PxActor(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {}
PX_INLINE PxActor(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
virtual ~PxActor() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxActor", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,281 @@
// 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 PX_AGGREGATE_H
#define PX_AGGREGATE_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxActor;
class PxBVH;
class PxScene;
struct PxAggregateType
{
enum Enum
{
eGENERIC = 0, //!< Aggregate will contain various actors of unspecified types
eSTATIC = 1, //!< Aggregate will only contain static actors
eKINEMATIC = 2 //!< Aggregate will only contain kinematic actors
};
};
// PxAggregateFilterHint is used for more efficient filtering of aggregates outside of the broadphase.
// It is a combination of a PxAggregateType and a self-collision bit.
typedef PxU32 PxAggregateFilterHint;
PX_CUDA_CALLABLE PX_FORCE_INLINE PxAggregateFilterHint PxGetAggregateFilterHint(PxAggregateType::Enum type, bool enableSelfCollision)
{
const PxU32 selfCollisionBit = enableSelfCollision ? 1 : 0;
return PxAggregateFilterHint((PxU32(type)<<1)|selfCollisionBit);
}
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 PxGetAggregateSelfCollisionBit(PxAggregateFilterHint hint)
{
return hint & 1;
}
PX_CUDA_CALLABLE PX_FORCE_INLINE PxAggregateType::Enum PxGetAggregateType(PxAggregateFilterHint hint)
{
return PxAggregateType::Enum(hint>>1);
}
/**
\brief Class to aggregate actors into a single broad-phase entry.
A PxAggregate object is a collection of PxActors, which will exist as a single entry in the
broad-phase structures. This has 3 main benefits:
1) it reduces "broad phase pollution" by allowing a collection of spatially coherent broad-phase
entries to be replaced by a single aggregated entry (e.g. a ragdoll or a single actor with a
large number of attached shapes).
2) it reduces broad-phase memory usage
3) filtering can be optimized a lot if self-collisions within an aggregate are not needed. For
example if you don't need collisions between ragdoll bones, it's faster to simply disable
filtering once and for all, for the aggregate containing the ragdoll, rather than filtering
out each bone-bone collision in the filter shader.
\see PxActor, PxPhysics.createAggregate
*/
class PxAggregate : public PxBase
{
public:
/**
\brief Deletes the aggregate object.
Deleting the PxAggregate object does not delete the aggregated actors. If the PxAggregate object
belongs to a scene, the aggregated actors are automatically re-inserted in that scene. If you intend
to delete both the PxAggregate and its actors, it is best to release the actors first, then release
the PxAggregate when it is empty.
*/
virtual void release() = 0;
/**
\brief Adds an actor to the aggregate object.
A warning is output if the total number of actors is reached, or if the incoming actor already belongs
to an aggregate.
If the aggregate belongs to a scene, adding an actor to the aggregate also adds the actor to that scene.
If the actor already belongs to a scene, a warning is output and the call is ignored. You need to remove
the actor from the scene first, before adding it to the aggregate.
\note When a BVH is provided the actor shapes are grouped together.
The scene query pruning structure inside PhysX SDK will store/update one
bound per actor. The scene queries against such an actor will query actor
bounds and then make a local space query against the provided BVH, which is in actor's local space.
\param [in] actor The actor that should be added to the aggregate
\param [in] bvh BVH for actor shapes.
return true if success
*/
virtual bool addActor(PxActor& actor, const PxBVH* bvh = NULL) = 0;
/**
\brief Removes an actor from the aggregate object.
A warning is output if the incoming actor does not belong to the aggregate. Otherwise the actor is
removed from the aggregate. If the aggregate belongs to a scene, the actor is reinserted in that
scene. If you intend to delete the actor, it is best to call #PxActor::release() directly. That way
the actor will be automatically removed from its aggregate (if any) and not reinserted in a scene.
\param [in] actor The actor that should be removed from the aggregate
return true if success
*/
virtual bool removeActor(PxActor& actor) = 0;
/**
\brief Adds an articulation to the aggregate object.
A warning is output if the total number of actors is reached (every articulation link counts as an actor),
or if the incoming articulation already belongs to an aggregate.
If the aggregate belongs to a scene, adding an articulation to the aggregate also adds the articulation to that scene.
If the articulation already belongs to a scene, a warning is output and the call is ignored. You need to remove
the articulation from the scene first, before adding it to the aggregate.
\param [in] articulation The articulation that should be added to the aggregate
return true if success
*/
virtual bool addArticulation(PxArticulationReducedCoordinate& articulation) = 0;
/**
\brief Removes an articulation from the aggregate object.
A warning is output if the incoming articulation does not belong to the aggregate. Otherwise the articulation is
removed from the aggregate. If the aggregate belongs to a scene, the articulation is reinserted in that
scene. If you intend to delete the articulation, it is best to call #PxArticulationReducedCoordinate::release() directly. That way
the articulation will be automatically removed from its aggregate (if any) and not reinserted in a scene.
\param [in] articulation The articulation that should be removed from the aggregate
return true if success
*/
virtual bool removeArticulation(PxArticulationReducedCoordinate& articulation) = 0;
/**
\brief Returns the number of actors contained in the aggregate.
You can use #getActors() to retrieve the actor pointers.
\return Number of actors contained in the aggregate.
\see PxActor getActors()
*/
virtual PxU32 getNbActors() const = 0;
/**
\brief Retrieves max amount of actors that can be contained in the aggregate.
\return Max actor size.
\see PxPhysics::createAggregate()
*/
virtual PxU32 getMaxNbActors() const = 0;
/**
\brief Retrieves max amount of shapes that can be contained in the aggregate.
\return Max shape size.
\see PxPhysics::createAggregate()
*/
virtual PxU32 getMaxNbShapes() const = 0;
/**
\brief Retrieve all actors contained in the aggregate.
You can retrieve the number of actor pointers by calling #getNbActors()
\param[out] userBuffer The buffer to store the actor pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first actor pointer to be retrieved
\return Number of actor pointers written to the buffer.
\see PxShape getNbShapes()
*/
virtual PxU32 getActors(PxActor** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/**
\brief Retrieves the scene which this aggregate belongs to.
\return Owner Scene. NULL if not part of a scene.
\see PxScene
*/
virtual PxScene* getScene() = 0;
/**
\brief Retrieves aggregate's self-collision flag.
\return self-collision flag
*/
virtual bool getSelfCollision() const = 0;
/**
\brief Sets the environment ID for this aggregate.
The environment ID is an extra built-in filter group for the GPU broadphase. Aggregates will only collide with actors or aggregates that
have the same environment ID.
The default value is PX_INVALID_U32. Aggregates with this ID will collide with other actors or aggregates, regardless of which environment
they are a part of.
The environment ID must be set before adding the aggregate to a scene, and cannot change while the aggregate is in the scene.
If it is not PX_INVALID_U32, the environment ID must be smaller than 1<<24, i.e. the system does not support more than 1<<24 environments.
Aggregated actors must have a default environment ID (PX_INVALID_U32). The environment ID of the aggregate is used in the broadphase, not
the environment IDs from aggregated actors.
<b>Default:</b> PX_INVALID_U32
\note This is not available for CPU broadphases.
\param[in] envID Environment ID for this aggregate.
\return True if success.
\see getEnvironmentID()
*/
virtual bool setEnvironmentID(PxU32 envID) = 0;
/**
\brief Returns the environment ID for this aggregate.
\return Environment ID for this aggregate.
\see setEnvironmentID()
*/
virtual PxU32 getEnvironmentID() const = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxAggregate"; }
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
PX_INLINE PxAggregate(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {}
PX_INLINE PxAggregate(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
virtual ~PxAggregate() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxAggregate", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,218 @@
// 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 PX_ANISOTROPY_H
#define PX_ANISOTROPY_H
#include "cudamanager/PxCudaContext.h"
#include "cudamanager/PxCudaContextManager.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#include "PxParticleSystem.h"
#include "foundation/PxArray.h"
#include "PxParticleGpu.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_SUPPORT_GPU_PHYSX
class PxgKernelLauncher;
class PxParticleNeighborhoodProvider;
/**
\brief Computes anisotropy information for a particle system to improve rendering quality
*/
class PxAnisotropyGenerator
{
public:
/**
\brief Schedules the compuation of anisotropy information on the specified cuda stream
\param[in] gpuParticleSystem A gpu pointer to access particle system data
\param[in] numParticles The number of particles
\param[in] stream The stream on which the cuda call gets scheduled
*/
virtual void generateAnisotropy(PxGpuParticleSystem* gpuParticleSystem, PxU32 numParticles, CUstream stream) = 0;
/**
\brief Schedules the compuation of anisotropy information on the specified cuda stream
\param[in] particlePositionsGpu A gpu pointer containing the particle positions
\param[in] neighborhoodProvider A neighborhood provider object that supports fast neighborhood queries
\param[in] numParticles The number of particles
\param[in] particleContactOffset The particle contact offset
\param[in] stream The stream on which the cuda call gets scheduled
*/
virtual void generateAnisotropy(PxVec4* particlePositionsGpu, PxParticleNeighborhoodProvider& neighborhoodProvider, PxU32 numParticles, PxReal particleContactOffset, CUstream stream) = 0;
/**
\brief Set a host buffer that holds the anisotropy data after the timestep completed
\param[in] anisotropy1 A host buffer holding the first row of the anisotropy matrix with memory for all particles already allocated
\param[in] anisotropy2 A host buffer holding the second row of the anisotropy matrix with memory for all particles already allocated
\param[in] anisotropy3 A host buffer holding the third row of the anisotropy matrix with memory for all particles already allocated
*/
virtual void setResultBufferHost(PxVec4* anisotropy1, PxVec4* anisotropy2, PxVec4* anisotropy3) = 0;
/**
\brief Set a device buffer that holds the anisotrpy data after the timestep completed
\param[in] anisotropy1 A device buffer holding the first row of the anisotropy matrix with memory for all particles already allocated
\param[in] anisotropy2 A device buffer holding the second row of the anisotropy matrix with memory for all particles already allocated
\param[in] anisotropy3 A device buffer holding the third row of the anisotropy matrix with memory for all particles already allocated
*/
virtual void setResultBufferDevice(PxVec4* anisotropy1, PxVec4* anisotropy2, PxVec4* anisotropy3) = 0;
/**
\brief Sets the maximum value anisotropy can reach in any direction
\param[in] maxAnisotropy The maximum anisotropy value
*/
virtual void setAnisotropyMax(float maxAnisotropy) = 0;
/**
\brief Sets the minimum value anisotropy can reach in any direction
\param[in] minAnisotropy The minimum anisotropy value
*/
virtual void setAnisotropyMin(float minAnisotropy) = 0;
/**
\brief Sets the anisotropy scale
\param[in] anisotropyScale The anisotropy scale
*/
virtual void setAnisotropyScale(float anisotropyScale) = 0;
/**
\brief Gets the maximal number of particles
\return The maximal number of particles
*/
virtual PxU32 getMaxParticles() const = 0;
/**
\brief Sets the maximal number of particles
\param[in] maxParticles The maximal number of particles
*/
virtual void setMaxParticles(PxU32 maxParticles) = 0;
/**
\brief Gets the device pointer for the anisotropy in x direction. Only available after calling setResultBufferHost or setResultBufferDevice
\return The device pointer for the anisotropy x direction and scale (w component contains the scale)
*/
virtual PxVec4* getAnisotropy1DevicePointer() const = 0;
/**
\brief Gets the device pointer for the anisotropy in y direction. Only available after calling setResultBufferHost or setResultBufferDevice
\return The device pointer for the anisotropy y direction and scale (w component contains the scale)
*/
virtual PxVec4* getAnisotropy2DevicePointer() const = 0;
/**
\brief Gets the device pointer for the anisotropy in z direction. Only available after calling setResultBufferHost or setResultBufferDevice
\return The device pointer for the anisotropy z direction and scale (w component contains the scale)
*/
virtual PxVec4* getAnisotropy3DevicePointer() const = 0;
/**
\brief Enables or disables the anisotropy generator
\param[in] enabled The boolean to set the generator to enabled or disabled
*/
virtual void setEnabled(bool enabled) = 0;
/**
\brief Allows to query if the anisotropy generator is enabled
\return True if enabled, false otherwise
*/
virtual bool isEnabled() const = 0;
/**
\brief Releases the instance and its data
*/
virtual void release() = 0;
/**
\brief Destructor
*/
virtual ~PxAnisotropyGenerator() {}
};
/**
\brief Default implementation of a particle system callback to trigger anisotropy calculations. A call to fetchResultsParticleSystem() on the
PxScene will synchronize the work such that the caller knows that the post solve task completed.
*/
class PxAnisotropyCallback : public PxParticleSystemCallback
{
public:
/**
\brief Initializes the anisotropy callback
\param[in] anistropyGenerator The anisotropy generator
*/
void initialize(PxAnisotropyGenerator* anistropyGenerator)
{
mAnistropyGenerator = anistropyGenerator;
}
virtual void onPostSolve(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream)
{
if (mAnistropyGenerator)
{
mAnistropyGenerator->generateAnisotropy(gpuParticleSystem.mDevicePtr, gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream);
}
}
virtual void onBegin(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
virtual void onAdvance(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
private:
PxAnisotropyGenerator* mAnistropyGenerator;
};
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,74 @@
// 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 PX_ARRAY_CONVERTER_H
#define PX_ARRAY_CONVERTER_H
#include "cudamanager/PxCudaContext.h"
#include "cudamanager/PxCudaContextManager.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_SUPPORT_GPU_PHYSX
/**
\brief Utility class to convert gpu arrays to a different memory layout
*/
class PxArrayConverter
{
public:
/**
\brief Helper function to merge two separate PxVec4 arrays into one interleaved PxVec3 array
\param[in] verticesD The vertices device memory buffer
\param[in] normalsD The normals device memory buffer
\param[in] length The number of vertices and normals
\param[out] interleavedResultBufferD The resulting interleaved buffer containing 2*length elements with the format vertex0, normal0, vertex1, normal1...
\param[in] stream The cuda stream on which the conversion is processed
*/
virtual void interleaveGpuBuffers(const PxVec4* verticesD, const PxVec4* normalsD, PxU32 length, PxVec3* interleavedResultBufferD, CUstream stream) = 0;
/**
\brief Destructor
*/
virtual ~PxArrayConverter() {}
};
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,74 @@
// 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 PX_ARTICULATION_FLAG_H
#define PX_ARTICULATION_FLAG_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief These flags determine what data is read or written to the internal articulation data via cache.
\see PxArticulationCache PxArticulationReducedCoordinate::copyInternalStateToCache PxArticulationReducedCoordinate::applyCache
*/
class PxArticulationCacheFlag
{
public:
enum Enum
{
eVELOCITY = (1 << 0), //!< The joint velocities, see PxArticulationCache::jointVelocity.
eACCELERATION = (1 << 1), //!< The joint accelerations, see PxArticulationCache::jointAcceleration.
ePOSITION = (1 << 2), //!< The joint positions, see PxArticulationCache::jointPosition.
eFORCE = (1 << 3), //!< The joint forces, see PxArticulationCache::jointForce.
eLINK_VELOCITY = (1 << 4), //!< The link velocities, see PxArticulationCache::linkVelocity. Link velocities cannot be set except for the root link velocity via PxArticulationCache::rootLinkData.
eLINK_ACCELERATION = (1 << 5), //!< The link accelerations, see PxArticulationCache::linkAcceleration.
eROOT_TRANSFORM = (1 << 6), //!< The root link transform, see PxArticulationCache::rootLinkData.
eROOT_VELOCITIES = (1 << 7), //!< The root link velocities (read/write) and accelerations (read), see PxArticulationCache::rootLinkData.
eLINK_INCOMING_JOINT_FORCE = (1 << 10), //!< The link incoming joint forces, see PxArticulationCache::linkIncomingJointForce.
eJOINT_TARGET_POSITIONS = (1 << 11), //!< The joint target positions, see PxArticulationCache::jointTargetPositions.
eJOINT_TARGET_VELOCITIES = (1 << 12), //!< The joint target velocities, see PxArticulationCache::jointTargetVelocities.
eLINK_FORCE = (1 << 13), //!< The link forces, see PxArticulationCache::linkForce.
eLINK_TORQUE = (1 << 14), //!< The link torques, see PxArticulationCache::linkTorque.
eALL = (eVELOCITY | eACCELERATION | ePOSITION | eLINK_VELOCITY | eLINK_ACCELERATION | eROOT_TRANSFORM | eROOT_VELOCITIES)
};
};
typedef PxFlags<PxArticulationCacheFlag::Enum, PxU32> PxArticulationCacheFlags;
PX_FLAGS_OPERATORS(PxArticulationCacheFlag::Enum, PxU32)
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,551 @@
// 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 PX_ARTICULATION_JOINT_RC_H
#define PX_ARTICULATION_JOINT_RC_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#include "solver/PxSolverDefs.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief A joint between two links in an articulation.
\see PxArticulationReducedCoordinate, PxArticulationLink
*/
class PxArticulationJointReducedCoordinate : public PxBase
{
public:
/**
\brief Gets the parent articulation link of this joint.
\return The parent link.
*/
virtual PxArticulationLink& getParentArticulationLink() const = 0;
/**
\brief Sets the joint pose in the parent link actor frame.
\param[in] pose The joint pose.
<b>Default:</b> The identity transform.
\note This call is not allowed while the simulation is running.
\see getParentPose
*/
virtual void setParentPose(const PxTransform& pose) = 0;
/**
\brief Gets the joint pose in the parent link actor frame.
\return The joint pose.
\see setParentPose
*/
virtual PxTransform getParentPose() const = 0;
/**
\brief Gets the child articulation link of this joint.
\return The child link.
*/
virtual PxArticulationLink& getChildArticulationLink() const = 0;
/**
\brief Sets the joint pose in the child link actor frame.
\param[in] pose The joint pose.
<b>Default:</b> The identity transform.
\note This call is not allowed while the simulation is running.
\see getChildPose
*/
virtual void setChildPose(const PxTransform& pose) = 0;
/**
\brief Gets the joint pose in the child link actor frame.
\return The joint pose.
\see setChildPose
*/
virtual PxTransform getChildPose() const = 0;
/**
\brief Sets the joint type (e.g. revolute).
\param[in] jointType The joint type to set.
\note Setting the joint type is not allowed while the articulation is in a scene.
In order to amend the joint type, remove and then re-add the articulation to the scene.
<b>Default:</b> PxArticulationJointType::eUNDEFINED
\see PxArticulationJointType, getJointType
*/
virtual void setJointType(PxArticulationJointType::Enum jointType) = 0;
/**
\brief Gets the joint type.
\return The joint type.
\see PxArticulationJointType, setJointType
*/
virtual PxArticulationJointType::Enum getJointType() const = 0;
/**
\brief Sets the joint motion for a given axis.
\param[in] axis The target axis.
\param[in] motion The motion type to set.
\note Setting the motion of joint axes is not allowed while the articulation is in a scene.
In order to set the motion, remove and then re-add the articulation to the scene.
<b>Default:</b> PxArticulationMotion::eLOCKED
\see PxArticulationAxis, PxArticulationMotion, getMotion
*/
virtual void setMotion(PxArticulationAxis::Enum axis, PxArticulationMotion::Enum motion) = 0;
/**
\brief Returns the joint motion for the given axis.
\param[in] axis The target axis.
\return The joint motion of the given axis.
\see PxArticulationAxis, PxArticulationMotion, setMotion
*/
virtual PxArticulationMotion::Enum getMotion(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint limits for a given axis.
- The motion of the corresponding axis should be set to PxArticulationMotion::eLIMITED in order for the limits to be enforced.
- The lower limit should be strictly smaller than the higher limit. If the limits should be equal, use PxArticulationMotion::eLOCKED
and an appropriate offset in the parent/child joint frames.
\param[in] axis The target axis.
\param[in] limit The joint limits.
\note This call is not allowed while the simulation is running.
\note For PxArticulationJointType::eSPHERICAL, limit.min and limit.max must both be in range [-Pi, Pi].
\note For PxArticulationJointType::eREVOLUTE, limit.min and limit.max must both be in range [-2*Pi, 2*Pi].
\note For PxArticulationJointType::eREVOLUTE_UNWRAPPED, limit.min and limit.max must both be in range [-PX_MAX_REAL, PX_MAX_REAL].
\note For PxArticulationJointType::ePRISMATIC, limit.min and limit.max must both be in range [-PX_MAX_REAL, PX_MAX_REAL].
<b>Default:</b> (0,0)
\see getLimitParams, PxArticulationAxis, PxArticulationLimit
*/
virtual void setLimitParams(PxArticulationAxis::Enum axis, const PxArticulationLimit& limit) = 0;
/**
\brief Returns the joint limits for a given axis.
\param[in] axis The target axis.
\return The joint limits.
\see setLimitParams, PxArticulationAxis, PxArticulationLimit
*/
virtual PxArticulationLimit getLimitParams(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Configures a joint drive for the given axis.
See PxArticulationDrive for parameter details; and the manual for further information, and the drives' implicit spring-damper (i.e. PD control) implementation in particular.
\param[in] axis The target axis.
\param[in] drive The drive parameters
\note This call is not allowed while the simulation is running.
\see getDriveParams, PxArticulationAxis, PxArticulationDrive
<b>Default:</b> PxArticulationDrive(0.0f, 0.0f, 0.0f, PxArticulationDriveType::eNONE)
*/
virtual void setDriveParams(PxArticulationAxis::Enum axis, const PxArticulationDrive& drive) = 0;
/**
\brief Gets the joint drive configuration for the given axis.
\param[in] axis The target axis.
\return The drive parameters.
\see setDriveParams, PxArticulationAxis, PxArticulationDrive
*/
virtual PxArticulationDrive getDriveParams(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint drive position target for the given axis.
The target units are linear units (equivalent to scene units) for a translational axis, or rad for a rotational axis.
\param[in] axis The target axis.
\param[in] target The target position.
\param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter
to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value.
\note This call is not allowed while the simulation is running.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note For spherical joints, target must be in range [-Pi, Pi].
\note The target is specified in the parent frame of the joint. If Gp, Gc are the parent and child actor poses in the world frame and Lp, Lc are the parent and child joint frames expressed in the parent and child actor frames then the joint will drive the parent and child links to poses that obey Gp * Lp * J = Gc * Lc. For joints restricted to angular motion, J has the form PxTranfsorm(PxVec3(PxZero), PxExp(PxVec3(twistTarget, swing1Target, swing2Target))). For joints restricted to linear motion, J has the form PxTransform(PxVec3(XTarget, YTarget, ZTarget), PxQuat(PxIdentity)).
\note For spherical joints with more than 1 degree of freedom, the joint target angles taken together can collectively represent a rotation of greater than Pi around a vector. When this happens the rotation that matches the joint drive target is not the shortest path rotation. The joint pose J that is the outcome after driving to the target pose will always be the equivalent of the shortest path rotation.
\see PxArticulationAxis, getDriveTarget
<b>Default:</b> 0.0
*/
virtual void setDriveTarget(PxArticulationAxis::Enum axis, const PxReal target, bool autowake = true) = 0;
/**
\brief Returns the joint drive position target for the given axis.
\param[in] axis The target axis.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\return The target position.
\see PxArticulationAxis, setDriveTarget
*/
virtual PxReal getDriveTarget(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint drive velocity target for the given axis.
The target units are linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis.
\param[in] axis The target axis.
\param[in] targetVel The target velocity.
\param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter
to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value.
\note This call is not allowed while the simulation is running.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationAxis, getDriveVelocity
<b>Default:</b> 0.0
*/
virtual void setDriveVelocity(PxArticulationAxis::Enum axis, const PxReal targetVel, bool autowake = true) = 0;
/**
\brief Returns the joint drive velocity target for the given axis.
\param[in] axis The target axis.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\return The target velocity.
\see PxArticulationAxis, setDriveVelocity
*/
virtual PxReal getDriveVelocity(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint armature for the given axis.
- The armature is directly added to the joint-space spatial inertia of the corresponding axis.
- The armature is in mass units for a prismatic (i.e. linear) joint, and in mass units * (scene linear units)^2 for a rotational joint.
\param[in] axis The target axis.
\param[in] armature The joint axis armature.
\note This call is not allowed while the simulation is running.
\see PxArticulationAxis, getArmature
<b>Default:</b> 0.0
*/
virtual void setArmature(PxArticulationAxis::Enum axis, const PxReal armature) = 0;
/**
\brief Gets the joint armature for the given axis.
\param[in] axis The target axis.
\return The armature set on the given axis.
\see PxArticulationAxis, setArmature
*/
virtual PxReal getArmature(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint friction coefficient, which applies to all joint axes.
- The joint friction is unitless and relates the magnitude of the spatial force [F_trans, T_trans] transmitted from parent to child link to
the maximal friction force F_resist that may be applied by the solver to resist joint motion, per axis; i.e. |F_resist| <= coefficient * (|F_trans| + |T_trans|),
where F_resist may refer to a linear force or torque depending on the joint axis.
- The simulated friction effect is therefore similar to static and Coulomb friction. In order to simulate dynamic joint friction, use a joint drive with
zero stiffness and zero velocity target, and an appropriately dimensioned damping parameter.
\param[in] coefficient The joint friction coefficient.
\note This call is not allowed while the simulation is running.
\see getFrictionCoefficient
<b>Default:</b> 0.05
*/
virtual PX_DEPRECATED void setFrictionCoefficient(const PxReal coefficient) = 0;
/**
\brief Gets the joint friction coefficient.
\return The joint friction coefficient.
\see setFrictionCoefficient
*/
virtual PX_DEPRECATED PxReal getFrictionCoefficient() const = 0;
/**
\brief Configures joint friction.
See PxJointFrictionParams for parameter details; and the manual for further information. The new friction model is applied to all axes where setFrictionParams() has been called.
For axes where setFrictionParams() hasn't been used, the deprecated friction model remains in effect. See setFrictionCoefficient().
\param[in] axis The target axis.
\param[in] jointFrictionParams The joint friction parameters.
\note This call is not allowed while the simulation is running.
<b>Default:</b> PxJointFrictionParams(0.0f, 0.0f, 0.0f)
*/
virtual void setFrictionParams(PxArticulationAxis::Enum axis, const PxJointFrictionParams& jointFrictionParams) = 0;
/**
\brief Gets per-axis joint friction parameters struct.
\param[in] axis The target axis.
\return The joint friction parameters.
\see setFrictionParams()
*/
virtual PxJointFrictionParams getFrictionParams(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the maximal joint velocity enforced for all axes.
- The solver will apply appropriate joint-space impulses in order to enforce the per-axis joint-velocity limit.
- The velocity units are linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis.
\param[in] maxJointV The maximal per-axis joint velocity.
\note This call is not allowed while the simulation is running.
\see getMaxJointVelocity
<b>Default:</b> 100.0
*/
virtual PX_DEPRECATED void setMaxJointVelocity(const PxReal maxJointV) = 0;
/**
\brief Gets the maximal joint velocity enforced for all axes.
\return The maximal per-axis joint velocity.
\see setMaxJointVelocity
*/
virtual PX_DEPRECATED PxReal getMaxJointVelocity() const = 0;
/**
\brief Sets the maximal joint velocity enforced for the given axis.
- The solver will apply appropriate joint-space impulses in order to enforce the per-axis joint-velocity limit.
- The velocity units are linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis.
\param[in] axis The target axis.
\param[in] maxJointV The maximal per-axis joint velocity.
\note This call is not allowed while the simulation is running.
\see getMaxJointVelocity()
<b>Default:</b> 100.0
*/
virtual void setMaxJointVelocity(PxArticulationAxis::Enum axis, const PxReal maxJointV) = 0;
/**
\brief Gets the maximal joint velocity enforced for the given axis.
\param[in] axis The target axis.
\return The maximal joint velocity for the given axis.
\see setMaxJointVelocity()
*/
virtual PxReal getMaxJointVelocity(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint position for the given axis.
- For performance, prefer PxArticulationCache::jointPosition to set joint positions in a batch articulation state update.
- Use PxArticulationReducedCoordinate::updateKinematic after all state updates to the articulation via non-cache API such as this method,
in order to update link states for the next simulation frame or querying.
\param[in] axis The target axis.
\param[in] jointPos The joint position in linear units (equivalent to scene units) for a translational axis, or radians for a rotational axis.
\note This call is not allowed while the simulation is running.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note For PxArticulationJointType::eSPHERICAL, jointPos must be in range [-Pi, Pi].
\note For PxArticulationJointType::eREVOLUTE, jointPos must be in range [-2*Pi, 2*Pi].
\note For PxArticulationJointType::eREVOLUTE_UNWRAPPED, jointPos must be in range [-PX_MAX_REAL, PX_MAX_REAL].
\note For PxArticulationJointType::ePRISMATIC, jointPos must be in range [-PX_MAX_REAL, PX_MAX_REAL].
\note Joint position is specified in the parent frame of the joint. If Gp, Gc are the parent and child actor poses in the world frame and Lp, Lc are the parent and child joint frames expressed in the parent and child actor frames then the parent and child links will be given poses that obey Gp * Lp * J = Gc * Lc with J denoting the joint pose. For joints restricted to angular motion, J has the form PxTranfsorm(PxVec3(PxZero), PxExp(PxVec3(twistPos, swing1Pos, swing2Pos))). For joints restricted to linear motion, J has the form PxTransform(PxVec3(xPos, yPos, zPos), PxQuat(PxIdentity)).
\note For spherical joints with more than 1 degree of freedom, the input joint positions taken together can collectively represent a rotation of greater than Pi around a vector. When this happens the rotation that matches the joint positions is not the shortest path rotation. The joint pose J that is the outcome of setting and applying the joint positions will always be the equivalent of the shortest path rotation.
\see PxArticulationAxis, getJointPosition, PxArticulationCache::jointPosition, PxArticulationReducedCoordinate::updateKinematic
<b>Default:</b> 0.0
*/
virtual void setJointPosition(PxArticulationAxis::Enum axis, const PxReal jointPos) = 0;
/**
\brief Gets the joint position for the given axis, i.e. joint degree of freedom (DOF).
For performance, prefer PxArticulationCache::jointPosition to get joint positions in a batch query.
\param[in] axis The target axis.
\return The joint position in linear units (equivalent to scene units) for a translational axis, or radians for a rotational axis.
\note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(),
and in PxContactModifyCallback or in contact report callbacks.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationAxis, setJointPosition, PxArticulationCache::jointPosition
*/
virtual PxReal getJointPosition(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Sets the joint velocity for the given axis.
- For performance, prefer PxArticulationCache::jointVelocity to set joint velocities in a batch articulation state update.
- Use PxArticulationReducedCoordinate::updateKinematic after all state updates to the articulation via non-cache API such as this method,
in order to update link states for the next simulation frame or querying.
\param[in] axis The target axis.
\param[in] jointVel The joint velocity in linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis.
\note This call is not allowed while the simulation is running.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationAxis, getJointVelocity, PxArticulationCache::jointVelocity, PxArticulationReducedCoordinate::updateKinematic
<b>Default:</b> 0.0
*/
virtual void setJointVelocity(PxArticulationAxis::Enum axis, const PxReal jointVel) = 0;
/**
\brief Gets the joint velocity for the given axis.
For performance, prefer PxArticulationCache::jointVelocity to get joint velocities in a batch query.
\param[in] axis The target axis.
\return The joint velocity in linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis.
\note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(),
and in PxContactModifyCallback or in contact report callbacks.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationAxis, setJointVelocity, PxArticulationCache::jointVelocity
*/
virtual PxReal getJointVelocity(PxArticulationAxis::Enum axis) const = 0;
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationJointReducedCoordinate"; }
virtual ~PxArticulationJointReducedCoordinate() {}
//public variables:
void* userData; //!< The user can assign this to whatever, usually to create a 1:1 relationship with a user object.
/**
\brief Sets a name string for the object that can be retrieved with getName().
This is for debugging and is not used by the SDK. The string is not copied by the SDK,
only the pointer is stored.
\param[in] name String to set the objects name to.
<b>Default:</b> NULL
\see getName()
*/
virtual void setName(const char* name) = 0;
/**
\brief Retrieves the name string set with setName().
\return Name string associated with object.
\see setName()
*/
virtual const char* getName() const = 0;
protected:
PX_INLINE PxArticulationJointReducedCoordinate(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxArticulationJointReducedCoordinate(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxArticulationJointReducedCoordinate", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,208 @@
// 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 PX_ARTICULATION_LINK_H
#define PX_ARTICULATION_LINK_H
#include "PxPhysXConfig.h"
#include "PxRigidBody.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief A component of an articulation that represents a rigid body.
Articulation links have a restricted subset of the functionality of a PxRigidDynamic:
- They may not be kinematic, and do not support contact-force thresholds.
- Their velocity or global pose cannot be set directly, but must be set via the articulation-root and joint positions/velocities.
- Sleep state and solver iteration counts are properties of the entire articulation rather than the individual links.
\see PxArticulationReducedCoordinate, PxArticulationReducedCoordinate::createLink, PxArticulationJointReducedCoordinate, PxRigidBody
*/
class PxArticulationLink : public PxRigidBody
{
public:
/**
\brief Releases the link from the articulation.
\note Only a leaf articulation link can be released.
\note Releasing a link is not allowed while the articulation link is in a scene. In order to release a link,
remove and then re-add the corresponding articulation to the scene.
\see PxArticulationReducedCoordinate::createLink()
*/
virtual void release() = 0;
/**
\brief Gets the articulation that the link is a part of.
\return The articulation.
\see PxArticulationReducedCoordinate
*/
virtual PxArticulationReducedCoordinate& getArticulation() const = 0;
/**
\brief Gets the joint which connects this link to its parent.
\return The joint connecting the link to the parent. NULL for the root link.
\see PxArticulationJointReducedCoordinate
*/
virtual PxArticulationJointReducedCoordinate* getInboundJoint() const = 0;
/**
\brief Gets the number of degrees of freedom of the joint which connects this link to its parent.
- The root link DOF-count is defined to be 0 regardless of PxArticulationFlag::eFIX_BASE.
- The return value is only valid for articulations that are in a scene.
\return The number of degrees of freedom, or 0xFFFFFFFF if the articulation is not in a scene.
\see PxArticulationJointReducedCoordinate
*/
virtual PxU32 getInboundJointDof() const = 0;
/**
\brief Gets the number of child links.
\return The number of child links.
\see getChildren
*/
virtual PxU32 getNbChildren() const = 0;
/**
\brief Gets the low-level link index that may be used to index into members of PxArticulationCache.
The low-level indices are built after an articulation is added to the scene following a breadth-first approach,
where all the links at the current depth are indexed sequentially before moving to the links at the next depth level.
The root of the articulation has therefore the index 0.
Note that the low-level indices may be different from the order in which the links were originally added to the articulation.
The return value is only valid for articulations that are in a scene.
\return The low-level index, or 0xFFFFFFFF if the articulation is not in a scene.
\see PxArticulationCache
*/
virtual PxU32 getLinkIndex() const = 0;
/**
\brief Retrieves the child links.
\param[out] userBuffer The buffer to receive articulation link pointers.
\param[in] bufferSize The size of the provided user buffer, use getNbChildren() for sizing.
\param[in] startIndex The index of the first child pointer to be retrieved.
\return The number of articulation links written to the buffer.
\see getNbChildren
*/
virtual PxU32 getChildren(PxArticulationLink** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief Set the constraint-force-mixing scale term.
The cfm scale term is a stabilization term that helps avoid instabilities with over-constrained
configurations. It should be a small value that is multiplied by 1/mass internally to produce
an additional bias added to the unit response term in the solver.
\param[in] cfm The constraint-force-mixing scale term.
<b>Default:</b> 0.025
<b>Range:</b> [0, 1]
\note This call is not allowed while the simulation is running.
\see getCfmScale
*/
virtual void setCfmScale(const PxReal cfm) = 0;
/**
\brief Get the constraint-force-mixing scale term.
\return The constraint-force-mixing scale term.
\see setCfmScale
*/
virtual PxReal getCfmScale() const = 0;
/**
\brief Get the linear velocity of the link.
- For performance, prefer PxArticulationCache::linkVelocity to get link spatial velocities in a batch query.
- When the articulation state is updated via non-cache API, use PxArticulationReducedCoordinate::updateKinematic before querying velocity.
\return The linear velocity of the link.
\note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(),
and in PxContactModifyCallback or in contact report callbacks.
\note The linear velocity is reported with respect to the link's center of mass and not the actor frame origin.
\see PxRigidBody::getCMassLocalPose
*/
virtual PxVec3 getLinearVelocity() const = 0;
/**
\brief Get the angular velocity of the link.
- For performance, prefer PxArticulationCache::linkVelocity to get link spatial velocities in a batch query.
- When the articulation state is updated via non-cache API, use PxArticulationReducedCoordinate::updateKinematic before querying velocity.
\return The angular velocity of the link.
\note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(),
and in PxContactModifyCallback or in contact report callbacks.
*/
virtual PxVec3 getAngularVelocity() const = 0;
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationLink"; }
protected:
PX_INLINE PxArticulationLink(PxType concreteType, PxBaseFlags baseFlags) : PxRigidBody(concreteType, baseFlags) {}
PX_INLINE PxArticulationLink(PxBaseFlags baseFlags) : PxRigidBody(baseFlags) {}
virtual ~PxArticulationLink() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxArticulationLink", PxRigidBody); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,166 @@
// 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 PX_ARTICULATION_MIMIC_JOINT_H
#define PX_ARTICULATION_MIMIC_JOINT_H
#include "foundation/PxSimpleTypes.h"
#include "solver/PxSolverDefs.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxArticulationReducedCoordinate;
class PxArticulationJointReducedCoordinate;
/**
* \brief A mimic joint enforces a linear relationship between the positions of two joints of the same articulation instance.
\see PxArticulationReducedCoodinate::createMimicJoint()
*/
class PxArticulationMimicJoint : public PxBase
{
public:
/**
\brief Releases the mimic joint.
\note Releasing a mimic joint is not allowed while the articulation is in a scene. In order to
release a mimic joint, remove and then re-add the articulation to the scene.
*/
virtual void release() = 0;
/**
\brief Returns the articulation that this mimic joint is part of.
\return A reference to the articulation.
*/
virtual PxArticulationReducedCoordinate& getArticulation() const = 0;
/**
\brief Get the gear of a mimic joint.
\return The gear ratio.
*/
virtual PxReal getGearRatio() const = 0;
/**
\brief Set the gear ratio of a mimic joint.
\param[in] gearRatio is the new gear ratio to be used in the next simulation step.
*/
virtual void setGearRatio(PxReal gearRatio) = 0;
/**
\brief Get the offset of a mimic joint.
\return The offset.
*/
virtual PxReal getOffset() const = 0;
/**
\brief Set the offset of a mimic joint.
\param[in] offset is the new offset to be used in the next simulation step.
*/
virtual void setOffset(PxReal offset) = 0;
/**
\brief Get the natural frequency of a mimic joint.
\return The natural frequency.
*/
virtual PxReal getNaturalFrequency() const = 0;
/**
\brief Set the natural frequency of a mimic joint.
\param[in] naturalFrequency is the new natural frequency to be used in the next simulation step.
*/
virtual void setNaturalFrequency(PxReal naturalFrequency) = 0;
/**
\brief Get the damping ratio of a mimic joint.
\return The damping ratio.
*/
virtual PxReal getDampingRatio() const = 0;
/**
\brief Set the damping ratio of a mimic joint.
\param[in] dampingRatio is the new damping ratio to be used in the next simulation step.
*/
virtual void setDampingRatio(PxReal dampingRatio) = 0;
/**
\brief Return the jointA specified in PxArticulationReducedCoordinate::createMimicJoint()
\return The jointA specified in PxArticulationReducedCoordinate::createMimicJoint()
\see PxArticulationReducedCoordinate::createMimicJoint()
*/
virtual PxArticulationJointReducedCoordinate& getJointA() const = 0;
/**
\brief Return the jointB specified in PxArticulationReducedCoordinate::createMimicJoint()
\return The jointB specified in PxArticulationReducedCoordinate::createMimicJoint()
\see PxArticulationReducedCoordinate::createMimicJoint()
*/
virtual PxArticulationJointReducedCoordinate& getJointB() const = 0;
/**
\brief Return the axisA specified in PxArticulationReducedCoordinate::createMimicJoint()
\return The axisA specified in PxArticulationReducedCoordinate::createMimicJoint()
\see PxArticulationReducedCoordinate::createMimicJoint()
*/
virtual PxArticulationAxis::Enum getAxisA() const = 0;
/**
\brief Return the axisB specified in PxArticulationReducedCoordinate::createMimicJoint()
\return The axisB specified in PxArticulationReducedCoordinate::createMimicJoint()
\see PxArticulationReducedCoordinate::createMimicJoint()
*/
virtual PxArticulationAxis::Enum getAxisB() const = 0;
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationMimicJoint"; }
virtual ~PxArticulationMimicJoint() {}
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
PX_INLINE PxArticulationMimicJoint(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxArticulationMimicJoint(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif //PX_ARTICULATION_MIMIC_JOINT_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,630 @@
// 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 PX_ARTICULATION_TENDON_H
#define PX_ARTICULATION_TENDON_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#include "solver/PxSolverDefs.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxArticulationSpatialTendon;
class PxArticulationFixedTendon;
class PxArticulationLink;
/**
\brief Defines the low/high limits of the length of a tendon.
*/
class PxArticulationTendonLimit
{
public:
PxReal lowLimit;
PxReal highLimit;
};
/**
\brief Defines a spatial tendon attachment point on a link.
*/
class PxArticulationAttachment : public PxBase
{
public:
virtual ~PxArticulationAttachment() {}
/**
\brief Sets the spring rest length for the sub-tendon from the root to this leaf attachment.
Setting this on non-leaf attachments has no effect.
\param[in] restLength The rest length of the spring.
<b>Default:</b> 0
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getRestLength(), isLeaf()
*/
virtual void setRestLength(const PxReal restLength) = 0;
/**
\brief Gets the spring rest length for the sub-tendon from the root to this leaf attachment.
\return The rest length.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setRestLength()
*/
virtual PxReal getRestLength() const = 0;
/**
\brief Sets the low and high limit on the length of the sub-tendon from the root to this leaf attachment.
Setting this on non-leaf attachments has no effect.
\param[in] parameters Struct with the low and high limit.
<b>Default:</b> (PX_MAX_F32, -PX_MAX_F32) (i.e. an invalid configuration that can only work if stiffness is zero)
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationTendonLimit, getLimitParameters(), isLeaf()
*/
virtual void setLimitParameters(const PxArticulationTendonLimit& parameters) = 0;
/**
\brief Gets the low and high limit on the length of the sub-tendon from the root to this leaf attachment.
\return Struct with the low and high limit.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationTendonLimit, setLimitParameters()
*/
virtual PxArticulationTendonLimit getLimitParameters() const = 0;
/**
\brief Sets the attachment's relative offset in the link actor frame.
\param[in] offset The relative offset in the link actor frame.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getRelativeOffset()
*/
virtual void setRelativeOffset(const PxVec3& offset) = 0;
/**
\brief Gets the attachment's relative offset in the link actor frame.
\return The relative offset in the link actor frame.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setRelativeOffset()
*/
virtual PxVec3 getRelativeOffset() const = 0;
/**
\brief Sets the attachment coefficient.
\param[in] coefficient The scale that the distance between this attachment and its parent is multiplied by when summing up the spatial tendon's length.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getCoefficient()
*/
virtual void setCoefficient(const PxReal coefficient) = 0;
/**
\brief Gets the attachment coefficient.
\return The scale that the distance between this attachment and its parent is multiplied by when summing up the spatial tendon's length.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setCoefficient()
*/
virtual PxReal getCoefficient() const = 0;
/**
\brief Gets the articulation link.
\return The articulation link that this attachment is attached to.
*/
virtual PxArticulationLink* getLink() const = 0;
/**
\brief Gets the parent attachment.
\return The parent attachment.
*/
virtual PxArticulationAttachment* getParent() const = 0;
/**
\brief Indicates that this attachment is a leaf, and thus defines a sub-tendon from the root to this attachment.
\return True: This attachment is a leaf and has zero children; False: Not a leaf.
*/
virtual bool isLeaf() const = 0;
/**
\brief Gets the spatial tendon that the attachment is a part of.
\return The tendon.
\see PxArticulationSpatialTendon
*/
virtual PxArticulationSpatialTendon* getTendon() const = 0;
/**
\brief Releases the attachment.
\note Releasing the attachment is not allowed while the articulation is in a scene. In order to
release the attachment, remove and then re-add the articulation to the scene.
\see PxArticulationSpatialTendon::createAttachment()
*/
virtual void release() = 0;
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationAttachment"; }
protected:
PX_INLINE PxArticulationAttachment(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxArticulationAttachment(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
};
/**
\brief Defines a fixed-tendon joint on an articulation joint degree of freedom.
*/
class PxArticulationTendonJoint : public PxBase
{
public:
virtual ~PxArticulationTendonJoint() {}
/**
\brief Sets the tendon joint coefficient.
\param[in] axis The degree of freedom that the tendon joint operates on (must correspond to a degree of freedom of the associated link's incoming joint).
\param[in] coefficient The scale that the axis' joint position is multiplied by when summing up the fixed tendon's length.
\param[in] recipCoefficient The scale that the tendon's response is multiplied by when applying to this tendon joint.
\note RecipCoefficient is commonly expected to be 1/coefficient, but it can be set to different values to tune behavior; for example, zero can be used to
have a joint axis only participate in the length computation of the tendon, but not have any tendon force applied to it.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getCoefficient()
*/
virtual void setCoefficient(const PxArticulationAxis::Enum axis, const PxReal coefficient, const PxReal recipCoefficient) = 0;
/**
\brief Gets the tendon joint coefficient.
\param[out] axis The degree of freedom that the tendon joint operates on.
\param[out] coefficient The scale that the axis' joint position is multiplied by when summing up the fixed tendon's length.
\param[in] recipCoefficient The scale that the tendon's response is multiplied by when applying to this tendon joint.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setCoefficient()
*/
virtual void getCoefficient(PxArticulationAxis::Enum& axis, PxReal& coefficient, PxReal& recipCoefficient) const = 0;
/**
\brief Gets the articulation link.
\return The articulation link (and its incoming joint in particular) that this tendon joint is associated with.
*/
virtual PxArticulationLink* getLink() const = 0;
/**
\brief Gets the parent tendon joint.
\return The parent tendon joint.
*/
virtual PxArticulationTendonJoint* getParent() const = 0;
/**
\brief Gets the tendon that the joint is a part of.
\return The tendon.
\see PxArticulationFixedTendon
*/
virtual PxArticulationFixedTendon* getTendon() const = 0;
/**
\brief Releases a tendon joint.
\note Releasing a tendon joint is not allowed while the articulation is in a scene. In order to
release the joint, remove and then re-add the articulation to the scene.
\see PxArticulationFixedTendon::createTendonJoint()
*/
virtual void release() = 0;
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationTendonJoint"; }
protected:
PX_INLINE PxArticulationTendonJoint(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxArticulationTendonJoint(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
};
/**
\brief Common API base class shared by PxArticulationSpatialTendon and PxArticulationFixedTendon.
*/
class PxArticulationTendon : public PxBase
{
public:
/**
\brief Sets the spring stiffness term acting on the tendon length.
\param[in] stiffness The spring stiffness.
<b>Default:</b> 0
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getStiffness()
*/
virtual void setStiffness(const PxReal stiffness) = 0;
/**
\brief Gets the spring stiffness of the tendon.
\return The spring stiffness.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setStiffness()
*/
virtual PxReal getStiffness() const = 0;
/**
\brief Sets the damping term acting both on the tendon length and tendon-length limits.
\param[in] damping The damping term.
<b>Default:</b> 0
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getDamping()
*/
virtual void setDamping(const PxReal damping) = 0;
/**
\brief Gets the damping term acting both on the tendon length and tendon-length limits.
\return The damping term.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setDamping()
*/
virtual PxReal getDamping() const = 0;
/**
\brief Sets the limit stiffness term acting on the tendon's length limits.
For spatial tendons, this parameter applies to all its leaf attachments / sub-tendons.
\param[in] stiffness The limit stiffness term.
<b>Default:</b> 0
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getLimitStiffness()
*/
virtual void setLimitStiffness(const PxReal stiffness) = 0;
/**
\brief Gets the limit stiffness term acting on the tendon's length limits.
For spatial tendons, this parameter applies to all its leaf attachments / sub-tendons.
\return The limit stiffness term.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setLimitStiffness()
*/
virtual PxReal getLimitStiffness() const = 0;
/**
\brief Sets the length offset term for the tendon.
An offset defines an amount to be added to the accumulated length computed for the tendon. It allows the
application to actuate the tendon by shortening or lengthening it.
\param[in] offset The offset term. <b>Default:</b> 0
\param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter
to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getOffset()
*/
virtual void setOffset(const PxReal offset, bool autowake = true) = 0;
/**
\brief Gets the length offset term for the tendon.
\return The offset term.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setOffset()
*/
virtual PxReal getOffset() const = 0;
/**
\brief Gets the articulation that the tendon is a part of.
\return The articulation.
\see PxArticulationReducedCoordinate
*/
virtual PxArticulationReducedCoordinate* getArticulation() const = 0;
/**
\brief Releases a tendon to remove it from the articulation and free its associated memory.
When an articulation is released, its attached tendons are automatically released.
\note Releasing a tendon is not allowed while the articulation is in a scene. In order to
release the tendon, remove and then re-add the articulation to the scene.
*/
virtual void release() = 0;
virtual ~PxArticulationTendon() {}
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
PX_INLINE PxArticulationTendon(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxArticulationTendon(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
};
/**
\brief A spatial tendon that attaches to an articulation.
A spatial tendon attaches to multiple links in an articulation using a set of PxArticulationAttachments.
The tendon is defined as a tree of attachment points, where each attachment can have an arbitrary number of children.
Each leaf of the attachment tree defines a subtendon between itself and the root attachment. The subtendon then
applies forces at the leaf, and an equal but opposing force at the root, in order to satisfy the spring-damper and limit
constraints that the user sets up. Attachments in between the root and leaf do not exert any force on the articulation,
but define the geometry of the tendon from which the length is computed together with the attachment coefficients.
*/
class PxArticulationSpatialTendon : public PxArticulationTendon
{
public:
/**
\brief Creates an articulation attachment and adds it to the list of children in the parent attachment.
Creating an attachment is not allowed while the articulation is in a scene. In order to
add the attachment, remove and then re-add the articulation to the scene.
\param[in] parent The parent attachment. Can be NULL for the root attachment of a tendon.
\param[in] coefficient A user-defined scale that the accumulated length is scaled by.
\param[in] relativeOffset An offset vector in the link's actor frame to the point where the tendon attachment is attached to the link.
\param[in] link The link that this attachment is associated with.
\return The newly-created attachment if creation was successful, otherwise a null pointer.
\see releaseAttachment()
*/
virtual PxArticulationAttachment* createAttachment(PxArticulationAttachment* parent, const PxReal coefficient, const PxVec3 relativeOffset, PxArticulationLink* link) = 0;
/**
\brief Fills a user-provided buffer of attachment pointers with the set of attachments.
\param[in] userBuffer The user-provided buffer.
\param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to attachments,
only as many as can fit are written. Use getNbAttachments to size for all attachments.
\param[in] startIndex Index of first attachment pointer to be retrieved.
\return The number of attachments that were filled into the user buffer.
\see getNbAttachments
*/
virtual PxU32 getAttachments(PxArticulationAttachment** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief Returns the number of attachments in the tendon.
\return The number of attachments.
*/
virtual PxU32 getNbAttachments() const = 0;
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationSpatialTendon"; }
virtual ~PxArticulationSpatialTendon() {}
protected:
PX_INLINE PxArticulationSpatialTendon(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationTendon(concreteType, baseFlags) {}
PX_INLINE PxArticulationSpatialTendon(PxBaseFlags baseFlags) : PxArticulationTendon(baseFlags) {}
};
/**
\brief A fixed tendon that can be used to link multiple degrees of freedom of multiple articulation joints via length and limit constraints.
Fixed tendons allow the simulation of coupled relationships between joint degrees of freedom in an articulation. Fixed tendons do not allow
linking arbitrary joint axes of the articulation: The respective joints must all be directly connected to each other in the articulation structure,
i.e. each of the joints in the tendon must be connected by a single articulation link to another joint in the same tendon. This implies both that
1) fixed tendons can branch along a branching articulation; and 2) they cannot be used to create relationships between axes in a spherical joint with
more than one degree of freedom. Locked joint axes or fixed joints are currently not supported.
*/
class PxArticulationFixedTendon : public PxArticulationTendon
{
public:
/**
\brief Creates an articulation tendon joint and adds it to the list of children in the parent tendon joint.
Creating a tendon joint is not allowed while the articulation is in a scene. In order to
add the joint, remove and then re-add the articulation to the scene.
\param[in] parent The parent tendon joint. Can be NULL for the root tendon joint of a tendon.
\param[in] axis The degree of freedom that this tendon joint is associated with.
\param[in] coefficient A user-defined scale that the accumulated tendon length is scaled by.
\param[in] recipCoefficient The scale that the tendon's response is multiplied by when applying to this tendon joint.
\param[in] link The link (and the link's incoming joint in particular) that this tendon joint is associated with.
\return The newly-created tendon joint if creation was successful, otherwise a null pointer.
\note
- The axis motion must not be configured as PxArticulationMotion::eLOCKED.
- The axis cannot be part of a fixed joint, i.e. joint configured as PxArticulationJointType::eFIX.
\see PxArticulationTendonJoint PxArticulationAxis
*/
virtual PxArticulationTendonJoint* createTendonJoint(PxArticulationTendonJoint* parent, PxArticulationAxis::Enum axis, const PxReal coefficient, const PxReal recipCoefficient, PxArticulationLink* link) = 0;
/**
\brief Fills a user-provided buffer of tendon-joint pointers with the set of tendon joints.
\param[in] userBuffer The user-provided buffer.
\param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to tendon joints,
only as many as can fit are written. Use getNbTendonJoints to size for all tendon joints.
\param[in] startIndex Index of first tendon joint pointer to be retrieved.
\return The number of tendon joints filled into the user buffer.
\see getNbTendonJoints
*/
virtual PxU32 getTendonJoints(PxArticulationTendonJoint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief Returns the number of tendon joints in the tendon.
\return The number of tendon joints.
*/
virtual PxU32 getNbTendonJoints() const = 0;
/**
\brief Sets the spring rest length of the tendon.
The accumulated "length" of a fixed tendon is a linear combination of the joint axis positions that the tendon is
associated with, scaled by the respective tendon joints' coefficients. As such, when the joint positions of all
joints are zero, the accumulated length of a fixed tendon is zero.
The spring of the tendon is not exerting any force on the articulation when the rest length is equal to the
tendon's accumulated length plus the tendon offset.
\param[in] restLength The spring rest length of the tendon.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see getRestLength()
*/
virtual void setRestLength(const PxReal restLength) = 0;
/**
\brief Gets the spring rest length of the tendon.
\return The spring rest length of the tendon.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see setRestLength()
*/
virtual PxReal getRestLength() const = 0;
/**
\brief Sets the low and high limit on the length of the tendon.
\param[in] parameter Struct with the low and high limit.
The limits, together with the damping and limit stiffness parameters, act on the accumulated length of the tendon.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationTendonLimit getLimitParameters() setRestLength()
*/
virtual void setLimitParameters(const PxArticulationTendonLimit& parameter) = 0;
/**
\brief Gets the low and high limit on the length of the tendon.
\return Struct with the low and high limit.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\see PxArticulationTendonLimit setLimitParameters()
*/
virtual PxArticulationTendonLimit getLimitParameters() const = 0;
/**
\brief Returns the string name of the dynamic type.
\return The string name.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxArticulationFixedTendon"; }
virtual ~PxArticulationFixedTendon() {}
protected:
PX_INLINE PxArticulationFixedTendon(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationTendon(concreteType, baseFlags) {}
PX_INLINE PxArticulationFixedTendon(PxBaseFlags baseFlags) : PxArticulationTendon(baseFlags) {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,120 @@
// 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 PX_ARTICULATION_TENDON_DATA_H
#define PX_ARTICULATION_TENDON_DATA_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec3.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief PxGpuSpatialTendonData
This data structure is to be used by the direct GPU API for spatial tendon data updates.
\see PxArticulationSpatialTendon PxDirectGPUAPI::getArticulationData PxDirectGPUAPI::setArticulationData
*/
PX_ALIGN_PREFIX(16)
class PxGpuSpatialTendonData
{
public:
PxReal stiffness;
PxReal damping;
PxReal limitStiffness;
PxReal offset;
}
PX_ALIGN_SUFFIX(16);
/**
\brief PxGpuFixedTendonData
This data structure is to be used by the direct GPU API for fixed tendon data updates.
\see PxArticulationFixedTendon PxDirectGPUAPI::getArticulationData PxDirectGPUAPI::setArticulationData
*/
PX_ALIGN_PREFIX(16)
class PxGpuFixedTendonData : public PxGpuSpatialTendonData
{
public:
PxReal lowLimit;
PxReal highLimit;
PxReal restLength;
PxReal padding;
}
PX_ALIGN_SUFFIX(16);
/**
\brief PxGpuTendonJointCoefficientData
This data structure is to be used by the direct GPU API for fixed tendon joint data updates.
\see PxArticulationTendonJoint PxDirectGPUAPI::getArticulationData PxDirectGPUAPI::setArticulationData
*/
PX_ALIGN_PREFIX(16)
class PxGpuTendonJointCoefficientData
{
public:
PxReal coefficient;
PxReal recipCoefficient;
PxU32 axis;
PxU32 pad;
}
PX_ALIGN_SUFFIX(16);
/**
\brief PxGpuTendonAttachmentData
This data structure is to be used by the direct GPU API for spatial tendon attachment data updates.
\see PxArticulationAttachment PxDirectGPUAPI::getArticulationData PxDirectGPUAPI::setArticulationData
*/
PX_ALIGN_PREFIX(16)
class PxGpuTendonAttachmentData
{
public:
PxVec3 relativeOffset;
PxReal restLength;
PxReal coefficient;
PxReal lowLimit;
PxReal highLimit;
PxReal padding;
}
PX_ALIGN_SUFFIX(16);
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,60 @@
// 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 PX_BASE_MATERIAL_H
#define PX_BASE_MATERIAL_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Base material class.
\see PxPhysics.createMaterial PxPhysics.createDeformableSurfaceMaterial PxPhysics.createDeformableVolumeMaterial PxPhysics.createPBDMaterial
*/
class PxBaseMaterial : public PxRefCounted
{
public:
PX_INLINE PxBaseMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags), userData(NULL) {}
PX_INLINE PxBaseMaterial(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {}
virtual ~PxBaseMaterial() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxBaseMaterial", PxRefCounted); }
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,802 @@
// 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 PX_BROAD_PHASE_H
#define PX_BROAD_PHASE_H
#include "PxPhysXConfig.h"
#include "foundation/PxBounds3.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxBaseTask;
class PxCudaContextManager;
class PxAllocatorCallback;
/**
\brief Broad phase algorithm used in the simulation
eSAP is a good generic choice with great performance when many objects are sleeping. Performance
can degrade significantly though, when all objects are moving, or when large numbers of objects
are added to or removed from the broad phase. This algorithm does not need world bounds to be
defined in order to work.
eMBP is an alternative broad phase algorithm that does not suffer from the same performance
issues as eSAP when all objects are moving or when inserting large numbers of objects. However
its generic performance when many objects are sleeping might be inferior to eSAP, and it requires
users to define world bounds in order to work.
eABP is a revisited implementation of MBP, which automatically manages broad-phase regions.
It offers the convenience of eSAP (no need to define world bounds or regions) and the performance
of eMBP when a lot of objects are moving. While eSAP can remain faster when most objects are
sleeping and eMBP can remain faster when it uses a large number of properly-defined regions,
eABP often gives the best performance on average and the best memory usage.
ePABP is a parallel implementation of ABP. It can often be the fastest (CPU) broadphase, but it
can use more memory than ABP.
eGPU is a GPU implementation of the incremental sweep and prune approach. Additionally, it uses a ABP-style
initial pair generation approach to avoid large spikes when inserting shapes. It not only has the advantage
of traditional SAP approch which is good for when many objects are sleeping, but due to being fully parallel,
it also is great when lots of shapes are moving or for runtime pair insertion and removal. It can become a
performance bottleneck if there are a very large number of shapes roughly projecting to the same values
on a given axis. If the scene has a very large number of shapes in an actor, e.g. a humanoid, it is recommended
to use an aggregate to represent multi-shape or multi-body actors to minimize stress placed on the broad phase.
*/
struct PxBroadPhaseType
{
enum Enum
{
eSAP, //!< 3-axes sweep-and-prune
eMBP, //!< Multi box pruning
eABP, //!< Automatic box pruning
ePABP, //!< Parallel automatic box pruning
eGPU, //!< GPU broad phase
eLAST
};
};
/**
\brief "Region of interest" for the broad-phase.
This is currently only used for the PxBroadPhaseType::eMBP broad-phase, which requires zones or regions to be defined
when the simulation starts in order to work. Regions can overlap and be added or removed at runtime, but at least one
region needs to be defined when the scene is created.
If objects that do no overlap any region are inserted into the scene, they will not be added to the broad-phase and
thus collisions will be disabled for them. A PxBroadPhaseCallback out-of-bounds notification will be sent for each one
of those objects.
The total number of regions is limited by PxBroadPhaseCaps::mMaxNbRegions.
The number of regions has a direct impact on performance and memory usage, so it is recommended to experiment with
various settings to find the best combination for your game. A good default setup is to start with global bounds
around the whole world, and subdivide these bounds into 4*4 regions. The PxBroadPhaseExt::createRegionsFromWorldBounds
function can do that for you.
\see PxBroadPhaseCallback PxBroadPhaseExt.createRegionsFromWorldBounds
*/
struct PxBroadPhaseRegion
{
PxBounds3 mBounds; //!< Region's bounds
void* mUserData; //!< Region's user-provided data
};
/**
\brief Information & stats structure for a region
*/
struct PxBroadPhaseRegionInfo
{
PxBroadPhaseRegion mRegion; //!< User-provided region data
PxU32 mNbStaticObjects; //!< Number of static objects in the region
PxU32 mNbDynamicObjects; //!< Number of dynamic objects in the region
bool mActive; //!< True if region is currently used, i.e. it has not been removed
bool mOverlap; //!< True if region overlaps other regions (regions that are just touching are not considering overlapping)
};
/**
\brief Caps class for broad phase.
*/
struct PxBroadPhaseCaps
{
PxU32 mMaxNbRegions; //!< Max number of regions supported by the broad-phase (0 = explicit regions not needed)
};
/**
\brief Descriptor for the GPU broad-phase.
This struct contains parameters that are only relevant for the GPU broad-phase.
\see PxBroadPhaseType::eGPU
*/
struct PxGpuBroadPhaseDesc
{
PxGpuBroadPhaseDesc() :
gpuBroadPhaseNbBitsShiftX (4),
gpuBroadPhaseNbBitsShiftY (4),
gpuBroadPhaseNbBitsShiftZ (4),
gpuBroadPhaseNbBitsEnvIDX (0),
gpuBroadPhaseNbBitsEnvIDY (0),
gpuBroadPhaseNbBitsEnvIDZ (0)
{
}
// The GPU broadphase encodes bounds as integers, and then right-shifts the data by this amount of bits.
// This makes the bounds a bit larger, which avoids losing and recreating overlaps over and over when
// two objects are just touching. This effect is similar to what can be achieved with the contact distance
// parameter, and the amount by which the bounds are inflated depends on the distance from the bounds to
// the origin (as the bounds encoding does not use a regular float-to-integer conversion, but instead a
// reinterpretation of the float's bits). The default value in the GPU broadphase has always been 4 bits
// but it is safe to use 0 here for more accurate bounds.
PxU8 gpuBroadPhaseNbBitsShiftX; //!< number of bits used for "snap to grid" on the X axis
PxU8 gpuBroadPhaseNbBitsShiftY; //!< number of bits used for "snap to grid" on the Y axis
PxU8 gpuBroadPhaseNbBitsShiftZ; //!< number of bits used for "snap to grid" on the Z axis
// The bits lost by the previous shifts (gpuBroadPhaseNbBitsShiftXYZ) can be replaced with bits of the
// environment IDs. This only makes sense when these parameters are used (see PxActor::setEnvironmentID
// and PxAggregate::setEnvironmentID). In this case a number of bits from the environment IDs are stored
// in the MSBs of encoded bounds. This has the effect of virtually spreading the bounds over 3D space,
// which reduces the number of internal overlaps inside the broad-phase. This is mainly useful in RL
// scenarios with "co-located" environments, but it can also provide performance gains with regular grid
// configurations, that also generate a lot of internal overlaps on all coordinate axes.
//
// Beware: when using this feature, each object of each environment should be assigned a proper environment
// ID. Objects shared between all environments (i.e. objects whose environment ID is PX_INVALID_U32) will
// otherwise be internally assigned bounds that cover the entire 3D space, creating a lot of overlaps and
// potential performance issues. This is only a concern when gpuBroadPhaseNbBitsEnvIDX/Y/Z are non zero,
// shared objects are fine otherwise.
PxU8 gpuBroadPhaseNbBitsEnvIDX; //!< number of environment ID bits merged with the bounds on the X axis
PxU8 gpuBroadPhaseNbBitsEnvIDY; //!< number of environment ID bits merged with the bounds on the Y axis
PxU8 gpuBroadPhaseNbBitsEnvIDZ; //!< number of environment ID bits merged with the bounds on the Z axis
PX_INLINE bool isValid() const
{
// This is used on 32bit data so it makes no sense to shift more than 32 bits.
// It also makes no sense to shift all the bits of source data.
if( gpuBroadPhaseNbBitsShiftX > 31
|| gpuBroadPhaseNbBitsShiftY > 31
|| gpuBroadPhaseNbBitsShiftZ > 31)
return false;
if( gpuBroadPhaseNbBitsEnvIDX > 31
|| gpuBroadPhaseNbBitsEnvIDY > 31
|| gpuBroadPhaseNbBitsEnvIDZ > 31)
return false;
// We can only store bits from environment IDs in bits shifted away from the source data.
// So we need to drop (shift) at least as many bits of the source data as we need for env IDs.
if( gpuBroadPhaseNbBitsEnvIDX > gpuBroadPhaseNbBitsShiftX
|| gpuBroadPhaseNbBitsEnvIDY > gpuBroadPhaseNbBitsShiftY
|| gpuBroadPhaseNbBitsEnvIDZ > gpuBroadPhaseNbBitsShiftZ)
return false;
return true;
}
};
/**
\brief Broadphase descriptor.
This structure is used to create a standalone broadphase. It captures all the parameters needed to
initialize a broadphase.
For the GPU broadphase (PxBroadPhaseType::eGPU) it is necessary to provide a CUDA context manager.
The kinematic filtering flags are currently not supported by the GPU broadphase. They are used to
dismiss pairs that involve kinematic objects directly within the broadphase.
\see PxCreateBroadPhase
*/
class PxBroadPhaseDesc
{
public:
PxBroadPhaseDesc(PxBroadPhaseType::Enum type = PxBroadPhaseType::eLAST) :
mType (type),
mContextID (0),
mContextManager (NULL),
mFoundLostPairsCapacity (256 * 1024),
mDiscardStaticVsKinematic (false),
mDiscardKinematicVsKinematic(false)
{}
PxBroadPhaseType::Enum mType; //!< Desired broadphase implementation
PxU64 mContextID; //!< Context ID for profiler. See PxProfilerCallback.
PxCudaContextManager* mContextManager; //!< (GPU) CUDA context manager, must be provided for PxBroadPhaseType::eGPU.
PxU32 mFoundLostPairsCapacity; //!< (GPU) Capacity of found and lost buffers allocated in GPU global memory. This is used for the found/lost pair reports in the BP.
bool mDiscardStaticVsKinematic; //!< Static-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU.
bool mDiscardKinematicVsKinematic; //!< kinematic-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU.
PX_INLINE bool isValid() const
{
if(PxU32(mType)>=PxBroadPhaseType::eLAST)
return false;
if(mType==PxBroadPhaseType::eGPU && !mContextManager)
return false;
return true;
}
};
typedef PxU32 PxBpIndex; //!< Broadphase index. Indexes bounds, groups and distance arrays.
typedef PxU32 PxBpFilterGroup; //!< Broadphase filter group.
#define PX_INVALID_BP_FILTER_GROUP 0xffffffff //!< Invalid broadphase filter group
/**
\brief Retrieves the filter group for static objects.
Mark static objects with this group when adding them to the broadphase.
Overlaps between static objects will not be detected. All static objects
should have the same group.
\return Filter group for static objects.
\see PxBpFilterGroup
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseStaticFilterGroup();
/**
\brief Retrieves a filter group for dynamic objects.
Mark dynamic objects with this group when adding them to the broadphase.
Each dynamic object must have an ID, and overlaps between dynamic objects that have
the same ID will not be detected. This is useful to dismiss overlaps between shapes
of the same (compound) actor directly within the broadphase.
\param id [in] ID/Index of dynamic object
\return Filter group for the object.
\see PxBpFilterGroup
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseDynamicFilterGroup(PxU32 id);
/**
\brief Retrieves a filter group for kinematic objects.
Mark kinematic objects with this group when adding them to the broadphase.
Each kinematic object must have an ID, and overlaps between kinematic objects that have
the same ID will not be detected.
\param id [in] ID/Index of kinematic object
\return Filter group for the object.
\see PxBpFilterGroup
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseKinematicFilterGroup(PxU32 id);
/**
\brief Broadphase data update structure.
This structure is used to update the low-level broadphase (PxBroadPhase). All added, updated and removed objects
must be batched and submitted at once to the broadphase.
Broadphase objects have bounds, a filtering group, and a distance. With the low-level broadphase the data must be
externally managed by the clients of the broadphase API, and passed to the update function.
The provided bounds are non-inflated "base" bounds that can be further extended by the broadphase using the passed
distance value. These can be contact offsets, or dynamically updated distance values for e.g. speculative contacts.
Either way they are optional and can be left to zero. The broadphase implementations efficiently combine the base
bounds with the per-object distance values at runtime.
The per-object filtering groups are used to discard some pairs directly within the broadphase, which is more
efficient than reporting the pairs and culling them in a second pass.
\see PxBpFilterGroup PxBpIndex PxBounds3 PxBroadPhase::update
*/
class PxBroadPhaseUpdateData
{
public:
PxBroadPhaseUpdateData( const PxBpIndex* created, PxU32 nbCreated,
const PxBpIndex* updated, PxU32 nbUpdated,
const PxBpIndex* removed, PxU32 nbRemoved,
const PxBounds3* bounds, const PxBpFilterGroup* groups, const float* distances,
PxU32 capacity) :
mCreated (created), mNbCreated (nbCreated),
mUpdated (updated), mNbUpdated (nbUpdated),
mRemoved (removed), mNbRemoved (nbRemoved),
mBounds (bounds), mGroups (groups), mDistances (distances),
mCapacity (capacity)
{
}
PxBroadPhaseUpdateData(const PxBroadPhaseUpdateData& other) :
mCreated (other.mCreated), mNbCreated (other.mNbCreated),
mUpdated (other.mUpdated), mNbUpdated (other.mNbUpdated),
mRemoved (other.mRemoved), mNbRemoved (other.mNbRemoved),
mBounds (other.mBounds), mGroups (other.mGroups), mDistances (other.mDistances),
mCapacity (other.mCapacity)
{
}
PxBroadPhaseUpdateData& operator=(const PxBroadPhaseUpdateData& other);
const PxBpIndex* mCreated; //!< Indices of created objects.
const PxU32 mNbCreated; //!< Number of created objects.
const PxBpIndex* mUpdated; //!< Indices of updated objects.
const PxU32 mNbUpdated; //!< Number of updated objects.
const PxBpIndex* mRemoved; //!< Indices of removed objects.
const PxU32 mNbRemoved; //!< Number of removed objects.
const PxBounds3* mBounds; //!< (Persistent) array of bounds.
const PxBpFilterGroup* mGroups; //!< (Persistent) array of groups.
const float* mDistances; //!< (Persistent) array of distances.
const PxU32 mCapacity; //!< Capacity of bounds / groups / distance buffers.
};
/**
\brief Broadphase pair.
A pair of indices returned by the broadphase for found or lost pairs.
\see PxBroadPhaseResults
*/
struct PxBroadPhasePair
{
PxBpIndex mID0; //!< Index of first object
PxBpIndex mID1; //!< Index of second object
};
/**
\brief Broadphase results.
Set of found and lost pairs after a broadphase update.
\see PxBroadPhasePair PxBroadPhase::fetchResults PxAABBManager::fetchResults
*/
struct PxBroadPhaseResults
{
PxBroadPhaseResults() : mNbCreatedPairs(0), mCreatedPairs(NULL), mNbDeletedPairs(0), mDeletedPairs(NULL) {}
PxU32 mNbCreatedPairs; //!< Number of new/found/created pairs.
const PxBroadPhasePair* mCreatedPairs; //!< Array of new/found/created pairs.
PxU32 mNbDeletedPairs; //!< Number of lost/deleted pairs.
const PxBroadPhasePair* mDeletedPairs; //!< Array of lost/deleted pairs.
};
/**
\brief Broadphase regions.
An API to manage broadphase regions. Only needed for the MBP broadphase (PxBroadPhaseType::eMBP).
\see PxBroadPhase::getRegions()
*/
class PxBroadPhaseRegions
{
protected:
PxBroadPhaseRegions() {}
virtual ~PxBroadPhaseRegions() {}
public:
/**
\brief Returns number of regions currently registered in the broad-phase.
\return Number of regions
*/
virtual PxU32 getNbRegions() const = 0;
/**
\brief Gets broad-phase regions.
\param userBuffer [out] Returned broad-phase regions
\param bufferSize [in] Size of provided userBuffer.
\param startIndex [in] Index of first desired region, in [0 ; getNbRegions()[
\return Number of written out regions.
\see PxBroadPhaseRegionInfo
*/
virtual PxU32 getRegions(PxBroadPhaseRegionInfo* userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/**
\brief Adds a new broad-phase region.
The total number of regions is limited to PxBroadPhaseCaps::mMaxNbRegions. If that number is exceeded, the call is ignored.
The newly added region will be automatically populated with already existing objects that touch it, if the
'populateRegion' parameter is set to true. Otherwise the newly added region will be empty, and it will only be
populated with objects when those objects are added to the simulation, or updated if they already exist.
Using 'populateRegion=true' has a cost, so it is best to avoid it if possible. In particular it is more efficient
to create the empty regions first (with populateRegion=false) and then add the objects afterwards (rather than
the opposite).
Objects automatically move from one region to another during their lifetime. The system keeps tracks of what
regions a given object is in. It is legal for an object to be in an arbitrary number of regions. However if an
object leaves all regions, or is created outside of all regions, several things happen:
- collisions get disabled for this object
- the object appears in the getOutOfBoundsObjects() array
If an out-of-bounds object, whose collisions are disabled, re-enters a valid broadphase region, then collisions
are re-enabled for that object.
\param region [in] User-provided region data
\param populateRegion [in] True to automatically populate the newly added region with existing objects touching it
\param bounds [in] User-managed array of bounds
\param distances [in] User-managed array of distances
\return Handle for newly created region, or 0xffffffff in case of failure.
\see PxBroadPhaseRegion getOutOfBoundsObjects()
*/
virtual PxU32 addRegion(const PxBroadPhaseRegion& region, bool populateRegion, const PxBounds3* bounds, const float* distances) = 0;
/**
\brief Removes a broad-phase region.
If the region still contains objects, and if those objects do not overlap any region any more, they are not
automatically removed from the simulation. Instead, the PxBroadPhaseCallback::onObjectOutOfBounds notification
is used for each object. Users are responsible for removing the objects from the simulation if this is the
desired behavior.
If the handle is invalid, or if a valid handle is removed twice, an error message is sent to the error stream.
\param handle [in] Region's handle, as returned by addRegion
\return True if success
*/
virtual bool removeRegion(PxU32 handle) = 0;
/*
\brief Return the number of objects that are not in any region.
*/
virtual PxU32 getNbOutOfBoundsObjects() const = 0;
/*
\brief Return an array of objects that are not in any region.
*/
virtual const PxU32* getOutOfBoundsObjects() const = 0;
};
/**
\brief Low-level broadphase API.
This low-level API only supports batched updates and leaves most of the data management to its clients.
This is useful if you want to use the broadphase with your own memory buffers. Note however that the GPU broadphase
works best with buffers allocated in CUDA memory. The getAllocator() function returns an allocator that is compatible
with the selected broadphase. It is recommended to allocate and deallocate the broadphase data (bounds, groups, distances)
using this allocator.
Important note: it must be safe to load 4 bytes past the end of the provided bounds array.
The high-level broadphase API (PxAABBManager) is an easier-to-use interface that automatically deals with these requirements.
\see PxCreateBroadPhase
*/
class PxBroadPhase
{
protected:
PxBroadPhase() {}
virtual ~PxBroadPhase() {}
public:
/*
\brief Releases the broadphase.
*/
virtual void release() = 0;
/**
\brief Gets the broadphase type.
\return Broadphase type.
\see PxBroadPhaseType::Enum
*/
virtual PxBroadPhaseType::Enum getType() const = 0;
/**
\brief Gets broad-phase caps.
\param caps [out] Broad-phase caps
\see PxBroadPhaseCaps
*/
virtual void getCaps(PxBroadPhaseCaps& caps) const = 0;
/**
\brief Retrieves the regions API if applicable.
For broadphases that do not use explicit user-defined regions, this call returns NULL.
\return Region API, or NULL.
\see PxBroadPhaseRegions
*/
virtual PxBroadPhaseRegions* getRegions() = 0;
/**
\brief Retrieves the broadphase allocator.
User-provided buffers should ideally be allocated with this allocator, for best performance.
This is especially true for the GPU broadphases, whose buffers need to be allocated in CUDA
host memory.
\return The broadphase allocator.
\see PxAllocatorCallback
*/
virtual PxAllocatorCallback* getAllocator() = 0;
/**
\brief Retrieves the profiler's context ID.
\return The context ID.
\see PxBroadPhaseDesc
*/
virtual PxU64 getContextID() const = 0;
/**
\brief Sets a scratch buffer
Some broadphases might take advantage of a scratch buffer to limit runtime allocations.
All broadphases still work without providing a scratch buffer, this is an optional function
that can potentially reduce runtime allocations.
\param scratchBlock [in] The scratch buffer
\param size [in] Size of the scratch buffer in bytes
*/
virtual void setScratchBlock(void* scratchBlock, PxU32 size) = 0;
/**
\brief Updates the broadphase and computes the lists of created/deleted pairs.
The provided update data describes changes to objects since the last broadphase update.
To benefit from potentially multithreaded implementations, it is necessary to provide a continuation
task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will
then run single-threaded.
\param updateData [in] The update data
\param continuation [in] Continuation task to enable multi-threaded implementations, or NULL.
\see PxBroadPhaseUpdateData PxBaseTask
*/
virtual void update(const PxBroadPhaseUpdateData& updateData, PxBaseTask* continuation=NULL) = 0;
/**
\brief Retrieves the broadphase results after an update.
This should be called once after each update call to retrieve the results of the broadphase. The
results are incremental, i.e. the system only returns new and lost pairs, not all current pairs.
\param results [out] The broadphase results
\see PxBroadPhaseResults
*/
virtual void fetchResults(PxBroadPhaseResults& results) = 0;
/**
\brief Helper for single-threaded updates.
This short helper function performs a single-theaded update and reports the results in a single call.
\param results [out] The broadphase results
\param updateData [in] The update data
\see PxBroadPhaseUpdateData PxBroadPhaseResults
*/
PX_FORCE_INLINE void updateAndFetchResults(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData)
{
update(updateData);
fetchResults(results);
}
/**
\brief Helper for single-threaded updates.
This short helper function performs a single-theaded update and reports the results in a single call.
\param results [out] The broadphase results
\param updateData [in] The update data
\see PxBroadPhaseUpdateData PxBroadPhaseResults
*/
PX_DEPRECATED PX_FORCE_INLINE void update(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData)
{
update(updateData);
fetchResults(results);
}
};
/**
\brief Broadphase factory function.
Use this function to create a new standalone broadphase.
\param desc [in] Broadphase descriptor
\return Newly created broadphase, or NULL
\see PxBroadPhase PxBroadPhaseDesc
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxBroadPhase* PxCreateBroadPhase(const PxBroadPhaseDesc& desc);
/**
\brief High-level broadphase API.
The low-level broadphase API (PxBroadPhase) only supports batched updates and has a few non-trivial
requirements for managing the bounds data.
The high-level broadphase API (PxAABBManager) is an easier-to-use one-object-at-a-time API that
automatically deals with the quirks of the PxBroadPhase data management.
\see PxCreateAABBManager
*/
class PxAABBManager
{
protected:
PxAABBManager() {}
virtual ~PxAABBManager() {}
public:
/*
\brief Releases the AABB manager.
*/
virtual void release() = 0;
/**
\brief Retrieves the underlying broadphase.
\return The managed broadphase.
\see PxBroadPhase
*/
virtual PxBroadPhase& getBroadPhase() = 0;
/**
\brief Retrieves the managed bounds.
This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion.
\return The managed object bounds.
\see PxBounds3
*/
virtual const PxBounds3* getBounds() const = 0;
/**
\brief Retrieves the managed distances.
This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion.
\return The managed object distances.
*/
virtual const float* getDistances() const = 0;
/**
\brief Retrieves the managed filter groups.
\return The managed object groups.
*/
virtual const PxBpFilterGroup* getGroups() const = 0;
/**
\brief Retrieves the managed buffers' capacity.
Bounds, distances and groups buffers have the same capacity.
\return The managed buffers' capacity.
*/
virtual PxU32 getCapacity() const = 0;
/**
\brief Adds an object to the manager.
Objects' indices are externally managed, i.e. they must be provided by users (as opposed to handles
that could be returned by this manager). The design allows users to identify an object by a single ID,
and use the same ID in multiple sub-systems.
\param index [in] The object's index
\param bounds [in] The object's bounds
\param group [in] The object's filter group
\param distance [in] The object's distance (optional)
\see PxBpIndex PxBounds3 PxBpFilterGroup
*/
virtual void addObject(PxBpIndex index, const PxBounds3& bounds, PxBpFilterGroup group, float distance=0.0f) = 0;
/**
\brief Removes an object from the manager.
\param index [in] The object's index
\see PxBpIndex
*/
virtual void removeObject(PxBpIndex index) = 0;
/**
\brief Updates an object in the manager.
This call can update an object's bounds, distance, or both.
It is not possible to update an object's filter group.
\param index [in] The object's index
\param bounds [in] The object's updated bounds, or NULL
\param distance [in] The object's updated distance, or NULL
\see PxBpIndex PxBounds3
*/
virtual void updateObject(PxBpIndex index, const PxBounds3* bounds=NULL, const float* distance=NULL) = 0;
/**
\brief Updates the broadphase and computes the lists of created/deleted pairs.
The data necessary for updating the broadphase is internally computed by the AABB manager.
To benefit from potentially multithreaded implementations, it is necessary to provide a continuation
task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will
then run single-threaded.
\param continuation [in] Continuation task to enable multi-threaded implementations, or NULL.
\see PxBaseTask
*/
virtual void update(PxBaseTask* continuation=NULL) = 0;
/**
\brief Retrieves the broadphase results after an update.
This should be called once after each update call to retrieve the results of the broadphase. The
results are incremental, i.e. the system only returns new and lost pairs, not all current pairs.
\param results [out] The broadphase results
\see PxBroadPhaseResults
*/
virtual void fetchResults(PxBroadPhaseResults& results) = 0;
/**
\brief Helper for single-threaded updates.
This short helper function performs a single-theaded update and reports the results in a single call.
\param results [out] The broadphase results
\see PxBroadPhaseResults
*/
PX_FORCE_INLINE void updateAndFetchResults(PxBroadPhaseResults& results)
{
update();
fetchResults(results);
}
/**
\brief Helper for single-threaded updates.
This short helper function performs a single-theaded update and reports the results in a single call.
\param results [out] The broadphase results
\see PxBroadPhaseResults
*/
PX_DEPRECATED PX_FORCE_INLINE void update(PxBroadPhaseResults& results)
{
update();
fetchResults(results);
}
};
/**
\brief AABB manager factory function.
Use this function to create a new standalone high-level broadphase.
\param broadphase [in] The broadphase that will be managed by the AABB manager
\return Newly created AABB manager, or NULL
\see PxAABBManager PxBroadPhase
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxAABBManager* PxCreateAABBManager(PxBroadPhase& broadphase);
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,57 @@
// 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 PX_CLIENT_H
#define PX_CLIENT_H
#include "foundation/PxFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief An ID to identify different clients for multiclient support.
\see PxScene::createClient()
*/
typedef PxU8 PxClientID;
/**
\brief The predefined default PxClientID value.
\see PxClientID PxScene::createClient()
*/
static const PxClientID PX_DEFAULT_CLIENT = 0;
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,124 @@
// 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 PX_CONE_LIMITED_CONSTRAINT_H
#define PX_CONE_LIMITED_CONSTRAINT_H
#include "foundation/PxVec3.h"
#include "foundation/PxVec4.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief A constraint descriptor for limiting movement to a conical region.
*/
struct PxConeLimitedConstraint
{
PxConeLimitedConstraint()
{
setToDefault();
}
/**
\brief Set values such that constraint is disabled.
*/
PX_INLINE void setToDefault()
{
mAxis = PxVec3(0.f, 0.f, 0.f);
mAngle = -1.f;
mLowLimit = -1.f;
mHighLimit = -1.f;
}
/**
\brief Checks for valitity.
\return true if the constaint is valid
*/
PX_INLINE bool isValid() const
{
//disabled
if (mAngle < 0.f && mLowLimit < 0.f && mHighLimit < 0.f)
{
return true;
}
if (!mAxis.isNormalized())
{
return false;
}
//negative signifies that cone is disabled
if (mAngle >= PxPi)
{
return false;
}
//negative signifies that distance limits are disabled
if (mLowLimit > mHighLimit && mHighLimit >= 0.0f && mLowLimit >= 0.0f)
{
return false;
}
return true;
}
PxVec3 mAxis; //!< Axis of the cone in actor space
PxReal mAngle; //!< Opening angle in radians, negative indicates unlimited
PxReal mLowLimit; //!< Minimum distance, negative indicates unlimited
PxReal mHighLimit; //!< Maximum distance, negative indicates unlimited
};
/**
\brief Compressed form of cone limit parameters
\see PxConeLimitedConstraint
*/
PX_ALIGN_PREFIX(16)
struct PxConeLimitParams
{
PX_CUDA_CALLABLE PxConeLimitParams() {}
PX_CUDA_CALLABLE PxConeLimitParams(const PxConeLimitedConstraint& coneLimitedConstraint) :
lowHighLimits(coneLimitedConstraint.mLowLimit, coneLimitedConstraint.mHighLimit, 0.0f, 0.0f),
axisAngle(coneLimitedConstraint.mAxis, coneLimitedConstraint.mAngle)
{
}
PxVec4 lowHighLimits; // [lowLimit, highLimit, unused, unused]
PxVec4 axisAngle; // [axis.x, axis.y, axis.z, angle]
}PX_ALIGN_SUFFIX(16);
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,291 @@
// 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 PX_CONSTRAINT_H
#define PX_CONSTRAINT_H
#include "PxPhysXConfig.h"
#include "PxConstraintDesc.h"
#include "common/PxBase.h"
#include "PxResidual.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxRigidActor;
class PxScene;
class PxConstraintConnector;
/**
\brief constraint flags
\note eBROKEN is a read only flag
*/
struct PxConstraintFlag
{
enum Enum
{
eBROKEN = 1<<0, //!< whether the constraint is broken
eCOLLISION_ENABLED = 1<<3, //!< whether contacts should be generated between the objects this constraint constrains
eVISUALIZATION = 1<<4, //!< whether this constraint should be visualized, if constraint visualization is turned on
eDRIVE_LIMITS_ARE_FORCES = 1<<5, //!< \deprecated Will be removed in a future version and the limits will always be forces. limits for drive strength are forces rather than impulses
eIMPROVED_SLERP = 1<<7, //!< perform preprocessing for improved accuracy on D6 Slerp Drive (this flag will be removed in a future release when preprocessing is no longer required)
eDISABLE_PREPROCESSING = 1<<8, //!< suppress constraint preprocessing, intended for use with rowResponseThreshold. May result in worse solver accuracy for ill-conditioned constraints.
eENABLE_EXTENDED_LIMITS = 1<<9, //!< enables extended limit ranges for angular limits (e.g., limit values > PxPi or < -PxPi)
eGPU_COMPATIBLE = 1<<10, //!< please do not raise this flag as it is for internal use only
eALWAYS_UPDATE = 1<<11, //!< updates the constraint each frame
eDISABLE_CONSTRAINT = 1<<12 //!< disables the constraint. SolverPrep functions won't be called for this constraint.
};
};
/**
\brief constraint flags
\see PxConstraintFlag
*/
typedef PxFlags<PxConstraintFlag::Enum, PxU16> PxConstraintFlags;
PX_FLAGS_OPERATORS(PxConstraintFlag::Enum, PxU16)
/**
\brief a table of function pointers for a constraint
\see PxConstraint
*/
struct PxConstraintShaderTable
{
PxConstraintSolverPrep solverPrep; //!< solver constraint generation function
PxConstraintVisualize visualize; //!< constraint visualization function
PxConstraintFlag::Enum flag; //!< constraint flags
};
/**
\brief A plugin class for implementing constraints
\see PxPhysics.createConstraint
*/
class PxConstraint : public PxBase
{
public:
/**
\brief Releases a PxConstraint instance.
\note This call does not wake up the connected rigid bodies.
\see PxPhysics.createConstraint, PxBase.release()
*/
virtual void release() = 0;
/**
\brief Retrieves the scene which this constraint belongs to.
\return Owner Scene. NULL if not part of a scene.
\see PxScene
*/
virtual PxScene* getScene() const = 0;
/**
\brief Retrieves the actors for this constraint.
\param[out] actor0 a reference to the pointer for the first actor
\param[out] actor1 a reference to the pointer for the second actor
\see PxActor
*/
virtual void getActors(PxRigidActor*& actor0, PxRigidActor*& actor1) const = 0;
/**
\brief Sets the actors for this constraint.
\param[in] actor0 a reference to the pointer for the first actor
\param[in] actor1 a reference to the pointer for the second actor
\see PxActor
*/
virtual void setActors(PxRigidActor* actor0, PxRigidActor* actor1) = 0;
/**
\brief Notify the scene that the constraint shader data has been updated by the application
*/
virtual void markDirty() = 0;
/**
\brief Retrieve the flags for this constraint
\return the constraint flags
\see PxConstraintFlags
*/
virtual PxConstraintFlags getFlags() const = 0;
/**
\brief Set the flags for this constraint
\param[in] flags the new constraint flags
default: PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES
\see PxConstraintFlags
*/
virtual void setFlags(PxConstraintFlags flags) = 0;
/**
\brief Set a flag for this constraint
\param[in] flag the constraint flag
\param[in] value the new value of the flag
\see PxConstraintFlags
*/
virtual void setFlag(PxConstraintFlag::Enum flag, bool value) = 0;
/**
\brief Retrieve the constraint force most recently applied to maintain this constraint.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\param[out] linear the constraint force
\param[out] angular the constraint torque
*/
virtual void getForce(PxVec3& linear, PxVec3& angular) const = 0;
/**
\brief whether the constraint is valid.
A constraint is valid if it has at least one dynamic rigid body or articulation link. A constraint that
is not valid may not be inserted into a scene, and therefore a static actor to which an invalid constraint
is attached may not be inserted into a scene.
Invalid constraints arise only when an actor to which the constraint is attached has been deleted.
*/
virtual bool isValid() const = 0;
/**
\brief Set the break force and torque thresholds for this constraint.
If either the force or torque measured at the constraint exceed these thresholds the constraint will break.
\param[in] linear the linear break threshold
\param[in] angular the angular break threshold
*/
virtual void setBreakForce(PxReal linear, PxReal angular) = 0;
/**
\brief Retrieve the constraint break force and torque thresholds
\param[out] linear the linear break threshold
\param[out] angular the angular break threshold
*/
virtual void getBreakForce(PxReal& linear, PxReal& angular) const = 0;
/**
\brief Set the minimum response threshold for a constraint row
When using mass modification for a joint or infinite inertia for a jointed body, very stiff solver constraints can be generated which
can destabilize simulation. Setting this value to a small positive value (e.g. 1e-8) will cause constraint rows to be ignored if very
large changes in impulses will generate only small changes in velocity. When setting this value, also set
PxConstraintFlag::eDISABLE_PREPROCESSING. The solver accuracy for this joint may be reduced.
\param[in] threshold the minimum response threshold
\see PxConstraintFlag::eDISABLE_PREPROCESSING
*/
virtual void setMinResponseThreshold(PxReal threshold) = 0;
/**
\brief Retrieve the constraint break force and torque thresholds
\return the minimum response threshold for a constraint row
*/
virtual PxReal getMinResponseThreshold() const = 0;
/**
\brief Fetch external owner of the constraint.
Provides a reference to the external owner of a constraint and a unique owner type ID.
\param[out] typeID Unique type identifier of the external object.
\return Reference to the external object which owns the constraint.
\see PxConstraintConnector.getExternalReference()
*/
virtual void* getExternalReference(PxU32& typeID) = 0;
/**
\brief Set the constraint functions for this constraint
\param[in] connector the constraint connector object by which the SDK communicates with the constraint.
\param[in] shaders the shader table for the constraint
\see PxConstraintConnector PxConstraintSolverPrep PxConstraintVisualize
*/
virtual void setConstraintFunctions(PxConstraintConnector& connector, const PxConstraintShaderTable& shaders) = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxConstraint"; }
/**
\brief Returns the residual for this constraint.
The residual represents the current error in this constraint measured as the delta impulse applied in the last velocity or position iteration.
If the solver converges perfectly, the residual should approach zero.
\return The residual for this constraint.
\see PxConstraintResidual
*/
virtual PxConstraintResidual getSolverResidual() const = 0;
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
PX_INLINE PxConstraint(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {}
PX_INLINE PxConstraint(PxBaseFlags baseFlags) : PxBase(baseFlags), userData(NULL) {}
virtual ~PxConstraint() {}
virtual bool isKindOf(const char* name) const PX_OVERRIDE { PX_IS_KIND_OF(name, "PxConstraint", PxBase); }
public:
/**
\cond
*/
// for internal use only
virtual PxConstraintGPUIndex getGPUIndex() const = 0;
/**
\endcond
*/
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,491 @@
// 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 PX_CONSTRAINT_DESC_H
#define PX_CONSTRAINT_DESC_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#include "foundation/PxVec3.h"
#include "foundation/PxTransform.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx { namespace pvdsdk {
#endif
class PvdDataStream;
#if !PX_DOXYGEN
}}
#endif
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Constraint row flags
These flags configure the post-processing of constraint rows and the behavior of the solver while solving constraints
*/
struct Px1DConstraintFlag
{
PX_CUDA_CALLABLE Px1DConstraintFlag(){}
enum Type
{
eSPRING = 1<<0, //!< whether the constraint is a spring. Mutually exclusive with eRESTITUTION. If set, eKEEPBIAS is ignored.
eACCELERATION_SPRING = 1<<1, //!< whether the constraint is a force or acceleration spring. Only valid if eSPRING is set.
eRESTITUTION = 1<<2, //!< whether the restitution model should be applied to generate the target velocity. Mutually exclusive with eSPRING. If restitution causes a bounces, eKEEPBIAS is ignored
eKEEPBIAS = 1<<3, //!< whether to keep the error term when solving for velocity. Ignored if restitution generates bounce, or eSPRING is set.
eOUTPUT_FORCE = 1<<4, //!< whether to accumulate the force value from this constraint in the force total that is reported for the constraint and tested for breakage
eHAS_DRIVE_LIMIT = 1<<5, //!< whether the constraint has a drive force limit (which will be scaled by dt unless #PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES is set)
eANGULAR_CONSTRAINT = 1<<6, //!< whether this is an angular or linear constraint
};
};
typedef PxFlags<Px1DConstraintFlag::Type, PxU16> Px1DConstraintFlags;
PX_FLAGS_OPERATORS(Px1DConstraintFlag::Type, PxU16)
/**
\brief Constraint type hints which the solver uses to optimize constraint handling
*/
struct PxConstraintSolveHint
{
enum Enum
{
eNONE = 0, //!< no special properties
eACCELERATION1 = 256, //!< a group of acceleration drive constraints with the same stiffness and drive parameters
eSLERP_SPRING = 258, //!< temporary special value to identify SLERP drive rows
eACCELERATION2 = 512, //!< a group of acceleration drive constraints with the same stiffness and drive parameters
eACCELERATION3 = 768, //!< a group of acceleration drive constraints with the same stiffness and drive parameters
eROTATIONAL_EQUALITY = 1024, //!< for internal purpose only, please do not use.
eROTATIONAL_INEQUALITY = 1025, //!< for internal purpose only, please do not use.
/**
\brief Mark as equality constraint.
If a 1D constraint is an equality constraint with [-PX_MAX_FLT, PX_MAX_FLT] force limits and a velocity target equal zero, then this
flag can be raised to allow the solver to internally change the jacobian of this constraint and have it being orthogonalized relative
to other equality constraints in the same PxConstraint (unless PxConstraintFlag::eDISABLE_PREPROCESSING is set). This can improve
the convergence when solving the constraints.
*/
eEQUALITY = 2048,
/**
\brief Mark as inequality constraint.
If a 1D constraint is an inequality constraint with [0, PX_MAX_FLT] force limits, then this flag can be raised to allow the solver
to internally change the jacobian of this constraint and have it being orthogonalized relative to the equality constraints in the
same PxConstraint (unless PxConstraintFlag::eDISABLE_PREPROCESSING is set). This can improve the convergence when solving the
constraints.
*/
eINEQUALITY = 2049
};
};
/**
\brief A one-dimensional constraint that constrains the relative motion of two rigid bodies.
A constraint is expressed as a set of 1-dimensional constraint rows which define the required constraint
on the objects' velocities.
The constraint Jacobian J is specified by the parameters linear0, angular0, linear1, angular1 as follows
J = {linear0, angular0, -linear1, -angular1}
The velocity target of the constraint is specified by Px1DConstraint::velocityTarget and the geometric error of the constraint
is specified by Px1DConstraint::geometricError.
The output of the constraint is a velocity state (sdot = ds/dt with s denoting the constraint state) expressed in the world frame:
sdot = {linearVelocity0, angularVelocity0, linearVelocity1, angularVelocity1}
with linearVelocity0 and angularVelocity0 denoting the linear and angular velocity of body0 of the constraint;
and linearVelocity1 and angularVelocity1 denoting the linear and angular velocity of body1 of the constraint.
The constraint seeks an updated sdot that obeys a simple constraint rule:
J*sdot + BaumgarteTerm*geometricError/dt - velocityTarget = 0
where BaumgarteTerm is a multiplier in range (0, 1). The Baumgarte term is not exposed but is instead internally
set according to a simple metric chosen to enhance numerical stability. If the PGS solver is employed then dt is
taken from the scene timestep.
Another way of expressing the constraint rule is as follows:
linear0.dot(linearVelocity0) + angular0.dot(angularVelocity0)
- linear1.dot(linearVelocity1) - angular1.dot(angularVelocity1)
+ BaumgarteTerm*geometricError/dt - velocityTarget = 0
The PhysX solver runs two phases: position iterations followed by velocity iterations. Position iterations derive
the velocity that is used to integrate the transform of a rigid body. Velocity iterations on the other hand derive
the final velocity of a rigid body. The constraint rule presented above only gets applied during position iterations,
during velocity iterations the geometricError term is usually ignored and the applied constraint rule is:
J*sdot - velocityTarget = 0
The flag Px1DConstraintFlag::eKEEPBIAS can be used to have velocity iterations apply the same constraint rule as
position iterations.
A 1d constraint may be either a restitution constraint or a hard constraint or a spring constraint.
Restitution constraints have two modes of operation, depending on the speed of the constraint. These two modes are:
a) a bounce mode that employs a restitution value specified by RestitutionModifiers::restitution
b) a non-bounce mode that employs zero restitution and ignores RestitutionModifiers::restitution.
The constraint speed immediately before the solver begins is computed as follows:
constraintPreSolverSpeed = J * sdotPreSolver
with sdotPreSolver denoting the rigid body velocities recorded after applying external forces and torques to the rigid bodies
but before the solver begins.
If the bounce mode is active, the pre solver velocity is expected to flip direction and have restitution applied:
bounceSpeed = -restitution * constraintPreSolverSpeed
Restitution will kick in if the following conditions are met:
\li -constraintPreSolverSpeed exceeds the bounce threshold (RestitutionModifiers::velocityThreshold)
\li (bounceSpeed * Px1DConstraint::geometricError) <= 0 (bounceSpeed points in the
opposite direction of the geometric error)
If these hold, then the provided Px1DConstraint::geometricError and Px1DConstraint::velocityTarget parameter will get overriden
internally. The former will get set to zero, the latter will get set to bounceSpeed. If restitution does not activate because
the listed conditions are not met, then the target velocity will be taken from the value stored in velocityTarget and the
geometric error will be taken from the value stored in geometricError.
RestitutionModifiers::restitution may be greater than 1 and may be less than 0 ie it is not limited to 0 <= restitution <= 1.
Hard constraints attempt to find sdot that satisfies the constraint equation:
J*sdot + BaumgarteTerm*geometricError/dt - velocityTarget = 0
Spring constraints are quite different from restitution and hard constraints in that they attempt to compute and apply a spring force as follows:
F = stiffness * -geometricError + damping * (velocityTarget - J*sdot)
where F is the constraint force or acceleration and J*sdot is the instantaneous constraint speed. Springs are
implemented with a fully implicit time-stepping scheme: that is, the force or acceleration is a function of the position
and velocity after the solve. Note that F gets applied to the first rigid body and -F to the second rigid body.
All constraints support limits on the minimum or maximum impulse applied.
*/
PX_ALIGN_PREFIX(16)
struct Px1DConstraint
{
PxVec3 linear0; //!< linear component of velocity jacobian in world space
PxReal geometricError; //!< geometric error of the constraint along this axis
PxVec3 angular0; //!< angular component of velocity jacobian in world space
PxReal velocityTarget; //!< velocity target for the constraint along this axis
PxVec3 linear1; //!< linear component of velocity jacobian in world space
PxReal minImpulse; //!< minimum impulse the solver may apply to enforce this constraint
PxVec3 angular1; //!< angular component of velocity jacobian in world space
PxReal maxImpulse; //!< maximum impulse the solver may apply to enforce this constraint
union
{
struct SpringModifiers
{
PxReal stiffness; //!< spring parameter, for spring constraints
PxReal damping; //!< damping parameter, for spring constraints
} spring;
struct RestitutionModifiers
{
PxReal restitution; //!< restitution parameter for determining additional "bounce"
PxReal velocityThreshold; //!< minimum impact velocity for bounce
} bounce;
} mods;
PxU16 flags; //!< a set of Px1DConstraintFlags
PxU16 solveHint; //!< constraint optimization hint, should be an element of PxConstraintSolveHint
PxU32 pad; // for padding only
}
PX_ALIGN_SUFFIX(16);
/**
\brief Flags for determining which components of the constraint should be visualized.
\see PxConstraintVisualize
*/
struct PxConstraintVisualizationFlag
{
enum Enum
{
eLOCAL_FRAMES = 1, //!< visualize constraint frames
eLIMITS = 2 //!< visualize constraint limits
};
};
/**
\brief Struct for specifying mass scaling for a pair of rigids
*/
PX_ALIGN_PREFIX(16)
struct PxConstraintInvMassScale
{
PxReal linear0; //!< multiplier for inverse mass of body0
PxReal angular0; //!< multiplier for inverse MoI of body0
PxReal linear1; //!< multiplier for inverse mass of body1
PxReal angular1; //!< multiplier for inverse MoI of body1
PX_CUDA_CALLABLE PX_FORCE_INLINE PxConstraintInvMassScale(){}
PX_CUDA_CALLABLE PX_FORCE_INLINE PxConstraintInvMassScale(PxReal lin0, PxReal ang0, PxReal lin1, PxReal ang1) : linear0(lin0), angular0(ang0), linear1(lin1), angular1(ang1){}
}
PX_ALIGN_SUFFIX(16);
/**
\brief Solver constraint generation shader
This function is called by the constraint solver framework. The function must be reentrant, since it may be called simultaneously
from multiple threads, and should access only the arguments passed into it.
Developers writing custom constraints are encouraged to read the documentation in the user guide and the implementation code in PhysXExtensions.
\param[out] constraints An array of solver constraint rows to be filled in
\param[out] bodyAWorldOffset The origin point (offset from the position vector of bodyA's center of mass) at which the constraint is resolved. This value does not affect how constraints are solved, only the constraint force reported.
\param[in] maxConstraints The size of the constraint buffer. At most this many constraints rows may be written
\param[out] invMassScale The inverse mass and inertia scales for the constraint
\param[in] constantBlock The constant data block
\param[in] bodyAToWorld The center of mass frame of the first constrained body (the identity transform if the first actor is static, or if a NULL actor pointer was provided for it)
\param[in] bodyBToWorld The center of mass frame of the second constrained body (the identity transform if the second actor is static, or if a NULL actor pointer was provided for it)
\param[in] useExtendedLimits Enables limit ranges outside of (-PI, PI)
\param[out] cAtW The world space location of body A's joint frame (position only)
\param[out] cBtW The world space location of body B's joint frame (position only)
\return the number of constraint rows written.
*/
typedef PxU32 (*PxConstraintSolverPrep)(Px1DConstraint* constraints,
PxVec3p& bodyAWorldOffset,
PxU32 maxConstraints,
PxConstraintInvMassScale& invMassScale,
const void* constantBlock,
const PxTransform& bodyAToWorld,
const PxTransform& bodyBToWorld,
bool useExtendedLimits,
PxVec3p& cAtW,
PxVec3p& cBtW);
/**
\brief API used to visualize details about a constraint.
*/
class PxConstraintVisualizer
{
protected:
virtual ~PxConstraintVisualizer(){}
public:
/** \brief Visualize joint frames
\param[in] parent Parent transformation
\param[in] child Child transformation
*/
virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) = 0;
/** \brief Visualize joint linear limit
\param[in] t0 Base transformation
\param[in] t1 End transformation
\param[in] value Distance
*/
virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value) = 0;
/** \brief Visualize joint angular limit
\param[in] t0 Transformation for the visualization
\param[in] lower Lower limit angle
\param[in] upper Upper limit angle
*/
virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper) = 0;
/** \brief Visualize limit cone
\param[in] t Transformation for the visualization
\param[in] tanQSwingY Tangent of the quarter Y angle
\param[in] tanQSwingZ Tangent of the quarter Z angle
*/
virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ) = 0;
/** \brief Visualize joint double cone
\param[in] t Transformation for the visualization
\param[in] angle Limit angle
*/
virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle) = 0;
/** \brief Visualize line
\param[in] p0 Start position
\param[in] p1 End postion
\param[in] color Color
*/
virtual void visualizeLine(const PxVec3& p0, const PxVec3& p1, PxU32 color) = 0;
};
/** \brief Solver constraint visualization function
This function is called by the constraint post-solver framework to visualize the constraint
\param[out] visualizer The render buffer to render to
\param[in] constantBlock The constant data block
\param[in] body0Transform The center of mass frame of the first constrained body (the identity if the actor is static, or a NULL pointer was provided for it)
\param[in] body1Transform The center of mass frame of the second constrained body (the identity if the actor is static, or a NULL pointer was provided for it)
\param[in] flags The visualization flags (PxConstraintVisualizationFlag)
\see PxRenderBuffer
*/
typedef void (*PxConstraintVisualize)(PxConstraintVisualizer& visualizer,
const void* constantBlock,
const PxTransform& body0Transform,
const PxTransform& body1Transform,
PxU32 flags);
/**
\brief Flags for determining how PVD should serialize a constraint update
\see PxConstraintConnector::updatePvdProperties, PvdSceneClient::updateConstraint
*/
struct PxPvdUpdateType
{
enum Enum
{
CREATE_INSTANCE, //!< triggers createPvdInstance call, creates an instance of a constraint
RELEASE_INSTANCE, //!< triggers releasePvdInstance call, releases an instance of a constraint
UPDATE_ALL_PROPERTIES, //!< triggers updatePvdProperties call, updates all properties of a constraint
UPDATE_SIM_PROPERTIES //!< triggers simUpdate call, updates all simulation properties of a constraint
};
};
/**
\brief This class connects a custom constraint to the SDK
This class connects a custom constraint to the SDK, and functions are called by the SDK
to query the custom implementation for specific information to pass on to the application
or inform the constraint when the application makes calls into the SDK which will update
the custom constraint's internal implementation
*/
class PxConstraintConnector
{
public:
/** \brief Pre-simulation data preparation
when the constraint is marked dirty, this function is called at the start of the simulation
step for the SDK to copy the constraint data block.
*/
virtual void* prepareData() = 0;
/**
\brief this function is called by the SDK to update PVD's view of it
*/
virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream& pvdConnection,
const PxConstraint* c,
PxPvdUpdateType::Enum updateType) const = 0;
/**
\brief this function is called by the SDK to update OmniPVD's view of it
*/
virtual void updateOmniPvdProperties() const = 0;
/**
\brief Constraint release callback
When the SDK deletes a PxConstraint object this function is called by the SDK. In general
custom constraints should not be deleted directly by applications: rather, the constraint
should respond to a release() request by calling PxConstraint::release(), then wait for
this call to release its own resources.
This function is also called when a PxConstraint object is deleted on cleanup due to
destruction of the PxPhysics object.
*/
virtual void onConstraintRelease() = 0;
/**
\brief Center-of-mass shift callback
This function is called by the SDK when the CoM of one of the actors is moved. Since the
API specifies constraint positions relative to actors, and the constraint shader functions
are supplied with coordinates relative to bodies, some synchronization is usually required
when the application moves an object's center of mass.
*/
virtual void onComShift(PxU32 actor) = 0;
/**
\brief Origin shift callback
This function is called by the SDK when the scene origin gets shifted and allows to adjust
custom data which contains world space transforms.
\note If the adjustments affect constraint shader data, it is necessary to call PxConstraint::markDirty()
to make sure that the data gets synced at the beginning of the next simulation step.
\param[in] shift Translation vector the origin is shifted by.
\see PxScene.shiftOrigin()
*/
virtual void onOriginShift(const PxVec3& shift) = 0;
/**
\brief Fetches external data for a constraint.
This function is used by the SDK to acquire a reference to the owner of a constraint and a unique
owner type ID. This information will be passed on when a breakable constraint breaks or when
#PxConstraint::getExternalReference() is called.
\param[out] typeID Unique type identifier of the external object. The value 0xffffffff is reserved and should not be used. Furthermore, if the PhysX extensions library is used, some other IDs are reserved already (see PxConstraintExtIDs)
\return Reference to the external object which owns the constraint.
\see PxConstraintInfo PxSimulationEventCallback.onConstraintBreak()
*/
virtual void* getExternalReference(PxU32& typeID) = 0;
/**
\brief Obtain a reference to a PxBase interface if the constraint has one.
If the constraint does not implement the PxBase interface, it should return NULL.
*/
virtual PxBase* getSerializable() = 0;
/**
\brief Obtain the shader function pointer used to prep rows for this constraint
*/
virtual PxConstraintSolverPrep getPrep() const = 0;
/**
\brief Obtain the pointer to the constraint's constant data
*/
virtual const void* getConstantBlock() const = 0;
/**
\brief Let the connector know it has been connected to a constraint.
*/
virtual void connectToConstraint(PxConstraint*) {}
/**
\brief virtual destructor
*/
virtual ~PxConstraintConnector() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,844 @@
// 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 PX_CONTACT_H
#define PX_CONTACT_H
#include "foundation/PxVec3.h"
#include "foundation/PxAssert.h"
#include "PxConstraintDesc.h"
#include "PxNodeIndex.h"
#include "PxMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#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
#define PXC_CONTACT_NO_FACE_INDEX 0xffffffff
class PxActor;
/**
\brief Header for a contact patch where all points share same material and normal
*/
PX_ALIGN_PREFIX(16)
struct PxContactPatch
{
enum PxContactPatchFlags
{
eHAS_FACE_INDICES = 1, //!< Indicates this contact stream has face indices.
eMODIFIABLE = 2, //!< Indicates this contact stream is modifiable.
eFORCE_NO_RESPONSE = 4, //!< Indicates this contact stream is notify-only (no contact response).
eHAS_MODIFIED_MASS_RATIOS = 8, //!< Indicates this contact stream has modified mass ratios
eHAS_TARGET_VELOCITY = 16, //!< Indicates this contact stream has target velocities set
eHAS_MAX_IMPULSE = 32, //!< Indicates this contact stream has max impulses set
eREGENERATE_PATCHES = 64, //!< Indicates this contact stream needs patches re-generated. This is required if the application modified either the contact normal or the material properties
eCOMPRESSED_MODIFIED_CONTACT = 128
};
/**
\brief Modifiers for scaling the inertia of the involved bodies
*/
PX_ALIGN(16, PxConstraintInvMassScale mMassModification);
/**
\brief Contact normal
*/
PX_ALIGN(16, PxVec3 normal);
/**
\brief Restitution coefficient
*/
PxReal restitution;
/**
\brief Dynamic friction coefficient
*/
PxReal dynamicFriction;
/**
\brief Static friction coefficient
*/
PxReal staticFriction;
/**
\brief Damping coefficient (for compliant contacts)
*/
PxReal damping;
/**
\brief Index of the first contact in the patch
*/
PxU16 startContactIndex;
/**
\brief The number of contacts in this patch
*/
PxU8 nbContacts;
/**
\brief The combined material flag of two actors that come in contact
\see PxMaterialFlag, PxCombineMode
*/
PxU8 materialFlags;
/**
\brief The PxContactPatchFlags for this patch
*/
PxU16 internalFlags;
/**
\brief Material index of first body
*/
PxU16 materialIndex0;
/**
\brief Material index of second body
*/
PxU16 materialIndex1;
PxU16 pad[5];
}
PX_ALIGN_SUFFIX(16);
/**
\brief Contact point data
*/
PX_ALIGN_PREFIX(16)
struct PxContact
{
/**
\brief Contact point in world space
*/
PxVec3 contact;
/**
\brief Separation value (negative implies penetration).
*/
PxReal separation;
}
PX_ALIGN_SUFFIX(16);
/**
\brief Contact point data with additional target and max impulse values
*/
PX_ALIGN_PREFIX(16)
struct PxExtendedContact : public PxContact
{
/**
\brief Target velocity
*/
PX_ALIGN(16, PxVec3 targetVelocity);
/**
\brief Maximum impulse
*/
PxReal maxImpulse;
}
PX_ALIGN_SUFFIX(16);
/**
\brief A modifiable contact point. This has additional fields per-contact to permit modification by user.
\note Not all fields are currently exposed to the user.
*/
PX_ALIGN_PREFIX(16)
struct PxModifiableContact : public PxExtendedContact
{
/**
\brief Contact normal
*/
PX_ALIGN(16, PxVec3 normal);
/**
\brief Restitution coefficient
*/
PxReal restitution;
/**
\brief Material Flags
*/
PxU32 materialFlags;
/**
\brief Shape A's material index
*/
PxU16 materialIndex0;
/**
\brief Shape B's material index
*/
PxU16 materialIndex1;
/**
\brief static friction coefficient
*/
PxReal staticFriction;
/**
\brief dynamic friction coefficient
*/
PxReal dynamicFriction;
}
PX_ALIGN_SUFFIX(16);
/**
\brief A class to iterate over a compressed contact stream. This supports read-only access to the various contact formats.
*/
struct PxContactStreamIterator
{
enum StreamFormat
{
eSIMPLE_STREAM,
eMODIFIABLE_STREAM,
eCOMPRESSED_MODIFIABLE_STREAM
};
/**
\brief Utility zero vector to optimize functions returning zero vectors when a certain flag isn't set.
\note This allows us to return by reference instead of having to return by value. Returning by value will go via memory (registers -> stack -> registers), which can
cause performance issues on certain platforms.
*/
PxVec3 zero;
/**
\brief The patch headers.
*/
const PxContactPatch* patch;
/**
\brief The contacts
*/
const PxContact* contact;
/**
\brief The contact triangle face index
*/
const PxU32* faceIndice;
/**
\brief The total number of patches in this contact stream
*/
PxU32 totalPatches;
/**
\brief The total number of contact points in this stream
*/
PxU32 totalContacts;
/**
\brief The current contact index
*/
PxU32 nextContactIndex;
/**
\brief The current patch Index
*/
PxU32 nextPatchIndex;
/**
\brief Size of contact patch header
\note This varies whether the patch is modifiable or not.
*/
PxU32 contactPatchHeaderSize;
/**
\brief Contact point size
\note This varies whether the patch has feature indices or is modifiable.
*/
PxU32 contactPointSize;
/**
\brief The stream format
*/
StreamFormat mStreamFormat;
/**
\brief Indicates whether this stream is notify-only or not.
*/
PxU32 forceNoResponse;
/**
\brief Internal helper for stepping the contact stream iterator
*/
bool pointStepped;
/**
\brief Specifies if this contactPatch has face indices (handled as bool)
\see faceIndice
*/
PxU32 hasFaceIndices;
/**
\brief Constructor
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxContactStreamIterator(const PxU8* contactPatches, const PxU8* contactPoints, const PxU32* contactFaceIndices, PxU32 nbPatches, PxU32 nbContacts)
: zero(0.f)
{
bool modify = false;
bool compressedModify = false;
bool response = false;
bool indices = false;
PxU32 pointSize = 0;
PxU32 patchHeaderSize = sizeof(PxContactPatch);
const PxContactPatch* patches = reinterpret_cast<const PxContactPatch*>(contactPatches);
if(patches)
{
modify = (patches->internalFlags & PxContactPatch::eMODIFIABLE) != 0;
compressedModify = (patches->internalFlags & PxContactPatch::eCOMPRESSED_MODIFIED_CONTACT) != 0;
indices = (patches->internalFlags & PxContactPatch::eHAS_FACE_INDICES) != 0;
patch = patches;
contact = reinterpret_cast<const PxContact*>(contactPoints);
faceIndice = contactFaceIndices;
pointSize = compressedModify ? sizeof(PxExtendedContact) : modify ? sizeof(PxModifiableContact) : sizeof(PxContact);
response = (patch->internalFlags & PxContactPatch::eFORCE_NO_RESPONSE) == 0;
}
mStreamFormat = compressedModify ? eCOMPRESSED_MODIFIABLE_STREAM : modify ? eMODIFIABLE_STREAM : eSIMPLE_STREAM;
hasFaceIndices = PxU32(indices);
forceNoResponse = PxU32(!response);
contactPatchHeaderSize = patchHeaderSize;
contactPointSize = pointSize;
nextPatchIndex = 0;
nextContactIndex = 0;
totalContacts = nbContacts;
totalPatches = nbPatches;
pointStepped = false;
}
/**
\brief Returns whether there are more patches in this stream.
\return Whether there are more patches in this stream.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextPatch() const
{
return nextPatchIndex < totalPatches;
}
/**
\brief Returns the total contact count.
\return Total contact count.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalContactCount() const
{
return totalContacts;
}
/**
\brief Returns the total patch count.
\return Total patch count.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalPatchCount() const
{
return totalPatches;
}
/**
\brief Advances iterator to next contact patch.
*/
PX_CUDA_CALLABLE PX_INLINE void nextPatch()
{
PX_ASSERT(nextPatchIndex < totalPatches);
if(nextPatchIndex)
{
if(nextContactIndex < patch->nbContacts)
{
PxU32 nbToStep = patch->nbContacts - this->nextContactIndex;
contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize * nbToStep);
}
patch = reinterpret_cast<const PxContactPatch*>(reinterpret_cast<const PxU8*>(patch) + contactPatchHeaderSize);
}
nextPatchIndex++;
nextContactIndex = 0;
}
/**
\brief Returns if the current patch has more contacts.
\return If there are more contacts in the current patch.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextContact() const
{
return nextContactIndex < (patch->nbContacts);
}
/**
\brief Advances to the next contact in the patch.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE void nextContact()
{
PX_ASSERT(nextContactIndex < patch->nbContacts);
if(pointStepped)
{
contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize);
faceIndice++;
}
nextContactIndex++;
pointStepped = true;
}
/**
\brief Gets the current contact's normal
\return The current contact's normal.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getContactNormal() const
{
return getContactPatch().normal;
}
/**
\brief Gets the inverse mass scale for body 0.
\return The inverse mass scale for body 0.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale0() const
{
return patch->mMassModification.linear0;
}
/**
\brief Gets the inverse mass scale for body 1.
\return The inverse mass scale for body 1.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale1() const
{
return patch->mMassModification.linear1;
}
/**
\brief Gets the inverse inertia scale for body 0.
\return The inverse inertia scale for body 0.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale0() const
{
return patch->mMassModification.angular0;
}
/**
\brief Gets the inverse inertia scale for body 1.
\return The inverse inertia scale for body 1.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale1() const
{
return patch->mMassModification.angular1;
}
/**
\brief Gets the contact's max impulse.
\return The contact's max impulse.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getMaxImpulse() const
{
return mStreamFormat != eSIMPLE_STREAM ? getExtendedContact().maxImpulse : PX_MAX_REAL;
}
/**
\brief Gets the contact's target velocity.
\return The contact's target velocity.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getTargetVel() const
{
return mStreamFormat != eSIMPLE_STREAM ? getExtendedContact().targetVelocity : zero;
}
/**
\brief Gets the contact's contact point.
\return The contact's contact point.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getContactPoint() const
{
return contact->contact;
}
/**
\brief Gets the contact's separation.
\return The contact's separation.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getSeparation() const
{
return contact->separation;
}
/**
\brief Gets the contact's face index for shape 0.
\return The contact's face index for shape 0.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getFaceIndex0() const
{
return PXC_CONTACT_NO_FACE_INDEX;
}
/**
\brief Gets the contact's face index for shape 1.
\return The contact's face index for shape 1.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getFaceIndex1() const
{
return hasFaceIndices ? *faceIndice : PXC_CONTACT_NO_FACE_INDEX;
}
/**
\brief Gets the contact's static friction coefficient.
\return The contact's static friction coefficient.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getStaticFriction() const
{
return getContactPatch().staticFriction;
}
/**
\brief Gets the contact's dynamic friction coefficient.
\return The contact's dynamic friction coefficient.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDynamicFriction() const
{
return getContactPatch().dynamicFriction;
}
/**
\brief Gets the contact's restitution coefficient.
\return The contact's restitution coefficient.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getRestitution() const
{
return getContactPatch().restitution;
}
/**
\brief Gets the contact's damping value.
\return The contact's damping value.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDamping() const
{
return getContactPatch().damping;
}
/**
\brief Gets the contact's material flags.
\return The contact's material flags.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getMaterialFlags() const
{
return getContactPatch().materialFlags;
}
/**
\brief Gets the contact's material index for shape 0.
\return The contact's material index for shape 0.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex0() const
{
return PxU16(getContactPatch().materialIndex0);
}
/**
\brief Gets the contact's material index for shape 1.
\return The contact's material index for shape 1.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 getMaterialIndex1() const
{
return PxU16(getContactPatch().materialIndex1);
}
/**
\brief Advances the contact stream iterator to a specific contact index.
\return True if advancing was possible
*/
bool advanceToIndex(const PxU32 initialIndex)
{
PX_ASSERT(this->nextPatchIndex == 0 && this->nextContactIndex == 0);
PxU32 numToAdvance = initialIndex;
if(numToAdvance == 0)
{
PX_ASSERT(hasNextPatch());
nextPatch();
return true;
}
while(numToAdvance)
{
while(hasNextPatch())
{
nextPatch();
PxU32 patchSize = patch->nbContacts;
if(numToAdvance <= patchSize)
{
contact = reinterpret_cast<const PxContact*>(reinterpret_cast<const PxU8*>(contact) + contactPointSize * numToAdvance);
nextContactIndex += numToAdvance;
return true;
}
else
{
numToAdvance -= patchSize;
}
}
}
return false;
}
private:
/**
\brief Internal helper
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxContactPatch& getContactPatch() const
{
return *static_cast<const PxContactPatch*>(patch);
}
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxExtendedContact& getExtendedContact() const
{
PX_ASSERT(mStreamFormat == eMODIFIABLE_STREAM || mStreamFormat == eCOMPRESSED_MODIFIABLE_STREAM);
return *static_cast<const PxExtendedContact*>(contact);
}
};
/**
\brief Contact patch friction information.
*/
struct PxFrictionPatch
{
/**
\brief Max anchors per patch
*/
static const PxU32 MAX_ANCHOR_COUNT = 2;
/**
\brief Friction anchors' positions
*/
PxVec3 anchorPositions[MAX_ANCHOR_COUNT];
/**
\brief Friction anchors' impulses
*/
PxVec3 anchorImpulses[MAX_ANCHOR_COUNT];
/**
\brief Friction anchor count
*/
PxU32 anchorCount;
};
/**
\brief A class to iterate over a friction anchor stream.
*/
class PxFrictionAnchorStreamIterator
{
public:
/**
\brief Constructor
\param contactPatches Pointer to first patch header in contact stream containing contact patch data
\param frictionPatches Buffer containing contact patches friction information.
\param patchCount Number of contact patches stored in the contact stream
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxFrictionAnchorStreamIterator(const PxU8* contactPatches, const PxU8* frictionPatches, PxU32 patchCount)
:
mContactPatches(reinterpret_cast<const PxContactPatch*>(contactPatches)),
mFrictionPatches(reinterpret_cast<const PxFrictionPatch*>(frictionPatches)),
mPatchCount(patchCount),
mFrictionAnchorIndex(-1),
mPatchIndex(-1)
{}
/**
\brief Check if there are more patches.
\return true if there are more patches.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextPatch() const
{
return isValid() && mPatchIndex < PxI32(mPatchCount) - 1;
}
/**
\brief Advance to the next patch.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE void nextPatch()
{
PX_ASSERT(hasNextPatch());
++mPatchIndex;
mFrictionAnchorIndex = -1;
}
/**
\brief Check if current patch has more friction anchors.
\return true if there are more friction anchors in current patch.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool hasNextFrictionAnchor() const
{
return patchIsValid() && mFrictionAnchorIndex < PxI32(mFrictionPatches[mPatchIndex].anchorCount) - 1;
}
/**
\brief Advance to the next friction anchor in the patch.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE void nextFrictionAnchor()
{
PX_ASSERT(hasNextFrictionAnchor());
mFrictionAnchorIndex++;
}
/**
\brief Get the friction anchor's position.
\return The friction anchor's position.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getPosition() const
{
PX_ASSERT(frictionAnchorIsValid());
return mFrictionPatches[mPatchIndex].anchorPositions[mFrictionAnchorIndex];
}
/**
\brief Get the friction anchor's impulse.
\return The friction anchor's impulse.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getImpulse() const
{
PX_ASSERT(frictionAnchorIsValid());
return mFrictionPatches[mPatchIndex].anchorImpulses[mFrictionAnchorIndex];
}
/**
\brief Get the friction anchor's normal.
\return The friction anchor's normal.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& getNormal() const
{
PX_ASSERT(patchIsValid());
return mContactPatches[mPatchIndex].normal;
}
/**
\brief Get current patch's static friction coefficient.
\return The patch's static friction coefficient.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getStaticFriction() const
{
PX_ASSERT(patchIsValid());
return mContactPatches[mPatchIndex].staticFriction;
}
/**
\brief Get current patch's dynamic friction coefficient.
\return The patch's dynamic friction coefficient.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDynamicFriction() const
{
PX_ASSERT(patchIsValid());
return mContactPatches[mPatchIndex].dynamicFriction;
}
/**
\brief Get current patch's combined material flags.
\return The patch's combined material flags.
\see PxMaterialFlag, PxCombineMode
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxMaterialFlags getMaterialFlags() const
{
PX_ASSERT(patchIsValid());
return PxMaterialFlags(mContactPatches[mPatchIndex].materialFlags);
}
private:
PX_CUDA_CALLABLE PX_FORCE_INLINE PxFrictionAnchorStreamIterator();
/**
\brief Check if valid.
\return true if valid.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() const
{
return mContactPatches && mFrictionPatches;
}
/**
\brief Check if current patch is valid.
\return true if current patch is valid.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool patchIsValid() const
{
return isValid() && mPatchIndex >= 0 && mPatchIndex < PxI32(mPatchCount);
}
/**
\brief Check if current friction anchor is valid.
\return true if current friction anchor is valid.
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE bool frictionAnchorIsValid() const
{
return patchIsValid() && mFrictionAnchorIndex >= 0 && mFrictionAnchorIndex < PxI32(mFrictionPatches[mPatchIndex].anchorCount);
}
const PxContactPatch* mContactPatches;
const PxFrictionPatch* mFrictionPatches;
PxU32 mPatchCount;
PxI32 mFrictionAnchorIndex;
PxI32 mPatchIndex;
};
/**
\brief Contains contact information for a contact reported by the direct-GPU contact report API. See PxDirectGPUAPI::copyContactData().
*/
struct PxGpuContactPair
{
PxU8* contactPatches; //!< Ptr to contact patches. Type: PxContactPatch*, size: nbPatches.
PxU8* contactPoints; //!< Ptr to contact points. Type: PxContact*, size: nbContacts.
PxReal* contactForces; //!< Ptr to contact forces. Size: nbContacts.
PxU8* frictionPatches; //!< Ptr to friction patch information. Type: PxFrictionPatch*, size: nbPatches.
PxU32 transformCacheRef0; //!< Ref to shape0's transform in transform cache.
PxU32 transformCacheRef1; //!< Ref to shape1's transform in transform cache.
PxNodeIndex nodeIndex0; //!< Unique Id for actor0 if the actor is dynamic.
PxNodeIndex nodeIndex1; //!< Unique Id for actor1 if the actor is dynamic.
PxActor* actor0; //!< Ptr to PxActor for actor0.
PxActor* actor1; //!< Ptr to PxActor for actor1.
PxU16 nbContacts; //!< Num contacts.
PxU16 nbPatches; //!< Num patches.
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,523 @@
// 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 PX_CONTACT_MODIFY_CALLBACK_H
#define PX_CONTACT_MODIFY_CALLBACK_H
#include "PxPhysXConfig.h"
#include "PxShape.h"
#include "PxContact.h"
#include "foundation/PxTransform.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxShape;
/**
\brief An array of contact points, as passed to contact modification.
The word 'set' in the name does not imply that duplicates are filtered in any
way. This initial set of contacts does potentially get reduced to a smaller
set before being passed to the solver.
You can use the accessors to read and write contact properties. The number of
contacts is immutable, other than being able to disable contacts using ignore().
\see PxContactModifyCallback, PxModifiableContact
*/
class PxContactSet
{
public:
/**
\brief Get the position of a specific contact point in the set.
\param[in] i Index of the point in the set
\return Position to the requested point in world space
\see PxModifiableContact.point
*/
PX_FORCE_INLINE const PxVec3& getPoint(PxU32 i) const { return mContacts[i].contact; }
/**
\brief Alter the position of a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] p The new position in world space
\see PxModifiableContact.point
*/
PX_FORCE_INLINE void setPoint(PxU32 i, const PxVec3& p) { mContacts[i].contact = p; }
/**
\brief Get the contact normal of a specific contact point in the set.
\param[in] i Index of the point in the set
\return The requested normal in world space
\see PxModifiableContact.normal
*/
PX_FORCE_INLINE const PxVec3& getNormal(PxU32 i) const { return mContacts[i].normal; }
/**
\brief Alter the contact normal of a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] n The new normal in world space
\note Changing the normal can cause contact points to be ignored.
\see PxModifiableContact.normal
*/
PX_FORCE_INLINE void setNormal(PxU32 i, const PxVec3& n)
{
PxContactPatch* patch = getPatch();
patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES;
mContacts[i].normal = n;
}
/**
\brief Get the separation distance of a specific contact point in the set.
\param[in] i Index of the point in the set
\return The separation. Negative implies penetration.
\see PxModifiableContact.separation
*/
PX_FORCE_INLINE PxReal getSeparation(PxU32 i) const { return mContacts[i].separation; }
/**
\brief Alter the separation of a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] s The new separation
\see PxModifiableContact.separation
*/
PX_FORCE_INLINE void setSeparation(PxU32 i, PxReal s) { mContacts[i].separation = s; }
/**
\brief Get the target velocity of a specific contact point in the set.
\param[in] i Index of the point in the set
\return The target velocity in world frame
\see PxModifiableContact.targetVelocity
*/
PX_FORCE_INLINE const PxVec3& getTargetVelocity(PxU32 i) const { return mContacts[i].targetVelocity; }
/**
\brief Alter the target velocity of a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] v The new velocity in world frame as seen from the second actor in the contact pair, i.e., the solver will try to achieve targetVel == (vel1 - vel2)
\note The sign of the velocity needs to be flipped depending on the order of the actors in the pair. There is no guarantee about the consistency of the order from frame to frame.
\see PxModifiableContact.targetVelocity
*/
PX_FORCE_INLINE void setTargetVelocity(PxU32 i, const PxVec3& v)
{
PxContactPatch* patch = getPatch();
patch->internalFlags |= PxContactPatch::eHAS_TARGET_VELOCITY;
mContacts[i].targetVelocity = v;
}
/**
\brief Get the face index with respect to the first shape of the pair for a specific contact point in the set.
\param[in] i Index of the point in the set
\return The face index of the first shape
\note At the moment, the first shape is never a tri-mesh, therefore this function always returns PXC_CONTACT_NO_FACE_INDEX
\see PxModifiableContact.internalFaceIndex0
*/
PX_FORCE_INLINE PxU32 getInternalFaceIndex0(PxU32 i) const { PX_UNUSED(i); return PXC_CONTACT_NO_FACE_INDEX; }
/**
\brief Get the face index with respect to the second shape of the pair for a specific contact point in the set.
\param[in] i Index of the point in the set
\return The face index of the second shape
\see PxModifiableContact.internalFaceIndex1
*/
PX_FORCE_INLINE PxU32 getInternalFaceIndex1(PxU32 i) const
{
PxContactPatch* patch = getPatch();
if (patch->internalFlags & PxContactPatch::eHAS_FACE_INDICES)
{
return reinterpret_cast<PxU32*>(mContacts + mCount)[mCount + i];
}
return PXC_CONTACT_NO_FACE_INDEX;
}
/**
\brief Get the maximum impulse for a specific contact point in the set.
\param[in] i Index of the point in the set
\return The maximum impulse
\see PxModifiableContact.maxImpulse
*/
PX_FORCE_INLINE PxReal getMaxImpulse(PxU32 i) const { return mContacts[i].maxImpulse; }
/**
\brief Alter the maximum impulse for a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] s The new maximum impulse
\note Must be nonnegative. If set to zero, the contact point will be ignored
\see PxModifiableContact.maxImpulse, ignore()
*/
PX_FORCE_INLINE void setMaxImpulse(PxU32 i, PxReal s)
{
PxContactPatch* patch = getPatch();
patch->internalFlags |= PxContactPatch::eHAS_MAX_IMPULSE;
mContacts[i].maxImpulse = s;
}
/**
\brief Get the restitution coefficient for a specific contact point in the set.
\param[in] i Index of the point in the set
\return The restitution coefficient
\see PxModifiableContact.restitution
*/
PX_FORCE_INLINE PxReal getRestitution(PxU32 i) const { return mContacts[i].restitution; }
/**
\brief Alter the restitution coefficient for a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] r The new restitution coefficient
\note Valid ranges [0,1]
\see PxModifiableContact.restitution
*/
PX_FORCE_INLINE void setRestitution(PxU32 i, PxReal r)
{
PxContactPatch* patch = getPatch();
patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES;
mContacts[i].restitution = r;
}
/**
\brief Get the static friction coefficient for a specific contact point in the set.
\param[in] i Index of the point in the set
\return The friction coefficient (dimensionless)
\see PxModifiableContact.staticFriction
*/
PX_FORCE_INLINE PxReal getStaticFriction(PxU32 i) const { return mContacts[i].staticFriction; }
/**
\brief Alter the static friction coefficient for a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] f The new friction coefficient (dimensionless), range [0, inf]
\see PxModifiableContact.staticFriction
*/
PX_FORCE_INLINE void setStaticFriction(PxU32 i, PxReal f)
{
PxContactPatch* patch = getPatch();
patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES;
mContacts[i].staticFriction = f;
}
/**
\brief Get the static friction coefficient for a specific contact point in the set.
\param[in] i Index of the point in the set
\return The friction coefficient
\see PxModifiableContact.dynamicFriction
*/
PX_FORCE_INLINE PxReal getDynamicFriction(PxU32 i) const { return mContacts[i].dynamicFriction; }
/**
\brief Alter the static dynamic coefficient for a specific contact point in the set.
\param[in] i Index of the point in the set
\param[in] f The new friction coefficient
\see PxModifiableContact.dynamicFriction
*/
PX_FORCE_INLINE void setDynamicFriction(PxU32 i, PxReal f)
{
PxContactPatch* patch = getPatch();
patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES;
mContacts[i].dynamicFriction = f;
}
/**
\brief Ignore the contact point.
\param[in] i Index of the point in the set
If a contact point is ignored then no force will get applied at this point. This can be used to disable collision in certain areas of a shape, for example.
*/
PX_FORCE_INLINE void ignore(PxU32 i) { setMaxImpulse(i, 0.0f); }
/**
\brief The number of contact points in the set.
*/
PX_FORCE_INLINE PxU32 size() const { return mCount; }
/**
\brief Returns the invMassScale of body 0
A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact
treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass.
*/
PX_FORCE_INLINE PxReal getInvMassScale0() const
{
PxContactPatch* patch = getPatch();
return patch->mMassModification.linear0;
}
/**
\brief Returns the invMassScale of body 1
A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact
treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass.
*/
PX_FORCE_INLINE PxReal getInvMassScale1() const
{
PxContactPatch* patch = getPatch();
return patch->mMassModification.linear1;
}
/**
\brief Returns the invInertiaScale of body 0
A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact
treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia.
*/
PX_FORCE_INLINE PxReal getInvInertiaScale0() const
{
PxContactPatch* patch = getPatch();
return patch->mMassModification.angular0;
}
/**
\brief Returns the invInertiaScale of body 1
A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact
treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia.
*/
PX_FORCE_INLINE PxReal getInvInertiaScale1() const
{
PxContactPatch* patch = getPatch();
return patch->mMassModification.angular1;
}
/**
\brief Sets the invMassScale of body 0
\param[in] scale The new scale
This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact
treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass.
*/
PX_FORCE_INLINE void setInvMassScale0(const PxReal scale)
{
PxContactPatch* patch = getPatch();
patch->mMassModification.linear0 = scale;
patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS;
}
/**
\brief Sets the invMassScale of body 1
\param[in] scale The new scale
This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact
treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass.
*/
PX_FORCE_INLINE void setInvMassScale1(const PxReal scale)
{
PxContactPatch* patch = getPatch();
patch->mMassModification.linear1 = scale;
patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS;
}
/**
\brief Sets the invInertiaScale of body 0
\param[in] scale The new scale
This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact
treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia.
*/
PX_FORCE_INLINE void setInvInertiaScale0(const PxReal scale)
{
PxContactPatch* patch = getPatch();
patch->mMassModification.angular0 = scale;
patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS;
}
/**
\brief Sets the invInertiaScale of body 1
\param[in] scale The new scale
This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact
treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia.
*/
PX_FORCE_INLINE void setInvInertiaScale1(const PxReal scale)
{
PxContactPatch* patch = getPatch();
patch->mMassModification.angular1 = scale;
patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS;
}
protected:
PX_FORCE_INLINE PxContactPatch* getPatch() const
{
const size_t headerOffset = sizeof(PxContactPatch)*mCount;
return reinterpret_cast<PxContactPatch*>(reinterpret_cast<PxU8*>(mContacts) - headerOffset);
}
PxU32 mCount; //!< Number of contact points in the set
PxModifiableContact* mContacts; //!< The contact points of the set
};
/**
\brief An array of instances of this class is passed to PxContactModifyCallback::onContactModify().
\see PxContactModifyCallback
*/
class PxContactModifyPair
{
public:
/**
\brief The actors which make up the pair in contact.
Note that these are the actors as seen by the simulation, and may have been deleted since the simulation step started.
*/
const PxRigidActor* actor[2];
/**
\brief The shapes which make up the pair in contact.
Note that these are the shapes as seen by the simulation, and may have been deleted since the simulation step started.
*/
const PxShape* shape[2];
/**
\brief The shape to world transforms of the two shapes.
These are the transforms as the simulation engine sees them, and may have been modified by the application
since the simulation step started.
*/
PxTransform transform[2];
/**
\brief An array of contact points between these two shapes.
*/
PxContactSet contacts;
};
/**
\brief An interface class that the user can implement in order to modify contact constraints.
<b>Threading:</b> It is <b>necessary</b> to make this class thread safe as it will be called in the context of the
simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded
parts of the physics engine.
You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in
the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects.
Please note:
+ Raising the contact modification flag will not wake the actors up automatically.
+ It is not possible to turn off the performance degradation by simply removing the callback from the scene, the
filter shader/callback has to be used to clear the contact modification flag.
+ The contacts will only be reported as long as the actors are awake. There will be no callbacks while the actors are sleeping.
\see PxScene.setContactModifyCallback() PxScene.getContactModifyCallback()
*/
class PxContactModifyCallback
{
public:
/**
\brief Passes modifiable arrays of contacts to the application.
The initial contacts are regenerated from scratch each frame by collision detection.
The number of contacts can not be changed, so you cannot add your own contacts. You may however
disable contacts using PxContactSet::ignore().
\param[in,out] pairs The contact pairs that may be modified
\param[in] count Number of contact pairs
\see PxContactModifyPair
*/
virtual void onContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0;
protected:
virtual ~PxContactModifyCallback(){}
};
/**
\brief An interface class that the user can implement in order to modify CCD contact constraints.
<b>Threading:</b> It is <b>necessary</b> to make this class thread safe as it will be called in the context of the
simulation thread. It might also be necessary to make it reentrant, since some calls can be made by multi-threaded
parts of the physics engine.
You can enable the use of this contact modification callback by raising the flag PxPairFlag::eMODIFY_CONTACTS in
the filter shader/callback (see #PxSimulationFilterShader) for a pair of rigid body objects.
Please note:
+ Raising the contact modification flag will not wake the actors up automatically.
+ It is not possible to turn off the performance degradation by simply removing the callback from the scene, the
filter shader/callback has to be used to clear the contact modification flag.
+ The contacts will only be reported as long as the actors are awake. There will be no callbacks while the actors are sleeping.
\see PxScene.setContactModifyCallback() PxScene.getContactModifyCallback()
*/
class PxCCDContactModifyCallback
{
public:
/**
\brief Passes modifiable arrays of contacts to the application.
The initial contacts are regenerated from scratch each frame by collision detection.
The number of contacts can not be changed, so you cannot add your own contacts. You may however
disable contacts using PxContactSet::ignore().
\param[in,out] pairs The contact pairs that may be modified
\param[in] count Number of contact pairs
*/
virtual void onCCDContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0;
protected:
virtual ~PxCCDContactModifyCallback(){}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,237 @@
// 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 PX_DEFORMABLE_ATTACHMENT_H
#define PX_DEFORMABLE_ATTACHMENT_H
#include "PxConeLimitedConstraint.h"
#include "PxFiltering.h"
#include "PxNodeIndex.h"
#include "foundation/PxTransform.h"
#include "common/PxCoreUtilityTypes.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Struct to specify attachment between a particle/vertex and a rigid
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
*/
struct PX_DEPRECATED PxParticleRigidAttachment : public PxParticleRigidFilterPair
{
PxParticleRigidAttachment() {}
PxParticleRigidAttachment(const PxConeLimitedConstraint& coneLimitedConstraint, const PxVec4& localPose0):
PxParticleRigidFilterPair(PxNodeIndex().getInd(), PxNodeIndex().getInd()),
mLocalPose0(localPose0),
mConeLimitParams(coneLimitedConstraint)
{
}
PX_ALIGN(16, PxVec4 mLocalPose0); //!< local pose in body frame - except for statics, these are using world positions.
PxConeLimitParams mConeLimitParams; //!< Parameters to specify cone constraints
};
/**
\brief Identifies the attachment target type for an actor involved in an attachment.
The target type provides actor related information about what kind of attachment should be created.
\see PxDeformableAttachmentData
*/
struct PxDeformableAttachmentTargetType
{
enum Enum
{
eVERTEX, //!< Attachment to vertex points of deformable mesh.
eTRIANGLE, //!< Attachment to points on triangles of deformable mesh.
eTETRAHEDRON, //!< Attachment to points in tetrahedrons of deformable mesh.
eRIGID, //!< Attachment to points in rigid actor local frame.
eWORLD, //!< Attachment to points in global frame.
eUNDEFINED //!< Internal use only.
};
};
/**
\brief Attachment data for a pair of actors where one of the actors must be a deformable. For attaching rigids to rigids or rigids to the world, use joints instead.
An attachment is created based on a collection of attachment points. The attachment
points are specified relatively to each of the two actors. They can be defined on the basis of
deformable mesh elements, such as vertices, triangles or tetrahedrons. Depending on the deformable mesh element type,
a baricentric coordinate further specifies the location on the element. For rigid or world attachments, the points are
specified using cartesion coordinates.
The points are specified by:
- Two actor instances and their types
- Two attachment target types
- Two sets of attachment data related to the target types
<a name="attachment_table1"></a>
Table 1) The type of an actor limits which target types can be used:
PxDeformableSurface: eVERTEX, eTRIANGLE
PxDeformableVolume: eVERTEX, eTETRAHEDRON (simulation mesh)
PxRigidActor: eRIGID
NULL: eWORLD
<a name="attachment_table2"></a>
Table 2) On the other hand, the target type dictates which per-actor attachment data is needed:
eVERTEX: indices
eTRIANGLE: indices, coords (barycentric: x, y, z)
eTETRAHEDRON: indices, coords (barycentric: x, y, z, w)
eRIGID: pose, coords (cartesian, local space: x, y, z)
eWORLD: pose, coords (cartesion, world space: x, y, z)
Each entry pair in (indices, coords) defines an attachment point. Therefore, the size of indices and coords need to match up, if both are required.
\note The topology of an attachment is fixed once it's been created. To change the attachment points,
the application will need to release the attachment and create a new attachment with the updated attachment points.
The pose for attachments to eRIGID or eWORLD, however, can be updated without re-creating the attachment.
\see PxDeformableAttachment, PxPhysics::createDeformableAttachment()
*/
struct PxDeformableAttachmentData
{
PxDeformableAttachmentData()
{
for (PxU32 i = 0; i < 2; i++)
{
actor[i] = NULL;
type[i] = PxDeformableAttachmentTargetType::eUNDEFINED;
pose[i] = PxTransform(PxIdentity);
}
}
/**
\brief Actor 0 and Actor 1. At least one of the actors must be a deformable. For attaching statically to the world, one actor is allowed to be NULL while the other is a deformable.
*/
PxActor* actor[2];
/**
\brief One target type per actor.
The target type must be supported by the corresponding actor type, see [table 1](#attachment_table1).
*/
PxDeformableAttachmentTargetType::Enum type[2];
/**
\brief Indices data per actor.
The content of the two index arrays depends on the corresponding target types 'type[0]' and 'type[1]'
as well as the number of attachments:
For PxDeformableAttachmentTargetType::eVERTEX, eTRIANGLE and eTETRAHEDRON, the corresponding array describes vertex,
triangle or tetrahedon indices, and the size of the array needs to match the number of attachments.
For PxDeformableAttachmentTargetType::eRIGID and eWORLD, the corresponding array needs to be empty.
See [table 2](#attachment_table2).
*/
PxTypedBoundedData<const PxU32> indices[2];
/**
\brief Coordinate data per actor.
The content of the two coords arrays depends on the corresponding target types 'type[0]' and 'type[1]'
as well as the number of attachments:
For PxDeformableAttachmentTargetType::eVERTEX, the corresponding array needs to be empty.
For PxDeformableAttachmentTargetType::eTRIANGLE and eTETRAHEDRON, the corresponding array descibes barycentric coordinates,
and the size of the array needs to match the number of attachments.
For PxDeformableAttachmentTargetType::eRIGID and eWORLD, the corresponding array describes cartesian coordinates and the size
of the array needs to match the number of attachments.
See [table 2](#attachment_table2).
*/
PxTypedBoundedData<const PxVec4> coords[2];
/**
\brief Pose per actor.
Global pose for PxDeformableAttachmentTargetType::eWORLD or local pose for PxDeformableAttachmentTargetType::eRIGID, see [table 2](#attachment_table2).
The pose represents a coordinate frame for all attachment points specified by the array of euclidean coords in the case of PxDeformableAttachmentTargetType::eRIGID and eWORLD attachments.
It can be updated after the attachment has been created.
\see PxDeformableAttachment::updatePose()
*/
PxTransform pose[2];
};
/**
\brief PxDeformableAttachment class representing an attachment for deformable actors.
An attachment is a collection of one or more positional constraints between a point on one actor and a point on another actor.
\see PxDeformableAttachmentData, PxPhysics::createDeformableAttachment()
*/
class PxDeformableAttachment : public PxBase
{
public:
/**
\brief Gets the two actors for this attachment.
\param[out] actor0 The first actor, may be NULL
\param[out] actor1 The second actor, may be NULL
*/
virtual void getActors(PxActor*& actor0, PxActor*& actor1) const = 0;
/**
\brief Updates the pose of the attachment.
\param[in] pose Pose relative to world or rigid actor transform. Valid only for attachment against world or rigid actor.
*/
virtual void updatePose(const PxTransform& pose) = 0;
/**
\brief Returns string name of PxDeformableAttachment, used for serialization
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE { return "PxDeformableAttachment"; }
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
virtual ~PxDeformableAttachment() {}
//serialization
/**
\brief Constructor
*/
PX_INLINE PxDeformableAttachment(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {}
/**
\brief Deserialization constructor
*/
PX_INLINE PxDeformableAttachment(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
/**
\brief Returns whether a given type name matches with the type of this instance
*/
virtual bool isKindOf(const char* name) const PX_OVERRIDE { PX_IS_KIND_OF(name, "PxDeformableAttachment", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,396 @@
// 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 PX_DEFORMABLE_BODY_H
#define PX_DEFORMABLE_BODY_H
#include "PxActor.h"
#include "PxDeformableBodyFlag.h"
#include "PxFEMParameter.h" // deprecated
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
class PxCudaContextManager;
/**
\brief Represents a deformable body, a base class for deformable actors
\see PxDeformableSurface, PxDeformableVolume, PxActor
*/
class PxDeformableBody : public PxActor
{
public:
/**
\brief Raises or clears a particular deformable body flag.
See the list of flags #PxDeformableBodyFlag
<b>Default:</b> No flags are set
\param[in] flag The PxDeformableBodyFlag to raise(set) or clear. See #PxDeformableBodyFlag.
\param[in] val The new boolean value for the flag.
*/
virtual void setDeformableBodyFlag(PxDeformableBodyFlag::Enum flag, bool val) = 0;
/**
\brief Sets deformable body flags.
See the list of flags #PxDeformableBodyFlag
<b>Default:</b> No flags are set
\param[in] flags The PxDeformableBodyFlags to set.
*/
virtual void setDeformableBodyFlags(PxDeformableBodyFlags flags) = 0;
/**
\brief Reads the deformable body flags.
See the list of flags #PxDeformableBodyFlag
\return The values of the deformable body flags.
\see setDeformableBodyFlag()
*/
virtual PxDeformableBodyFlags getDeformableBodyFlags() const = 0;
/**
\brief Sets the linear damping parameter.
After every timestep the velocity is reduced while the magnitude of the
reduction depends on the linearDamping value.
\see PxRigidBody.setLinearDamping
<b>Default:</b> 0.05
\param[in] linearDamping The linear damping parameter
*/
virtual void setLinearDamping(const PxReal linearDamping) = 0;
/**
\brief Retrieves linear velocity damping parameter.
\see setLinearDamping
\return The linear damping parameter
*/
virtual PxReal getLinearDamping() const = 0;
/**
\brief Sets the maximal velocity vertices can reach
Allows to limit the vertices' maximal velocity to control the maximal distance a vertex can move per frame
<b>Default:</b> 1.0e32
\param[in] maxLinearVelocity The maximal linear velocity
*/
virtual void setMaxLinearVelocity(const PxReal maxLinearVelocity) = 0;
/**
\brief Sets the maximal velocity vertices can reach
\deprecated Use setMaxLinearVelocity instead.
Allows to limit the vertices' maximal velocity to control the maximal distance a vertex can move per frame
<b>Default:</b> 1.0e32
\param[in] maxVelocity The maximal velocity
*/
PX_DEPRECATED PX_FORCE_INLINE void setMaxVelocity(const PxReal maxVelocity) { setMaxLinearVelocity(maxVelocity); }
/**
\brief Retrieves maximal velocity a vertex can have.
\return The maximal velocity
*/
virtual PxReal getMaxLinearVelocity() const = 0;
/**
\brief Retrieves maximal velocity a vertex can have.
\deprecated Use getMaxLinearVelocity instead.
\return The maximal velocity
*/
PX_DEPRECATED PX_FORCE_INLINE PxReal getMaxVelocity() const { return getMaxLinearVelocity(); }
/**
\brief Sets the maximal depenetration velocity vertices can reach
Allows to limit the vertices' maximal depenetration velocity to avoid that collision responses lead to very high particle velocities
<b>Default:</b> 1.0e32
\param[in] maxDepenetrationVelocity The maximal depenetration velocity
*/
virtual void setMaxDepenetrationVelocity(const PxReal maxDepenetrationVelocity) = 0;
/**
\brief Retrieves maximal depenetration velocity a vertex can have.
\return The maximal depenetration velocity
*/
virtual PxReal getMaxDepenetrationVelocity() const = 0;
/**
\brief Sets the self collision filter distance.
Penetration distance that needs to be exceeded before contacts for self collision are generated.
Will only have an effect if self collisions are enabled.
<b>Default:</b> 0.1
\param[in] selfCollisionFilterDistance The self collision filter distance
*/
virtual void setSelfCollisionFilterDistance(const PxReal selfCollisionFilterDistance) = 0;
/**
\brief Retrieves the self collision filter distance.
\return The self collision filter distance
\see setSelfCollisionFilterDistance
*/
virtual PxReal getSelfCollisionFilterDistance() const = 0;
/**
\brief Sets the solver iteration count for the deformable body.
Since deformables are currently implemented using an XPBD solver (extended position based dynamics), minVelocityIters is ignored.
<b>Default:</b> 4 position iterations, 1 velocity iteration
\param[in] minPositionIters Number of position iterations the solver should perform for this deformable body. <b>Range:</b> [1,255]
\param[in] minVelocityIters Number of velocity iterations, currently ignored. <b>Range:</b> [1,255]
\see getSolverIterationCounts()
*/
virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0;
/**
\brief Retrieves the solver iteration counts.
\see setSolverIterationCounts()
*/
virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0;
/**
\brief Sets the threshold controlling sleeping of the deformable body.
Threshold that defines the maximal magnitude of the linear motion a deformable body can move in one second
before it becomes a candidate for sleeping.
\see PxRigidDynamic.setSleepThreshold
<b>Default:</b> 0.05
\param[in] sleepThreshold The sleep threshold
*/
virtual void setSleepThreshold(const PxReal sleepThreshold) = 0;
/**
\brief Retrieves the sleep threshold.
\see setSleepThreshold
\return The sleep threshold
*/
virtual PxReal getSleepThreshold() const = 0;
/**
\brief Sets the threshold controlling settling phase before sleeping of the deformable body.
Threshold that defines the maximal magnitude of the linear motion a deformable body can move
in one second before it becomes a candidate for sleeping and settling damping is engaged.
The settling threshold needs to be higher than the sleep threshold.
<b>Default:</b> 0.1
\see setSettlingDamping
\param[in] settlingThreshold The settling threshold
*/
virtual void setSettlingThreshold(const PxReal settlingThreshold) = 0;
/**
\brief Retrieves the settling threshold.
\see setSettlingThreshold
\return The settling threshold
*/
virtual PxReal getSettlingThreshold() const = 0;
/**
\brief Sets the damping parameter used for settling phase.
If the maximum linear velocity of the deformable body falls below the settling threshold, the deformable body
enters the settling phase in which the settling damping is applied.
<b>Default:</b> 10.0
\param[in] settlingDamping The settling damping
\see setLinearDamping, setSettlingThreshold
*/
virtual void setSettlingDamping(const PxReal settlingDamping) = 0;
/**
\brief Retrieves settling damping parameter.
\see setSettlingDamping
\return The settling damping parameter
*/
virtual PxReal getSettlingDamping() const = 0;
/**
\brief Sets the wake counter for the deformable body.
The wake counter value determines the minimum amount of time until the deformable body can be put to sleep. Please note
that a deformable body will not be put to sleep if any vertex velocity is above the specified threshold
or if other awake objects are touching it.
\note Passing in a positive value will wake the deformable body up automatically.
<b>Default:</b> 0.4 (which corresponds to 20 frames for a time step of 0.02)
\param[in] wakeCounterValue Wake counter value. <b>Range:</b> [0, PX_MAX_F32)
\see isSleeping() getWakeCounter()
*/
virtual void setWakeCounter(PxReal wakeCounterValue) = 0;
/**
\brief Returns the wake counter of the deformable body.
\return The wake counter of the deformable body.
\see isSleeping() setWakeCounter()
*/
virtual PxReal getWakeCounter() const = 0;
/**
\brief Returns true if this deformable body is sleeping.
When an actor does not move for a period of time, it is no longer simulated in order to save time. This state
is called sleeping. However, because the object automatically wakes up when it is either touched by an awake object,
or a sleep-affecting property is changed by the user, the entire sleep mechanism should be transparent to the user.
A deformable volume can only go to sleep if all vertices are ready for sleeping. A deformable body is guaranteed to be awake
if at least one of the following holds:
\li The wake counter is positive (\see setWakeCounter()).
\li The velocity of any vertex is above the sleep threshold.
If a deformable body is sleeping, the following state is guaranteed:
\li The wake counter is zero.
\li The linear velocity of all vertices is zero.
When a deformable body gets inserted into a scene, it will be considered asleep if all the points above hold, else it will
be treated as awake.
\note It is invalid to use this method if the deformable body has not been added to a scene already.
\return True if the deformable body is sleeping.
\see isSleeping()
*/
virtual bool isSleeping() const = 0;
/**
\brief Retrieve a shape pointer belonging to the actor.
\see PxShape getNbShapes() PxShape::release()
*/
virtual PxShape* getShape() = 0;
/**
\brief Attaches a shape
Attaches the shape to use for collision detection for deformable surfaces and volumes.
Each deformable needs to have exactly one exclusive shape attached for simulation. If a shape has
already been attached to a deformable, detachShape needs to be called prior to attaching
a new shape.
Deformable surfaces need a shape with triangle mesh geometry, which can be created with
PxPhysics::createShape(const PxGeometry&, const PxDeformableSurfaceMaterial& material, bool, PxShapeFlags), or
PxPhysics::createShape(const PxGeometry&, PxDeformableSurfaceMaterial*const*, PxU16, bool, PxShapeFlags)
Deformable surfaces use the same triangle mesh for collision detection and dynamics computations.
Deformable volumes need a shape with tetrahedron mesh geometry, which can be created with
PxPhysics::createShape(const PxGeometry&, const PxDeformableVolumeMaterial& material, bool, PxShapeFlags), or
PxPhysics::createShape(const PxGeometry&, PxDeformableVolumeMaterial*const*, PxU16, bool, PxShapeFlags)
Deformable volumes additionally need a separate tetrahedron mesh for dynamics, which can be attached using
PxDeformbleVolume::attachSimulationMesh.
\param[in] shape The shape to use for collisions, (and dynamics in case of deformable surfaces)
\return Returns true if the operation was successful
*/
virtual bool attachShape(PxShape& shape) = 0;
/**
\brief Detaches the shape
Detaches the shape used for collision detection.
\see void PxDeformableVolume.detachSimulationMesh()
*/
virtual void detachShape() = 0;
/**
\brief Returns the cuda context manager
\return The cuda context manager
*/
virtual PxCudaContextManager* getCudaContextManager() const = 0;
/**
\brief Deprecated: Sets parameters for FEM internal solve
\param[in] params parameters
\see getParameter()
*/
PX_DEPRECATED virtual void setParameter(const PxFEMParameters& params) = 0;
/**
\brief Deprecated: Gets parameters for FEM internal solve
\return parameters
\see setParameter()
*/
PX_DEPRECATED virtual PxFEMParameters getParameter() const = 0;
protected:
PX_INLINE PxDeformableBody(PxType concreteType, PxBaseFlags baseFlags) : PxActor(concreteType, baseFlags) {}
PX_INLINE PxDeformableBody(PxBaseFlags baseFlags) : PxActor(baseFlags) {}
virtual ~PxDeformableBody() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxDeformableBody", PxActor); }
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_DEFORMABLE_BODY_H

View File

@@ -0,0 +1,59 @@
// 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 PX_DEFORMABLE_BODY_FLAGS_H
#define PX_DEFORMABLE_BODY_FLAGS_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Flags to enable or disable special modes of a PxDeformableBody instance
*/
struct PxDeformableBodyFlag
{
enum Enum
{
eDISABLE_SELF_COLLISION = 1 << 0, //!< Determines if self collision will be detected and resolved
eENABLE_SPECULATIVE_CCD = 1 << 1, //!< Enables support for speculative contact generation, see #PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD
eKINEMATIC = 1 << 2 //!< Enables support for kinematic motion of the simulation mesh, see #PxRigidBodyFlag::eKINEMATIC
};
};
typedef PxFlags<PxDeformableBodyFlag::Enum, PxU8> PxDeformableBodyFlags;
#if !PX_DOXYGEN
}
#endif
#endif // PX_DEFORMABLE_BODY_FLAGS_H

View File

@@ -0,0 +1,169 @@
// 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 PX_DEFORMABLE_ELEMENT_FILTER_H
#define PX_DEFORMABLE_ELEMENT_FILTER_H
#include "common/PxCoreUtilityTypes.h"
#include "common/PxBase.h"
/** \addtogroup physics
@{
*/
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Element filter data for a pair of actors where one of the actors must be a deformable.
An element filter defines mesh element wise collision filtering between two deformable actors, or one deformable actor and
a rigid actor.
The element types used for collision filtering are implicitely given by the deformable actor type:
PxDeformableSurface: PxTriangleMesh triangle indices.
PxDeformableVolume: PxTetrahedronMesh tetrahedron indices (collision mesh)
If the actor is rigid, then filtering always relates to the actor as a whole.
In order to effectively specify which elements shouldn't collide against which other elements, the following representation is used.
A pair of element groups specifies that none of the elements in the first group collides against any elements of the second group. One group relates
to one actor, and the other group relates to the other actor. The whole collision filter consists of a set of element group pairs.
In the following we use "A" to denote one of the two actors, so either actor with index 0 or index 1 in the actor array, and "B" for the other actor.
The element groups are specified for each actor separately:
The groups for actor A are specified by groupElemCounts[A] and groupElemIndices[A]
The size of groupElemCounts[A] and groupElemCounts[B] specifies the number of group pairs. They need to have the same number of entries (there is an exception, see further below).
Each entry in the groupElemCounts[A] specifies the size of each group of elements in the mesh of actor A.
The entries in groupElemIndices[A] represent all elements referenced by the groupElemCounts[A], in the order of the groups specified in groupElemCounts[A].
Below are some examples to clarify the concept.
Example 1: Two groups for each actor.
groupElemCounts[0] = [2, 1], groupElemIndices[0] = [3, 4, 6]
groupElemCounts[1] = [2, 3], groupElemIndices[1] = [9, 7, 2, 5, 6]
For the first group, the count is 2 for both actors. So element 3 and 4 of actor[0] is filtered against element 9 and 7 of actor[1].
For the second group, the element count is 1 for actor[0] and 3 for actor[1]. So element 6 of actor[0] is filtered against element 2, 5 and 6 of actor[1].
Example 2: Pairwise filtering.
groupElemCounts[0] = [1, 1], groupElemIndices[0] = [3, 4]
groupElemCounts[1] = [1, 1], groupElemIndices[1] = [9, 7]
For the first group, element 3 of actor[0] is filtered against element 9 of actor[1]
For the second group, element 4 of actor[0] is filtered against element 7 of actor[1]
There are two special cases that are supported by the element filter.
- groupElemCounts[A] entries that are 0, indicate that elements of the corresponding group of actor B are filtered against all elements of actor A.
- empty groupElemCounts[A], indicates that all groups of actor B are filtered against all elements of actor A. This is always the case if actor A is a rigid.
\see PxDeformableElementFilter, PxPhysics::createDeformableElementFilter()
*/
struct PxDeformableElementFilterData
{
PxDeformableElementFilterData()
{
for (PxU32 i = 0; i < 2; i++)
{
actor[i] = NULL;
}
}
/**
\brief Actor 0 and Actor 1. NULL actors are not allowed.
*/
PxActor* actor[2];
/**
\brief Element counts for all filter groups, per actor.
*/
PxTypedBoundedData<const PxU32> groupElementCounts[2];
/**
\brief Element indices for all filter groups, per actor.
*/
PxTypedBoundedData<const PxU32> groupElementIndices[2];
};
/**
\brief PxDeformableElementFilter class representing an element level collision filter for deformable actors.
Element filters define how parts of deformable actors are excluded from collisions.
They are usually added to avoid conflicting attachment and contact constraints.
\see PxDeformableElementFilterData, PxPhysics::createDeformableElementFilter()
*/
class PxDeformableElementFilter : public PxBase
{
public:
/**
\brief Gets the actors for this element filter.
\param[out] actor0 The first actor.
\param[out] actor1 The second actor.
*/
virtual void getActors(PxActor*& actor0, PxActor*& actor1) const = 0;
/**
\brief Returns string name of PxDeformableElementFilter, used for serialization
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE { return "PxDeformableElementFilter"; }
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
virtual ~PxDeformableElementFilter() {}
//serialization
/**
\brief Constructor
*/
PX_INLINE PxDeformableElementFilter(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {}
/**
\brief Deserialization constructor
*/
PX_INLINE PxDeformableElementFilter(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
/**
\brief Returns whether a given type name matches with the type of this instance
*/
virtual bool isKindOf(const char* name) const PX_OVERRIDE { PX_IS_KIND_OF(name, "PxDeformableElementFilter", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
/** @} */
#endif

View File

@@ -0,0 +1,133 @@
// 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 PX_DEFORMABLE_MATERIAL_H
#define PX_DEFORMABLE_MATERIAL_H
#include "PxPhysXConfig.h"
#include "PxBaseMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxScene;
/**
\brief Material class to represent a set of deformable material properties.
\see PxPhysics.createDeformableVolumeMaterial
*/
class PxDeformableMaterial : public PxBaseMaterial
{
public:
/**
\brief Sets young's modulus which defines the body's stiffness
<b>Default:</b> 1.e6
\param[in] young Young's modulus. <b>Range:</b> [0, PX_MAX_F32)
\see getYoungsModulus()
*/
virtual void setYoungsModulus(PxReal young) = 0;
/**
\brief Retrieves the young's modulus value.
\return The young's modulus value.
\see setYoungsModulus()
*/
virtual PxReal getYoungsModulus() const = 0;
/**
\brief Sets the Poisson's ratio which defines the body's volume preservation.
<b>Default:</b> 0.45
\param[in] poisson Poisson's ratio. <b>Range:</b> [0, 0.5]
\see getPoissons()
*/
virtual void setPoissons(PxReal poisson) = 0;
/**
\brief Retrieves the Poisson's ratio.
\return The Poisson's ratio.
\see setPoissons()
*/
virtual PxReal getPoissons() const = 0;
/**
\brief Sets the dynamic friction value which defines the strength of resistance when two objects slide relative to each other while in contact.
<b>Default:</b> 0.0
\param[in] dynamicFriction The dynamic friction value. <b>Range:</b> [0, PX_MAX_F32)
\see getDynamicFriction()
*/
virtual void setDynamicFriction(PxReal dynamicFriction) = 0;
/**
\brief Retrieves the dynamic friction value
\return The dynamic friction value
\see setDynamicFriction()
*/
virtual PxReal getDynamicFriction() const = 0;
/**
\brief Sets material damping
\param[in] elasticityDamping Material damping.
\see getDamping()
*/
virtual void setElasticityDamping(PxReal elasticityDamping) = 0;
/**
\brief Retrieves the material damping.
\return damping.
\see setDamping()
*/
virtual PxReal getElasticityDamping() const = 0;
protected:
PX_INLINE PxDeformableMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBaseMaterial(concreteType, baseFlags) {}
PX_INLINE PxDeformableMaterial(PxBaseFlags baseFlags) : PxBaseMaterial(baseFlags) {}
virtual ~PxDeformableMaterial() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxDeformableMaterial", PxBaseMaterial); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_DEFORMABLE_MATERIAL_H

View File

@@ -0,0 +1,224 @@
// 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 PX_DEFORMABLE_SKINNING_H
#define PX_DEFORMABLE_SKINNING_H
#include "foundation/PxPreprocessor.h"
#include "foundation/PxVec2.h"
#include "foundation/PxVec3.h"
#include "foundation/PxFlags.h"
#include "PxNodeIndex.h"
#include "cudamanager/PxCudaContextManager.h"
#include "common/PxCoreUtilityTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Structure for triangle mesh skinning embedding information.
*/
PX_ALIGN_PREFIX(16)
struct PxTriangleMeshEmbeddingInfo
{
/**
\brief UV coordinates for skinning.
*/
PxVec2 uv;
/**
\brief Offset along the interpolated normal.
*/
PxReal offsetAlongInterpolatedNormal;
/**
\brief ID of the guide triangle.
*/
PxU32 guideTriangleId;
/**
\brief Constructor for PxTriangleMeshEmbeddingInfo.
\param uv_ UV coordinates.
\param offsetAlongInterpolatedNormal_ Offset along the interpolated normal.
\param guideTriangleId_ ID of the guide triangle.
*/
PxTriangleMeshEmbeddingInfo(
const PxVec2& uv_,
PxReal offsetAlongInterpolatedNormal_, PxU32 guideTriangleId_) :
uv(uv_), offsetAlongInterpolatedNormal(offsetAlongInterpolatedNormal_), guideTriangleId(guideTriangleId_)
{}
} PX_ALIGN_SUFFIX(16);
/**
\brief Structure for tetrahedron mesh skinning embedding information.
*/
PX_ALIGN_PREFIX(16)
struct PxTetrahedronMeshEmbeddingInfo
{
/**
\brief UVW coordinates for skinning.
*/
PxVec3 uvw;
/**
\brief ID of the guide tetrahedron.
*/
PxU32 guideTetrahedronId;
/**
\brief Constructor for PxTetrahedronMeshEmbeddingInfo.
\param uvw_ UVW coordinates.
\param guideTetrahedronId_ ID of the guide tetrahedron.
*/
PxTetrahedronMeshEmbeddingInfo(const PxVec3& uvw_, PxU32 guideTetrahedronId_) :
uvw(uvw_), guideTetrahedronId(guideTetrahedronId_)
{}
} PX_ALIGN_SUFFIX(16);
#if PX_SUPPORT_GPU_PHYSX
/**
\brief Structure for GPU data related to tetmesh skinning.
*/
struct PxTetmeshSkinningGpuData
{
/**
\brief Pointer to guide vertices data on the GPU.
*/
PxTypedBoundedData<PxVec3> guideVerticesD;
/**
\brief Pointer to guide tetrahedra data on the GPU.
*/
PxU32* guideTetrahedraD;
/**
\brief Pointer to skinning information per vertex on the GPU.
*/
PxTetrahedronMeshEmbeddingInfo* skinningInfoPerVertexD;
/**
\brief Pointer to embedded vertices data on the GPU.
*/
PxTypedBoundedData<PxVec3> skinnedVerticesD;
};
/**
\brief Structure for GPU data related to trimesh skinning.
*/
struct PxTrimeshSkinningGpuData
{
/**
\brief Pointer to guide vertices data on the GPU.
*/
PxTypedBoundedData<PxVec3> guideVerticesD;
/**
\brief Pointer to guide normals data on the GPU.
*/
PxTypedBoundedData<PxVec3> guideNormalsD;
/**
\brief Pointer to guide triangles data on the GPU.
*/
PxU32* guideTrianglesD;
/**
\brief Pointer to skinning information per vertex on the GPU.
*/
PxTriangleMeshEmbeddingInfo* skinningInfoPerVertexD;
/**
\brief Pointer to skinned vertices data on the GPU.
*/
PxTypedBoundedData<PxVec3> skinnedVerticesD;
/**
\brief Half of the deformable surface thickness.
*/
PxReal halfSurfaceThickness;
/**
\brief Number of guide triangles.
*/
PxU32 nbGuideTriangles;
};
/**
\brief Abstract base class for deformable skinning operations.
*/
class PxDeformableSkinning
{
public:
/**
\brief Computes normal vectors for cloth skinning data.
\param skinningDataArrayD Array of cloth skinning data structures.
\param arrayLength The number of elements in the skinning data array.
\param stream CUDA stream to be used for computation.
\param nbGpuThreads Number of GPU threads to use per cloth (default is 8192).
*/
virtual void computeNormalVectors(
PxTrimeshSkinningGpuData* skinningDataArrayD, PxU32 arrayLength,
CUstream stream, PxU32 nbGpuThreads = 8192) = 0;
/**
\brief Evaluates interpolated deformable surface vertices.
\param skinningDataArrayD Array of deformable surface skinning data structures.
\param arrayLength The number of elements in the skinning data array.
\param stream CUDA stream to be used for computation.
\param nbGpuThreads Number of GPU threads to use per deformable surface (default is 8192).
*/
virtual void evaluateVerticesEmbeddedIntoSurface(
PxTrimeshSkinningGpuData* skinningDataArrayD, PxU32 arrayLength,
CUstream stream, PxU32 nbGpuThreads = 8192) = 0;
/**
\brief Evaluates interpolated deformable volume vertices.
\param skinningDataArrayD Array of deformable volume skinning data structures.
\param arrayLength Length of the skinning data array.
\param stream CUDA stream to be used for computation.
\param nbGpuThreads Number of GPU threads to use per deformable volume (default is 8192).
*/
virtual void evaluateVerticesEmbeddedIntoVolume(
PxTetmeshSkinningGpuData* skinningDataArrayD, PxU32 arrayLength,
CUstream stream, PxU32 nbGpuThreads = 8192) = 0;
/**
\brief Virtual destructor for PxDeformableSkinning.
*/
virtual ~PxDeformableSkinning() { }
};
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,287 @@
// 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 PX_PHYSICS_DEFORMABLE_SURFACE_H
#define PX_PHYSICS_DEFORMABLE_SURFACE_H
#include "PxDeformableBody.h"
#include "PxDeformableSurfaceFlag.h"
#include "foundation/PxArray.h"
#include "PxConeLimitedConstraint.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
class PxCudaContextManager;
/**
\brief The maximum number of triangles supported in a surface deformable mesh
The current limit is 1'048'575.
*/
#define PX_MAX_NB_DEFORMABLE_SURFACE_TRI 0x000fffff
/**
\brief The maximum number of vertices supported in a surface deformable mesh
The current limit is 1'048'575.
*/
#define PX_MAX_NB_DEFORMABLE_SURFACE_VTX 0x000fffff
/**
\brief The maximum number of deformable surfaces supported in a scene
The current limit is 4095.
*/
#define PX_MAX_NB_DEFORMABLE_SURFACE 0xfff
/**
\brief Represents a deformable surface
The deformable surface feature is exclusively supported on GPU. The full GPU pipeline needs to
be enabled in order to make use of deformable bodies, see #PxSceneFlag::eENABLE_GPU_DYNAMICS,
#PxBroadPhaseType::eGPU.
*/
class PxDeformableSurface : public PxDeformableBody
{
public:
/**
\brief Raises or clears a particular deformable surface flag.
See the list of flags #PxDeformableSurfaceFlag
<b>Default:</b> No flags are set
\param[in] flag The PxDeformableSurfaceFlag to raise(set) or clear. See #PxDeformableSurfaceFlag.
\param[in] val The new boolean value for the flag.
*/
virtual void setDeformableSurfaceFlag(PxDeformableSurfaceFlag::Enum flag, bool val) = 0;
/**
\brief Sets deformable surface flags.
See the list of flags #PxDeformableSurfaceFlag
<b>Default:</b> No flags are set
\param[in] flags The PxDeformableSurfaceFlags to set.
*/
virtual void setDeformableSurfaceFlags(PxDeformableSurfaceFlags flags) = 0;
/**
\brief Reads the deformable surface flags.
See the list of flags #PxDeformableSurfaceFlag
\return The values of the deformable surface flags.
\see setDeformableSurfaceFlag()
*/
virtual PxDeformableSurfaceFlags getDeformableSurfaceFlags() const = 0;
/**
\brief Sets the number of collision pair updates per timestep.
Collision pair is updated at least once per timestep and increasing the frequency provides better collision pairs.
<b>Default:</b> 1
\param[in] frequency It sets the number of collision pair updates per timestep.
\see getNbCollisionPairUpdatesPerTimestep()
*/
virtual void setNbCollisionPairUpdatesPerTimestep(const PxU32 frequency) = 0;
/**
\brief Retrieves number of collision pair updates per timestep.
\return The number of collision pair updates per timestep.
\see setNbCollisionPairUpdatesPerTimestep()
*/
virtual PxU32 getNbCollisionPairUpdatesPerTimestep() const = 0;
/**
\brief Sets the number of collision substeps in each sub-timestep.
Collision constraints can be applied multiple times in each sub-timestep
<b>Default:</b> 1
\param[in] frequency It sets the number of collision substeps in each sub-timestep.
\see getNbCollisionSubsteps()
*/
virtual void setNbCollisionSubsteps(const PxU32 frequency) = 0;
/**
\brief Retrieves the number of collision substeps in each sub-timestep.
\return The number of collision substeps in each sub-timestep.
\see setNbCollisionSubsteps()
*/
virtual PxU32 getNbCollisionSubsteps() const = 0;
/**
\brief Gets a pointer to a device buffer containing positions and inverse masses of the
surface deformable.
This function returns a pointer to device memory for the positions and inverse masses of
the surface deformable. The device memory buffer is used to both initialize/update the vertices of the surface deformable and
read the simulation results.
\note It is mandatory to call PxDeformableSurface::markDirty() with PxDeformableSurfaceDataFlag::ePOSITION_INVMASS when
updating data in this buffer.
The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary.
The first 3 floats specify the positions and the last float specifies the inverse mass of the vertex.
The size of the buffer is the number of vertices of the surface deformable mesh * sizeof(PxVec4).
\see PxTriangleMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a shape is attached to the
deformable surface. Calling PxDeformableSurface::detachShape() will deallocate the memory.
It is not allowed to write to this buffer from the start of the PxScene::simulate() call
until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks
have finished, reading the data during a completion task is explicitly allowed. The
simulation will read and write directly from/into this buffer.
It is the users' responsibility to initialize this buffer with the initial positions of
the vertices of the surface deformable mesh.
\return PxVec4* A pointer to a device buffer containing positions and inverse masses of
the surface deformable mesh.
*/
virtual PxVec4* getPositionInvMassBufferD() = 0;
/**
\brief Gets a pointer to a device buffer containing velocities of the deformable surface.
This function returns a pointer to device memory for the velocities of the deformable surface. This buffer
is used to both initialize/update the vertices of the surface deformable and read the simulation results.
\note It is mandatory to call PxDeformableSurface::markDirty() with PxDeformableSurfaceDataFlag::eVELOCITY when
updating data in this buffer.
The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary. The
first 3 floats specify the velocity of the vertex. The final float is unused. The size of
the buffer is the number of vertices of the surface deformable mesh * sizeof(PxVec4).
\see PxTriangleMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a shape is attached to the
deformable surface. Calling PxDeformableSurface::detachShape() will deallocate the memory.
It is not allowed to write to this buffer from the start of the PxScene::simulate() call
until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks
have finished, reading the data during a completion task is explicitly allowed. The
simulation will read and write directly from/into this buffer.
It is the users' responsibility to initialize this buffer with the initial velocities of
the vertices of the surface deformable mesh.
\return PxVec4* A pointer to a device buffer containing the velocities of the surface deformable mesh.
*/
virtual PxVec4* getVelocityBufferD() = 0;
/**
\brief Gets a pointer to a device buffer containing the rest positions of the deformable surface.
This function returns a pointer to device memory for the rest positions of the deformable surface.
This buffer is used to initialize/update the rest positions of the vertices of the deformable surface.
\note It is mandatory to call PxDeformableSurface::markDirty() with PxDeformableSurfaceDataFlag::eREST_POSITION when
updating data in this buffer.
The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary.
The first 3 specify the rest position. The last float is unused. The size of the buffer
is the number of vertices of the surface deformable mesh * sizeof(PxVec4). \see PxTriangleMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a shape is attached to the
deformable surface. Calling PxDeformableSurface::detachShape() will deallocate the memory.
It is not allowed to write to this buffer from the start of the PxScene::simulate() call
until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks
have finished, reading the data during a completion task is explicitly allowed. The
simulation will read directly from this buffer.
It is the users' responsibility to initialize this buffer with the initial rest positions of
the vertices of the surface deformable mesh.
\return PxVec4* A pointer to a device buffer containing the rest positions of the surface deformable mesh.
*/
virtual PxVec4* getRestPositionBufferD() = 0;
/**
\brief Marks per-vertex simulation state and configuration buffers dirty to signal to the simulation
that changes have been made.
Calling this function is required to notify the simulation of changes made in the positionInvMass,
velocity and rest position buffers.
This function can be called multiple times, and dirty flags are accumulated internally until
PxScene::simulate() is called.
\see getPositionInvMassBufferD, getVelocityBufferD, getRestPositionBufferD
\param flags The buffers that have been updated.
*/
virtual void markDirty(PxDeformableSurfaceDataFlags flags) = 0;
/**
\brief Gets the concrete type name.
\return The name of the concrete type.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxDeformableSurface"; }
protected:
PX_INLINE PxDeformableSurface(PxType concreteType, PxBaseFlags baseFlags) : PxDeformableBody(concreteType, baseFlags) {}
PX_INLINE PxDeformableSurface(PxBaseFlags baseFlags) : PxDeformableBody(baseFlags) {}
virtual ~PxDeformableSurface() {}
virtual bool isKindOf(const char* name) const PX_OVERRIDE { PX_IS_KIND_OF(name, "PxDeformableSurface", PxDeformableBody); }
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_PHYSICS_DEFORMABLE_SURFACE_H

View File

@@ -0,0 +1,73 @@
// 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 PX_PHYSICS_DEFORMABLE_SURFACE_FLAGS_H
#define PX_PHYSICS_DEFORMABLE_SURFACE_FLAGS_H
#include "foundation/PxFlags.h"
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
struct PxDeformableSurfaceFlag
{
enum Enum
{
eUSE_ANISOTROPIC_MODEL = 1 << 0, // 0: use isotropic model, 1: use anistropic model
eENABLE_FLATTENING = 1 << 1 // 0: query rest bending angle from rest shape, 1: use zero rest bending angle
};
};
typedef PxFlags<PxDeformableSurfaceFlag::Enum, PxU16> PxDeformableSurfaceFlags;
/**
\brief Identifies input and output buffers for PxDeformableSurface.
*/
struct PxDeformableSurfaceDataFlag
{
enum Enum
{
eNONE = 0,
ePOSITION_INVMASS = 1 << 0,
eVELOCITY = 1 << 1,
eREST_POSITION = 1 << 2,
eALL = ePOSITION_INVMASS | eVELOCITY | eREST_POSITION
};
};
typedef PxFlags<PxDeformableSurfaceDataFlag::Enum, PxU32> PxDeformableSurfaceDataFlags;
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_PHYSICS_DEFORMABLE_SURFACE_FLAGS_H

View File

@@ -0,0 +1,119 @@
// 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 PX_DEFORMABLE_SURFACE_MATERIAL_H
#define PX_DEFORMABLE_SURFACE_MATERIAL_H
#include "PxDeformableMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Material class to represent surface deformable material properties.
\see PxPhysics.createDeformableSurfaceMaterial
*/
class PxDeformableSurfaceMaterial : public PxDeformableMaterial
{
public:
/**
\brief Sets material thickness
<b>Default:</b> 0.001
\param[in] thickness Material thickness.
\see getThickness()
*/
virtual void setThickness(PxReal thickness) = 0;
/**
\brief Retrieves the material thickness.
<b>Default:</b> 0.001
\return thickness.
\see setThickness()
*/
virtual PxReal getThickness() const = 0;
/**
\brief Sets material bending stiffness
<b>Default:</b> 0.0
\param[in] bendingStiffness Material bending stiffness.
\see getBendingStiffness()
*/
virtual void setBendingStiffness(PxReal bendingStiffness) = 0;
/**
\brief Retrieves the material bending stiffness.
\return bendingStiffness.
\see setBendingStiffness()
*/
virtual PxReal getBendingStiffness() const = 0;
/**
\brief Sets material bending damping
\param[in] bendingDamping Material bending damping.
\see getBendingDamping()
*/
virtual void setBendingDamping(PxReal bendingDamping) = 0;
/**
\brief Retrieves the material bending damping.
\return bending damping.
\see setBendingDamping()
*/
virtual PxReal getBendingDamping() const = 0;
/**
\brief Gets the concrete type name.
\return The name of the concrete type.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxDeformableSurfaceMaterial"; }
protected:
PX_INLINE PxDeformableSurfaceMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxDeformableMaterial(concreteType, baseFlags) {}
PX_INLINE PxDeformableSurfaceMaterial(PxBaseFlags baseFlags) : PxDeformableMaterial(baseFlags) {}
virtual ~PxDeformableSurfaceMaterial() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxDeformableSurfaceMaterial", PxDeformableMaterial); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_DEFORMABLE_SURFACE_MATERIAL_H

View File

@@ -0,0 +1,702 @@
// 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 PX_DEFORMABLE_VOLUME_H
#define PX_DEFORMABLE_VOLUME_H
#include "PxDeformableBody.h"
#include "PxDeformableVolumeFlag.h"
#include "PxConeLimitedConstraint.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
class PxCudaContextManager;
class PxTetrahedronMesh;
class PxDeformableVolumeAuxData;
class PxDeformableSurface;
class PxParticleBuffer;
/**
\brief The maximum number of tetrahedrons supported in a deformable volume tetrahedron mesh
The current limit is 1'048'575.
*/
#define PX_MAX_NB_DEFORMABLE_VOLUME_TET 0x000fffff
/**
\brief The maximum number of deformable volumes supported in a scene
The current limit is 4095.
*/
#define PX_MAX_NB_DEFORMABLE_VOLUME 0xfff
/**
\brief Represents a deformable volume
The deformable volume feature is exclusively supported on GPU. The full GPU pipeline needs to
be enabled in order to make use of deformable bodies, see #PxSceneFlag::eENABLE_GPU_DYNAMICS,
#PxBroadPhaseType::eGPU.
*/
class PxDeformableVolume : public PxDeformableBody
{
public:
/**
\brief Raises or clears a particular deformable volume flag.
See the list of flags #PxDeformableVolumeFlag
<b>Default:</b> No flags are set
\param[in] flag The PxDeformableVolumeFlag to raise(set) or clear. See #PxDeformableVolumeFlag.
\param[in] val The new boolean value for the flag.
*/
virtual void setDeformableVolumeFlag(PxDeformableVolumeFlag::Enum flag, bool val) = 0;
/**
\brief Sets deformable volume flags.
See the list of flags #PxDeformableVolumeFlag
<b>Default:</b> No flags are set
\param[in] flags The PxDeformableVolumeFlags to set.
*/
virtual void setDeformableVolumeFlags(PxDeformableVolumeFlags flags) = 0;
/**
\brief Reads the deformable volume flags.
See the list of flags #PxDeformableVolumeFlag
\return The values of the deformable volume flags.
\see setDeformableVolumeFlag()
*/
virtual PxDeformableVolumeFlags getDeformableVolumeFlags() const = 0;
/**
\brief Sets the self collision stress tolerance.
Stress threshold to deactivate collision contacts in case the local stress magnitude exceeds the threshold.
<b>Default:</b> 0.9
\param[in] selfCollisionStressTolerance The maximal depenetration velocity
*/
virtual void setSelfCollisionStressTolerance(const PxReal selfCollisionStressTolerance) = 0;
/**
\brief Retrieves the self collision stress tolerance.
\return The self collision filter distance
\see setSelfCollisionFilterDistance
*/
virtual PxReal getSelfCollisionStressTolerance() const = 0;
/**
\brief Gets a pointer to a device buffer containing positions and inverse masses of the
collision mesh.
This function returns a pointer to device memory for the positions and inverse masses of
the deformable volume. This buffer is used to both initialize/update the collision mesh vertices
of the deformable volume and read the simulation results.
\note It is mandatory to call PxDeformableVolume::markDirty() with PxDeformableVolumeDataFlag::ePOSITION_INVMASS
when updating data in this buffer.
The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary.
The first 3 floats specify the vertex position and the last float contains the inverse mass of the
vertex. The size of the buffer is the number of vertices of the collision mesh * sizeof(PxVec4).
\see PxTetrahedronMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a shape is attached to the
deformable volume. Calling PxDeformableVolume::detachShape() will deallocate the memory.
It is not allowed to write to this buffer from the start of the PxScene::simulate() call
until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks
have finished, reading the data during a completion task is explicitly allowed. The
simulation will read and write directly from/into this buffer.
It is the users' responsibility to initialize this buffer with the initial positions of
the vertices of the collision mesh. See PxDeformableVolumeExt::allocateAndInitializeHostMirror(),
PxDeformableVolumeExt::copyToDevice().
\return PxVec4* A pointer to a device buffer containing positions and inverse masses of
the collision mesh.
*/
virtual PxVec4* getPositionInvMassBufferD() = 0;
/**
\brief Gets a pointer to a device buffer containing rest positions of the collision mesh vertices.
This function returns a pointer to device memory for the rest positions of the deformable volume collision
mesh. This buffer is used to initialize the rest positions of the collision mesh vertices.
\note It is mandatory to call PxDeformableVolume::markDirty() with PxDeformableVolumeDataFlag::eREST_POSITION when
updating data in this buffer.
The simulation expects 4 floats per vertex, aligned to a 16B boundary. The first 3 specify the
rest position. The last float is unused. The size of the buffer is the number of vertices in
the collision mesh * sizeof(PxVec4). \see PxTetrahedronMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a shape is attached to the deformable volume.
Calling PxDeformableVolume::detachShape() will deallocate the memory.
It is not allowed to write data into this buffer from the start of PxScene::simulate() until
PxScene::fetchResults() returns.
It is the users' responsibility to initialize this buffer with the initial rest positions of the
vertices of the collision mesh. See PxDeformableVolumeExt::allocateAndInitializeHostMirror(),
PxDeformableVolumeExt::copyToDevice().
\return PxVec4* A pointer to a device buffer containing the rest positions of the collision mesh.
*/
virtual PxVec4* getRestPositionBufferD() = 0;
/**
\brief Gets a pointer to a device buffer containing the vertex positions of the simulation mesh.
This function returns a pointer to device memory for the positions and inverse masses of the deformable volume
simulation mesh. This buffer is used to both initialize/update the simulation mesh vertices
of the deformable volume and read the simulation results.
\note It is mandatory to call PxDeformableVolume::markDirty() with PxDeformableVolumeDataFlag::eSIM_POSITION_INVMASS when
updating data in this buffer.
The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary. The
first 3 floats specify the positions and the last float specifies the inverse mass of the vertex.
The size of the buffer is the number of vertices of the simulation mesh * sizeof(PxVec4).
\see PxTetrahedronMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a simulation mesh is attached to the
deformable volume. Calling PxDeformableVolume::detachSimulationMesh() will deallocate the memory.
It is not allowed to write to this buffer from the start of the PxScene::simulate() call
until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks
have finished, reading the data during a completion task is explicitly allowed. The
simulation will read and write directly from/into this buffer.
It is the users' responsibility to initialize this buffer with the initial positions of
the vertices of the simulation mesh. See PxDeformableVolumeExt::allocateAndInitializeHostMirror(),
PxDeformableVolumeExt::copyToDevice().
\return PxVec4* A pointer to a device buffer containing the vertex positions of the simulation mesh.
*/
virtual PxVec4* getSimPositionInvMassBufferD() = 0;
/**
\brief Gets a pointer to a device buffer containing the vertex velocities of the simulation mesh.
This function returns a pointer to device memory for the velocities of the deformable volume simulation mesh
vertices. This buffer is used to both initialize/update the simulation mesh vertex velocities
of the deformable volume and read the simulation results.
\note It is mandatory to call PxDeformableVolume::markDirty() with PxDeformableVolumeDataFlag::eSIM_VELOCITY when
updating data in this buffer.
The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary. The
first 3 specify the velocities for each vertex. The final float is unused. The size of the
buffer is the number of vertices of the simulation mesh * sizeof(PxVec4).
\see PxTetrahedronMesh::getNbVertices().
The device memory pointed to by this pointer is allocated when a simulation mesh is attached to the
deformable volume. Calling PxDeformableVolume::detachSimulationMesh() will deallocate the memory.
It is not allowed to write to this buffer from the start of the PxScene::simulate() call
until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks
have finished, reading the data during a completion task is explicitly allowed. The
simulation will read and write directly from/into this buffer.
It is the users' responsibility to initialize this buffer with the initial velocities of
the vertices of the simulation mesh. See PxDeformableVolumeExt::allocateAndInitializeHostMirror(),
PxDeformableVolumeExt::copyToDevice().
\return PxVec4* A pointer to a device buffer containing the vertex velocities of the simulation mesh.
*/
virtual PxVec4* getSimVelocityBufferD() = 0;
/**
\brief Marks per-vertex simulation state and configuration buffers dirty to signal to the simulation
that changes have been made.
Calling this function is mandatory to notify the simulation of changes made in the positionInvMass,
simPositionInvMass, simVelocity and rest position buffers.
This function can be called multiple times, and dirty flags are accumulated internally until
PxScene::simulate() is called.
\see getPositionInvMassBufferD, getSimVelocityBufferD, getRestPositionBufferD, getSimPositionInvMassBufferD
\param flags The buffers that have been updated.
*/
virtual void markDirty(PxDeformableVolumeDataFlags flags) = 0;
/**
\brief Sets the device buffer containing the kinematic targets for this deformable volume.
This function sets the kinematic targets for a deformable volume to a user-provided device buffer. This buffer is
read by the simulation to obtain the target position for each vertex of the simulation mesh.
The simulation expects 4 consecutive float for each vertex, aligned to a 16B boundary. The first 3
floats specify the target positions. The last float determines (together with the flag argument)
if the target is active or not.
For a deformable volume with the flag PxDeformableBodyFlag::eKINEMATIC raised, all target positions are considered
valid. In case a deformable volume has the PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC raised, only target
positions whose corresponding last float has been set to 0.f are considered valid target positions.
\see PxConfigureDeformableVolumeKinematicTarget
Setting the kinematic targets has no effect if neither PxDeformableBodyFlag::eKINEMATIC nor
PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC is set.
The size of the buffer is the number of vertices of the simulation mesh * sizeof(PxVec4).
\see PxTetrahedronMesh::getNbVertices().
It is the users responsibility to manage the memory pointed to by the input to this function,
as well as guaranteeing the integrity of the input data. In particular, this means that it is
not allowed to write this data from from the start of PxScene::simulate() until PxScene::fetchResults()
returns. The memory is not allowed to be deallocated until PxScene::fetchResults() returns.
Calling this function with a null pointer for the positions will clear the input and resume normal
simulation. PxDeformableBodyFlag::eKINEMATIC or PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC are ignored
if no targets are set.
This call is persistent across calls to PxScene::simulate(). Once this function is called, the
simulation will look up the target positions from the same buffer for every call to PxScene::simulate().
The user is allowed to update the target positions without calling this function again, provided that
the synchronization requirements are adhered to (no changes between start of PxScene::simulate() until
PxScene::fetchResults() returns).
\param positions A pointer to a device buffer containing the kinematic targets for this deformable volume.
*/
virtual void setKinematicTargetBufferD(const PxVec4* positions) = 0;
/**
\brief Deprecated: Sets the device buffer containing the kinematic targets for this deformable volume.
This function sets the kinematic targets for a deformable volume to a user-provided device buffer. This buffer is
read by the simulation to obtain the target position for each vertex of the simulation mesh.
The simulation expects 4 consecutive float for each vertex, aligned to a 16B boundary. The first 3
floats specify the target positions. The last float determines (together with the flag argument)
if the target is active or not.
For a deformable volume with the flag PxDeformableVolumeFlag::eKINEMATIC raised, all target positions are considered
valid. In case a deformable volume has the PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC raised, only target
positions whose corresponding last float has been set to 0.f are considered valid target positions.
\see PxConfigureDeformableVolumeKinematicTarget
The size of the buffer is the number of vertices of the simulation mesh * sizeof(PxVec4).
\see PxTetrahedronMesh::getNbVertices().
It is the users responsibility to manage the memory pointed to by the input to this function,
as well as guaranteeing the integrity of the input data. In particular, this means that it is
not allowed to write this data from from the start of PxScene::simulate() until PxScene::fetchResults()
returns. The memory is not allowed to be deallocated until PxScene::fetchResults() returns.
Calling this function with a null pointer for the positions will clear the input and resume normal
simulation. This will also clear both the PxDeformableVolumeFlag::eKINEMATIC and PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC
flags of the deformable volume.
This call is persistent across calls to PxScene::simulate(). Once this function is called, the
simulation will look up the target positions from the same buffer for every call to PxScene::simulate().
The user is allowed to update the target positions without calling this function again, provided that
the synchronization requirements are adhered to (no changes between start of PxScene::simulate() until
PxScene::fetchResults() returns).
\param positions A pointer to a device buffer containing the kinematic targets for this deformable volume.
\param flags Flags specifying the type of kinematic deformable volume: this function ignores all flags except PxDeformableVolumeFlag::eKINEMATIC and PxDeformableVolumeFlag::ePARTIALLY_KINEMATIC.
*/
PX_DEPRECATED virtual void setKinematicTargetBufferD(const PxVec4* positions, PxDeformableVolumeFlags flags) = 0;
/**
\brief Attaches a simulation mesh
Attaches the simulation mesh (geometry) and a state containing inverse mass, rest pose
etc. required to compute the deformation.
\param[in] simulationMesh The tetrahedral mesh used to compute the deformable's deformation
\param[in] deformableVolumeAuxData A state that contain a mapping from simulation to collision mesh, volume information etc.
\return Returns true if the operation was successful
\see detachSimulationMesh, PxDeformableBody.attachShape
*/
virtual bool attachSimulationMesh(PxTetrahedronMesh& simulationMesh, PxDeformableVolumeAuxData& deformableVolumeAuxData) = 0;
/**
\brief Detaches the simulation mesh
Detaches the simulation mesh and simulation state used to compute the deformation.
\see attachSimulationMesh, PxDeformableBody.detachShape
*/
virtual void detachSimulationMesh() = 0;
/**
\brief Retrieves the simulation mesh pointer.
Allows to access the geometry of the tetrahedral mesh used to compute the object's deformation
\return Pointer to the simulation mesh
*/
virtual PxTetrahedronMesh* getSimulationMesh() = 0;
//! \brief Const version of getSimulationMesh()
virtual const PxTetrahedronMesh* getSimulationMesh() const = 0;
/**
\brief Retrieve the collision mesh pointer.
Allows to access the geometry of the tetrahedral mesh used to perform collision detection
\return Pointer to the collision mesh
*/
virtual PxTetrahedronMesh* getCollisionMesh() = 0;
//! \brief Const version of getCollisionMesh()
virtual const PxTetrahedronMesh* getCollisionMesh() const = 0;
/**
\brief Retrieves the simulation state pointer.
Allows to access the additional data of the simulation mesh (inverse mass, rest state etc.).
The geometry part of the data is stored in the simulation mesh.
\return Pointer to the simulation state
*/
virtual PxDeformableVolumeAuxData* getDeformableVolumeAuxData() = 0;
//! \brief const version of getDeformableVolumeAuxData()
virtual const PxDeformableVolumeAuxData*
getDeformableVolumeAuxData() const = 0;
/**
\brief Returns the GPU deformable volume index.
\return The GPU index, or 0xFFFFFFFF if the deformable volume is not in a scene.
*/
virtual PxU32 getGpuDeformableVolumeIndex() = 0;
/**
\brief Gets the concrete type name.
\return The name of the concrete type.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxDeformableVolume"; }
/**
\brief Deprecated
\see setDeformableVolumeFlag
*/
PX_DEPRECATED PX_FORCE_INLINE void setSoftBodyFlag(PxDeformableVolumeFlag::Enum flag, bool val) { return setDeformableVolumeFlag(flag, val); }
/**
\brief Deprecated
\see setDeformableVolumeFlags
*/
PX_DEPRECATED PX_FORCE_INLINE void setSoftBodyFlags(PxDeformableVolumeFlags flags) { return setDeformableVolumeFlags(flags); }
/**
\brief Deprecated
\see getDeformableVolumeFlags
*/
PX_DEPRECATED PX_FORCE_INLINE PxDeformableVolumeFlags getSoftBodyFlag() const { return getDeformableVolumeFlags(); }
/**
\brief Deprecated
\see getDeformableVolumeAuxData
*/
PX_DEPRECATED PX_FORCE_INLINE PxDeformableVolumeAuxData* getSoftBodyAuxData() { return getDeformableVolumeAuxData(); }
/**
\brief Deprecated
\see getDeformableVolumeAuxData
*/
PX_DEPRECATED PX_FORCE_INLINE const PxDeformableVolumeAuxData* getSoftBodyAuxData() const { return getDeformableVolumeAuxData(); }
/**
\brief Deprecated
<b>Default:</b> 4 position iterations, 1 velocity iteration
\param[in] minPositionIters Minimal number of position iterations the solver should perform for this body. <b>Range:</b> [1,255]
\param[in] minVelocityIters Minimal number of velocity iterations the solver should perform for this body. <b>Range:</b> [1,255]
\see PxDeformableBody.setSolverIterationCounts()
*/
PX_DEPRECATED virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0;
/**
\brief Deprecated
\see PxDeformableBody.setSolverIterationCount()
*/
PX_DEPRECATED virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0;
/**
\brief Creates a collision filter between a particle and a tetrahedron in the deformable volume's collision mesh.
\param[in] particlesystem The particle system used for the collision filter
\param[in] buffer The PxParticleBuffer to which the particle belongs to.
\param[in] particleId The particle whose collisions with the tetrahedron in the deformable volume are filtered.
\param[in] tetId The tetradedron in the deformable volume that is filtered. If tetId is PX_MAX_NB_DEFORMABLE_VOLUME_TET, this particle will filter against all tetrahedra in this deformable volume.
*/
PX_DEPRECATED virtual void addParticleFilter(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId) = 0;
/**
\brief Removes a collision filter between a particle and a tetrahedron in the deformable volume's collision mesh.
\param[in] particlesystem The particle system used for the collision filter
\param[in] buffer The PxParticleBuffer to which the particle belongs to.
\param[in] particleId The particle whose collisions with the tetrahedron in the deformable volume are filtered.
\param[in] tetId The tetrahedron in the deformable volume is filtered.
*/
PX_DEPRECATED virtual void removeParticleFilter(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId) = 0;
/**
\brief Creates an attachment between a particle and a deformable volume.
Be aware that destroying the particle system before destroying the attachment is illegal and may cause a crash.
The deformable volume keeps track of these attachments but the particle system does not.
\param[in] particlesystem The particle system used for the attachment
\param[in] buffer The PxParticleBuffer to which the particle belongs to.
\param[in] particleId The particle that is attached to a tetrahedron in the deformable volume's collision mesh.
\param[in] tetId The tetrahedron in the deformable volume's collision mesh to attach the particle to.
\param[in] barycentric The barycentric coordinates of the particle attachment position with respect to the tetrahedron specified with tetId.
\return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later
*/
PX_DEPRECATED virtual PxU32 addParticleAttachment(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId, const PxVec4& barycentric) = 0;
/**
\brief Removes an attachment between a particle and a deformable volume.
Be aware that destroying the particle system before destroying the attachment is illegal and may cause a crash.
The deformable volume keeps track of these attachments but the particle system does not.
\param[in] particlesystem The particle system used for the attachment
\param[in] handle Index that identifies the attachment. This handle gets returned by the addParticleAttachment when the attachment is created
*/
PX_DEPRECATED virtual void removeParticleAttachment(PxPBDParticleSystem* particlesystem, PxU32 handle) = 0;
/**
\brief Creates a collision filter between a vertex in a deformable volume and a rigid body.
\param[in] actor The rigid body actor used for the collision filter
\param[in] vertId The index of a vertex in the deformable volume's collision mesh whose collisions with the rigid body are filtered.
*/
PX_DEPRECATED virtual void addRigidFilter(PxRigidActor* actor, PxU32 vertId) = 0;
/**
\brief Removes a collision filter between a vertex in a deformable volume and a rigid body.
\param[in] actor The rigid body actor used for the collision filter
\param[in] vertId The index of a vertex in the deformable volume's collision mesh whose collisions with the rigid body are filtered.
*/
PX_DEPRECATED virtual void removeRigidFilter(PxRigidActor* actor, PxU32 vertId) = 0;
/**
\brief Creates a rigid attachment between a deformable volume and a rigid body.
Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash.
The deformable volume keeps track of these attachments but the rigid body does not.
This method attaches a vertex on the deformable volume collision mesh to the rigid body.
\param[in] actor The rigid body actor used for the attachment
\param[in] vertId The index of a vertex in the deformable volume's collision mesh that gets attached to the rigid body.
\param[in] actorSpacePose The location of the attachment point expressed in the rigid body's coordinate system.
\param[in] constraint The user defined cone distance limit constraint to limit the movement between a vertex in the deformable volume and rigid body.
\return Returns a handle that identifies the attachment created. This handle can be used to relese the attachment later
*/
PX_DEPRECATED virtual PxU32 addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint = NULL) = 0;
/**
\brief Releases a rigid attachment between a deformable volume and a rigid body.
Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash.
The deformable volume keeps track of these attachments but the rigid body does not.
This method removes a previously-created attachment between a vertex of the deformable volume collision mesh and the rigid body.
\param[in] actor The rigid body actor used for the attachment
\param[in] handle Index that identifies the attachment. This handle gets returned by the addRigidAttachment when the attachment is created
*/
PX_DEPRECATED virtual void removeRigidAttachment(PxRigidActor* actor, PxU32 handle) = 0;
/**
\brief Creates collision filter between a tetrahedron in a deformable volume and a rigid body.
\param[in] actor The rigid body actor used for collision filter
\param[in] tetIdx The index of a tetrahedron in the deformable volume's collision mesh whose collisions with the rigid body is filtered.
*/
PX_DEPRECATED virtual void addTetRigidFilter(PxRigidActor* actor, PxU32 tetIdx) = 0;
/**
\brief Removes collision filter between a tetrahedron in a deformable volume and a rigid body.
\param[in] actor The rigid body actor used for collision filter
\param[in] tetIdx The index of a tetrahedron in the deformable volume's collision mesh whose collisions with the rigid body is filtered.
*/
PX_DEPRECATED virtual void removeTetRigidFilter(PxRigidActor* actor, PxU32 tetIdx) = 0;
/**
\brief Creates a rigid attachment between a deformable volume and a rigid body.
Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash.
The deformable volume keeps track of these attachments but the rigid body does not.
This method attaches a point inside a tetrahedron of the collision to the rigid body.
\param[in] actor The rigid body actor used for the attachment
\param[in] tetIdx The index of a tetrahedron in the deformable volume's collision mesh that contains the point to be attached to the rigid body
\param[in] barycentric The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx
\param[in] actorSpacePose The location of the attachment point expressed in the rigid body's coordinate system.
\param[in] constraint The user defined cone distance limit constraint to limit the movement between a tet and rigid body.
\return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later
*/
PX_DEPRECATED virtual PxU32 addTetRigidAttachment(PxRigidActor* actor, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint = NULL) = 0;
/**
\brief Creates collision filter between a tetrahedron in a deformable volume and a tetrahedron in another deformable volume.
\param[in] otherDeformableVolume The other deformable volume actor used for collision filter
\param[in] otherTetIdx The index of the tetrahedron in the other deformable volume's collision mesh to be filtered.
\param[in] tetIdx1 The index of the tetrahedron in the deformable volume's collision mesh to be filtered. If tetId1 is PX_MAX_NB_DEFORMABLE_VOLUME_TET, the tetrahedron with index `otherTetIdx' in the other deformable volume will filter against all tetrahedra in this deformable volume.
*/
PX_DEPRECATED virtual void addSoftBodyFilter(PxDeformableVolume* otherDeformableVolume, PxU32 otherTetIdx, PxU32 tetIdx1) = 0;
/**
\brief Removes collision filter between a tetrahedron in a deformable volume and a tetrahedron in other deformable volume.
\param[in] otherDeformableVolume The other deformable volume actor used for collision filter
\param[in] otherTetIdx The index of the other tetrahedron in the other deformable volume's collision mesh whose collision with the tetrahedron with the deformable volume is filtered.
\param[in] tetIdx1 The index of the tetrahedron in the deformable volume's collision mesh whose collision with the other tetrahedron with the other deformable volume is filtered.
*/
PX_DEPRECATED virtual void removeSoftBodyFilter(PxDeformableVolume* otherDeformableVolume, PxU32 otherTetIdx, PxU32 tetIdx1) = 0;
/**
\brief Creates collision filters between a tetrahedron in a deformable volume with another deformable volume.
\param[in] otherDeformableVolume The other deformable volume actor used for collision filter
\param[in] otherTetIndices The indices of the tetrahedron in the other deformable volume's collision mesh to be filtered.
\param[in] tetIndices The indices of the tetrahedron of the deformable volume's collision mesh to be filtered.
\param[in] tetIndicesSize The size of tetIndices.
*/
PX_DEPRECATED virtual void addSoftBodyFilters(PxDeformableVolume* otherDeformableVolume, PxU32* otherTetIndices, PxU32* tetIndices, PxU32 tetIndicesSize) = 0;
/**
\brief Removes collision filters between a tetrahedron in a deformable volume with another deformable volume.
\param[in] otherDeformableVolume The other deformable volume actor used for collision filter
\param[in] otherTetIndices The indices of the tetrahedron in the other deformable volume's collision mesh to be filtered.
\param[in] tetIndices The indices of the tetrahedron of the deformable volume's collision mesh to be filtered.
\param[in] tetIndicesSize The size of tetIndices.
*/
PX_DEPRECATED virtual void removeSoftBodyFilters(PxDeformableVolume* otherDeformableVolume, PxU32* otherTetIndices, PxU32* tetIndices, PxU32 tetIndicesSize) = 0;
/**
\brief Creates an attachment between two deformable volumes.
This method attaches a point inside a tetrahedron of the collision mesh to a point in another deformable volume's tetrahedron collision mesh.
\param[in] deformableVolume0 The deformable volume actor used for the attachment
\param[in] tetIdx0 The index of a tetrahedron in the other deformable volume that contains the point to be attached to the deformable volume
\param[in] tetBarycentric0 The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx0
\param[in] tetIdx1 The index of a tetrahedron in the deformable volume's collision mesh that contains the point to be attached to the deformableVolume0
\param[in] tetBarycentric1 The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx1
\param[in] constraint The user defined cone distance limit constraint to limit the movement between tets.
\param[in] constraintOffset Offsets the cone and distance limit constraint along its axis, in order to specify the location of the cone tip.
\return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later
*/
PX_DEPRECATED virtual PxU32 addSoftBodyAttachment(PxDeformableVolume* deformableVolume0, PxU32 tetIdx0, const PxVec4& tetBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1,
PxConeLimitedConstraint* constraint = NULL, PxReal constraintOffset = 0.0f) = 0;
/**
\brief Releases an attachment between a deformable volume and the other deformable volume.
Be aware that destroying the deformable volume before destroying the attachment is illegal and may cause a crash.
This method removes a previously-created attachment between a point inside a tetrahedron of the collision mesh to a point in another deformable volume's tetrahedron collision mesh.
\param[in] deformableVolume0 The deformable volume actor used for the attachment.
\param[in] handle Index that identifies the attachment. This handle gets returned by the addSoftBodyAttachment when the attachment is created.
*/
PX_DEPRECATED virtual void removeSoftBodyAttachment(PxDeformableVolume* deformableVolume0, PxU32 handle) = 0;
/**
\brief Deprecated
\see getGpuDeformableVolumeIndex
*/
PX_DEPRECATED PX_FORCE_INLINE PxU32 getGpuSoftBodyIndex() { return getGpuDeformableVolumeIndex(); }
protected:
PX_INLINE PxDeformableVolume(PxType concreteType, PxBaseFlags baseFlags) : PxDeformableBody(concreteType, baseFlags) {}
PX_INLINE PxDeformableVolume(PxBaseFlags baseFlags) : PxDeformableBody(baseFlags) {}
virtual ~PxDeformableVolume() {}
virtual bool isKindOf(const char* name) const PX_OVERRIDE { PX_IS_KIND_OF(name, "PxDeformableVolume", PxDeformableBody); }
};
/**
\brief Adjusts a deformable volume kinematic target such that it is properly set as active or inactive. Inactive targets will not affect vertex position, they are ignored by the solver.
\param[in] target The kinematic target
\param[in] isActive A boolean indicating if the returned target should be marked as active or not
\return The target with adjusted w component
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4 PxConfigureDeformableVolumeKinematicTarget(const PxVec4& target, bool isActive)
{
PxVec4 result = target;
if (isActive)
result.w = 0.0f;
else
{
//Any non-zero value will mark the target as inactive
if (result.w == 0.0f)
result.w = 1.0f;
}
return result;
}
/**
\brief Sets up a deformable volume kinematic target such that it is properly set as active or inactive. Inactive targets will not affect vertex position, they are ignored by the solver.
\param[in] target The kinematic target
\param[in] isActive A boolean indicating if the returned target should be marked as active or not
\return The target with configured w component
*/
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4 PxConfigureDeformableVolumeKinematicTarget(const PxVec3& target, bool isActive)
{
return PxConfigureDeformableVolumeKinematicTarget(PxVec4(target, 0.0f), isActive);
}
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_DEFORMABLE_VOLUME_H

View File

@@ -0,0 +1,84 @@
// 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 PX_DEFORMABLE_VOLUME_FLAGS_H
#define PX_DEFORMABLE_VOLUME_FLAGS_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Flags to enable or disable special modes of a PxDeformableVolume instance
*/
struct PxDeformableVolumeFlag
{
enum Enum
{
eCOMPUTE_STRESS_TENSOR = 1 << 0, //!< Enables computation of a Cauchy stress tensor for every tetrahedron in the simulation mesh. The tensors can be accessed through the deformable volume direct API
ePARTIALLY_KINEMATIC = 1 << 1, //!< Enables partially kinematic motion of the collision and simulation mesh.
eDISPLAY_SIM_MESH PX_DEPRECATED = 1 << 2, //!< Deprecated
eDISABLE_SELF_COLLISION PX_DEPRECATED = 1 << 3, //!< Deprecated, use PxDeformableBodyFlag::eDISABLE_SELF_COLLISION instead
eENABLE_CCD PX_DEPRECATED = 1 << 4, //!< Deprecated, use PxDeformableBodyFlag::eENABLE_SPECULATIVE_CCD
eKINEMATIC PX_DEPRECATED = 1 << 5 //!< Deprecated, use PxDeformableBodyFlag::eKINEMATIC instead
};
};
typedef PxFlags<PxDeformableVolumeFlag::Enum, PxU16> PxDeformableVolumeFlags;
/**
\brief Identifies the buffers of a PxDeformableVolume instance.
\see PxDeformableVolume::markDirty()
*/
struct PxDeformableVolumeDataFlag
{
enum Enum
{
eNONE = 0,
ePOSITION_INVMASS = 1 << 0, //!< The collision mesh's positions
eSIM_POSITION_INVMASS = 1 << 1, //!< The simulation mesh's positions and inverse masses
eSIM_VELOCITY = 1 << 2, //!< The simulation mesh's velocities
eREST_POSITION_INVMASS = 1 << 3, //!< The collision mesh's rest positions
eALL = ePOSITION_INVMASS | eSIM_POSITION_INVMASS | eSIM_VELOCITY | eREST_POSITION_INVMASS
};
};
typedef PxFlags<PxDeformableVolumeDataFlag::Enum, PxU32> PxDeformableVolumeDataFlags;
#if !PX_DOXYGEN
}
#endif
#endif // PX_DEFORMABLE_VOLUME_FLAGS_H

View File

@@ -0,0 +1,136 @@
// 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 PX_DEFORMABLE_VOLUME_MATERIAL_H
#define PX_DEFORMABLE_VOLUME_MATERIAL_H
#include "PxDeformableMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
struct PxDeformableVolumeMaterialModel
{
enum Enum
{
eCO_ROTATIONAL, //!< Default model. Well suited for high stiffness. Does need tetrahedra with good shapes (no extreme slivers) in the rest pose.
eNEO_HOOKEAN //!< Well suited for lower stiffness. Robust to any tetrahedron shape.
};
};
class PxScene;
/**
\brief Material class to represent a set of deformable volume material properties.
\see PxPhysics.createDeformableVolumeMaterial
*/
class PxDeformableVolumeMaterial : public PxDeformableMaterial
{
public:
/**
\brief Sets material velocity damping term
\deprecated Use setElasticityDamping instead.
\param[in] damping Material velocity damping term. <b>Range:</b> [0, PX_MAX_F32)<br>
\see getDamping
*/
PX_DEPRECATED virtual void setDamping(PxReal damping) = 0;
/**
\brief Retrieves velocity damping
\deprecated Use getElasticityDamping instead.
\return The velocity damping.
\see setDamping()
*/
PX_DEPRECATED virtual PxReal getDamping() const = 0;
/**
\brief Sets material damping scale. A scale of 1 corresponds to default damping, a value of 0 will only apply damping to certain motions leading to special effects that look similar to water filled softbodies.
\deprecated Damping scale is deprecated.
\param[in] scale Damping scale term. <b>Default:</b> 1 <b>Range:</b> [0, 1]
\see getDampingScale
*/
PX_DEPRECATED virtual void setDampingScale(PxReal scale) = 0;
/**
\brief Retrieves material damping scale.
\deprecated Damping scale is deprecated.
\return The damping scale term.
\see setDamping()
*/
PX_DEPRECATED virtual PxReal getDampingScale() const = 0;
/**
\brief Sets the material model.
\param[in] model The material model
\see getMaterialModel
*/
virtual void setMaterialModel(PxDeformableVolumeMaterialModel::Enum model) = 0;
/**
\brief Retrieves the material model.
\return The material model.
\see setMaterialModel()
*/
virtual PxDeformableVolumeMaterialModel::Enum getMaterialModel() const = 0;
/**
\brief Gets the concrete type name.
\return The name of the concrete type.
*/
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxDeformableVolumeMaterial"; }
protected:
PX_INLINE PxDeformableVolumeMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxDeformableMaterial(concreteType, baseFlags) {}
PX_INLINE PxDeformableVolumeMaterial(PxBaseFlags baseFlags) : PxDeformableMaterial(baseFlags) {}
virtual ~PxDeformableVolumeMaterial() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxDeformableVolumeMaterial", PxDeformableMaterial); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_DEFORMABLE_VOLUME_MATERIAL_H

View File

@@ -0,0 +1,100 @@
// 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 PX_DELETION_LISTENER_H
#define PX_DELETION_LISTENER_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Flags specifying deletion event types.
\see PxDeletionListener::onRelease PxPhysics.registerDeletionListener()
*/
struct PxDeletionEventFlag
{
enum Enum
{
eUSER_RELEASE = (1<<0), //!< The user has called release on an object.
eMEMORY_RELEASE = (1<<1) //!< The destructor of an object has been called and the memory has been released.
};
};
/**
\brief Collection of set bits defined in PxDeletionEventFlag.
\see PxDeletionEventFlag
*/
typedef PxFlags<PxDeletionEventFlag::Enum,PxU8> PxDeletionEventFlags;
PX_FLAGS_OPERATORS(PxDeletionEventFlag::Enum,PxU8)
/**
\brief interface to get notification on object deletion
*/
class PxDeletionListener
{
public:
/**
\brief Notification if an object or its memory gets released
If release() gets called on a PxBase object, an eUSER_RELEASE event will get fired immediately. The object state can be queried in the callback but
it is not allowed to change the state. Furthermore, when reading from the object it is the user's responsibility to make sure that no other thread
is writing at the same time to the object (this includes the simulation itself, i.e., #PxScene::fetchResults() must not get called at the same time).
Calling release() on a PxBase object does not necessarily trigger its destructor immediately. For example, the object can be shared and might still
be referenced by other objects or the simulation might still be running and accessing the object state. In such cases the destructor will be called
as soon as it is safe to do so. After the destruction of the object and its memory, an eMEMORY_RELEASE event will get fired. In this case it is not
allowed to dereference the object pointer in the callback.
\param[in] observed The object for which the deletion event gets fired.
\param[in] userData The user data pointer of the object for which the deletion event gets fired. Not available for all object types in which case it will be set to 0.
\param[in] deletionEvent The type of deletion event. Do not dereference the object pointer argument if the event is eMEMORY_RELEASE.
*/
virtual void onRelease(const PxBase* observed, void* userData, PxDeletionEventFlag::Enum deletionEvent) = 0;
protected:
PxDeletionListener() {}
virtual ~PxDeletionListener() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,470 @@
// 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 PX_DIRECT_GPU_API_H
#define PX_DIRECT_GPU_API_H
#include "cudamanager/PxCudaTypes.h"
#include "foundation/PxVec4.h"
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief This flag specifies the type of data to get when calling PxDirectGPUAPI::getRigidDynamicData().
*/
class PxRigidDynamicGPUAPIReadType
{
public:
enum Enum
{
eGLOBAL_POSE = 0, //!< Get the global poses. Type: 1 PxTransform per PxRigidDynamic.
eLINEAR_VELOCITY, //!< Get the linear velocities. Type: 1 PxVec3 per PxRigidDynamic.
eANGULAR_VELOCITY, //!< Get the angular velocities. Type: 1 PxVec3 per PxRigidDynamic.
// eLINEAR_ACCELERATION and eANGULAR_ACCELERATION are only available if PxSceneFlag::eENABLE_BODY_ACCELERATIONS is enabled.
eLINEAR_ACCELERATION, //!< Get the linear accelerations. Type: 1 PxVec3 per PxRigidDynamic.
eANGULAR_ACCELERATION //!< Get the angular accelerations. Type: 1 PxVec3 per PxRigidDynamic.
};
};
/**
\brief This flag specifies the type of data to set when calling PxDirectGPUAPI::setRigidDynamicData().
*/
class PxRigidDynamicGPUAPIWriteType
{
public:
enum Enum
{
eGLOBAL_POSE = 0, //!< Set the global poses. Type: 1 PxTransform per PxRigidDynamic.
eLINEAR_VELOCITY, //!< Set the linear velocities. Type: 1 PxVec3 per PxRigidDynamic.
eANGULAR_VELOCITY, //!< Set the angular velocities. Type: 1 PxVec3 per PxRigidDynamic.
eFORCE, //!< Set the forces. Will be applied at the center of gravity of the bodies. Type: 1 PxVec3 per PxRigidDynamic.
eTORQUE //!< Set the torques. Will be applied at the center of gravity of the bodies. Type: 1 PxVec3 per PxRigidDynamic.
};
};
/**
\brief This flag specifies the type of data to get when calling PxDirectGPUAPI::getArticulationData().
*/
class PxArticulationGPUAPIReadType
{
public:
enum Enum
{
eJOINT_POSITION = 0, //!< The joint positions. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_VELOCITY, //!< The joint velocities. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_ACCELERATION, //!< The joint accelerations. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_FORCE, //!< The joint forces or torques applied using setArticulationData. 1 PxReal per dof. Block size per articulation: maxDofs. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
eJOINT_TARGET_VELOCITY, //!< The velocity targets applied using setArticulationData. 1 PxReal per dof. Block size per articulation: maxDofs. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
eJOINT_TARGET_POSITION, //!< The position targets applied using setArticulationData. 1 PxReal per dof. Block size per articulation: maxDofs. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
eROOT_GLOBAL_POSE, //!< The root link global pose. 1 PxTransform per articulation. Block size per articulation: 1.
eROOT_LINEAR_VELOCITY, //!< The root link linear velocity. 1 PxVec3 per articulation. Block size per articulation: 1.
eROOT_ANGULAR_VELOCITY, //!< The root link angular velocity. 1 PxVec3 per articulation. Block size per articulation: 1.
eLINK_GLOBAL_POSE, //!< The link global pose including root link. 1 PxTransform per link. Block size per articulation: maxLinks.
eLINK_LINEAR_VELOCITY, //!< The link linear velocities including root link. 1 PxVec3 per link. Block size per articulation: maxLinks.
eLINK_ANGULAR_VELOCITY, //!< The link angular velocities including root link. 1 PxVec3 per link. Block size per articulation: maxLinks.
eLINK_LINEAR_ACCELERATION, //!< The link linear accelerations including root link. 1 PxVec3 per link. Block size per articulation: maxLinks.
eLINK_ANGULAR_ACCELERATION, //!< The link angular accelerations including root link. 1 PxVec3 per link. Block size per articulation: maxLinks.
eLINK_INCOMING_JOINT_FORCE, //!< The link incoming joint forces including root link. The force is reported in the child joint frame of the link's incoming joint. 2 PxVec3 per link. The first PxVec3 contains the force, and the second PxVec3 contains the torque. Block size per articulation: maxLinks.
eFIXED_TENDON, //!< Fixed tendon data. 1 PxGpuFixedTendonData per fixed tendon. Block size per articulation: maxFixedTendons. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
eFIXED_TENDON_JOINT, //!< Fixed tendon joint data. 1 PxGpuTendonJointCoefficientData per fixed tendon joint. Block size per articulation: maxFixedTendons * maxFixedTendonJoints. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
eSPATIAL_TENDON, //!< Spatial tendon data. 1 PxGpuSpatialTendonData per spatial tendon. Block size per articulation: maxSpatialTendons. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
eSPATIAL_TENDON_ATTACHMENT //!< Spatial tendon attachment data. 1 PxGpuTendonAttachmentData per spatial tendon attachment. Block size per articulation: maxSpatialTendons * maxSpatialTendonAttachments. Not updated by the simulation, will return the values set by PxDirectGPUAPI::setArticulationData().
};
};
/**
\brief This flag specifies the type of data to set when calling PxDirectGPUAPI::setArticulationData().
*/
class PxArticulationGPUAPIWriteType
{
public:
enum Enum
{
eJOINT_POSITION = 0, //!< The joint positions. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_VELOCITY, //!< The joint velocities. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_FORCE, //!< The applied joint forces or torques. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_TARGET_VELOCITY, //!< The velocity targets for the joint drives. 1 PxReal per dof. Block size per articulation: maxDofs.
eJOINT_TARGET_POSITION, //!< The position targets for the joint drives. 1 PxReal per dof. Block size per articulation: maxDofs.
eROOT_GLOBAL_POSE, //!< The root link transform. 1 PxTransform per articulation. Block size per articulation: 1.
eROOT_LINEAR_VELOCITY, //!< The root link linear velocity. 1 PxVec3 per articulation. Block size per articulation: 1.
eROOT_ANGULAR_VELOCITY, //!< The root link angular velocity. 1 PxVec3 per articulation. Block size per articulation: 1.
eLINK_FORCE, //!< The forces to apply to links. 1 PxVec3 per link. Block size per articulation: maxLinks.
eLINK_TORQUE, //!< The torques to apply to links. 1 PxVec3 per link. Block size per articulation: maxLinks.
eFIXED_TENDON, //!< Fixed tendon data. 1 PxGpuFixedTendonData per fixed tendon. Block size per articulation: maxFixedTendons.
eFIXED_TENDON_JOINT, //!< Fixed tendon joint data. 1 PxGpuTendonJointCoefficientData per fixed tendon joint. Block size per articulation: maxFixedTendons * maxFixedTendonJoints.
eSPATIAL_TENDON, //!< Spatial tendon data. 1 PxGpuSpatialTendonData per spatial tendon. Block size per articulation: maxSpatialTendons.
eSPATIAL_TENDON_ATTACHMENT //!< Spatial tendon attachment data. 1 PxGpuTendonAttachmentData per spatial tendon attachment. Block size per articulation: maxSpatialTendons * maxSpatialTendonAttachments.
};
};
/**
\brief This flag specifies the type of operation to perform when calling PxDirectGPUAPI::computeArticulationData.
*/
class PxArticulationGPUAPIComputeType
{
public:
enum Enum
{
eUPDATE_KINEMATIC = 0, //!< Updates the link state for all the articulations specified in the index list. This operation can be performed
//!< by the user to propagate changes made to root transform/root velocities/joint positions/joint velocities to
//!< be reflected in the link transforms/velocities. Performing this operation will clear output values calculated by
//!< the simulation, specifically link accelerations, link incoming joint forces, and joint accelerations. Note
//!< that this is only necessary if the user wants to query link state, otherwise it will be performed automatically
//!< at the start of the next call to simulate(). The data input parameter will be ignored and can be set to NULL for
//!< this operation.
eDENSE_JACOBIANS, //!< Computes the dense Jacobian for the articulation in world space, including the dofs of a potentially floating base.
//!< This is the batched, direct-GPU equivalent of PxArticulationReducedCoordinate::computeDenseJacobian. The output data
//!< buffer is laid out into sequential blocks per articulation, where each block has the size
//!< (6 + maxDofs) * (6 + (maxLinks - 1) * 6) * sizeof(float). maxLinks and maxDofs are the maximum link and dof counts
//!< across all the articulations in the scene, and can be queried by calling PxDirectGPUAPI::getArticulationGPUAPIMaxCounts().
//!< The size of the jacobian can vary by articulation, and will be determined using these formulas:
//!< nCols = (fixedBase ? 0 : 6) + dofCount, nRows = (fixedBase ? 0 : 6) + (linkCount - 1) * 6. The matrix is indexed [nCols * row + column].
eGENERALIZED_MASS_MATRICES PX_DEPRECATED, //!< Deprecated, use PxArticulationGPUAPIComputeType::eMASS_MATRICES instead.
//!< Computes the joint-space inertia matrices that maps joint accelerations to joint forces: forces = M * accelerations on the GPU.
//!< This is the batched, direct-GPU equivalent of PxArticulationReducedCoordinate::computeGeneralizedMassMatrix().
//!< The output buffer is laid out into sequential blocks per articulation, where each block has the size maxDofs * maxDofs * sizeof(float).
//!< maxDofs is the maximum dof count across all the articulations in the scene, and can be queried by calling
//!< PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). The size of the matrix can vary by articulation, and will be dofCount * dofCount.
//!< The dof indices will be according to the low-level indexing, we refer to the documentation of PxArticulationCache for an explanation.
eGENERALIZED_GRAVITY_FORCES PX_DEPRECATED, //!< Deprecated, use PxArticulationGPUAPIComputeType::eGRAVITY_COMPENSATION instead.
//!< Computes the joint dof forces required to counteract gravitational forces for the given articulation pose. This is the
//!< batched, direct-GPU equivalent of PxArticulationReducedCoordinate::computeGeneralizedGravityForce(). The output data
//!< buffer is laid out into sequential blocks per articulation, where each block has the size maxDofs * sizeof(float). maxDofs
//!< is the maximum dof count across all the articulations in the scene, and can be queried by calling
//!< PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). The data layout within each block follows the PxArticulationCache layout,
//!< for which we refer to the user guide. There will be 1 PxReal per articulation dof.
eCORIOLIS_AND_CENTRIFUGAL_FORCES PX_DEPRECATED, //!< Deprecated, use PxArticulationGPUAPIComputeType::eCORIOLIS_AND_CENTRIFUGAL_COMPENSATION instead.
//!< Computes the joint dof forces required to counteract Coriolis and centrifugal forces for the given articulation pose.
//!< This is the batched, direct-GPU equivalent to PxArticulationReducedCoordinate::computeCoriolisAndCentrifugalForce(). The output data
//!< buffer is laid out into sequential blocks per articulation, where each block has the size maxDofs * sizeof(float). maxDofs
//!< is the maximum dof count across all the articulations in the scene, and can be queried by calling
//!< PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). The data layout within each block follows the PxArticulationCache layout,
//!< for which we refer to the user guide. There will be 1 PxReal per articulation dof.
eMASS_MATRICES, //!< Computes the mass matrices that maps accelerations to forces: forces = M * accelerations on the GPU.
//!< This is the batched, direct-GPU equivalent of PxArticulationReducedCoordinate::computeMassMatrix(). The output buffer is laid
//!< out into sequential blocks per articulation, where each block has the size (maxDofs + 6) * (maxDofs + 6) * sizeof(float).
//!< maxDofs is the maximum dof count across all the articulations in the scene, and can be queried by calling
//!< PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(), The size of the matrix can vary by articulation, and will be dofCount * dofCount
//!< for fixed-base articulations and (dofCount + 6) * (dofCount + 6) for floating-base articulations.
//!< We refer to the documentation of PxArticulationCache and PxArticulationReducedCoordinate::computeMassMatrix() for a more detailed explanation.
eCORIOLIS_AND_CENTRIFUGAL_COMPENSATION, //!< Computes the joint dof forces (and root force) required to counteract Coriolis and centrifugal forces for the given articulation pose.
//!< This is the batched, direct-GPU equivalent to PxArticulationReducedCoordinate::computeCoriolisCompensation(). The output data
//!< buffer is laid out into sequential blocks per articulation, where each block has the size (maxDofs + 6) * sizeof(float). maxDofs
//!< is the maximum dof count across all the articulations in the scene, and can be queried by calling
//!< PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). The size of the output can vary by articulation, and will be dofCount
//!< for fixed-base articulations and (dofCount + 6) for floating-base articulations. We refer to the documentation of
//!< PxArticulationCache and PxArticulationReducedCoordinate::computeCoriolisCompensation() for a more detailed explanation.
eGRAVITY_COMPENSATION, //!< Computes the forces required to counteract gravitational forces for the given articulation pose. This is the batched,
//!< direct-GPU equivalent of PxArticulationReducedCoordinate::computeGravityCompensation(). The output data buffer is laid out
//!< into sequential blocks per articulation, where each block has the size (maxDofs + 6) * sizeof(float). maxDofs
//!< is the maximum dof count across all the articulations in the scene, and can be queried by calling
//!< PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). The size of the output can vary by articulation, and will be dofCount
//!< for fixed-base articulations and (dofCount + 6) for floating-base articulations. We refer to the documentation of
//!< PxArticulationCache and PxArticulationReducedCoordinate::computeGravityCompensation() for a more detailed explanation.
eARTICULATION_COMS_WORLD_FRAME, //!< Computes the articulation's center of mass in the world frame for the given articulation pose.
//!< This is the batched, direct-GPU equivalent to PxArticulationReducedCoordinate::computeArticulationCOM(). The output data
//!< buffer is laid out into sequential blocks per articulation, where each block has the size sizeof(float) * 3.
eARTICULATION_COMS_ROOT_FRAME, //!< Computes the articulation's center of mass in the root frame for the given articulation pose.
//!< This is the batched, direct-GPU equivalent to PxArticulationReducedCoordinate::computeArticulationCOM(). The output data
//!< buffer is laid out into sequential blocks per articulation, where each block has the size sizeof(float) * 3.
eCENTROIDAL_MOMENTUM_MATRICES //!< Computes the centroidal momentum matrix and bias force for a floating-base articulation.
//!< This is the batched, direct-GPU equivalent to PxArticulationReducedCoordinate::computeCentroidalMomentumMatrix(). The data buffer is laid
//!< out into four main blocks. The two first blocks correspond to the input (mass matrix, Coriolis and Centrifugal compensation force),
//!< and the two last blocks correspond to the output (centroidal momentum matrix, bias force). Each block must be organized into sequential
//!< subblocks per articulation. The size of the subblock is (maxDofs + 6) * (maxDofs + 6) * sizeof(float) for the mass matrix,
//!< (maxDofs + 6) * sizeof(float) for the Coriolis and Centrifugal compensation force, 6 * (maxDofs + 6) * sizeof(float) for the centroidal
//!< momentum matrix, and 6 * sizeof(float) for the bias force. maxDofs is the maximum dof count across all the articulations in the scene,
//!< and can be queried by calling PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). The size of the actual data in each subblock can vary by
//!< articulation, and will depend on the value of dofCount. The dof indices will be according to the low-level indexing, we refer to
//!< the documentation of PxArticulationCache for an explanation.
};
};
/**
\brief Container to hold the results of PxDirectGPUAPI::getArticulationGPUAPIMaxCounts(). All the quantities are the maximum values
for the PxScene associated with this instance of PxDirectGPUAPI.
*/
struct PxArticulationGPUAPIMaxCounts
{
PxU32 maxDofs;
PxU32 maxLinks;
PxU32 maxFixedTendons;
PxU32 maxFixedTendonJoints;
PxU32 maxSpatialTendons;
PxU32 maxSpatialTendonAttachments;
PxArticulationGPUAPIMaxCounts() :
maxDofs(0),
maxLinks(0),
maxFixedTendons(0),
maxFixedTendonJoints(0),
maxSpatialTendons(0),
maxSpatialTendonAttachments(0)
{ }
};
/**
\brief This flag specifies the type of data to get when calling #PxDirectGPUAPI::getD6JointData().
*/
class PxD6JointGPUAPIReadType
{
public:
enum Enum
{
/**
\brief The joint forces applied by the solver.
The forces are in world space. 1 PxVec3 per joint.
\note Replaces calls to PxConstraint::getForce() which will not work properly anymore if direct GPU API is used.
*/
eJOINT_FORCE,
/**
\brief The joint torques applied by the solver.
The torques are in world space. 1 PxVec3 per joint.
\note Replaces calls to PxConstraint::getForce() which will not work properly anymore if direct GPU API is used.
*/
eJOINT_TORQUE
};
};
/**
\brief PxDirectGPUAPI exposes an API that enables batched direct access to GPU data for a PxScene.
The functions in this class allow batched direct access to GPU data for PxRigidDynamic, PxArticulationReducedCoordinate,
PxShape and PxD6Joint types. This allows interoperation with GPU post- and preprocessing for users and allows the user
to implement more efficient CPU-GPU data copies based on the specific needs of the application.
Using this direct-API will disable the existing CPU-based API for all the data exposed in the direct-API. For any API function
that does not have a counterpart in this direct-API, the existing API will continue to work.
To use this API, PxSceneFlag::eENABLE_DIRECT_GPU_API needs to be raised, in combination with PxSceneFlag::eENABLE_GPU_DYNAMICS
and PxBroadphaseType::eGPU. Note that these options are immutable and cannot be changed after the scene has been created.
Due to the internal architecture of the GPU-accelerated parts of PhysX, using this API comes with caveats:
1) All GPU-CPU copies for data exposed in this API will be disabled. This means that the existing CPU-based API will
return outdated data, and any setters for data exposed in the interface will not work. On the other hand, significant
speedups can be achieved because of the reduced amount of GPU-CPU memory copies.
2) Due to the internal architecture of the GPU-accelerated PhysX, this API will only work after a first simulation step has been
taken. The reason for this is that the PxScene first needs to know all the actors it will have to simulate, and setup the
sizes of the GPU-based structures. For setup, the existing CPU API should be used.
\note Due to the fact that this API is exposing low-level data, we do reserve the right to change this API without deprecation
in case of changes in the internal implementations.
*/
class PxDirectGPUAPI
{
protected:
PxDirectGPUAPI() {}
virtual ~PxDirectGPUAPI() {}
public:
/**
\brief Copies the simulation state for a set of PxRigidDynamic actors into a user-provided GPU data buffer.
\param[out] data User-provided GPU data buffer which has size nbElements * sizeof(type). For the types, see the dataType options in PxRigidDynamicGPUAPIReadType.
\param[in] gpuIndices User-provided GPU index buffer containing elements of PxRigidDynamicGPUIndex. This buffer contains the GPU indices of the PxRigidDynamic objects that are part of this get operation. See #PxRigidDynamic::getGPUIndex(). The size of this buffer needs to be nbElements * sizeof(PxRigidDynamicGPUIndex). The data requested for the PxRigidDynamic with its GPU index at position x in the gpuIndices array will be located at position x in the data array.
\param[in] dataType The type of data to get. See #PxRigidDynamicGPUAPIReadType.
\param[in] nbElements The number of rigid bodies to be copied.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the copy immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the copy to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
*/
virtual bool getRigidDynamicData(void* data, const PxRigidDynamicGPUIndex* gpuIndices, PxRigidDynamicGPUAPIReadType::Enum dataType, PxU32 nbElements, CUevent startEvent = NULL, CUevent finishEvent = NULL) const = 0;
/**
\brief Sets the simulation state for a set of PxRigidDynamic actors from a user-provided GPU data buffer.
\param[in] data User-provided GPU data buffer which has size nbElements * sizeof(type). For the types, see the dataType options in PxRigidDynamicGPUAPIWriteType.
\param[in] gpuIndices User-provided GPU index buffer containing elements of PxRigidDynamicGPUIndex. This buffer contains the GPU indices of the PxRigidDynamic objects that are part of this set operation. See #PxRigidDynamic::getGPUIndex(). The size of this buffer needs to be nbElements * sizeof(PxRigidDynamicGPUIndex). The data for the PxRigidDynamic with its GPU index at position x in the gpuIndices array needs to be located at position x in the data array.
\param[in] dataType The type of data to set. See #PxRigidDynamicGPUAPIWriteType.
\param[in] nbElements The number of rigid bodies to be set.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the copy immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the copy to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
*/
virtual bool setRigidDynamicData(const void* data, const PxRigidDynamicGPUIndex* gpuIndices, PxRigidDynamicGPUAPIWriteType::Enum dataType, PxU32 nbElements, CUevent startEvent = NULL, CUevent finishEvent = NULL) = 0;
/**
\brief Gets the simulation state for a set of articulations, i.e. PxArticulationReducedCoordinate objects and copies into a user-provided GPU data buffer.
\param[out] data User-provided GPU data buffer that is appropriately sized for the data being requested. The sizing is explained in detail below.
\param[in] gpuIndices User-provided GPU index buffer containing elements of PxArticulationGPUIndex. This buffer contains the GPU indices of the PxArticulationReducedCoordinate objects that are part of this get operation. See #PxArticulationReducedCoordinate::getGPUIndex(). The size of this buffer needs to be nbElements * sizeof(PxArticulationGPUIndex). The data for the PxArticulationReducedCoordinate with its GPU index at position x in the gpuIndices array will have its data block located at position x in the data array.
\param[in] dataType The type of data to get. See #PxArticulationGPUAPIReadType.
\param[in] nbElements The number of articulations to copy data from.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the copy immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the copy to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
The data buffer must be sized according to the maximum component counts across all articulations in the PxScene, as summarised in PxArticulationGPUAPIMaxCounts. The data buffer is split into sequential
blocks that are of equal size and can hold the data for all components of an articulation. For example, for a link-centric data type (PxArticulationGPUAPIReadType::eLINK_GLOBAL_POSE, for example)
each of these blocks has to be maxLinks * sizeof(dataType). The size of the complete buffer would then be nbElements * maxLinks * sizeof(dataType). For a dof-centric data type,
the block size would be maxDofs * sizeof(dataType). The specific layout for each dataType is detailed in the API documentation of PxArticulationGPUAPIReadType.
The max counts for a scene can be obtained by calling PxDirectGPUAPI::getArticulationGPUAPIMaxCounts().
The link and dof indexing of these blocks then follows the same pattern as the PxArticulationCache API. We refer to the user guide for an explanation.
*/
virtual bool getArticulationData(void* data, const PxArticulationGPUIndex* gpuIndices, PxArticulationGPUAPIReadType::Enum dataType, PxU32 nbElements, CUevent startEvent = NULL, CUevent finishEvent = NULL) const = 0;
/**
\brief Sets the simulation state for a set of articulations, i.e. PxArticulationReducedCoordinate objects from a user-provided GPU data buffer.
\param[in] data User-provided GPU data buffer that is appropriately sized for the data to be set. The sizing is explained in detail below.
\param[in] gpuIndices User-provided GPU index buffer containing elements of PxArticulationGPUIndex. This buffer contains the GPU indices of the PxArticulationReducedCoordinate objects that are part of this set operation. See #PxArticulationReducedCoordinate::getGPUIndex(). The size of this buffer needs to be nbElements * sizeof(PxArticulationGPUIndex). The data for the PxArticulationReducedCoordinate with its GPU index at position x in the gpuIndices array needs to have its data block located at position x in the data array.
\param[in] dataType The type of data to set. See #PxArticulationGPUAPIWriteType.
\param[in] nbElements The number of articulations to set data for.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the copy immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the copy to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
The data buffer must be sized according to the maximum component counts across all articulations in the PxScene, as summarised in PxArticulationGPUAPIMaxCounts. The data buffer is split into sequential
blocks that are of equal size and can hold the data for all components of an articulation. For example, for a link-centric data type (PxArticulationGPUAPIWriteType::eLINK_FORCE, for example)
each of these blocks has to be maxLinks * sizeof(dataType). The size of the complete buffer would then be nbElements * maxLinks * sizeof(dataType). For a dof-centric data type,
the block size would be maxDofs * sizeof(dataType). The specific layout for each dataType is detailed in the API documentation of PxArticulationGPUAPIWriteType.
The max counts for a scene can be obtained by calling PxDirectGPUAPI::getArticulationGPUAPIMaxCounts().
The internal indexing of these blocks then follows the same pattern as the PxArticulationCache API. We refer to the user guide for an explanation.
*/
virtual bool setArticulationData(const void* data, const PxArticulationGPUIndex* gpuIndices, PxArticulationGPUAPIWriteType::Enum dataType, PxU32 nbElements, CUevent startEvent = NULL, CUevent finishEvent = NULL) = 0;
/**
\brief performs a compute operation on a set of articulations, i.e. PxArticulationReducedCoordinate objects.
\param[in,out] data User-provided GPU data buffer that is appropriately sized for the operation to be performed. Depending on the operation, can be input or output data.
\param[in] gpuIndices User-provided GPU index buffer containing elements of PxArticulationGPUIndex. This buffer contains the GPU indices of the PxArticulationReducedCoordinate objects that are part of this compute operation. See #PxArticulationReducedCoordinate::getGPUIndex(). The size of this buffer needs to be nbElements * sizeof(PxArticulationGPUIndex).
\param[in] operation The operation to perform. See PxArticulationGPUAPIComputeType::Enum.
\param[in] nbElements The number of articulations to perform this compute operation on.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the computation immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the computation to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
The appropriate sizing of the data buffer as well as the data layout is documented alongside the compute operations in the API documentation of PxArticulationGPUAPIComputeType.
*/
virtual bool computeArticulationData(void* data, const PxArticulationGPUIndex* gpuIndices, PxArticulationGPUAPIComputeType::Enum operation, PxU32 nbElements, CUevent startEvent = NULL, CUevent finishEvent = NULL) = 0;
/**
\brief Copy rigid body (PxRigidBody) and articulation (PxArticulationReducedCoordinate) contact data to a user-provided GPU data buffer.
\note This function only reports contact data for actor pairs where both actors are either rigid bodies or articulations.
\note The contact data contains pointers to internal state and is only valid until the next call to simulate().
\param[out] data User-provided GPU data buffer, which should be the size of PxGpuContactPair * maxPairs
\param[out] nbContactPairs User-provided GPU data buffer of 1 * sizeof(PxU32) that contains the actual number of pairs that was written.
\param[in] maxPairs The maximum number of pairs that the buffer can contain.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the copy immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the copy to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
*/
virtual bool copyContactData(void* data, PxU32* nbContactPairs, PxU32 maxPairs, CUevent startEvent = NULL, CUevent finishEvent = NULL) const = 0;
/**
\brief Evaluate sample point distances and gradients on SDF shapes in local space. Local space is the space in which the mesh's raw vertex positions are represented.
\param[out] localGradientAndSignedDistanceConcatenated User-provided GPU buffer where the evaluated gradients and distances in SDF local space get stored. It has the same structure as localSamplePointsConcatenated. The PxVec4 elements contain the gradient and the distance (gradX, gradY, gradZ, distance).
\param[in] shapeIndices User-provided GPU index buffer containing elements of PxShapeGPUIndex. This buffer contains the GPU indices of the PxShape objects that are part of this operation. See #PxShape::getGPUIndex(). The size of this buffer (in bytes) needs to be nbElements * sizeof(PxShapeGPUIndex). The shapes must be triangle mesh shapes with SDFs.
\param[in] localSamplePointsConcatenated User-provided GPU buffer containing the sample point locations for every shape in the shapes' local space. The buffer stride is maxPointCount.
\param[in] samplePointCountPerShape User-provided GPU buffer containing the number of sample points for every shape.
\param[in] nbElements The number of shapes to be queried.
\param[in] maxPointCount The maximum value in the array samplePointCountPerShape. Note that the arrays localGradientAndSignedDistanceConcatenated and localSamplePointsConcatenated must have the size (in bytes) nbElements * maxPointCount * sizeof(PxVec4).
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the computation immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the computation to finish before returning.
Example: Ten shapes are part of the simulation. Three of them have an SDF (shapeIndices of the SDF meshes are 2, 4 and 6). For the first shape, the SDF distance of 10 sample points should be queried. 20 sample
points for the second mesh and 30 sample points for the third mesh. The slice size (=maxPointCount) is the maximum of sample points required for any shape participating in the query, 30 = max(10, 20, 30) for this example.
The buffers required for the method evaluateSDFDistances are constructed as follows (not including optional parameters):
* localGradientAndSignedDistanceConcatenated[length: 3 * 30]:
* No initialization needed. It will hold the result after the finishEvent occurred. It has the same structure as localSamplePointsConcatenated, see below.
* The format of the written PxVec4 is as follows (gradX, gradY, gradZ, sdfDistance)
* shapeIndices[length: 3]
* The content is {2, 4, 6} which are the shape indices for this example
* localSamplePointsConcatenated[length: 3 * 30]:
* Slice 0...29 has only the first 10 elements set to local sample points (w component is unused) with respect to the coordinate frame of the first shape to be queried
* Slice 30...59 has only the first 20 elements set to local sample points (w component is unused) with respect to the coordinate frame of the second shape to be queried
* Slice 60...89 has all 30 elements set to local sample points (w component is unused) with respect to the coordinate frame of the third shape to be queried
* samplePointCountPerShape[length: 3]
* The content is {10, 20, 30} which are the number of samples to evaluate per shape used in this example. Note that the slice size (=maxPointCount) is the maximum value in this list.
* nbElements: 3 for this example since 3 shapes are participating in the query
* maxPointCount: 30 for this example since 30 is the slice size (= maxPointCount = 30 = max(10, 20, 30))
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
*/
virtual bool evaluateSDFDistances(PxVec4* localGradientAndSignedDistanceConcatenated, const PxShapeGPUIndex* shapeIndices, const PxVec4* localSamplePointsConcatenated, const PxU32* samplePointCountPerShape, PxU32 nbElements, PxU32 maxPointCount, CUevent startEvent = NULL, CUevent finishEvent = NULL) const = 0;
/**
\brief Get the maximal articulation index and component counts for a PxScene.
Get the maximal articulation index and component counts for a PxScene. This is a helper function to ease the derivation of the correct data layout
for the articulation functions in PxDirectGPUAPI. Specifically, this function will return maxLinks, maxDofs, maxFixedTendons, maxFixedTendonJoints,
maxSpatialTendons and maxSpatialTendonAttachments for a scene. See #PxArticulationGPUAPIMaxCounts.
\see PxDirectGPUAPI::getArticulationData, PxDirectGPUAPI::setArticulationData, PxDirectGPUAPI::computeArticulationData
\return PxArticulationGPUAPIMaxCounts the max counts across the scene for all articulation indices and components.
*/
virtual PxArticulationGPUAPIMaxCounts getArticulationGPUAPIMaxCounts() const = 0;
/**
\brief Copies the simulation state for a set of PxD6Joint instances into a user-provided GPU data buffer.
\param[out] data User-provided GPU data buffer which has size nbElements * sizeof(type). For the types, see the options in #PxD6JointGPUAPIReadType.
\param[in] gpuIndices User-provided GPU index buffer containing elements of PxD6JointGPUIndex. This buffer contains the GPU indices of the PxD6Joint objects that are part of this get operation
(see #PxD6Joint::getGPUIndex()). The size of this buffer needs to be nbElements * sizeof(PxD6JointGPUIndex). The data requested for the PxD6Joint with its GPU index at position x in the
gpuIndices array will be located at position x in the data array.
\param[in] dataType The type of data to get (see #PxD6JointGPUAPIReadType).
\param[in] nbElements The number of provided GPU indices and as such the number of data entries that will be written to the provided GPU data buffer.
\param[in] startEvent User-provided CUDA event that is awaited at the start of this function. Defaults to NULL which means the function will dispatch the copy immediately.
\param[in] finishEvent User-provided CUDA event that is recorded at the end of this function. Defaults to NULL which means the function will wait for the copy to finish before returning.
\return bool Whether the operation was successful. Note that this might not include asynchronous CUDA errors.
*/
virtual bool getD6JointData(void* data, const PxD6JointGPUIndex* gpuIndices, PxD6JointGPUAPIReadType::Enum dataType, PxU32 nbElements, CUevent startEvent = NULL, CUevent finishEvent = NULL) const = 0;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,49 @@
// 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 PX_FEM_MATERIAL_H
#define PX_FEM_MATERIAL_H
#include "PxDeformableMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Deprecated
\see PxDeformableMaterial
*/
typedef PX_DEPRECATED PxDeformableMaterial PxFEMMaterial;
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_FEM_MATERIAL_H

View File

@@ -0,0 +1,102 @@
// 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 PX_PHYSICS_FEM_PARAMETER_H
#define PX_PHYSICS_FEM_PARAMETER_H
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Deprecated. Set of parameters to control the sleeping and collision behavior of FEM based objects
\deprecated See methods of PxDeformableBody.
*/
struct PX_DEPRECATED PxFEMParameters
{
public:
/**
\brief Velocity damping value. After every timestep the velocity is reduced while the magnitude of the reduction depends on velocityDamping
<b>Default:</b> 0.05
\deprecated See PxDeformableBody.setLinearDamping
*/
PX_DEPRECATED PxReal velocityDamping;
/**
\brief Threshold that defines the maximal magnitude of the linear motion a fem body can move in one second before it becomes a candidate for sleeping
<b>Default:</b> 0.1
\deprecated See PxDeformableBody.setSettlingThreshold
*/
PX_DEPRECATED PxReal settlingThreshold;
/**
\brief Threshold that defines the maximal magnitude of the linear motion a fem body can move in one second such that it can go to sleep in the next frame
<b>Default:</b> 0.05
\deprecated See PxDeformableBody.setSleepThreshold
*/
PX_DEPRECATED PxReal sleepThreshold;
/**
\brief Damping value that damps the motion of bodies that move slow enough to be candidates for sleeping (see settlingThreshold)
<b>Default:</b> 10
\deprecated See PxDeformableBody.setSettlingDamping
*/
PX_DEPRECATED PxReal sleepDamping;
/**
\brief Penetration value that needs to get exceeded before contacts for self collision are generated. Will only have an effect if self collisions are enabled.
<b>Default:</b> 0.1
\deprecated See PxDeformableBody.setSelfCollisionFilterDistance
*/
PX_DEPRECATED PxReal selfCollisionFilterDistance;
/**
\brief Stress threshold to deactivate collision contacts in case the tetrahedron's stress magnitude exceeds the threshold
<b>Default:</b> 0.9
\deprecated See PxDeformableVolume.setSelfCollisionStressTolerance
*/
PX_DEPRECATED PxReal selfCollisionStressTolerance;
#if !PX_CUDA_COMPILER
PxFEMParameters()
{
velocityDamping = 0.05f;
settlingThreshold = 0.1f;
sleepThreshold = 0.05f;
sleepDamping = 10.f;
selfCollisionFilterDistance = 0.1f;
selfCollisionStressTolerance = 0.9f;
}
#endif
};
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,56 @@
// 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 PX_FEM_SOFT_BODY_MATERIAL_H
#define PX_FEM_SOFT_BODY_MATERIAL_H
#include "PxDeformableVolumeMaterial.h"
#include "PxFEMMaterial.h" // deprecated
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Deprecated
\see PxDeformableVolumeMaterialModel
*/
typedef PX_DEPRECATED PxDeformableVolumeMaterialModel PxFEMSoftBodyMaterialModel;
/**
\brief Deprecated
\see PxDeformableVolumeMaterial
*/
typedef PX_DEPRECATED PxDeformableVolumeMaterial PxFEMSoftBodyMaterial;
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif // PX_FEM_SOFT_BODY_MATERIAL_H

View File

@@ -0,0 +1,778 @@
// 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 PX_FILTERING_H
#define PX_FILTERING_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxActor;
class PxShape;
/**
\brief Collection of flags describing the actions to take for a collision pair.
\see PxPairFlags PxSimulationFilterShader.filter() PxSimulationFilterCallback
*/
struct PxPairFlag
{
enum Enum
{
/**
\brief Process the contacts of this collision pair in the dynamics solver.
\note Only takes effect if the colliding actors are rigid bodies.
*/
eSOLVE_CONTACT = (1<<0),
/**
\brief Call contact modification callback for this collision pair
\note Only takes effect if the colliding actors are rigid bodies.
\see PxContactModifyCallback
*/
eMODIFY_CONTACTS = (1<<1),
/**
\brief Call contact report callback or trigger callback when this collision pair starts to be in contact.
If one of the two collision objects is a trigger shape (see #PxShapeFlag::eTRIGGER_SHAPE)
then the trigger callback will get called as soon as the other object enters the trigger volume.
If none of the two collision objects is a trigger shape then the contact report callback will get
called when the actors of this collision pair start to be in contact.
\note Only takes effect if the colliding actors are rigid bodies.
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger()
*/
eNOTIFY_TOUCH_FOUND = (1<<2),
/**
\brief Call contact report callback while this collision pair is in contact
If none of the two collision objects is a trigger shape then the contact report callback will get
called while the actors of this collision pair are in contact.
\note Triggers do not support this event. Persistent trigger contacts need to be tracked separately by observing eNOTIFY_TOUCH_FOUND/eNOTIFY_TOUCH_LOST events.
\note Only takes effect if the colliding actors are rigid bodies.
\note No report will get sent if the objects in contact are sleeping.
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\note If this flag gets enabled while a pair is in touch already, there will be no eNOTIFY_TOUCH_PERSISTS events until the pair loses and regains touch.
\see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger()
*/
eNOTIFY_TOUCH_PERSISTS = (1<<3),
/**
\brief Call contact report callback or trigger callback when this collision pair stops to be in contact
If one of the two collision objects is a trigger shape (see #PxShapeFlag::eTRIGGER_SHAPE)
then the trigger callback will get called as soon as the other object leaves the trigger volume.
If none of the two collision objects is a trigger shape then the contact report callback will get
called when the actors of this collision pair stop to be in contact.
\note Only takes effect if the colliding actors are rigid bodies.
\note This event will also get triggered if one of the colliding objects gets deleted.
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger()
*/
eNOTIFY_TOUCH_LOST = (1<<4),
/**
\brief Call contact report callback when this collision pair is in contact during CCD passes.
If CCD with multiple passes is enabled, then a fast moving object might bounce on and off the same
object multiple times. Hence, the same pair might be in contact multiple times during a simulation step.
This flag will make sure that all the detected collision during CCD will get reported. For performance
reasons, the system can not always tell whether the contact pair lost touch in one of the previous CCD
passes and thus can also not always tell whether the contact is new or has persisted. eNOTIFY_TOUCH_CCD
just reports when the two collision objects were detected as being in contact during a CCD pass.
\note Only takes effect if the colliding actors are rigid bodies.
\note Trigger shapes are not supported.
\note Only takes effect if eDETECT_CCD_CONTACT is raised
\see PxSimulationEventCallback.onContact() PxSimulationEventCallback.onTrigger()
*/
eNOTIFY_TOUCH_CCD = (1<<5),
/**
\brief Call contact report callback when the contact force between the actors of this collision pair exceeds one of the actor-defined force thresholds.
\note Only takes effect if the colliding actors are rigid bodies.
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\note Only works with PGS solver, and only on CPU.
\see PxSimulationEventCallback.onContact()
*/
eNOTIFY_THRESHOLD_FORCE_FOUND = (1<<6),
/**
\brief Call contact report callback when the contact force between the actors of this collision pair continues to exceed one of the actor-defined force thresholds.
\note Only takes effect if the colliding actors are rigid bodies.
\note If a pair gets re-filtered and this flag has previously been disabled, then the report will not get fired in the same frame even if the force threshold has been reached in the
previous one (unless #eNOTIFY_THRESHOLD_FORCE_FOUND has been set in the previous frame).
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\note Only works with PGS solver, and only on CPU.
\see PxSimulationEventCallback.onContact()
*/
eNOTIFY_THRESHOLD_FORCE_PERSISTS = (1<<7),
/**
\brief Call contact report callback when the contact force between the actors of this collision pair falls below one of the actor-defined force thresholds (includes the case where this collision pair stops being in contact).
\note Only takes effect if the colliding actors are rigid bodies.
\note If a pair gets re-filtered and this flag has previously been disabled, then the report will not get fired in the same frame even if the force threshold has been reached in the
previous one (unless #eNOTIFY_THRESHOLD_FORCE_FOUND or #eNOTIFY_THRESHOLD_FORCE_PERSISTS has been set in the previous frame).
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\note Only works with PGS solver, and only on CPU.
\see PxSimulationEventCallback.onContact()
*/
eNOTIFY_THRESHOLD_FORCE_LOST = (1<<8),
/**
\brief Provide contact points in contact reports for this collision pair.
\note Only takes effect if the colliding actors are rigid bodies and if used in combination with the flags eNOTIFY_TOUCH_... or eNOTIFY_THRESHOLD_FORCE_...
\note Only takes effect if eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT is raised
\see PxSimulationEventCallback.onContact() PxContactPair PxContactPair.extractContacts()
*/
eNOTIFY_CONTACT_POINTS = (1<<9),
/**
\brief This flag is used to indicate whether this pair generates discrete collision detection contacts.
\note Contacts are only responded to if eSOLVE_CONTACT is enabled.
*/
eDETECT_DISCRETE_CONTACT = (1<<10),
/**
\brief This flag is used to indicate whether this pair generates CCD contacts.
\note The contacts will only be responded to if eSOLVE_CONTACT is enabled on this pair.
\note The scene must have PxSceneFlag::eENABLE_CCD enabled to use this feature.
\note Non-static bodies of the pair should have PxRigidBodyFlag::eENABLE_CCD specified for this feature to work correctly.
\note This flag is not supported with trigger shapes. However, CCD trigger events can be emulated using non-trigger shapes
and requesting eNOTIFY_TOUCH_FOUND and eNOTIFY_TOUCH_LOST and not raising eSOLVE_CONTACT on the pair.
\see PxRigidBodyFlag::eENABLE_CCD
\see PxSceneFlag::eENABLE_CCD
*/
eDETECT_CCD_CONTACT = (1<<11),
/**
\brief Provide pre solver velocities in contact reports for this collision pair.
If the collision pair has contact reports enabled, the velocities of the rigid bodies before contacts have been solved
will be provided in the contact report callback unless the pair lost touch in which case no data will be provided.
\note Usually it is not necessary to request these velocities as they will be available by querying the velocity from the provided
PxRigidActor object directly. However, it might be the case that the velocity of a rigid body gets set while the simulation is running
in which case the PxRigidActor would return this new velocity in the contact report callback and not the velocity the simulation used.
\see PxSimulationEventCallback.onContact(), PxContactPairVelocity, PxContactPairHeader.extraDataStream
*/
ePRE_SOLVER_VELOCITY = (1<<12),
/**
\brief Provide post solver velocities in contact reports for this collision pair.
If the collision pair has contact reports enabled, the velocities of the rigid bodies after contacts have been solved
will be provided in the contact report callback unless the pair lost touch in which case no data will be provided.
\see PxSimulationEventCallback.onContact(), PxContactPairVelocity, PxContactPairHeader.extraDataStream
*/
ePOST_SOLVER_VELOCITY = (1<<13),
/**
\brief Provide rigid body poses in contact reports for this collision pair.
If the collision pair has contact reports enabled, the rigid body poses at the contact event will be provided
in the contact report callback unless the pair lost touch in which case no data will be provided.
\note Usually it is not necessary to request these poses as they will be available by querying the pose from the provided
PxRigidActor object directly. However, it might be the case that the pose of a rigid body gets set while the simulation is running
in which case the PxRigidActor would return this new pose in the contact report callback and not the pose the simulation used.
Another use case is related to CCD with multiple passes enabled, A fast moving object might bounce on and off the same
object multiple times. This flag can be used to request the rigid body poses at the time of impact for each such collision event.
\see PxSimulationEventCallback.onContact(), PxContactPairPose, PxContactPairHeader.extraDataStream
*/
eCONTACT_EVENT_POSE = (1<<14),
eNEXT_FREE = (1<<15), //!< For internal use only.
/**
\brief Provided default flag to do simple contact processing for this collision pair.
*/
eCONTACT_DEFAULT = eSOLVE_CONTACT | eDETECT_DISCRETE_CONTACT,
/**
\brief Provided default flag to get commonly used trigger behavior for this collision pair.
*/
eTRIGGER_DEFAULT = eNOTIFY_TOUCH_FOUND | eNOTIFY_TOUCH_LOST | eDETECT_DISCRETE_CONTACT
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxPairFlag.
\see PxPairFlag
*/
typedef PxFlags<PxPairFlag::Enum, PxU16> PxPairFlags;
PX_FLAGS_OPERATORS(PxPairFlag::Enum, PxU16)
/**
\brief Collection of flags describing the filter actions to take for a collision pair.
\see PxFilterFlags PxSimulationFilterShader PxSimulationFilterCallback
*/
struct PxFilterFlag
{
enum Enum
{
/**
\brief Ignore the collision pair as long as the bounding volumes of the pair objects overlap.
Killed pairs will be ignored by the simulation and won't run through the filter again until one
of the following occurs:
\li The bounding volumes of the two objects overlap again (after being separated)
\li The user enforces a re-filtering (see #PxScene::resetFiltering())
\see PxScene::resetFiltering()
*/
eKILL = (1<<0),
/**
\brief Ignore the collision pair as long as the bounding volumes of the pair objects overlap or until filtering relevant data changes for one of the collision objects.
Suppressed pairs will be ignored by the simulation and won't make another filter request until one
of the following occurs:
\li Same conditions as for killed pairs (see #eKILL)
\li The filter data or the filter object attributes change for one of the collision objects
\see PxFilterData PxFilterObjectAttributes
*/
eSUPPRESS = (1<<1),
/**
\brief Invoke the filter callback (#PxSimulationFilterCallback::pairFound()) for this collision pair.
\see PxSimulationFilterCallback
*/
eCALLBACK = (1<<2),
/**
\brief Track this collision pair with the filter callback mechanism.
When the bounding volumes of the collision pair lose contact, the filter callback #PxSimulationFilterCallback::pairLost()
will be invoked. Furthermore, the filter status of the collision pair can be adjusted through #PxSimulationFilterCallback::statusChange()
once per frame (until a pairLost() notification occurs).
\see PxSimulationFilterCallback
*/
eNOTIFY = (1<<3) | eCALLBACK,
/**
\brief Provided default to get standard behavior:
The application configure the pair's collision properties once when bounding volume overlap is found and
doesn't get asked again about that pair until overlap status or filter properties changes, or re-filtering is requested.
No notification is provided when bounding volume overlap is lost
The pair will not be killed or suppressed, so collision detection will be processed
*/
eDEFAULT = 0
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxFilterFlag.
\see PxFilterFlag
*/
typedef PxFlags<PxFilterFlag::Enum, PxU16> PxFilterFlags;
PX_FLAGS_OPERATORS(PxFilterFlag::Enum, PxU16)
/**
\brief PxFilterData is user-definable data which gets passed into the collision filtering shader and/or callback.
\see PxShape.setSimulationFilterData() PxShape.getSimulationFilterData() PxSimulationFilterShader PxSimulationFilterCallback
*/
struct PxFilterData
{
PX_INLINE PxFilterData(const PxEMPTY)
{
}
/**
\brief Default constructor.
*/
PX_INLINE PxFilterData()
{
word0 = word1 = word2 = word3 = 0;
}
/**
\brief Copy constructor.
*/
PX_INLINE PxFilterData(const PxFilterData& fd) : word0(fd.word0), word1(fd.word1), word2(fd.word2), word3(fd.word3) {}
/**
\brief Constructor to set filter data initially.
*/
PX_INLINE PxFilterData(PxU32 w0, PxU32 w1, PxU32 w2, PxU32 w3) : word0(w0), word1(w1), word2(w2), word3(w3) {}
/**
\brief (re)sets the structure to the default.
*/
PX_INLINE void setToDefault()
{
*this = PxFilterData();
}
/**
\brief Assignment operator
*/
PX_INLINE void operator = (const PxFilterData& fd)
{
word0 = fd.word0;
word1 = fd.word1;
word2 = fd.word2;
word3 = fd.word3;
}
/**
\brief Comparison operator to allow use in Array.
*/
PX_INLINE bool operator == (const PxFilterData& a) const
{
return a.word0 == word0 && a.word1 == word1 && a.word2 == word2 && a.word3 == word3;
}
/**
\brief Comparison operator to allow use in Array.
*/
PX_INLINE bool operator != (const PxFilterData& a) const
{
return !(a == *this);
}
PxU32 word0;
PxU32 word1;
PxU32 word2;
PxU32 word3;
};
/**
\brief Identifies each type of filter object.
\see PxGetFilterObjectType()
*/
struct PxFilterObjectType
{
enum Enum
{
/**
\brief A static rigid body
\see PxRigidStatic
*/
eRIGID_STATIC,
/**
\brief A dynamic rigid body
\see PxRigidDynamic
*/
eRIGID_DYNAMIC,
/**
\brief An articulation
\see PxArticulationReducedCoordinate
*/
eARTICULATION,
/**
\brief A deformable surface
\see PxDeformableSurface
*/
eDEFORMABLE_SURFACE,
/**
\brief A deformable volume
\see PxDeformableVolume
*/
eDEFORMABLE_VOLUME,
eSOFTBODY PX_DEPRECATED = eDEFORMABLE_VOLUME, //!< \deprecated
/**
\brief A particle system
\see PxParticleSystem
*/
ePARTICLESYSTEM,
//! \brief internal use only!
eMAX_TYPE_COUNT = 16,
//! \brief internal use only!
eUNDEFINED = eMAX_TYPE_COUNT-1
};
};
// For internal use only
struct PxFilterObjectFlag
{
enum Enum
{
eKINEMATIC = (1<<4),
eTRIGGER = (1<<5),
eCUSTOM_GEOMETRY = (1 << 6),
eNEXT_FREE = (1<<7) // Used internally
};
};
/**
\brief Structure which gets passed into the collision filtering shader and/or callback providing additional information on objects of a collision pair
\see PxSimulationFilterShader PxSimulationFilterCallback getActorType() PxFilterObjectIsKinematic() PxFilterObjectIsTrigger()
*/
typedef PxU32 PxFilterObjectAttributes;
/**
\brief Extract filter object type from the filter attributes of a collision pair object
\param[in] attr The filter attribute of a collision pair object
\return The type of the collision pair object.
\see PxFilterObjectType
*/
PX_INLINE PxFilterObjectType::Enum PxGetFilterObjectType(PxFilterObjectAttributes attr)
{
return PxFilterObjectType::Enum(attr & (PxFilterObjectType::eMAX_TYPE_COUNT-1));
}
/**
\brief Specifies whether the collision object belongs to a kinematic rigid body
\param[in] attr The filter attribute of a collision pair object
\return True if the object belongs to a kinematic rigid body, else false
\see PxRigidBodyFlag::eKINEMATIC
*/
PX_INLINE bool PxFilterObjectIsKinematic(PxFilterObjectAttributes attr)
{
return (attr & PxFilterObjectFlag::eKINEMATIC) != 0;
}
/**
\brief Specifies whether the collision object is a trigger shape
\param[in] attr The filter attribute of a collision pair object
\return True if the object is a trigger shape, else false
\see PxShapeFlag::eTRIGGER_SHAPE
*/
PX_INLINE bool PxFilterObjectIsTrigger(PxFilterObjectAttributes attr)
{
return (attr & PxFilterObjectFlag::eTRIGGER) != 0;
}
/**
\brief Filter method to specify how a pair of potentially colliding objects should be processed.
Collision filtering is a mechanism to specify how a pair of potentially colliding objects should be processed by the
simulation. A pair of objects is potentially colliding if the bounding volumes of the two objects overlap.
In short, a collision filter decides whether a collision pair should get processed, temporarily ignored or discarded.
If a collision pair should get processed, the filter can additionally specify how it should get processed, for instance,
whether contacts should get resolved, which callbacks should get invoked or which reports should be sent etc.
The function returns the PxFilterFlag flags and sets the PxPairFlag flags to define what the simulation should do with the given collision pair.
\note A default implementation of a filter shader is provided in the PhysX extensions library, see #PxDefaultSimulationFilterShader.
This methods gets called when:
\li The bounding volumes of two objects start to overlap.
\li The bounding volumes of two objects overlap and the filter data or filter attributes of one of the objects changed
\li A re-filtering was forced through resetFiltering() (see #PxScene::resetFiltering())
\li Filtering is requested in scene queries
\note Certain pairs of objects are always ignored and this method does not get called. This is the case for the
following pairs:
\li Pair of static rigid actors
\li A static rigid actor and a kinematic actor (unless one is a trigger or if explicitly enabled through PxPairFilteringMode::eKEEP)
\li Two kinematic actors (unless one is a trigger or if explicitly enabled through PxPairFilteringMode::eKEEP)
\li Two jointed rigid bodies and the joint was defined to disable collision
\li Two articulation links if connected through an articulation joint
\note This is a performance critical method and should be stateless. You should neither access external objects
from within this method nor should you call external methods that are not inlined. If you need a more complex
logic to filter a collision pair then use the filter callback mechanism for this pair (see #PxSimulationFilterCallback,
#PxFilterFlag::eCALLBACK, #PxFilterFlag::eNOTIFY).
\param[in] attributes0 The filter attribute of the first object
\param[in] filterData0 The custom filter data of the first object
\param[in] attributes1 The filter attribute of the second object
\param[in] filterData1 The custom filter data of the second object
\param[out] pairFlags Flags giving additional information on how an accepted pair should get processed
\param[in] constantBlock The constant global filter data (see #PxSceneDesc.filterShaderData)
\param[in] constantBlockSize Size of the global filter data (see #PxSceneDesc.filterShaderDataSize)
\return Filter flags defining whether the pair should be discarded, temporarily ignored, processed and whether the
filter callback should get invoked for this pair.
\see PxSimulationFilterCallback PxFilterData PxFilterObjectAttributes PxFilterFlag PxFilterFlags PxPairFlag PxPairFlags PxSceneDesc.filterShader
*/
typedef PxFilterFlags (*PxSimulationFilterShader)
(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize);
/**
\brief Filter callback to specify handling of collision pairs.
This class is provided to implement more complex and flexible collision pair filtering logic, for instance, taking
the state of the user application into account. Filter callbacks also give the user the opportunity to track collision
pairs and update their filter state.
You might want to check the documentation on #PxSimulationFilterShader as well since it includes more general information
on filtering.
\note SDK state should not be modified from within the callbacks. In particular objects should not
be created or destroyed. If state modification is needed then the changes should be stored to a buffer
and performed after the simulation step.
\note The callbacks may execute in user threads or simulation threads, possibly simultaneously. The corresponding objects
may have been deleted by the application earlier in the frame. It is the application's responsibility to prevent race conditions
arising from using the SDK API in the callback while an application thread is making write calls to the scene, and to ensure that
the callbacks are thread-safe. Return values which depend on when the callback is called during the frame will introduce nondeterminism
into the simulation.
\see PxSceneDesc.filterCallback PxSimulationFilterShader
*/
class PxSimulationFilterCallback
{
public:
/**
\brief Filter method to specify how a pair of potentially colliding objects should be processed.
This method gets called when the filter flags returned by the filter shader (see #PxSimulationFilterShader)
indicate that the filter callback should be invoked (#PxFilterFlag::eCALLBACK or #PxFilterFlag::eNOTIFY set).
Return the PxFilterFlag flags and set the PxPairFlag flags to define what the simulation should do with the given
collision pair.
\param[in] pairID Unique ID of the collision pair used to issue filter status changes for the pair (see #statusChange())
\param[in] attributes0 The filter attribute of the first object
\param[in] filterData0 The custom filter data of the first object
\param[in] a0 Actor pointer of the first object
\param[in] s0 Shape pointer of the first object (NULL if the object has no shapes)
\param[in] attributes1 The filter attribute of the second object
\param[in] filterData1 The custom filter data of the second object
\param[in] a1 Actor pointer of the second object
\param[in] s1 Shape pointer of the second object (NULL if the object has no shapes)
\param[in,out] pairFlags In: Pair flags returned by the filter shader. Out: Additional information on how an accepted pair should get processed
\return Filter flags defining whether the pair should be discarded, temporarily ignored or processed and whether the pair
should be tracked and send a report on pair deletion through the filter callback
\see PxSimulationFilterShader PxFilterData PxFilterObjectAttributes PxFilterFlag PxPairFlag
*/
virtual PxFilterFlags pairFound( PxU64 pairID,
PxFilterObjectAttributes attributes0, PxFilterData filterData0, const PxActor* a0, const PxShape* s0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1, const PxActor* a1, const PxShape* s1,
PxPairFlags& pairFlags) = 0;
/**
\brief Callback to inform that a tracked collision pair is gone.
This method gets called when a collision pair disappears or gets re-filtered. Only applies to
collision pairs which have been marked as filter callback pairs (#PxFilterFlag::eNOTIFY set in #pairFound()).
\param[in] pairID Unique ID of the collision pair that disappeared
\param[in] attributes0 The filter attribute of the first object
\param[in] filterData0 The custom filter data of the first object
\param[in] attributes1 The filter attribute of the second object
\param[in] filterData1 The custom filter data of the second object
\param[in] objectRemoved True if the pair was lost because one of the objects got removed from the scene
\see pairFound() PxSimulationFilterShader PxFilterData PxFilterObjectAttributes
*/
virtual void pairLost( PxU64 pairID,
PxFilterObjectAttributes attributes0, PxFilterData filterData0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
bool objectRemoved) = 0;
/**
\brief Callback to give the opportunity to change the filter state of a tracked collision pair.
This method gets called once per simulation step to let the application change the filter and pair
flags of a collision pair that has been reported in #pairFound() and requested callbacks by
setting #PxFilterFlag::eNOTIFY. To request a change of filter status, the target pair has to be
specified by its ID, the new filter and pair flags have to be provided and the method should return true.
\note If this method changes the filter status of a collision pair and the pair should keep being tracked
by the filter callbacks then #PxFilterFlag::eNOTIFY has to be set.
\note The application is responsible to ensure that this method does not get called for pairs that have been
reported as lost, see #pairLost().
\param[out] pairID ID of the collision pair for which the filter status should be changed
\param[out] pairFlags The new pairFlags to apply to the collision pair
\param[out] filterFlags The new filterFlags to apply to the collision pair
\return True if the changes should be applied. In this case the method will get called again. False if
no more status changes should be done in the current simulation step. In that case the provided flags will be discarded.
\see pairFound() pairLost() PxFilterFlag PxPairFlag
*/
virtual bool statusChange(PxU64& pairID, PxPairFlags& pairFlags, PxFilterFlags& filterFlags) = 0;
protected:
virtual ~PxSimulationFilterCallback() {}
};
struct PxPairFilteringMode
{
enum Enum
{
/**
\brief Output pair from BP, potentially send to user callbacks, create regular interaction object.
Enable contact pair filtering between kinematic/static or kinematic/kinematic rigid bodies.
By default contacts between these are suppressed (see #PxFilterFlag::eSUPPRESS) and don't get reported to the filter mechanism.
Use this mode if these pairs should go through the filtering pipeline nonetheless.
\note This mode is not mutable, and must be set in PxSceneDesc at scene creation.
*/
eKEEP,
/**
\brief Output pair from BP, create interaction marker. Can be later switched to regular interaction.
*/
eSUPPRESS,
/**
\brief Don't output pair from BP. Cannot be later switched to regular interaction, needs "resetFiltering" call.
*/
eKILL,
/**
\brief Default is eSUPPRESS for compatibility with previous PhysX versions.
*/
eDEFAULT = eSUPPRESS
};
};
/**
\brief Struct for storing a particle/vertex - rigid filter pair with comparison operators
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
*/
struct PX_DEPRECATED PxParticleRigidFilterPair
{
PX_CUDA_CALLABLE PxParticleRigidFilterPair() {}
PX_CUDA_CALLABLE PxParticleRigidFilterPair(const PxU64 id0, const PxU64 id1): mID0(id0), mID1(id1) {}
PxU64 mID0; //!< Rigid node index
PxU64 mID1; //!< Particle/vertex id
PX_CUDA_CALLABLE bool operator<(const PxParticleRigidFilterPair& other) const
{
if(mID0 < other.mID0)
return true;
if(mID0 == other.mID0 && mID1 < other.mID1)
return true;
return false;
}
PX_CUDA_CALLABLE bool operator>(const PxParticleRigidFilterPair& other) const
{
if(mID0 > other.mID0)
return true;
if(mID0 == other.mID0 && mID1 > other.mID1)
return true;
return false;
}
PX_CUDA_CALLABLE bool operator==(const PxParticleRigidFilterPair& other) const
{
return (mID0 == other.mID0 && mID1 == other.mID1);
}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,60 @@
// 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 PX_FORCE_MODE_H
#define PX_FORCE_MODE_H
#include "foundation/PxPreprocessor.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Parameter to addForce() and addTorque() calls, determines the exact operation that is carried out.
\see PxRigidBody.addForce() PxRigidBody.addTorque()
*/
struct PxForceMode
{
enum Enum
{
eFORCE, //!< parameter has unit of mass * length / time^2, i.e., a force
eIMPULSE, //!< parameter has unit of mass * length / time, i.e., force * time
eVELOCITY_CHANGE, //!< parameter has unit of length / time, i.e., the effect is mass independent: a velocity change.
eACCELERATION //!< parameter has unit of length/ time^2, i.e., an acceleration. It gets treated just like a force except the mass is not divided out before integration.
};
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,740 @@
// 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 PX_IMMEDIATE_MODE_H
#define PX_IMMEDIATE_MODE_H
#include "PxPhysXConfig.h"
#include "foundation/PxMemory.h"
#include "solver/PxSolverDefs.h"
#include "collision/PxCollisionDefs.h"
#include "PxArticulationReducedCoordinate.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxCudaContextManager;
class PxBaseTask;
class PxGeometry;
#if !PX_DOXYGEN
namespace immediate
{
#endif
typedef void* PxArticulationHandle;
/**
\brief Structure to store linear and angular components of spatial vector
*/
struct PxSpatialVector
{
PxVec3 top;
PxReal pad0;
PxVec3 bottom;
PxReal pad1;
};
/**
\brief Structure to store rigid body properties
*/
struct PxRigidBodyData
{
PX_ALIGN(16, PxVec3 linearVelocity); //!< 12 Linear velocity
PxReal invMass; //!< 16 Inverse mass
PxVec3 angularVelocity; //!< 28 Angular velocity
PxReal maxDepenetrationVelocity; //!< 32 Maximum de-penetration velocity
PxVec3 invInertia; //!< 44 Mass-space inverse interia diagonal vector
PxReal maxContactImpulse; //!< 48 Maximum permissable contact impulse
PxTransform body2World; //!< 76 World space transform
PxReal linearDamping; //!< 80 Linear damping coefficient
PxReal angularDamping; //!< 84 Angular damping coefficient
PxReal maxLinearVelocitySq; //!< 88 Squared maximum linear velocity
PxReal maxAngularVelocitySq; //!< 92 Squared maximum angular velocity
PxU32 pad; //!< 96 Padding for 16-byte alignment
};
/**
\brief Callback class to record contact points produced by immediate::PxGenerateContacts
*/
class PxContactRecorder
{
public:
/**
\brief Method to record new contacts
\param [in] contactPoints The contact points produced
\param [in] nbContacts The number of contact points produced
\param [in] index The index of this pair. This is an index from 0-N-1 identifying which pair this relates to from within the array of pairs passed to PxGenerateContacts
\return a boolean to indicate if this callback successfully stored the contacts or not.
*/
virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 index) = 0;
virtual ~PxContactRecorder(){}
};
/**
\brief Constructs a PxSolverBodyData structure based on rigid body properties. Applies gravity, damping and clamps maximum velocity.
\param [in] inRigidData The array rigid body properties
\param [out] outSolverBodyData The array of solverBodyData produced to represent these bodies
\param [in] nbBodies The total number of solver bodies to create
\param [in] gravity The gravity vector
\param [in] dt The timestep
\param [in] gyroscopicForces Indicates whether gyroscopic forces should be integrated
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructSolverBodies(const PxRigidBodyData* inRigidData, PxSolverBodyData* outSolverBodyData, PxU32 nbBodies, const PxVec3& gravity, PxReal dt, bool gyroscopicForces = false);
/**
\brief Constructs a PxSolverBodyData structure for a static body at a given pose.
\param [in] globalPose The pose of this static actor
\param [out] solverBodyData The solver body representation of this static actor
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructStaticSolverBody(const PxTransform& globalPose, PxSolverBodyData& solverBodyData);
/**
\brief Groups together sets of independent PxSolverConstraintDesc objects to be solved using SIMD SOA approach.
\param [in] solverConstraintDescs The set of solver constraint descs to batch
\param [in] nbConstraints The number of constraints to batch
\param [in,out] solverBodies The array of solver bodies that the constraints reference. Some fields in these structures are written to as scratch memory for the batching.
\param [in] nbBodies The number of bodies
\param [out] outBatchHeaders The batch headers produced by this batching process. This array must have at least 1 entry per input constraint
\param [out] outOrderedConstraintDescs A reordered copy of the constraint descs. This array is referenced by the constraint batches. This array must have at least 1 entry per input constraint.
\param [in,out] articulations The array of articulations that the constraints reference. Some fields in these structures are written to as scratch memory for the batching.
\param [in] nbArticulations The number of articulations
\return The total number of batches produced. This should be less than or equal to nbConstraints.
\note This method considers all bodies within the range [0, nbBodies-1] to be valid dynamic bodies. A given dynamic body can only be referenced in a batch once. Static or kinematic bodies can be
referenced multiple times within a batch safely because constraints do not affect their velocities. The batching will implicitly consider any bodies outside of the range [0, nbBodies-1] to be
infinite mass (static or kinematic). This means that either appending static/kinematic to the end of the array of bodies or placing static/kinematic bodies at before the start body pointer
will ensure that the minimum number of batches are produced.
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxU32 PxBatchConstraints( const PxSolverConstraintDesc* solverConstraintDescs, PxU32 nbConstraints, PxSolverBody* solverBodies, PxU32 nbBodies,
PxConstraintBatchHeader* outBatchHeaders, PxSolverConstraintDesc* outOrderedConstraintDescs,
PxArticulationHandle* articulations=NULL, PxU32 nbArticulations=0);
/**
\brief Creates a set of contact constraint blocks. Note that, depending the results of PxBatchConstraints, each batchHeader may refer to up to 4 solverConstraintDescs.
This function will allocate both constraint and friction patch data via the PxConstraintAllocator provided. Constraint data is only valid until PxSolveConstraints has completed.
Friction data is to be retained and provided by the application for friction correlation.
\param [in] batchHeaders Array of batch headers to process
\param [in] nbHeaders The total number of headers
\param [in] contactDescs An array of contact descs defining the pair and contact properties of each respective contacting pair
\param [in] allocator An allocator callback to allocate constraint and friction memory
\param [in] invDt The inverse timestep
\param [in] bounceThreshold The bounce threshold. Relative velocities below this will be solved by bias only. Relative velocities above this will be solved by restitution. If restitution is zero
then these pairs will always be solved by bias.
\param [in] frictionOffsetThreshold The friction offset threshold. Contacts whose separations are below this threshold can generate friction constraints.
\param [in] correlationDistance The correlation distance used by friction correlation to identify whether a friction patch is broken on the grounds of relation separation.
\param [out] Z Temporary buffer for impulse propagation.
\return a boolean to define if this method was successful or not.
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateContactConstraints(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxSolverContactDesc* contactDescs,
PxConstraintAllocator& allocator, PxReal invDt, PxReal bounceThreshold, PxReal frictionOffsetThreshold, PxReal correlationDistance,
PxSpatialVector* Z = NULL);
/**
\brief Creates a set of joint constraint blocks. Note that, depending the results of PxBatchConstraints, the batchHeader may refer to up to 4 solverConstraintDescs
\param [in] batchHeaders The array of batch headers to be processed.
\param [in] nbHeaders The total number of batch headers to process.
\param [in] jointDescs An array of constraint prep descs defining the properties of the constraints being created.
\param [in] allocator An allocator callback to allocate constraint data.
\param [in] dt The timestep.
\param [in] invDt The inverse timestep.
\param [out] Z Deprecated, no longer used. Any value (including NULL) can be passed.
\return a boolean indicating if this method was successful or not.
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraints(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxSolverConstraintPrepDesc* jointDescs,
PxConstraintAllocator& allocator, PxSpatialVector* Z, PxReal dt, PxReal invDt);
/**
\brief Creates a set of joint constraint blocks. This function runs joint shaders defined inside PxConstraint** param, fills in joint row information in jointDescs and then calls PxCreateJointConstraints.
\param [in] batchHeaders The set of batchHeaders to be processed.
\param [in] nbBatchHeaders The number of batch headers to process.
\param [in] constraints The set of constraints to be used to produce constraint rows.
\param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created.
\param [in] allocator An allocator callback to allocate constraint data.
\param [in] dt The timestep.
\param [in] invDt The inverse timestep.
\param [out] Z Temporary buffer for impulse propagation.
\return a boolean indicating if this method was successful or not.
\see PxCreateJointConstraints
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithShaders(PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxConstraint** constraints, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal invDt, PxSpatialVector* Z = NULL);
struct PxImmediateConstraint
{
PxConstraintSolverPrep prep;
const void* constantBlock;
};
/**
\brief Creates a set of joint constraint blocks. This function runs joint shaders defined inside PxImmediateConstraint* param, fills in joint row information in jointDescs and then calls PxCreateJointConstraints.
\param [in] batchHeaders The set of batchHeaders to be processed.
\param [in] nbBatchHeaders The number of batch headers to process.
\param [in] constraints The set of constraints to be used to produce constraint rows.
\param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created.
\param [in] allocator An allocator callback to allocate constraint data.
\param [in] dt The timestep.
\param [in] invDt The inverse timestep.
\param [out] Z Temporary buffer for impulse propagation.
\return a boolean indicating if this method was successful or not.
\see PxCreateJointConstraints
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithImmediateShaders(PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxImmediateConstraint* constraints, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal invDt, PxSpatialVector* Z = NULL);
/**
\brief Iteratively solves the set of constraints defined by the provided PxConstraintBatchHeader and PxSolverConstraintDesc structures. Updates deltaVelocities inside the PxSolverBody structures. Produces resulting linear and angular motion velocities.
\param [in] batchHeaders The set of batch headers to be solved
\param [in] nbBatchHeaders The total number of batch headers to be solved
\param [in] solverConstraintDescs The reordererd set of solver constraint descs referenced by the batch headers
\param [in,out] solverBodies The set of solver bodies the bodies reference
\param [out] linearMotionVelocity The resulting linear motion velocity
\param [out] angularMotionVelocity The resulting angular motion velocity.
\param [in] nbSolverBodies The total number of solver bodies
\param [in] nbPositionIterations The number of position iterations to run
\param [in] nbVelocityIterations The number of velocity iterations to run
\param [in] dt Timestep. Only needed if articulations are sent to the function.
\param [in] invDt Inverse timestep. Only needed if articulations are sent to the function.
\param [in] nbSolverArticulations Number of articulations to solve constraints for.
\param [in] solverArticulations Array of articulations to solve constraints for.
\param [out] Z Deprecated, no longer used. Any value (including NULL) can be passed.
\param [out] deltaV Temporary buffer for velocity change
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxSolveConstraints(const PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs,
const PxSolverBody* solverBodies, PxVec3* linearMotionVelocity, PxVec3* angularMotionVelocity, PxU32 nbSolverBodies, PxU32 nbPositionIterations, PxU32 nbVelocityIterations,
float dt=0.0f, float invDt=0.0f, PxU32 nbSolverArticulations=0, PxArticulationHandle* solverArticulations=NULL, PxSpatialVector* Z = NULL, PxSpatialVector* deltaV = NULL);
/**
\brief Integrates a rigid body, returning the new velocities and transforms. After this function has been called, solverBodyData stores all the body's velocity data.
\param [in,out] solverBodyData The array of solver body data to be integrated
\param [in,out] solverBody The bodies' linear and angular velocities
\param [in,out] linearMotionVelocity The bodies' linear motion velocity array
\param [in,out] angularMotionState The bodies' angular motion velocity array
\param [in] nbBodiesToIntegrate The total number of bodies to integrate
\param [in] dt The timestep
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxIntegrateSolverBodies(PxSolverBodyData* solverBodyData, PxSolverBody* solverBody, PxVec3* linearMotionVelocity, PxVec3* angularMotionState, PxU32 nbBodiesToIntegrate, PxReal dt);
/**
\brief Performs contact generation for a given pair of geometries at the specified poses. Produced contacts are stored in the provided contact recorder. Information is cached in PxCache structure
to accelerate future contact generation between pairs. This cache data is valid only as long as the memory provided by PxCacheAllocator has not been released/re-used. Recommendation is to
retain that data for a single simulation frame, discarding cached data after 2 frames. If the cached memory has been released/re-used prior to the corresponding pair having contact generation
performed again, it is the application's responsibility to reset the PxCache.
\param [in] geom0 Array of geometries to perform collision detection on.
\param [in] geom1 Array of geometries to perform collision detection on
\param [in] pose0 Array of poses associated with the corresponding entry in the geom0 array
\param [in] pose1 Array of poses associated with the corresponding entry in the geom1 array
\param [in,out] contactCache Array of contact caches associated with each pair geom0[i] + geom1[i]
\param [in] nbPairs The total number of pairs to process
\param [out] contactRecorder A callback that is called to record contacts for each pair that detects contacts
\param [in] contactDistance The distance at which contacts begin to be generated between the pairs
\param [in] meshContactMargin The mesh contact margin.
\param [in] toleranceLength The toleranceLength. Used for scaling distance-based thresholds internally to produce appropriate results given simulations in different units
\param [in] allocator A callback to allocate memory for the contact cache
\return a boolean indicating if the function was successful or not.
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxGenerateContacts( const PxGeometry* const * geom0, const PxGeometry* const * geom1, const PxTransform* pose0, const PxTransform* pose1,
PxCache* contactCache, PxU32 nbPairs, PxContactRecorder& contactRecorder,
PxReal contactDistance, PxReal meshContactMargin, PxReal toleranceLength, PxCacheAllocator& allocator);
struct PxArticulationJointDataRC
{
PxTransform parentPose;
PxTransform childPose;
PxArticulationMotion::Enum motion[PxArticulationAxis::eCOUNT];
PxArticulationLimit limits[PxArticulationAxis::eCOUNT];
PxArticulationDrive drives[PxArticulationAxis::eCOUNT];
PxReal targetPos[PxArticulationAxis::eCOUNT];
PxReal targetVel[PxArticulationAxis::eCOUNT];
PxReal armature[PxArticulationAxis::eCOUNT];
PxReal jointPos[PxArticulationAxis::eCOUNT];
PxReal jointVel[PxArticulationAxis::eCOUNT];
PxReal frictionCoefficient;
PxReal maxJointVelocity[PxArticulationAxis::eCOUNT];
PxArticulationJointType::Enum type;
void initData()
{
parentPose = PxTransform(PxIdentity);
childPose = PxTransform(PxIdentity);
frictionCoefficient = 0.05f;
type = PxArticulationJointType::eUNDEFINED; // For root
for(PxU32 i=0;i<PxArticulationAxis::eCOUNT;i++)
{
motion[i] = PxArticulationMotion::eLOCKED;
limits[i] = PxArticulationLimit(0.0f, 0.0f);
drives[i] = PxArticulationDrive(0.0f, 0.0f, 0.0f);
armature[i] = 0.0f;
jointPos[i] = 0.0f;
jointVel[i] = 0.0f;
maxJointVelocity[i] = 100.0f;
}
PxMemSet(targetPos, 0xff, sizeof(PxReal)*PxArticulationAxis::eCOUNT);
PxMemSet(targetVel, 0xff, sizeof(PxReal)*PxArticulationAxis::eCOUNT);
}
};
struct PxArticulationDataRC
{
PxArticulationFlags flags;
};
struct PxArticulationLinkMutableDataRC
{
PxVec3 inverseInertia;
float inverseMass;
float linearDamping;
float angularDamping;
float maxLinearVelocitySq;
float maxAngularVelocitySq;
float cfmScale;
bool disableGravity;
void initData()
{
inverseInertia = PxVec3(1.0f);
inverseMass = 1.0f;
linearDamping = 0.05f;
angularDamping = 0.05f;
maxLinearVelocitySq = 100.0f * 100.0f;
maxAngularVelocitySq = 50.0f * 50.0f;
cfmScale = 0.025f;
disableGravity = false;
}
};
struct PxArticulationLinkDerivedDataRC
{
PxTransform pose;
PxVec3 linearVelocity;
PxVec3 angularVelocity;
};
struct PxArticulationLinkDataRC : PxArticulationLinkMutableDataRC
{
PxArticulationLinkDataRC() { PxArticulationLinkDataRC::initData(); }
void initData()
{
pose = PxTransform(PxIdentity);
PxArticulationLinkMutableDataRC::initData();
inboundJoint.initData();
}
PxArticulationJointDataRC inboundJoint;
PxTransform pose;
};
typedef void* PxArticulationCookie;
struct PxArticulationLinkCookie
{
PxArticulationCookie articulation;
PxU32 linkId;
};
struct PxCreateArticulationLinkCookie : PxArticulationLinkCookie
{
PX_FORCE_INLINE PxCreateArticulationLinkCookie(PxArticulationCookie art=NULL, PxU32 id=0xffffffff)
{
articulation = art;
linkId = id;
}
};
struct PxArticulationLinkHandle
{
PX_FORCE_INLINE PxArticulationLinkHandle(PxArticulationHandle art=NULL, PxU32 id=0xffffffff) : articulation(art), linkId(id) {}
PxArticulationHandle articulation;
PxU32 linkId;
};
/**
\brief Begin creation of an immediate-mode reduced-coordinate articulation.
Returned cookie must be used to add links to the articulation, and to complete creating the articulation.
The cookie is a temporary ID for the articulation, only valid until PxEndCreateArticulationRC is called.
\param [in] data Articulation data
\return Articulation cookie
\see PxAddArticulationLink PxEndCreateArticulationRC
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxArticulationCookie PxBeginCreateArticulationRC(const PxArticulationDataRC& data);
/**
\brief Add a link to the articulation.
All links must be added before the articulation is completed. It is not possible to add a new link at runtime.
Returned cookie is a temporary ID for the link, only valid until PxEndCreateArticulationRC is called.
\param [in] articulation Cookie value returned by PxBeginCreateArticulationRC
\param [in] parent Parent for the new link, or NULL if this is the root link
\param [in] data Link data
\return Link cookie
\see PxBeginCreateArticulationRC PxEndCreateArticulationRC
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxArticulationLinkCookie PxAddArticulationLink(PxArticulationCookie articulation, const PxArticulationLinkCookie* parent, const PxArticulationLinkDataRC& data);
/**
\brief End creation of an immediate-mode reduced-coordinate articulation.
This call completes the creation of the articulation. All involved cookies become unsafe to use after that point.
The links are actually created in this function, and it returns the actual link handles to users. The given buffer should be large enough
to contain as many links as created between the PxBeginCreateArticulationRC & PxEndCreateArticulationRC calls, i.e.
if N calls were made to PxAddArticulationLink, the buffer should be large enough to contain N handles.
\param [in] articulation Cookie value returned by PxBeginCreateArticulationRC
\param [out] linkHandles Articulation link handles of all created articulation links
\param [in] bufferSize Size of linkHandles buffer. Must match internal expected number of articulation links.
\return Articulation handle, or NULL if creation failed
\see PxAddArticulationLink PxEndCreateArticulationRC
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxArticulationHandle PxEndCreateArticulationRC(PxArticulationCookie articulation, PxArticulationLinkHandle* linkHandles, PxU32 bufferSize);
/**
\brief Releases an immediate-mode reduced-coordinate articulation.
\param [in] articulation Articulation handle
\see PxCreateFeatherstoneArticulation
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxReleaseArticulation(PxArticulationHandle articulation);
/**
\brief Creates an articulation cache.
\param [in] articulation Articulation handle
\return Articulation cache
\see PxReleaseArticulationCache
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxArticulationCache* PxCreateArticulationCache(PxArticulationHandle articulation);
/**
\brief Copy the internal data of the articulation to the cache
\param[in] articulation Articulation handle.
\param[in] cache Articulation data
\param[in] flag Indicates which values of the articulation system are copied to the cache
\see createCache PxApplyArticulationCache
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxCopyInternalStateToArticulationCache(PxArticulationHandle articulation, PxArticulationCache& cache, PxArticulationCacheFlags flag);
/**
\brief Apply the user defined data in the cache to the articulation system
\param[in] articulation Articulation handle.
\param[in] cache Articulation data.
\param[in] flag Defines which values in the cache will be applied to the articulation
\see createCache PxCopyInternalStateToArticulationCache
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxApplyArticulationCache(PxArticulationHandle articulation, PxArticulationCache& cache, PxArticulationCacheFlags flag);
/**
\brief Release an articulation cache
\param[in] cache The cache to release
\see PxCreateArticulationCache PxCopyInternalStateToArticulationCache PxCopyInternalStateToArticulationCache
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxReleaseArticulationCache(PxArticulationCache& cache);
/**
\brief Retrieves non-mutable link data from a link handle.
The data here is computed by the articulation code but cannot be directly changed by users.
\param [in] link Link handle
\param [out] data Link data
\return True if success
\see PxGetAllLinkData
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxGetLinkData(const PxArticulationLinkHandle& link, PxArticulationLinkDerivedDataRC& data);
/**
\brief Retrieves non-mutable link data from an articulation handle (all links).
The data here is computed by the articulation code but cannot be directly changed by users.
\param [in] articulation Articulation handle
\param [out] data Link data for N links, or NULL to just retrieve the number of links.
\return Number of links in the articulation = number of link data structure written to the data array.
\see PxGetLinkData
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxU32 PxGetAllLinkData(const PxArticulationHandle articulation, PxArticulationLinkDerivedDataRC* data);
/**
\brief Retrieves mutable link data from a link handle.
\param [in] link Link handle
\param [out] data Data for this link
\return True if success
\see PxSetMutableLinkData
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxGetMutableLinkData(const PxArticulationLinkHandle& link, PxArticulationLinkMutableDataRC& data);
/**
\brief Sets mutable link data for given link.
\param [in] link Link handle
\param [in] data Data for this link
\return True if success
\see PxGetMutableLinkData
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxSetMutableLinkData(const PxArticulationLinkHandle& link, const PxArticulationLinkMutableDataRC& data);
/**
\brief Retrieves joint data from a link handle.
\param [in] link Link handle
\param [out] data Joint data for this link
\return True if success
\see PxSetJointData
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxGetJointData(const PxArticulationLinkHandle& link, PxArticulationJointDataRC& data);
/**
\brief Sets joint data for given link.
\param [in] link Link handle
\param [in] data Joint data for this link
\return True if success
\see PxGetJointData
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxSetJointData(const PxArticulationLinkHandle& link, const PxArticulationJointDataRC& data);
/**
\brief Computes unconstrained velocities for a given articulation.
\param [in] articulation Articulation handle
\param [in] gravity Gravity vector
\param [in] dt Timestep
\param [in] invLengthScale 1/lengthScale from PxTolerancesScale.
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxComputeUnconstrainedVelocities(PxArticulationHandle articulation, const PxVec3& gravity, PxReal dt, PxReal invLengthScale);
/**
\brief Updates bodies for a given articulation.
\param [in] articulation Articulation handle
\param [in] dt Timestep
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxUpdateArticulationBodies(PxArticulationHandle articulation, PxReal dt);
/**
\brief Computes unconstrained velocities for a given articulation.
\param [in] articulation Articulation handle
\param [in] gravity Gravity vector
\param [in] dt Timestep/numPosIterations
\param [in] totalDt Timestep
\param [in] invDt 1/(Timestep/numPosIterations)
\param [in] invTotalDt 1/Timestep
\param [in] invLengthScale 1/lengthScale from PxTolerancesScale.
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxComputeUnconstrainedVelocitiesTGS( PxArticulationHandle articulation, const PxVec3& gravity, PxReal dt,
PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal invLengthScale);
/**
\brief Updates bodies for a given articulation.
\param [in] articulation Articulation handle
\param [in] dt Timestep
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxUpdateArticulationBodiesTGS(PxArticulationHandle articulation, PxReal dt);
/**
\brief Constructs a PxSolverBodyData structure based on rigid body properties. Applies gravity, damping and clamps maximum velocity.
\param [in] inRigidData The array rigid body properties
\param [out] outSolverBodyVel The array of PxTGSSolverBodyVel structures produced to represent these bodies
\param [out] outSolverBodyTxInertia The array of PxTGSSolverBodyTxInertia produced to represent these bodies
\param [out] outSolverBodyData The array of PxTGSolverBodyData produced to represent these bodies
\param [in] nbBodies The total number of solver bodies to create
\param [in] gravity The gravity vector
\param [in] dt The timestep
\param [in] gyroscopicForces Indicates whether gyroscopic forces should be integrated
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructSolverBodiesTGS(const PxRigidBodyData* inRigidData, PxTGSSolverBodyVel* outSolverBodyVel, PxTGSSolverBodyTxInertia* outSolverBodyTxInertia, PxTGSSolverBodyData* outSolverBodyData, PxU32 nbBodies, const PxVec3& gravity, PxReal dt, bool gyroscopicForces = false);
/**
\brief Constructs a PxSolverBodyData structure for a static body at a given pose.
\param [in] globalPose The pose of this static actor
\param [out] solverBodyVel The velocity component of this body (will be zero)
\param [out] solverBodyTxInertia The intertia and transform delta component of this body (will be zero)
\param [out] solverBodyData The solver body representation of this static actor
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructStaticSolverBodyTGS(const PxTransform& globalPose, PxTGSSolverBodyVel& solverBodyVel, PxTGSSolverBodyTxInertia& solverBodyTxInertia, PxTGSSolverBodyData& solverBodyData);
/**
\brief Groups together sets of independent PxSolverConstraintDesc objects to be solved using SIMD SOA approach.
\param [in] solverConstraintDescs The set of solver constraint descs to batch
\param [in] nbConstraints The number of constraints to batch
\param [in,out] solverBodies The array of solver bodies that the constraints reference. Some fields in these structures are written to as scratch memory for the batching.
\param [in] nbBodies The number of bodies
\param [out] outBatchHeaders The batch headers produced by this batching process. This array must have at least 1 entry per input constraint
\param [out] outOrderedConstraintDescs A reordered copy of the constraint descs. This array is referenced by the constraint batches. This array must have at least 1 entry per input constraint.
\param [in,out] articulations The array of articulations that the constraints reference. Some fields in these structures are written to as scratch memory for the batching.
\param [in] nbArticulations The number of articulations
\return The total number of batches produced. This should be less than or equal to nbConstraints.
\note This method considers all bodies within the range [0, nbBodies-1] to be valid dynamic bodies. A given dynamic body can only be referenced in a batch once. Static or kinematic bodies can be
referenced multiple times within a batch safely because constraints do not affect their velocities. The batching will implicitly consider any bodies outside of the range [0, nbBodies-1] to be
infinite mass (static or kinematic). This means that either appending static/kinematic to the end of the array of bodies or placing static/kinematic bodies at before the start body pointer
will ensure that the minimum number of batches are produced.
*/
PX_C_EXPORT PX_PHYSX_CORE_API PxU32 PxBatchConstraintsTGS( const PxSolverConstraintDesc* solverConstraintDescs, PxU32 nbConstraints, PxTGSSolverBodyVel* solverBodies, PxU32 nbBodies,
PxConstraintBatchHeader* outBatchHeaders, PxSolverConstraintDesc* outOrderedConstraintDescs,
PxArticulationHandle* articulations = NULL, PxU32 nbArticulations = 0);
/**
\brief Creates a set of contact constraint blocks. Note that, depending the results of PxBatchConstraints, each batchHeader may refer to up to 4 solverConstraintDescs.
This function will allocate both constraint and friction patch data via the PxConstraintAllocator provided. Constraint data is only valid until PxSolveConstraints has completed.
Friction data is to be retained and provided by the application for friction correlation.
\param [in] batchHeaders Array of batch headers to process
\param [in] nbHeaders The total number of headers
\param [in] contactDescs An array of contact descs defining the pair and contact properties of each respective contacting pair
\param [in] allocator An allocator callback to allocate constraint and friction memory
\param [in] invDt The inverse timestep/nbPositionIterations
\param [in] invTotalDt The inverse time-step
\param [in] bounceThreshold The bounce threshold. Relative velocities below this will be solved by bias only. Relative velocities above this will be solved by restitution. If restitution is zero
then these pairs will always be solved by bias.
\param [in] frictionOffsetThreshold The friction offset threshold. Contacts whose separations are below this threshold can generate friction constraints.
\param [in] correlationDistance The correlation distance used by friction correlation to identify whether a friction patch is broken on the grounds of relation separation.
\return a boolean to define if this method was successful or not.
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateContactConstraintsTGS( PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxTGSSolverContactDesc* contactDescs,
PxConstraintAllocator& allocator, PxReal invDt, PxReal invTotalDt, PxReal bounceThreshold,
PxReal frictionOffsetThreshold, PxReal correlationDistance);
/**
\brief Creates a set of joint constraint blocks. Note that, depending the results of PxBatchConstraints, the batchHeader may refer to up to 4 solverConstraintDescs
\param [in] batchHeaders The array of batch headers to be processed
\param [in] nbHeaders The total number of batch headers to process
\param [in] jointDescs An array of constraint prep descs defining the properties of the constraints being created
\param [in] allocator An allocator callback to allocate constraint data
\param [in] dt The total time-step/nbPositionIterations
\param [in] totalDt The total time-step
\param [in] invDt The inverse (timestep/nbPositionIterations)
\param [in] invTotalDt The inverse total time-step
\param [in] lengthScale PxToleranceScale::length, i.e. a meter in simulation units
\return a boolean indicating if this method was successful or not.
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsTGS( PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders,
PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt,
PxReal invTotalDt, PxReal lengthScale);
/**
\brief Creates a set of joint constraint blocks. This function runs joint shaders defined inside PxConstraint** param, fills in joint row information in jointDescs and then calls PxCreateJointConstraints.
\param [in] batchHeaders The set of batchHeaders to be processed
\param [in] nbBatchHeaders The number of batch headers to process.
\param [in] constraints The set of constraints to be used to produce constraint rows
\param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created
\param [in] allocator An allocator callback to allocate constraint data
\param [in] dt The total time-step/nbPositionIterations
\param [in] totalDt The total time-step
\param [in] invDt The inverse (timestep/nbPositionIterations)
\param [in] invTotalDt The inverse total time-step
\param [in] lengthScale PxToleranceScale::length, i.e. a meter in simulation units
\return a boolean indicating if this method was successful or not.
\see PxCreateJointConstraints
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithShadersTGS( PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxConstraint** constraints, PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator,
PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal lengthScale);
/**
\brief Creates a set of joint constraint blocks. This function runs joint shaders defined inside PxImmediateConstraint* param, fills in joint row information in jointDescs and then calls PxCreateJointConstraints.
\param [in] batchHeaders The set of batchHeaders to be processed
\param [in] nbBatchHeaders The number of batch headers to process.
\param [in] constraints The set of constraints to be used to produce constraint rows
\param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created
\param [in] allocator An allocator callback to allocate constraint data
\param [in] dt The total time-step/nbPositionIterations
\param [in] totalDt The total time-step
\param [in] invDt The inverse (timestep/nbPositionIterations)
\param [in] invTotalDt The inverse total time-step
\param [in] lengthScale PxToleranceScale::length, i.e. a meter in simulation units
\return a boolean indicating if this method was successful or not.
\see PxCreateJointConstraints
*/
PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithImmediateShadersTGS(PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxImmediateConstraint* constraints, PxTGSSolverConstraintPrepDesc* jointDescs,
PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal lengthScale);
/**
\brief Iteratively solves the set of constraints defined by the provided PxConstraintBatchHeader and PxSolverConstraintDesc structures. Updates deltaVelocities inside the PxSolverBody structures. Produces resulting linear and angular motion velocities.
\param [in] batchHeaders The set of batch headers to be solved
\param [in] nbBatchHeaders The total number of batch headers to be solved
\param [in] solverConstraintDescs The reordererd set of solver constraint descs referenced by the batch headers
\param [in,out] solverBodies The set of solver bodies the bodies reference
\param [in,out] txInertias The set of solver body TxInertias the bodies reference
\param [in] nbSolverBodies The total number of solver bodies
\param [in] nbPositionIterations The number of position iterations to run
\param [in] nbVelocityIterations The number of velocity iterations to run
\param [in] dt time-step/nbPositionIterations
\param [in] invDt 1/(time-step/nbPositionIterations)
\param [in] nbSolverArticulations Number of articulations to solve constraints for.
\param [in] solverArticulations Array of articulations to solve constraints for.
\param [out] Z Deprecated, no longer used. Any value (including NULL) can be passed.
\param [out] deltaV Temporary buffer for velocity change (only if articulations are used, size should be at least as large as the maximum number of links in any articulations being simulated)
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxSolveConstraintsTGS( const PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs,
PxTGSSolverBodyVel* solverBodies, PxTGSSolverBodyTxInertia* txInertias, PxU32 nbSolverBodies, PxU32 nbPositionIterations, PxU32 nbVelocityIterations,
float dt, float invDt, PxU32 nbSolverArticulations = 0, PxArticulationHandle* solverArticulations = NULL, PxSpatialVector* Z = NULL, PxSpatialVector* deltaV = NULL);
/**
\brief Integrates a rigid body, returning the new velocities and transforms. After this function has been called, solverBody stores all the body's velocity data.
\param [in,out] solverBody The array of solver bodies to be integrated
\param [in] txInertia The delta pose and inertia terms
\param [in,out] poses The original poses of the bodies. Updated to be the new poses of the bodies
\param [in] nbBodiesToIntegrate The total number of bodies to integrate
\param [in] dt The timestep
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PxIntegrateSolverBodiesTGS(PxTGSSolverBodyVel* solverBody, const PxTGSSolverBodyTxInertia* txInertia, PxTransform* poses, PxU32 nbBodiesToIntegrate, PxReal dt);
#if !PX_DOXYGEN
}
#endif
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,348 @@
// 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 PX_ISOSURFACE_EXTRACTION_H
#define PX_ISOSURFACE_EXTRACTION_H
#include "cudamanager/PxCudaContext.h"
#include "cudamanager/PxCudaContextManager.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#include "PxParticleSystem.h"
#include "PxSparseGridParams.h"
#include "foundation/PxArray.h"
#include "PxParticleGpu.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_SUPPORT_GPU_PHYSX
/**
\brief Identifies filter type to be applied on the isosurface grid.
*/
struct PxIsosurfaceGridFilteringType
{
enum Enum
{
eNONE = 0, //!< No filtering
eSMOOTH = 1, //!< Gaussian-blur-like filtering
eGROW = 2, //!< A dilate/erode operation will be applied that makes the fluid grow approximately one cell size
eSHRINK = 3 //!< A dilate/erode operation will be applied that makes the fluid shrink approximately one cell size
};
};
/**
\brief Parameters to define the isosurface extraction settings like isosurface level, filtering etc.
*/
struct PxIsosurfaceParams
{
/**
\brief Default constructor.
*/
PX_INLINE PxIsosurfaceParams()
{
particleCenterToIsosurfaceDistance = 0.2f;
numMeshSmoothingPasses = 4;
numMeshNormalSmoothingPasses = 4;
gridFilteringFlags = 0;
gridSmoothingRadius = 0.2f;
}
/**
\brief Clears the filtering operations
*/
PX_INLINE void clearFilteringPasses()
{
gridFilteringFlags = 0;
}
/**
\brief Adds a smoothing pass after the existing ones
At most 32 smoothing passes can be defined. Every pass can repeat itself up to 4 times.
\param[in] operation The smoothing operation to add
\return The index of the smoothing pass that was added
*/
PX_INLINE PxU64 addGridFilteringPass(PxIsosurfaceGridFilteringType::Enum operation)
{
for (PxU32 i = 0; i < 32; ++i)
{
PxIsosurfaceGridFilteringType::Enum o;
if (!getGridFilteringPass(i, o))
{
setGridFilteringPass(i, operation);
return i;
}
}
return 0xFFFFFFFFFFFFFFFF;
}
/**
\brief Sets the operation of a smoothing pass
\param[in] passIndex The index of the smoothing pass whose operation should be set <b>Range:</b> [0, 31]
\param[in] operation The operation the modified smoothing will perform
*/
PX_INLINE void setGridFilteringPass(PxU32 passIndex, PxIsosurfaceGridFilteringType::Enum operation)
{
PX_ASSERT(passIndex < 32u);
PxU32 shift = passIndex * 2;
gridFilteringFlags &= ~(PxU64(3) << shift);
gridFilteringFlags |= PxU64(operation) << shift;
}
/**
\brief Returns the operation of a smoothing pass
\param[in] passIndex The index of the smoothing pass whose operation is requested <b>Range:</b> [0, 31]
\param[out] operation The operation the requested smoothing pass will perform
\return true if the requested pass performs an operation
*/
PX_INLINE bool getGridFilteringPass(PxU32 passIndex, PxIsosurfaceGridFilteringType::Enum& operation) const
{
PxU32 shift = passIndex * 2;
PxU64 v = gridFilteringFlags >> shift;
v &= 3; //Extract last 2 bits
operation = PxIsosurfaceGridFilteringType::Enum(v);
return operation != PxIsosurfaceGridFilteringType::eNONE;
}
PxReal particleCenterToIsosurfaceDistance; //!< Distance form a particle center to the isosurface
PxU32 numMeshSmoothingPasses; //!< Number of Taubin mesh postprocessing smoothing passes. Using an even number of passes lead to less shrinking.
PxU32 numMeshNormalSmoothingPasses; //!< Number of mesh normal postprocessing smoothing passes.
PxU64 gridFilteringFlags; //!< Encodes the smoothing steps to apply on the sparse grid. Use setGridSmoothingPass method to set up.
PxReal gridSmoothingRadius; //!< Gaussian blur smoothing kernel radius used for smoothing operations on the grid
};
/**
\brief Base class for isosurface extractors. Allows to register the data arrays for the isosurface and to obtain the number vertices/triangles in use.
*/
class PxIsosurfaceExtractor
{
public:
/**
\brief Returns the isosurface parameters.
\return The isosurfacesettings used for the isosurface extraction
*/
virtual PxIsosurfaceParams getIsosurfaceParams() const = 0;
/**
\brief Set the isosurface extraction parameters
Allows to configure the isosurface extraction by controlling threshold value, smoothing options etc.
\param[in] params A collection of settings to control the isosurface extraction
*/
virtual void setIsosurfaceParams(const PxIsosurfaceParams& params) = 0;
/**
\brief Returns the number of vertices that the current isosurface triangle mesh uses
\return The number of vertices currently in use
*/
virtual PxU32 getNumVertices() const = 0;
/**
\brief Returns the number of triangles that the current isosurface triangle mesh uses
\return The number of triangles currently in use
*/
virtual PxU32 getNumTriangles() const = 0;
/**
\brief Returns the maximum number of vertices that the isosurface triangle mesh can contain
\return The maximum number of vertices that can be genrated
*/
virtual PxU32 getMaxVertices() const = 0;
/**
\brief Returns the maximum number of triangles that the isosurface triangle mesh can contain
\return The maximum number of triangles that can be generated
*/
virtual PxU32 getMaxTriangles() const = 0;
/**
\brief Resizes the internal triangle mesh buffers.
If the output buffers are device buffers, nothing will get resized but new output buffers can be set using setResultBufferDevice.
For host side output buffers, temporary buffers will get resized. The new host side result buffers with the same size must be set using setResultBufferHost.
\param[in] maxNumVertices The maximum number of vertices the output buffer can hold
\param[in] maxNumTriangles The maximum number of triangles the ouput buffer can hold
*/
virtual void setMaxVerticesAndTriangles(PxU32 maxNumVertices, PxU32 maxNumTriangles) = 0;
/**
\brief The maximal number of particles the isosurface extractor can process
\return The maximal number of particles
*/
virtual PxU32 getMaxParticles() const = 0;
/**
\brief Sets the maximal number of particles the isosurface extractor can process
\param[in] maxParticles The maximal number of particles
*/
virtual void setMaxParticles(PxU32 maxParticles) = 0;
/**
\brief Releases the isosurface extractor instance and its data
*/
virtual void release() = 0;
/**
\brief Triggers the compuation of a new isosurface based on the specified particle locations
\param[in] deviceParticlePos A gpu pointer pointing to the start of the particle array
\param[in] numParticles The number of particles
\param[in] stream The stream on which all the gpu work will be performed
\param[in] phases A phase value per particle
\param[in] validPhaseMask A mask that specifies which phases should contribute to the isosurface. If the binary and operation
between this mask and the particle phase is non zero, then the particle will contribute to the isosurface
\param[in] activeIndices Optional array with indices of all active particles
\param[in] anisotropy1 Optional anisotropy information, x axis direction (xyz) and scale in w component
\param[in] anisotropy2 Optional anisotropy information, y axis direction (xyz) and scale in w component
\param[in] anisotropy3 Optional anisotropy information, z axis direction (xyz) and scale in w component
\param[in] anisotropyFactor A factor to multiply with the anisotropy scale
*/
virtual void extractIsosurface(PxVec4* deviceParticlePos, const PxU32 numParticles, CUstream stream, PxU32* phases = NULL, PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid,
PxU32* activeIndices = NULL, PxVec4* anisotropy1 = NULL, PxVec4* anisotropy2 = NULL, PxVec4* anisotropy3 = NULL, PxReal anisotropyFactor = 1.0f) = 0;
/**
\brief Allows to register the host buffers into which the final isosurface triangle mesh will get stored
\param[in] vertices A host buffer to store the vertices of the isosurface mesh
\param[in] triIndices A host buffer to store the triangles of the isosurface mesh
\param[in] normals A host buffer to store the normals of the isosurface mesh
*/
virtual void setResultBufferHost(PxVec4* vertices, PxU32* triIndices, PxVec4* normals = NULL) = 0;
/**
\brief Allows to register the host buffers into which the final isosurface triangle mesh will get stored
\param[in] vertices A device buffer to store the vertices of the isosurface mesh
\param[in] triIndices A device buffer to store the triangles of the isosurface mesh
\param[in] normals A device buffer to store the normals of the isosurface mesh
*/
virtual void setResultBufferDevice(PxVec4* vertices, PxU32* triIndices, PxVec4* normals) = 0;
/**
\brief Enables or disables the isosurface extractor
\param[in] enabled The boolean to set the extractor to enabled or disabled
*/
virtual void setEnabled(bool enabled) = 0;
/**
\brief Allows to query if the isosurface extractor is enabled
\return True if enabled, false otherwise
*/
virtual bool isEnabled() const = 0;
/**
\brief Destructor
*/
virtual ~PxIsosurfaceExtractor() {}
};
/**
\brief Base class for sparse grid based isosurface extractors. Allows to register the data arrays for the isosurface and to obtain the number vertices/triangles in use.
*/
class PxSparseGridIsosurfaceExtractor : public PxIsosurfaceExtractor
{
/**
\brief Returns the sparse grid parameters.
\return The sparse grid settings used for the isosurface extraction
*/
virtual PxSparseGridParams getSparseGridParams() const = 0;
/**
\brief Set the sparse grid parameters
Allows to configure cell size, number of subgrids etc.
\param[in] params A collection of settings to control the isosurface grid
*/
virtual void setSparseGridParams(const PxSparseGridParams& params) = 0;
};
/**
\brief Default implementation of a particle system callback to trigger the isosurface extraction. A call to fetchResultsParticleSystem() on the
PxScene will synchronize the work such that the caller knows that the post solve task completed.
*/
class PxIsosurfaceCallback : public PxParticleSystemCallback
{
public:
/**
\brief Initializes the isosurface callback
\param[in] isosurfaceExtractor The isosurface extractor
\param[in] validPhaseMask The valid phase mask marking the phase bits that particles must have set in order to contribute to the isosurface
*/
void initialize(PxIsosurfaceExtractor* isosurfaceExtractor, PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid)
{
mIsosurfaceExtractor = isosurfaceExtractor;
mValidPhaseMask = validPhaseMask;
}
virtual void onPostSolve(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream)
{
mIsosurfaceExtractor->extractIsosurface(reinterpret_cast<PxVec4*>(gpuParticleSystem.mHostPtr->mUnsortedPositions_InvMass),
gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream, gpuParticleSystem.mHostPtr->mUnsortedPhaseArray, mValidPhaseMask);
}
virtual void onBegin(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
virtual void onAdvance(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
private:
PxIsosurfaceExtractor* mIsosurfaceExtractor;
PxU32 mValidPhaseMask;
};
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,87 @@
// 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 PX_LOCKED_DATA_H
#define PX_LOCKED_DATA_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
struct PxDataAccessFlag
{
enum Enum
{
eREADABLE = (1 << 0),
eWRITABLE = (1 << 1),
eDEVICE = (1 << 2)
};
};
/**
\brief collection of set bits defined in PxDataAccessFlag.
\see PxDataAccessFlag
*/
typedef PxFlags<PxDataAccessFlag::Enum,PxU8> PxDataAccessFlags;
PX_FLAGS_OPERATORS(PxDataAccessFlag::Enum,PxU8)
/**
\brief Parent class for bulk data that is shared between the SDK and the application.
*/
class PxLockedData
{
public:
/**
\brief Any combination of PxDataAccessFlag::eREADABLE and PxDataAccessFlag::eWRITABLE
\see PxDataAccessFlag
*/
virtual PxDataAccessFlags getDataAccessFlags() = 0;
/**
\brief Unlocks the bulk data.
*/
virtual void unlock() = 0;
/**
\brief virtual destructor
*/
virtual ~PxLockedData() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,372 @@
// 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 PX_MATERIAL_H
#define PX_MATERIAL_H
#include "PxBaseMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxScene;
/**
\brief Flags which control the behavior of a material.
\see PxMaterial
*/
struct PxMaterialFlag
{
enum Enum
{
/**
\brief If this flag is set, friction computations are always skipped between shapes with this material and any other shape.
*/
eDISABLE_FRICTION = 1 << 0,
/**
\brief Whether to use strong friction.
The difference between "normal" and "strong" friction is that the strong friction feature
remembers the "friction error" between simulation steps. The friction is a force trying to
hold objects in place (or slow them down) and this is handled in the solver. But since the
solver is only an approximation, the result of the friction calculation can include a small
"error" - e.g. a box resting on a slope should not move at all if the static friction is in
action, but could slowly glide down the slope because of a small friction error in each
simulation step. The strong friction counter-acts this by remembering the small error and
taking it to account during the next simulation step.
However, in some cases the strong friction could cause problems, and this is why it is
possible to disable the strong friction feature by setting this flag. One example is
raycast vehicles that are sliding fast across the surface, but still need a precise
steering behavior. It may be a good idea to reenable the strong friction when objects
are coming to a rest, to prevent them from slowly creeping down inclines.
Note: This flag only has an effect if the PxMaterialFlag::eDISABLE_FRICTION bit is 0.
*/
eDISABLE_STRONG_FRICTION = 1 << 1,
/**
\brief If this flag is raised in combination with negative restitution, the computed spring-damper output will be interpreted as
acceleration instead of force targets, analog to acceleration spring constraints.
The flag has no effect for non-compliant contacts (i.e., if restitution is nonnegative).
In an interaction between a compliant-force and a compliant-acceleration body the latter will dominate.
\see PxMaterial.setRestitution, PxMaterial.setDamping
\see Px1DConstraintFlag.eACCELERATION_SPRING
*/
eCOMPLIANT_ACCELERATION_SPRING = 1 << 4
};
};
/**
\brief collection of set bits defined in PxMaterialFlag.
\see PxMaterialFlag
*/
typedef PxFlags<PxMaterialFlag::Enum,PxU16> PxMaterialFlags;
PX_FLAGS_OPERATORS(PxMaterialFlag::Enum,PxU16)
/**
\brief Enumeration that determines the way in which two material properties will be combined to yield a friction or restitution coefficient for a collision.
When two actors come in contact with each other, they each have materials with various coefficients, but we only need a single set of coefficients for the pair.
Physics doesn't have any inherent combinations because the coefficients are determined empirically on a case by case
basis. However, simulating this with a pairwise lookup table is often impractical.
For this reason the following combine behaviors are available:
eAVERAGE
eMIN
eMULTIPLY
eMAX
The effective combine mode for the pair is maximum(material0.combineMode, material1.combineMode).
Notes that the restitution coefficient is overloaded if it is negative and represents a spring stiffness for compliant contacts. In the compliant contact case, the following rules apply:
* If a compliant (restitution < 0) material interacts with a rigid (restitution >= 0) material, the compliant behavior will be chosen independent
of combine mode. In all other cases (i.e., also for compliant-compliant interactions) the combine mode is used.
* For a compliant-compliant interaction with eMULTIPLY combine mode, we multiply the values but keep the sign negative.
* The material damping follows the same logic, i.e., for the compliant vs non-compliant case, we take the damping value of the compliant material. Otherwise the combine mode is respected.
* In an interaction between a compliant-force and a compliant-acceleration body the latter will dominate and exclusively determine the collision behavior with its parameters.
\see PxMaterial.setFrictionCombineMode() PxMaterial.getFrictionCombineMode() PxMaterial.setRestitutionCombineMode() PxMaterial.getFrictionCombineMode()
*/
struct PxCombineMode
{
enum Enum
{
eAVERAGE = 0, //!< Average: (a + b)/2
eMIN = 1, //!< Minimum: minimum(a,b)
eMULTIPLY = 2, //!< Multiply: a*b
eMAX = 3, //!< Maximum: maximum(a,b)
eN_VALUES = 4, //!< This is not a valid combine mode, it is a sentinel to denote the number of possible values. We assert that the variable's value is smaller than this.
ePAD_32 = 0x7fffffff //!< This is not a valid combine mode, it is to assure that the size of the enum type is big enough.
};
};
/**
\brief Material class to represent a set of surface properties.
\see PxPhysics.createMaterial
*/
class PxMaterial : public PxBaseMaterial
{
public:
/**
\brief Sets the coefficient of dynamic friction.
The coefficient of dynamic friction should be in [0, PX_MAX_F32). If set to greater than staticFriction, the effective value of staticFriction will be increased to match.
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] coef Coefficient of dynamic friction. <b>Range:</b> [0, PX_MAX_F32)
\see getDynamicFriction()
*/
virtual void setDynamicFriction(PxReal coef) = 0;
/**
\brief Retrieves the DynamicFriction value.
\return The coefficient of dynamic friction.
\see setDynamicFriction
*/
virtual PxReal getDynamicFriction() const = 0;
/**
\brief Sets the coefficient of static friction
The coefficient of static friction should be in the range [0, PX_MAX_F32)
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] coef Coefficient of static friction. <b>Range:</b> [0, PX_MAX_F32)
\see getStaticFriction()
*/
virtual void setStaticFriction(PxReal coef) = 0;
/**
\brief Retrieves the coefficient of static friction.
\return The coefficient of static friction.
\see setStaticFriction
*/
virtual PxReal getStaticFriction() const = 0;
/**
\brief Sets the coefficient of restitution or the spring stiffness for compliant contact
A coefficient of 0 makes the object bounce as little as possible, higher values up to 1.0 result in more bounce.
If a negative value is provided it is interpreted as stiffness term for an implicit spring
simulated at the contact site, with the spring positional error defined by
the contact separation value. Higher stiffness terms produce stiffer springs that behave more like a rigid contact.
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] rest Coefficient of restitution / negative spring stiffness <b>Range:</b> (-INF,1]
\see getRestitution() setDamping()
*/
virtual void setRestitution(PxReal rest) = 0;
/**
\brief Retrieves the coefficient of restitution.
See #setRestitution.
\return The coefficient of restitution.
\see setRestitution()
*/
virtual PxReal getRestitution() const = 0;
/**
\brief Sets the coefficient of damping
This property only affects the simulation if compliant contact mode is enabled, i.e., a negative restitution value is set.
Damping works together with spring stiffness. Spring stiffness corrects positional error while
damping resists relative velocity. Setting a high damping coefficient can produce spongy contacts.
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] damping Coefficient of damping. <b>Range:</b> [0,INF)
\see getDamping()
*/
virtual void setDamping(PxReal damping) = 0;
/**
\brief Retrieves the coefficient of damping.
See #setDamping.
\return The coefficient of damping.
\see setDamping()
*/
virtual PxReal getDamping() const = 0;
/**
\brief Raises or clears a particular material flag.
See the list of flags #PxMaterialFlag
<b>Default:</b> No flag raised.
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] flag The PxMaterial flag to raise(set) or clear.
\param[in] b New state of the flag
\see getFlags() setFlags() PxMaterialFlag
*/
virtual void setFlag(PxMaterialFlag::Enum flag, bool b) = 0;
/**
\brief sets all the material flags.
See the list of flags #PxMaterialFlag
<b>Default:</b> No flag raised.
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] flags All PxMaterial flags
\see getFlags() setFlag() PxMaterialFlag
*/
virtual void setFlags(PxMaterialFlags flags) = 0;
/**
\brief Retrieves the flags. See #PxMaterialFlag.
\return The material flags.
\see PxMaterialFlag setFlags()
*/
virtual PxMaterialFlags getFlags() const = 0;
/**
\brief Sets the friction combine mode.
See the enum ::PxCombineMode .
<b>Default:</b> PxCombineMode::eAVERAGE
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] combMode Friction combine mode to set for this material. See #PxCombineMode.
\see PxCombineMode getFrictionCombineMode setStaticFriction() setDynamicFriction()
*/
virtual void setFrictionCombineMode(PxCombineMode::Enum combMode) = 0;
/**
\brief Retrieves the friction combine mode.
See #setFrictionCombineMode.
\return The friction combine mode for this material.
\see PxCombineMode setFrictionCombineMode()
*/
virtual PxCombineMode::Enum getFrictionCombineMode() const = 0;
/**
\brief Sets the restitution combine mode.
See the enum ::PxCombineMode .
<b>Default:</b> PxCombineMode::eAVERAGE
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] combMode Restitution combine mode for this material. See #PxCombineMode.
\see PxCombineMode getRestitutionCombineMode() setRestitution()
*/
virtual void setRestitutionCombineMode(PxCombineMode::Enum combMode) = 0;
/**
\brief Retrieves the restitution combine mode.
See #setRestitutionCombineMode.
\return The coefficient of restitution combine mode for this material.
\see PxCombineMode setRestitutionCombineMode getRestitution()
*/
virtual PxCombineMode::Enum getRestitutionCombineMode() const = 0;
/**
\brief Sets the damping combine mode.
See the enum ::PxCombineMode .
<b>Default:</b> PxCombineMode::eAVERAGE
<b>Sleeping:</b> Does <b>NOT</b> wake any actors which may be affected.
\param[in] combMode Damping combine mode for this material. See #PxCombineMode.
\see PxCombineMode getDampingCombineMode() setDamping()
*/
virtual void setDampingCombineMode(PxCombineMode::Enum combMode) = 0;
/**
\brief Retrieves the damping combine mode.
\return The damping combine mode for this material.
\see PxCombineMode setDampingCombineMode() getDamping()
*/
virtual PxCombineMode::Enum getDampingCombineMode() const = 0;
// PxBase
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxMaterial"; }
//~PxBase
protected:
PX_INLINE PxMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBaseMaterial(concreteType, baseFlags) {}
PX_INLINE PxMaterial(PxBaseFlags baseFlags) : PxBaseMaterial(baseFlags) {}
virtual ~PxMaterial() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxMaterial", PxBaseMaterial); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,102 @@
// 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 PX_NODEINDEX_H
#define PX_NODEINDEX_H
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#define PX_INVALID_NODE 0xFFFFFFFFu
/**
\brief PxNodeIndex
Node index is the unique index for each actor referenced by the island gen. It contains details like
if the actor is an articulation or rigid body. If it is an articulation, the node index also contains
the link index of the rigid body within the articulation. Also, it contains information to detect whether
the rigid body is static body or not
*/
class PxNodeIndex
{
struct IDs
{
PxU32 mID;
PxU32 mLinkID;
};
union
{
IDs mIDs;
PxU64 mInd;
};
public:
explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxNodeIndex(PxU32 id, PxU32 articLinkId)
{
setIndices(id, articLinkId);
}
explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxNodeIndex(PxU32 id = PX_INVALID_NODE)
{
setIndices(id);
}
explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxNodeIndex(PxU64 ind)
{
mInd = ind;
}
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 index() const { return mIDs.mID; }
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 articulationLinkId() const { return mIDs.mLinkID >> 1; }
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 isArticulation() const { return mIDs.mLinkID & 1; }
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isStaticBody() const { return mIDs.mID == PX_INVALID_NODE; }
PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() const { return mIDs.mID != PX_INVALID_NODE; }
PX_CUDA_CALLABLE PX_FORCE_INLINE void setIndices(PxU32 index, PxU32 articLinkId) { mIDs.mID = index; mIDs.mLinkID = (articLinkId << 1) | 1; }
PX_CUDA_CALLABLE PX_FORCE_INLINE void setIndices(PxU32 index) { mIDs.mID = index; mIDs.mLinkID = 0; }
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU64 getInd() const { return mInd; }
PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator < (const PxNodeIndex& other) const { return getInd() < other.getInd(); }
PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator <= (const PxNodeIndex& other) const { return getInd() <= other.getInd(); }
PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator == (const PxNodeIndex& other) const { return getInd() == other.getInd(); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,318 @@
// 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 PX_PBD_MATERIAL_H
#define PX_PBD_MATERIAL_H
#include "PxBaseMaterial.h"
#include "PxParticleMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxScene;
/**
\brief Material class to represent a set of PBD particle material properties.
\see #PxPhysics.createPBDMaterial
*/
class PxPBDMaterial : public PxBaseMaterial
{
public:
/**
\brief Sets friction
\param[in] friction Friction. <b>Range:</b> [0, PX_MAX_F32)
\see #getFriction()
*/
virtual void setFriction(PxReal friction) = 0;
/**
\brief Retrieves the friction value.
\return The friction value.
\see #setFriction()
*/
virtual PxReal getFriction() const = 0;
/**
\brief Sets velocity damping term
\param[in] damping Velocity damping term. <b>Range:</b> [0, PX_MAX_F32)
\see #getDamping
*/
virtual void setDamping(PxReal damping) = 0;
/**
\brief Retrieves the velocity damping term
\return The velocity damping term.
\see #setDamping()
*/
virtual PxReal getDamping() const = 0;
/**
\brief Sets adhesion term
\param[in] adhesion adhesion coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see #getAdhesion
*/
virtual void setAdhesion(PxReal adhesion) = 0;
/**
\brief Retrieves the adhesion term
\return The adhesion term.
\see #setAdhesion()
*/
virtual PxReal getAdhesion() const = 0;
/**
\brief Sets gravity scale term
\param[in] scale gravity scale coefficient. <b>Range:</b> (-PX_MAX_F32, PX_MAX_F32)
\see #getAdhesion
*/
virtual void setGravityScale(PxReal scale) = 0;
/**
\brief Retrieves the gravity scale term
\return The gravity scale term.
\see #setAdhesion()
*/
virtual PxReal getGravityScale() const = 0;
/**
\brief Sets material adhesion radius scale. This is multiplied by the particle rest offset to compute the fall-off distance
at which point adhesion ceases to operate.
\param[in] scale Material adhesion radius scale. <b>Range:</b> [0, PX_MAX_F32)
\see #getAdhesionRadiusScale
*/
virtual void setAdhesionRadiusScale(PxReal scale) = 0;
/**
\brief Retrieves the adhesion radius scale.
\return The adhesion radius scale.
\see #setAdhesionRadiusScale()
*/
virtual PxReal getAdhesionRadiusScale() const = 0;
/**
\brief Sets viscosity
\param[in] viscosity Viscosity. <b>Range:</b> [0, PX_MAX_F32)
\see #getViscosity()
*/
virtual void setViscosity(PxReal viscosity) = 0;
/**
\brief Retrieves the viscosity value.
\return The viscosity value.
\see #setViscosity()
*/
virtual PxReal getViscosity() const = 0;
/**
\brief Sets material vorticity confinement coefficient
\param[in] vorticityConfinement Material vorticity confinement coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see #getVorticityConfinement()
*/
virtual void setVorticityConfinement(PxReal vorticityConfinement) = 0;
/**
\brief Retrieves the vorticity confinement coefficient.
\return The vorticity confinement coefficient.
\see #setVorticityConfinement()
*/
virtual PxReal getVorticityConfinement() const = 0;
/**
\brief Sets material surface tension coefficient
\param[in] surfaceTension Material surface tension coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see #getSurfaceTension()
*/
virtual void setSurfaceTension(PxReal surfaceTension) = 0;
/**
\brief Retrieves the surface tension coefficient.
\return The surface tension coefficient.
\see #setSurfaceTension()
*/
virtual PxReal getSurfaceTension() const = 0;
/**
\brief Sets material cohesion coefficient
\param[in] cohesion Material cohesion coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see #getCohesion()
*/
virtual void setCohesion(PxReal cohesion) = 0;
/**
\brief Retrieves the cohesion coefficient.
\return The cohesion coefficient.
\see #setCohesion()
*/
virtual PxReal getCohesion() const = 0;
/**
\brief Sets material lift coefficient
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\param[in] lift Material lift coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see #getLift()
*/
PX_DEPRECATED virtual void setLift(PxReal lift) = 0;
/**
\brief Retrieves the lift coefficient.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\return The lift coefficient.
\see #setLift()
*/
PX_DEPRECATED virtual PxReal getLift() const = 0;
/**
\brief Sets material drag coefficient
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\param[in] drag Material drag coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see #getDrag()
*/
PX_DEPRECATED virtual void setDrag(PxReal drag) = 0;
/**
\brief Retrieves the drag coefficient.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\return The drag coefficient.
\see #setDrag()
*/
PX_DEPRECATED virtual PxReal getDrag() const = 0;
/**
\brief Sets the CFL coefficient. Limits the relative motion between two approaching fluid particles.
The distance to which the motion is clamped is defined by CFLcoefficient*particleContactOffset*2.
A value of 0.5 will thus limit the appoaching motion to a distance of particleContactOffset.
A value much larger than one will typically not limit the motion of the particles.
\param[in] coefficient CFL coefficient. <b>Range:</b> [0, PX_MAX_F32), <b>Default:</b> 1.0
\see #getCFLCoefficient()
*/
virtual void setCFLCoefficient(PxReal coefficient) = 0;
/**
\brief Retrieves the CFL coefficient.
\return The CFL coefficient.
\see #setCFLCoefficient()
*/
virtual PxReal getCFLCoefficient() const = 0;
/**
\brief Sets material particle friction scale. This allows the application to scale up/down the frictional effect between particles independent of the friction
coefficient, which also defines frictional behavior between the particle and rigid bodies/soft bodies/cloth etc.
\param[in] scale particle friction scale. <b>Range:</b> [0, PX_MAX_F32)
\see #getParticleFrictionScale()
*/
virtual void setParticleFrictionScale(PxReal scale) = 0;
/**
\brief Retrieves the particle friction scale.
\return The particle friction scale.
\see #setParticleFrictionScale()
*/
virtual PxReal getParticleFrictionScale() const = 0;
/**
\brief Sets material particle adhesion scale value. This is the adhesive value between particles defined as a scaled multiple of the adhesion parameter.
\param[in] adhesion particle adhesion scale value. <b>Range:</b> [0, PX_MAX_F32)
\see #getParticleAdhesionScale()
*/
virtual void setParticleAdhesionScale(PxReal adhesion) = 0;
/**
\brief Retrieves the particle adhesion scale value.
\return The particle adhesion scale value.
\see #setParticleAdhesionScale()
*/
virtual PxReal getParticleAdhesionScale() const = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxPBDMaterial"; }
protected:
PX_INLINE PxPBDMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBaseMaterial(concreteType, baseFlags) {}
PX_INLINE PxPBDMaterial(PxBaseFlags baseFlags) : PxBaseMaterial(baseFlags) {}
virtual ~PxPBDMaterial() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxPBDMaterial", PxBaseMaterial); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,652 @@
// 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 PX_PBD_PARTICLE_SYSTEM_H
#define PX_PBD_PARTICLE_SYSTEM_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec3.h"
#include "foundation/PxArray.h"
#include "cudamanager/PxCudaTypes.h"
#include "PxParticleSystemFlag.h"
#include "PxFiltering.h"
#include "PxActor.h"
#include "PxParticleSystem.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
class PxCudaContextManager;
class PxGpuParticleSystem;
class PxParticleAndDiffuseBuffer;
class PxParticleBuffer;
/**
\brief Container to hold a pair of corresponding device and host pointers. These pointers should point to GPU / CPU mirrors of the same data, but
this is not enforced.
*/
template <typename Type>
struct PxGpuMirroredPointer
{
Type* mDevicePtr;
Type* mHostPtr;
PxGpuMirroredPointer(Type* devicePtr, Type* hostPtr) : mDevicePtr(devicePtr), mHostPtr(hostPtr) { }
};
/**
\brief Particle system callback base class to schedule work that should be done before, while or after the particle system updates.
A call to fetchResultsParticleSystem() on the PxScene will synchronize the work such that the caller knows that all tasks of this callback completed.
*/
class PxParticleSystemCallback
{
public:
/**
\brief Method gets called when dirty data from the particle system is uploated to the gpu
\param[in] gpuParticleSystem Pointers to the particle systems gpu data available as host accessible pointer and as gpu accessible pointer
\param[in] stream The stream on which all cuda kernel calls get scheduled for execution. A call to fetchResultsParticleSystem() on the
PxScene will synchronize the work such that the caller knows that the task completed.
*/
virtual void onBegin(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream) = 0;
/**
\brief Method gets called when the simulation step of the particle system is performed
\param[in] gpuParticleSystem Pointers to the particle systems gpu data available as host accessible pointer and as gpu accessible pointer
\param[in] stream The stream on which all cuda kernel calls get scheduled for execution. A call to fetchResultsParticleSystem() on the
PxScene will synchronize the work such that the caller knows that the task completed.
*/
virtual void onAdvance(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream) = 0;
/**
\brief Method gets called after the particle system simulation step completed
\param[in] gpuParticleSystem Pointers to the particle systems gpu data available as host accessible pointer and as gpu accessible pointer
\param[in] stream The stream on which all cuda kernel calls get scheduled for execution. A call to fetchResultsParticleSystem() on the
PxScene will synchronize the work such that the caller knows that the task completed.
*/
virtual void onPostSolve(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream) = 0;
/**
\brief Destructor
*/
virtual ~PxParticleSystemCallback() {}
};
/**
\brief Special callback that forwards calls to arbitrarily many sub-callbacks
*/
class PxMultiCallback : public PxParticleSystemCallback
{
private:
PxArray<PxParticleSystemCallback*> mCallbacks;
public:
PxMultiCallback() : mCallbacks(0) {}
virtual void onPostSolve(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream) PX_OVERRIDE
{
for (PxU32 i = 0; i < mCallbacks.size(); ++i)
mCallbacks[i]->onPostSolve(gpuParticleSystem, stream);
}
virtual void onBegin(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream) PX_OVERRIDE
{
for (PxU32 i = 0; i < mCallbacks.size(); ++i)
mCallbacks[i]->onBegin(gpuParticleSystem, stream);
}
virtual void onAdvance(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream) PX_OVERRIDE
{
for (PxU32 i = 0; i < mCallbacks.size(); ++i)
mCallbacks[i]->onAdvance(gpuParticleSystem, stream);
}
/**
\brief Adds a callback
\param[in] callback The callback to add
\return True if the callback was added
*/
bool addCallback(PxParticleSystemCallback* callback)
{
if (mCallbacks.find(callback) != mCallbacks.end())
return false;
mCallbacks.pushBack(callback);
return true;
}
/**
\brief Removes a callback
\param[in] callback The callback to remove
\return True if the callback was removed
*/
bool removeCallback(const PxParticleSystemCallback* callback)
{
for (PxU32 i = 0; i < mCallbacks.size(); ++i)
{
if (mCallbacks[i] == callback)
{
mCallbacks.remove(i);
return true;
}
}
return false;
}
};
/**
\brief Flags which control the behaviour of a particle system.
See #PxPBDParticleSystem::setParticleFlag(), #PxPBDParticleSystem::setParticleFlags(), #PxPBDParticleSystem::getParticleFlags()
*/
struct PxParticleFlag
{
enum Enum
{
eDISABLE_SELF_COLLISION = 1 << 0, //!< Disables particle self-collision
eDISABLE_RIGID_COLLISION = 1 << 1, //!< Disables particle-rigid body collision
eFULL_DIFFUSE_ADVECTION = 1 << 2, //!< Enables full advection of diffuse particles. By default, diffuse particles are advected only by particles in the cell they are contained. This flag enables full neighbourhood generation (more expensive).
eENABLE_SPECULATIVE_CCD = 1 << 3 //!< Enables speculative CCD for particle-rigid body collision. \see PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD.
};
};
typedef PxFlags<PxParticleFlag::Enum, PxU32> PxParticleFlags;
/**
\brief Collection of flags providing a mechanism to lock motion along a specific axis.
\see PxParticleSystem.setParticleLockFlag(), PxParticleSystem.getParticleLockFlags()
*/
struct PxParticleLockFlag
{
enum Enum
{
eLOCK_X = (1 << 0),
eLOCK_Y = (1 << 1),
eLOCK_Z = (1 << 2)
};
};
typedef PxFlags<PxParticleLockFlag::Enum, PxU8> PxParticleLockFlags;
PX_FLAGS_OPERATORS(PxParticleLockFlag::Enum, PxU8)
/**
\brief A particle system that uses the position based dynamics(PBD) solver.
The position based dynamics solver for particle systems supports behaviors like
fluid, cloth, inflatables etc.
*/
class PxPBDParticleSystem : public PxActor
{
public:
virtual ~PxPBDParticleSystem() {}
/**
\brief Sets the solver iteration counts for the body.
The solver iteration count determines how accurately joints and contacts are resolved.
If you are having trouble with jointed bodies oscillating and behaving erratically, then
setting a higher position iteration count may improve their stability.
If intersecting bodies are being depenetrated too violently, increase the number of velocity
iterations. More velocity iterations will drive the relative exit velocity of the intersecting
objects closer to the correct value given the restitution.
<b>Default:</b> 4 position iterations, 1 velocity iteration
\param[in] minPositionIters Number of position iterations the solver should perform for this body. <b>Range:</b> [1,255]
\param[in] minVelocityIters Number of velocity iterations the solver should perform for this body. <b>Range:</b> [1,255]
See #getSolverIterationCounts()
*/
virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0;
/**
\brief Retrieves the solver iteration counts.
See #setSolverIterationCounts()
*/
virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0;
/**
\brief Retrieves the collision filter settings.
\return The filter data
*/
virtual PxFilterData getSimulationFilterData() const = 0;
/**
\brief Set collision filter settings
Allows to control with which objects the particle system collides
\param[in] data The filter data
*/
virtual void setSimulationFilterData(const PxFilterData& data) = 0;
/**
\brief Set particle flag
Allows to control self collision etc.
\param[in] flag The flag to set
\param[in] val The new value of the flag
*/
virtual void setParticleFlag(PxParticleFlag::Enum flag, bool val) = 0;
/**
\brief Set particle flags
Allows to control self collision etc.
\param[in] flags The flags to set
*/
virtual void setParticleFlags(PxParticleFlags flags) = 0;
/**
\brief Retrieves the particle flags.
\return The particle flags
*/
virtual PxParticleFlags getParticleFlags() const = 0;
/**
\brief Set the maximal depenetration velocity particles can reach
Allows to limit the particles' maximal depenetration velocity to avoid that collision responses lead to very high particle velocities
\param[in] maxDepenetrationVelocity The maximal depenetration velocity
*/
virtual void setMaxDepenetrationVelocity(PxReal maxDepenetrationVelocity) = 0;
/**
\brief Retrieves maximal depenetration velocity a particle can have.
\return The maximal depenetration velocity
*/
virtual PxReal getMaxDepenetrationVelocity() const = 0;
/**
\brief Set the maximal velocity particles can reach
Allows to limit the particles' maximal velocity to control the maximal distance a particle can move per frame
\param[in] maxVelocity The maximal velocity
*/
virtual void setMaxVelocity(PxReal maxVelocity) = 0;
/**
\brief Retrieves maximal velocity a particle can have.
\return The maximal velocity
*/
virtual PxReal getMaxVelocity() const = 0;
/**
\brief Return the cuda context manager
\return The cuda context manager
*/
virtual PxCudaContextManager* getCudaContextManager() const = 0;
/**
\brief Set the rest offset for the collision between particles and rigids or deformable bodies.
A particle and a rigid or deformable body will come to rest at a distance equal to the sum of their restOffset values.
\param[in] restOffset <b>Range:</b> (0, contactOffset)
*/
virtual void setRestOffset(PxReal restOffset) = 0;
/**
\brief Return the rest offset
\return the rest offset
See #setRestOffset()
*/
virtual PxReal getRestOffset() const = 0;
/**
\brief Set the contact offset for the collision between particles and rigids or soft bodies
The contact offset needs to be larger than the rest offset.
Contact constraints are generated for a particle and a rigid or deformable below the distance equal to the sum of their contacOffset values.
\param[in] contactOffset <b>Range:</b> (restOffset, PX_MAX_F32)
*/
virtual void setContactOffset(PxReal contactOffset) = 0;
/**
\brief Return the contact offset
\return the contact offset
See #setContactOffset()
*/
virtual PxReal getContactOffset() const = 0;
/**
\brief Set the contact offset for the interactions between particles
The particle contact offset needs to be larger than the fluid rest offset and larger than the solid rest offset.
Interactions for two particles are computed if their distance is below twice the particleContactOffset value.
\param[in] particleContactOffset <b>Range:</b> (Max(solidRestOffset, fluidRestOffset), PX_MAX_F32)
*/
virtual void setParticleContactOffset(PxReal particleContactOffset) = 0;
/**
\brief Return the particle contact offset
\return the particle contact offset
See #setParticleContactOffset()
*/
virtual PxReal getParticleContactOffset() const = 0;
/**
\brief Set the solid rest offset
Two solid particles (or a solid and a fluid particle) will come to rest at a distance equal to twice the solidRestOffset value.
\param[in] solidRestOffset <b>Range:</b> (0, particleContactOffset)
*/
virtual void setSolidRestOffset(PxReal solidRestOffset) = 0;
/**
\brief Return the solid rest offset
\return the solid rest offset
See #setSolidRestOffset()
*/
virtual PxReal getSolidRestOffset() const = 0;
/**
\brief Creates a rigid attachment between a particle and a rigid actor.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
This method creates a symbolic attachment between the particle system and a rigid body for the purpose of island management.
The actual attachments will be contained in the particle buffers.
Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash.
The particle system keeps track of these attachments but the rigid body does not.
\param[in] actor The rigid actor used for the attachment
*/
PX_DEPRECATED virtual void addRigidAttachment(PxRigidActor* actor) = 0;
/**
\brief Removes a rigid attachment between a particle and a rigid body.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
This method destroys a symbolic attachment between the particle system and a rigid body for the purpose of island management.
Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash.
The particle system keeps track of these attachments but the rigid body does not.
\param[in] actor The rigid body actor used for the attachment
*/
PX_DEPRECATED virtual void removeRigidAttachment(PxRigidActor* actor) = 0;
/**
\brief Enable continuous collision detection for particles
\deprecated Replaced by particle flag, \see PxParticleFlag::eENABLE_SPECULATIVE_CCD.
\param[in] enable Boolean indicates whether continuous collision detection is enabled.
*/
PX_DEPRECATED virtual void enableCCD(bool enable) = 0;
/**
\brief Reads the particle lock flags.
See the list of flags #PxParticleLockFlag
\return The values of the particle lock flags.
\see PxParticleLockFlag setParticleLockFlag()
*/
virtual PxParticleLockFlags getParticleLockFlags() const = 0;
/**
\brief Raises or clears a particular particle lock flag.
See the list of flags #PxParticleLockFlag
<b>Default:</b> no flags are set
\param[in] flag The PxParticleLockFlag to raise(set) or clear.
\param[in] value The new boolean value for the flag.
\see PxParticleLockFlag getParticleLockFlags()
*/
virtual void setParticleLockFlag(PxParticleLockFlag::Enum flag, bool value) = 0;
/**
\brief Set all particle lock flags.
\see setParticleLockFlag()
*/
virtual void setParticleLockFlags(PxParticleLockFlags flags) = 0;
/**
\brief Creates combined particle flag with particle material and particle phase flags.
\param[in] material A material instance to associate with the new particle group.
\param[in] flags The particle phase flags.
\return The combined particle group index and phase flags.
See #PxParticlePhaseFlag
*/
virtual PxU32 createPhase(PxPBDMaterial* material, PxParticlePhaseFlags flags) = 0;
/**
\brief Returns number of particle materials referenced by particle phases
\return The number of particle materials
*/
virtual PxU32 getNbParticleMaterials() const = 0;
/**
\brief Returns particle materials referenced by particle phases
\return The particle materials
*/
virtual PxU32 getParticleMaterials(PxPBDMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief Sets a user notify object which receives special simulation events when they occur.
\note Do not set the callback while the simulation is running. Calls to this method while the simulation is running will be ignored.
\note A call to fetchResultsParticleSystem() on the PxScene will synchronize the work such that the caller knows that all worke done in the callback completed.
\param[in] callback User notification callback. See PxSimulationEventCallback.
See #PxParticleSystemCallback, #getParticleSystemCallback()
*/
virtual void setParticleSystemCallback(PxParticleSystemCallback* callback) = 0;
/**
\brief Retrieves the simulationEventCallback pointer set with setSimulationEventCallback().
\return The current user notify pointer. See PxSimulationEventCallback.
See #PxParticleSystemCallback, #setParticleSystemCallback()
*/
virtual PxParticleSystemCallback* getParticleSystemCallback() const = 0;
/**
\brief Add an existing particle buffer to the particle system.
\param[in] particleBuffer a PxParticleBuffer*.
See #PxParticleBuffer.
*/
virtual void addParticleBuffer(PxParticleBuffer* particleBuffer) = 0;
/**
\brief Remove particle buffer from the particle system.
\param[in] particleBuffer a PxParticleBuffer*.
See #PxParticleBuffer.
*/
virtual void removeParticleBuffer(PxParticleBuffer* particleBuffer) = 0;
/**
\brief Returns the GPU particle system index.
\return The GPU index, if the particle system is in a scene and PxSceneFlag::eENABLE_DIRECT_GPU_API is set, or 0xFFFFFFFF otherwise.
*/
virtual PxU32 getGpuParticleSystemIndex() = 0;
/**
\brief Set wind direction and intensity
\param[in] wind The wind direction and intensity
*/
virtual void setWind(const PxVec3& wind) = 0;
/**
\brief Retrieves the wind direction and intensity.
\return The wind direction and intensity
*/
virtual PxVec3 getWind() const = 0;
/**
\brief Set the fluid boundary density scale
Defines how strong of a contribution the boundary (typically a rigid surface) should have on a fluid particle's density.
\param[in] fluidBoundaryDensityScale <b>Range:</b> (0.0, 1.0)
*/
virtual void setFluidBoundaryDensityScale(PxReal fluidBoundaryDensityScale) = 0;
/**
\brief Return the fluid boundary density scale
\return the fluid boundary density scale
See #setFluidBoundaryDensityScale()
*/
virtual PxReal getFluidBoundaryDensityScale() const = 0;
/**
\brief Set the fluid rest offset
Two fluid particles will come to rest at a distance equal to twice the fluidRestOffset value.
\param[in] fluidRestOffset <b>Range:</b> (0, particleContactOffset)
*/
virtual void setFluidRestOffset(PxReal fluidRestOffset) = 0;
/**
\brief Return the fluid rest offset
\return the fluid rest offset
See #setFluidRestOffset()
*/
virtual PxReal getFluidRestOffset() const = 0;
/**
\brief Set the particle system grid size x dimension
\param[in] gridSizeX x dimension in the particle grid
*/
virtual void setGridSizeX(PxU32 gridSizeX) = 0;
/**
\brief Get the particle system grid size x dimension
\return[in] the x dimension in the particle grid
See #setGridSizeX()
*/
virtual PxU32 getGridSizeX() const = 0;
/**
\brief Set the particle system grid size y dimension
\param[in] gridSizeY y dimension in the particle grid
*/
virtual void setGridSizeY(PxU32 gridSizeY) = 0;
/**
\brief Get the particle system grid size y dimension
\return[in] the y dimension in the particle grid
See #setGridSizeY()
*/
virtual PxU32 getGridSizeY() const = 0;
/**
\brief Set the particle system grid size z dimension
\param[in] gridSizeZ z dimension in the particle grid
*/
virtual void setGridSizeZ(PxU32 gridSizeZ) = 0;
/**
\brief Get the particle system grid size z dimension
\return[in] the z dimension in the particle grid
See #setGridSizeZ()
*/
virtual PxU32 getGridSizeZ() const = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxPBDParticleSystem"; }
protected:
PX_INLINE PxPBDParticleSystem(PxType concreteType, PxBaseFlags baseFlags) : PxActor(concreteType, baseFlags) {}
PX_INLINE PxPBDParticleSystem(PxBaseFlags baseFlags) : PxActor(baseFlags) {}
virtual bool isKindOf(const char* name) const PX_OVERRIDE { PX_IS_KIND_OF(name, "PxPBDParticleSystem", PxActor); }
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,626 @@
// 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 PX_PARTICLE_BUFFER_H
#define PX_PARTICLE_BUFFER_H
#include "common/PxBase.h"
#include "common/PxPhysXCommonConfig.h"
#include "common/PxTypeInfo.h"
#include "PxParticleSystemFlag.h"
#include "foundation/PxBounds3.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
class PxCudaContextManager;
struct PxParticleRigidFilterPair;
struct PxParticleRigidAttachment;
/**
\brief Particle volume structure. Used to track the bounding volume of a user-specified set of particles. The particles are required
to be laid out contiguously within the same PxParticleBuffer.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
*/
PX_ALIGN_PREFIX(16)
struct PX_DEPRECATED PxParticleVolume
{
PxBounds3 bound; //!< The current bounds of the particles contained in this #PxParticleVolume.
PxU32 particleIndicesOffset; //!< The index into the particle list of the #PxParticleBuffer for the first particle of this volume.
PxU32 numParticles; //!< The number of particles contained in this #PxParticleVolume.
} PX_ALIGN_SUFFIX(16);
/**
\brief The shared base class for all particle buffers, can be instantiated directly to simulate granular and fluid particles.
See #PxPhysics::createParticleBuffer.
A particle buffer is a container that specifies per-particle attributes of a set of particles that will be used during the simulation
of a particle system. It exposes direct access to the underlying GPU buffers and is independent of the scene and particle system. Particle
buffers can be added/removed from a particle system at any time between simulation steps, and transferred from one particle system to another.
*/
class PxParticleBuffer : public PxBase
{
public:
/**
\brief Get positions and inverse masses for this particle buffer.
\return A pointer to a device buffer containing the positions and inverse mass packed as PxVec4(pos.x, pos.y, pos.z, inverseMass).
*/
virtual PxVec4* getPositionInvMasses() const = 0;
/**
\brief Get velocities for this particle buffer.
\return A pointer to a device buffer containing the velocities packed as PxVec4(vel.x, vel.y, vel.z, 0.0f).
*/
virtual PxVec4* getVelocities() const = 0;
/**
\brief Get phases for this particle buffer.
See #PxParticlePhaseFlag
\return A pointer to a device buffer containing the per-particle phases for this particle buffer.
*/
virtual PxU32* getPhases() const = 0;
/**
\brief Get particle volumes for this particle buffer.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxParticleVolume
\return A pointer to a device buffer containing the #PxParticleVolume s for this particle buffer.
*/
PX_DEPRECATED virtual PxParticleVolume* getParticleVolumes() const = 0;
/**
\brief Set the number of active particles for this particle buffer.
\param[in] nbActiveParticles The number of active particles.
The number of active particles can be <= PxParticleBuffer::getMaxParticles(). The particle system will simulate the first
x particles in the #PxParticleBuffer, where x is the number of active particles.
*/
virtual void setNbActiveParticles(PxU32 nbActiveParticles) = 0;
/**
\brief Get the number of active particles for this particle buffer.
\return The number of active particles.
*/
virtual PxU32 getNbActiveParticles() const = 0;
/**
\brief Get the maximum number particles this particle buffer can hold.
The maximum number of particles is specified when creating a #PxParticleBuffer. See #PxPhysics::createParticleBuffer.
\return The maximum number of particles.
*/
virtual PxU32 getMaxParticles() const = 0;
/**
\brief Get the number of particle volumes in this particle buffer.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\return The number of #PxParticleVolume s for this particle buffer.
*/
PX_DEPRECATED virtual PxU32 getNbParticleVolumes() const = 0;
/**
\brief Set the number of #PxParticleVolume s for this particle buffer.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\param[in] nbParticleVolumes The number of particle volumes in this particle buffer.
*/
PX_DEPRECATED virtual void setNbParticleVolumes(PxU32 nbParticleVolumes) = 0;
/**
\brief Get the maximum number of particle volumes this particle buffer can hold.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxParticleVolume.
\return The maximum number of particle volumes this particle buffer can hold.
*/
PX_DEPRECATED virtual PxU32 getMaxParticleVolumes() const = 0;
/**
\brief Set the #PxParticleRigidFilterPair s for collision filtering of particles in this buffer with rigid bodies.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxParticleRigidFilterPair
\param[in] filters A device buffer containing #PxParticleRigidFilterPair s.
\param[in] nbFilters The number of particle-rigid body collision filtering pairs.
*/
PX_DEPRECATED virtual void setRigidFilters(PxParticleRigidFilterPair* filters, PxU32 nbFilters) = 0;
/**
\brief Set the particle-rigid body attachments for particles in this particle buffer.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxParticleRigidAttachment
\param[in] attachments A device buffer containing #PxParticleRigidAttachment s.
\param[in] nbAttachments The number of particle-rigid body attachments.
*/
PX_DEPRECATED virtual void setRigidAttachments(PxParticleRigidAttachment* attachments, PxU32 nbAttachments) = 0;
/**
\brief Get the start index for the first particle of this particle buffer in the complete list of
particles of the particle system this buffer is used in.
The return value is only correct if the particle buffer is assigned to a particle system and at least
one call to simulate() has been performed.
\return The index of the first particle in the complete particle list.
*/
virtual PxU32 getFlatListStartIndex() const = 0;
/**
\brief Raise dirty flags on this particle buffer to communicate that the corresponding data has been updated
by the user.
\param[in] flags The flag corresponding to the data that is dirty.
See #PxParticleBufferFlag.
*/
virtual void raiseFlags(PxParticleBufferFlag::Enum flags) = 0;
/**
\brief Release this buffer and deallocate all the memory.
*/
virtual void release() = 0;
/**
\deprecated Will be removed in a future version, use getUniqueId() instead.
\brief Unique index that does not change over the lifetime of a PxParticleBuffer.
*/
PX_DEPRECATED PxU32 bufferUniqueId;
/**
\brief Retrieve unique index that does not change over the lifetime of a PxParticleBuffer.
*/
virtual PxU32 getUniqueId() const = 0;
//public variables:
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
virtual ~PxParticleBuffer() { }
PX_INLINE PxParticleBuffer(PxType type) : PxBase(type, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), bufferUniqueId(PX_INVALID_U32), userData(NULL) {}
private:
PX_NOCOPY(PxParticleBuffer)
};
/**
\brief Parameters to configure the behavior of diffuse particles
*/
class PxDiffuseParticleParams
{
public:
/**
\brief Construct parameters with default values.
*/
PX_INLINE PxDiffuseParticleParams()
{
threshold = 100.0f;
lifetime = 5.0f;
airDrag = 0.0f;
bubbleDrag = 0.5f;
buoyancy = 0.8f;
kineticEnergyWeight = 0.01f;
pressureWeight = 1.0f;
divergenceWeight = 5.0f;
collisionDecay = 0.5f;
useAccurateVelocity = false;
}
/**
\brief (re)sets the structure to the default.
*/
PX_INLINE void setToDefault()
{
*this = PxDiffuseParticleParams();
}
PxReal threshold; //!< Particles with potential value greater than the threshold will spawn diffuse particles
PxReal lifetime; //!< Diffuse particle will be removed after the specified lifetime
PxReal airDrag; //!< Air drag force factor for spray particles
PxReal bubbleDrag; //!< Fluid drag force factor for bubble particles
PxReal buoyancy; //!< Buoyancy force factor for bubble particles
PxReal kineticEnergyWeight; //!< Contribution from kinetic energy when deciding diffuse particle creation.
PxReal pressureWeight; //!< Contribution from pressure when deciding diffuse particle creation.
PxReal divergenceWeight; //!< Contribution from divergence when deciding diffuse particle creation.
PxReal collisionDecay; //!< Decay factor of diffuse particles' lifetime after they collide with shapes.
bool useAccurateVelocity; //!< If true, enables accurate velocity estimation when using PBD solver.
};
/**
\brief A particle buffer used to simulate diffuse particles.
See #PxPhysics::createParticleAndDiffuseBuffer.
*/
class PxParticleAndDiffuseBuffer : public PxParticleBuffer
{
public:
/**
\brief Get a device buffer of positions and remaining lifetimes for the diffuse particles.
\return A device buffer containing positions and lifetimes of diffuse particles packed as PxVec4(pos.x, pos.y, pos.z, lifetime).
*/
virtual PxVec4* getDiffusePositionLifeTime() const = 0;
/**
\brief Get a device buffer of velocities for the diffuse particles.
\return A device buffer containing velocities of diffuse particles.
*/
virtual PxVec4* getDiffuseVelocities() const = 0;
/**
\brief Get number of currently active diffuse particles.
\return The number of currently active diffuse particles.
*/
virtual PxU32 getNbActiveDiffuseParticles() const = 0;
/**
\brief Set the maximum possible number of diffuse particles for this buffer.
\param[in] maxActiveDiffuseParticles the maximum number of active diffuse particles.
\note Must be in the range [0, PxParticleAndDiffuseBuffer::getMaxDiffuseParticles()]
*/
virtual void setMaxActiveDiffuseParticles(PxU32 maxActiveDiffuseParticles) = 0;
/**
\brief Get maximum possible number of diffuse particles.
\return The maximum possible number diffuse particles.
*/
virtual PxU32 getMaxDiffuseParticles() const = 0;
/**
\brief Set the parameters for diffuse particle simulation.
\param[in] params The diffuse particle parameters.
See #PxDiffuseParticleParams
*/
virtual void setDiffuseParticleParams(const PxDiffuseParticleParams& params) = 0;
/**
\brief Get the parameters currently used for diffuse particle simulation.
\return A PxDiffuseParticleParams structure.
*/
virtual PxDiffuseParticleParams getDiffuseParticleParams() const = 0;
protected:
virtual ~PxParticleAndDiffuseBuffer() {}
PX_INLINE PxParticleAndDiffuseBuffer(PxType type) : PxParticleBuffer(type){}
private:
PX_NOCOPY(PxParticleAndDiffuseBuffer)
};
/**
\brief Holds all the information for a spring constraint between two particles. Used for particle cloth simulation.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
*/
struct PX_DEPRECATED PX_ALIGN_PREFIX(8) PxParticleSpring
{
PxU32 ind0; //!< particle index of first particle
PxU32 ind1; //!< particle index of second particle
PxReal length; //!< spring length
PxReal stiffness; //!< spring stiffness
PxReal damping; //!< spring damping factor
PxReal pad; //!< padding bytes.
} PX_ALIGN_SUFFIX(8);
/**
\brief Particle cloth structure. Holds information about a single piece of cloth that is part of a #PxParticleClothBuffer.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
*/
struct PX_DEPRECATED PxParticleCloth
{
PxU32 startVertexIndex; //!< Index of the first particle of this cloth in the position/velocity buffers of the parent #PxParticleClothBuffer
PxU32 numVertices; //!< The number of particles of this piece of cloth
PxReal clothBlendScale; //!< Used internally.
PxReal restVolume; //!< The rest volume of this piece of cloth, used for inflatable simulation.
PxReal pressure; //!< The factor of the rest volume to specify the target volume for this piece of cloth, used for inflatable simulation.
PxU32 startTriangleIndex; //!< The index of the first triangle of this piece of cloth in the triangle list.
PxU32 numTriangles; //!< The number of triangles of this piece of cloth.
bool operator <= (const PxParticleCloth& other) const { return startVertexIndex <= other.startVertexIndex; }
bool operator >= (const PxParticleCloth& other) const { return startVertexIndex >= other.startVertexIndex; }
bool operator < (const PxParticleCloth& other) const { return startVertexIndex < other.startVertexIndex; }
bool operator > (const PxParticleCloth& other) const { return startVertexIndex > other.startVertexIndex; }
bool operator == (const PxParticleCloth& other) const { return startVertexIndex == other.startVertexIndex; }
};
/**
\brief Structure to describe the set of particle cloths in the same #PxParticleClothBuffer. Used an input for the cloth preprocessing.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
*/
struct PX_DEPRECATED PxParticleClothDesc
{
PxParticleClothDesc() : cloths(NULL), triangles(NULL), springs(NULL), restPositions(NULL),
nbCloths(0), nbSprings(0), nbTriangles(0), nbParticles(0)
{
}
PxParticleCloth* cloths; //!< List of PxParticleCloth s, describes the individual cloths.
PxU32* triangles; //!< List of triangle indices, 3 consecutive PxU32 that map triangle vertices to particles
PxParticleSpring* springs; //!< List of PxParticleSpring s.
PxVec4* restPositions; //!< List of rest positions for all particles
PxU32 nbCloths; //!< The number of cloths in described using this cloth descriptor
PxU32 nbSprings; //!< The number of springs in this cloth descriptor
PxU32 nbTriangles; //!< The number of triangles in this cloth descriptor
PxU32 nbParticles; //!< The number of particles in this cloth descriptor
};
/**
\brief Structure to describe the output of the particle cloth preprocessing. Used as an input to specify cloth data for a #PxParticleClothBuffer.
All the pointers point to pinned host memory.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxParticleClothPreProcessor
*/
struct PX_DEPRECATED PX_PHYSX_CORE_API PxPartitionedParticleCloth
{
PxU32* accumulatedSpringsPerPartitions; //!< The number of springs in each partition. Size: numPartitions.
PxU32* accumulatedCopiesPerParticles; //!< Start index for each particle in the accumulation buffer. Size: numParticles.
PxU32* remapOutput; //!< Index of the next copy of this particle in the next partition, or in the accumulation buffer. Size: numSprings * 2.
PxParticleSpring* orderedSprings; //!< Springs ordered by partition. Size: numSprings.
PxU32* sortedClothStartIndices; //!< The first particle index into the position buffer of the #PxParticleClothBuffer for each cloth. Cloths are sorted by start particle index. Size: numCloths.
PxParticleCloth* cloths; //!< The #PxParticleCloth s sorted by start particle index.
PxU32 remapOutputSize; //!< Size of remapOutput.
PxU32 nbPartitions; //!< The number of partitions.
PxU32 nbSprings; //!< The number of springs.
PxU32 nbCloths; //!< The number of cloths.
PxU32 maxSpringsPerPartition; //!< The maximum number of springs in a partition.
PxCudaContextManager* mCudaManager; //!< A cuda context manager.
PxPartitionedParticleCloth();
~PxPartitionedParticleCloth();
/**
\brief allocate all the buffers for this #PxPartitionedParticleCloth.
\param[in] nbParticles the number of particles this #PxPartitionedParticleCloth will be generated for.
\param[in] cudaManager a cuda context manager.
*/
void allocateBuffers(PxU32 nbParticles, PxCudaContextManager* cudaManager);
};
/**
\brief A particle buffer used to simulate particle cloth.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxPhysics::createParticleClothBuffer.
*/
class PX_DEPRECATED PxParticleClothBuffer : public PxParticleBuffer
{
public:
/**
\brief Get rest positions for this particle buffer.
\return A pointer to a device buffer containing the rest positions packed as PxVec4(pos.x, pos.y, pos.z, 0.0f).
*/
virtual PxVec4* getRestPositions() = 0;
/**
\brief Get the triangle indices for this particle buffer.
\return A pointer to a device buffer containing the triangle indices for this cloth buffer.
*/
virtual PxU32* getTriangles() const = 0;
/**
\brief Set the number of triangles for this particle buffer.
\param[in] nbTriangles The number of triangles for this particle cloth buffer.
*/
virtual void setNbTriangles(PxU32 nbTriangles) = 0;
/**
\brief Get the number of triangles for this particle buffer.
\return The number triangles for this cloth buffer.
*/
virtual PxU32 getNbTriangles() const = 0;
/**
\brief Get the number of springs in this particle buffer.
\return The number of springs in this cloth buffer.
*/
virtual PxU32 getNbSprings() const = 0;
/**
\brief Get the springs for this particle buffer.
\return A pointer to a device buffer containing the springs for this cloth buffer.
*/
virtual PxParticleSpring* getSprings() = 0;
/**
\brief Set cloths for this particle buffer.
\param[in] cloths A pointer to a PxPartitionedParticleCloth.
See #PxPartitionedParticleCloth, #PxParticleClothPreProcessor
*/
virtual void setCloths(PxPartitionedParticleCloth& cloths) = 0;
protected:
virtual ~PxParticleClothBuffer() {}
PX_INLINE PxParticleClothBuffer(PxType type) : PxParticleBuffer(type) {}
private:
PX_NOCOPY(PxParticleClothBuffer)
};
/**
\brief A particle buffer used to simulate rigid bodies using shape matching with particles.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
See #PxPhysics::createParticleRigidBuffer.
*/
class PX_DEPRECATED PxParticleRigidBuffer : public PxParticleBuffer
{
public:
/**
\brief Get the particle indices of the first particle for each shape matched rigid body.
\return A device buffer containing the list of particle start indices of each shape matched rigid body.
*/
virtual PxU32* getRigidOffsets() const = 0;
/**
\brief Get the stiffness coefficients for all shape matched rigid bodies in this buffer.
Stiffness must be in the range [0, 1].
\return A device buffer containing the list of stiffness coefficients for each rigid body.
*/
virtual PxReal* getRigidCoefficients() const = 0;
/**
\brief Get the local position of each particle relative to the rigid body's center of mass.
\return A pointer to a device buffer containing the local position for each particle.
*/
virtual PxVec4* getRigidLocalPositions() const = 0;
/**
\brief Get the world-space translations for all rigid bodies in this buffer.
\return A pointer to a device buffer containing the world-space translations for all shape-matched rigid bodies in this buffer.
*/
virtual PxVec4* getRigidTranslations() const = 0;
/**
\brief Get the world-space rotation of every shape-matched rigid body in this buffer.
Rotations are specified as quaternions.
\return A pointer to a device buffer containing the world-space rotation for every shape-matched rigid body in this buffer.
*/
virtual PxVec4* getRigidRotations() const = 0;
/**
\brief Get the local space normals for each particle relative to the shape of the corresponding rigid body.
The 4th component of every PxVec4 should be the negative signed distance of the particle inside its shape.
\return A pointer to a device buffer containing the local-space normals for each particle.
*/
virtual PxVec4* getRigidLocalNormals() const = 0;
/**
\brief Set the number of shape matched rigid bodies in this buffer.
\param[in] nbRigids The number of shape matched rigid bodies
*/
virtual void setNbRigids(PxU32 nbRigids) = 0;
/**
\brief Get the number of shape matched rigid bodies in this buffer.
\return The number of shape matched rigid bodies in this buffer.
*/
virtual PxU32 getNbRigids() const = 0;
protected:
virtual ~PxParticleRigidBuffer() {}
PX_INLINE PxParticleRigidBuffer(PxType type) : PxParticleBuffer(type) {}
private:
PX_NOCOPY(PxParticleRigidBuffer)
};
/**
\brief Preprocessor to prepare particle cloths for simulation.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
Preprocessing is done by calling #PxParticleClothPreProcessor::partitionSprings() on an instance of this class. This will allocate the memory in the
output object, partition the springs and fill all the members of the ouput object. The output can then be passed without
any further modifications to #PxParticleClothBuffer::setCloths().
See #PxParticleClothDesc, #PxPartitionedParticleCloth
*/
class PX_DEPRECATED PxParticleClothPreProcessor
{
public:
/**
\brief Release this object and deallocate all the memory.
*/
virtual void release() = 0;
/**
\brief Partition the spring constraints for particle cloth simulation.
\param[in] clothDesc Reference to a valid #PxParticleClothDesc.
\param[in] output Reference to a #PxPartitionedParticleCloth object. This is the output of the preprocessing and should be passed to a #PxParticleClothBuffer.
*/
virtual void partitionSprings(const PxParticleClothDesc& clothDesc, PxPartitionedParticleCloth& output) = 0;
protected:
virtual ~PxParticleClothPreProcessor(){}
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
/**
\brief Create a particle cloth preprocessor.
\deprecated Particle-cloth, -rigids, -attachments and -volumes have been deprecated.
\param[in] cudaContextManager A cuda context manager.
See #PxParticleClothDesc, #PxPartitionedParticleCloth.
*/
PX_DEPRECATED PX_C_EXPORT PX_PHYSX_CORE_API physx::PxParticleClothPreProcessor* PX_CALL_CONV PxCreateParticleClothPreProcessor(physx::PxCudaContextManager* cudaContextManager);
#endif

View File

@@ -0,0 +1,188 @@
// 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 PX_GPU_PARTICLE_SYSTEM_H
#define PX_GPU_PARTICLE_SYSTEM_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec3.h"
#include "PxParticleSystem.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Common material properties for particles. See #PxPBDMaterial.
Accessed by either integration or particle-rigid collisions
*/
struct PxsParticleMaterialData
{
PxReal friction; // 4
PxReal damping; // 8
PxReal adhesion; // 12
PxReal gravityScale; // 16
PxReal adhesionRadiusScale; // 20
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#if PX_SUPPORT_GPU_PHYSX
struct float4;
PX_CUDA_CALLABLE inline physx::PxU32 PxGetGroup(physx::PxU32 phase) { return phase & physx::PxParticlePhaseFlag::eParticlePhaseGroupMask; }
PX_CUDA_CALLABLE inline bool PxGetFluid(physx::PxU32 phase) { return (phase & physx::PxParticlePhaseFlag::eParticlePhaseFluid) != 0; }
PX_CUDA_CALLABLE inline bool PxGetSelfCollide(physx::PxU32 phase) { return (phase & physx::PxParticlePhaseFlag::eParticlePhaseSelfCollide) != 0; }
PX_CUDA_CALLABLE inline bool PxGetSelfCollideFilter(physx::PxU32 phase) { return (phase & physx::PxParticlePhaseFlag::eParticlePhaseSelfCollideFilter) != 0; }
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief An iterator class to iterate over the neighbors of a particle during particle system simulation.
*/
class PxNeighborhoodIterator
{
const PxU32* PX_RESTRICT mCollisionIndex; //!< Pointer to the current state of the iterator.
PxU32 mMaxParticles; //!< The maximum number of particles of the particle system this iterator is used on.
public:
PX_CUDA_CALLABLE PxNeighborhoodIterator(const PxU32* PX_RESTRICT collisionIndex, PxU32 maxParticles) :
mCollisionIndex(collisionIndex), mMaxParticles(maxParticles)
{
}
PX_CUDA_CALLABLE PxU32 getNextIndex()
{
PxU32 result = *mCollisionIndex;
mCollisionIndex += mMaxParticles;
return result;
}
PX_INLINE PxNeighborhoodIterator(const PxNeighborhoodIterator& params)
{
mCollisionIndex = params.mCollisionIndex;
mMaxParticles = params.mMaxParticles;
}
PX_INLINE void operator = (const PxNeighborhoodIterator& params)
{
mCollisionIndex = params.mCollisionIndex;
mMaxParticles = params.mMaxParticles;
}
};
/**
\brief Structure that holds simulation parameters of a #PxGpuParticleSystem.
*/
struct PxGpuParticleData
{
PxReal mGridCellWidth; //!< Grid cell width, derived from particle contact offset * neighborhood scale
PxU32 mGridSizeX; //!< Size of the x-dimension of the background simulation grid. Translates to an absolute size of mGridSizeX * mGridCellWidth.
PxU32 mGridSizeY; //!< Size of the y-dimension of the background simulation grid. Translates to an absolute size of mGridSizeY * mGridCellWidth.
PxU32 mGridSizeZ; //!< Size of the z-dimension of the background simulation grid. Translates to an absolute size of mGridSizeZ * mGridCellWidth.
PxReal mParticleContactDistance; //!< Two particles start interacting if their distance is lower than mParticleContactDistance.
PxReal mParticleContactDistanceInv; //!< 1.f / mParticleContactDistance.
PxReal mParticleContactDistanceSq; //!< mParticleContactDistance * mParticleContactDistance.
PxU32 mNumParticles; //!< The number of particles in this particle system.
PxU32 mMaxParticles; //!< The maximum number of particles that can be simulated in this particle system.
PxU32 mMaxNeighborhood; //!< The maximum number of particles considered when computing neighborhood based particle interactions.
PxU32 mMaxDiffuseParticles; //!< The maximum number of diffuse particles that can be simulated using this particle system.
PxU32 mNumParticleBuffers; //!< The number of particle buffers that are simulated in this particle system.
};
/**
\brief Container class for a GPU particle system. Used to communicate particle system parameters and simulation state
between the internal SDK simulation and the particle system callbacks.
See #PxPBDParticleSystem, #PxParticleSystemCallback.
*/
class PxGpuParticleSystem
{
public:
/**
\brief Returns the number of cells of the background simulation grid.
\return PxU32 the number of cells.
*/
PX_FORCE_INLINE PxU32 getNumCells() { return mCommonData.mGridSizeX * mCommonData.mGridSizeY * mCommonData.mGridSizeZ; }
/* Unsorted particle state buffers */
float4* mUnsortedPositions_InvMass; //!< GPU pointer to unsorted particle positions and inverse masses.
float4* mUnsortedVelocities; //!< GPU pointer to unsorted particle velocities.
PxU32* mUnsortedPhaseArray; //!< GPU pointer to unsorted particle phase array. See #PxParticlePhaseFlag.
/* Sorted particle state buffers. Sorted by increasing hash value in background grid. */
float4* mSortedPositions_InvMass; //!< GPU pointer to sorted particle positions
float4* mSortedVelocities; //!< GPU pointer to sorted particle velocities
PxU32* mSortedPhaseArray; //!< GPU pointer to sorted particle phase array
/* Mappings to/from sorted particle states */
PxU32* mUnsortedToSortedMapping; //!< GPU pointer to the mapping from unsortedParticle ID to sorted particle ID
PxU32* mSortedToUnsortedMapping; //!< GPU pointer to the mapping from sorted particle ID to unsorted particle ID
/* Neighborhood information */
PxU32* mParticleSelfCollisionCount; //!< Per-particle neighborhood count
PxU32* mCollisionIndex; //!< Set of sorted particle indices per neighbor
PxsParticleMaterialData* mParticleMaterials; //!< GPU pointer to the particle materials used in this particle system.
PxGpuParticleData mCommonData; //!< Structure holding simulation parameters and state for this particle system. See #PxGpuParticleData.
/**
\brief Get a PxNeighborhoodIterator initialized for usage with this particle system.
\param particleId An initial particle index for the initialization of the iterator.
\return An initialized PxNeighborhoodIterator.
*/
PX_CUDA_CALLABLE PxNeighborhoodIterator getIterator(PxU32 particleId) const
{
return PxNeighborhoodIterator(mCollisionIndex + particleId, mCommonData.mMaxParticles);
}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif
#endif

View File

@@ -0,0 +1,47 @@
// 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 PX_PARTICLE_MATERIAL_H
#define PX_PARTICLE_MATERIAL_H
#include "foundation/PxPreprocessor.h"
#include "PxPBDMaterial.h"
#if !PX_DOXYGEN
namespace physx
{
/**
\deprecated This typedef only serves for deprecation and will be removed in a future version.
*/
typedef PX_DEPRECATED PxPBDMaterial PxParticleMaterial;
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,130 @@
// 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 PX_PARTICLE_NEIGHBORHOOD_PROVIDER_H
#define PX_PARTICLE_NEIGHBORHOOD_PROVIDER_H
#include "cudamanager/PxCudaContext.h"
#include "cudamanager/PxCudaContextManager.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#include "PxParticleSystem.h"
#include "foundation/PxArray.h"
#include "PxParticleGpu.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_SUPPORT_GPU_PHYSX
/**
\brief Computes neighborhood information for a point cloud
*/
class PxParticleNeighborhoodProvider
{
public:
/**
\brief Schedules the compuation of neighborhood information on the specified cuda stream
\param[in] deviceParticlePos A gpu pointer containing the particle positions
\param[in] numParticles The number of particles
\param[in] stream The stream on which the cuda call gets scheduled
\param[in] devicePhases An optional gpu pointer with particle phases
\param[in] validPhaseMask An optional phase mask to define which particles should be included into the neighborhood computation
\param[in] deviceActiveIndices An optional device pointer containing all indices of particles that are currently active
*/
virtual void buildNeighborhood(PxVec4* deviceParticlePos, const PxU32 numParticles, CUstream stream, PxU32* devicePhases = NULL,
PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid, const PxU32* deviceActiveIndices = NULL) = 0;
/**
\brief Gets the maximal number of particles
\return The maximal number of particles
*/
virtual PxU32 getMaxParticles() const = 0;
/**
\brief Sets the maximal number of particles
\param[in] maxParticles The maximal number of particles
*/
virtual void setMaxParticles(PxU32 maxParticles) = 0;
/**
\brief Gets the maximal number of grid cells
\return The maximal number of grid cells
*/
virtual PxU32 getMaxGridCells() const = 0;
/**
\brief Gets the cell size
\return The cell size
*/
virtual PxReal getCellSize() const = 0;
/**
\brief Gets the number of grid cells in use
\return The number of grid cells in use
*/
virtual PxU32 getNumGridCellsInUse() const = 0;
/**
\brief Sets the maximal number of particles
\param[in] maxGridCells The maximal number of grid cells
\param[in] cellSize The cell size. Should be equal to 2*contactOffset for PBD particle systems.
*/
virtual void setCellProperties(PxU32 maxGridCells, PxReal cellSize) = 0;
/**
\brief Releases the instance and its data
*/
virtual void release() = 0;
/**
\brief Destructor
*/
virtual ~PxParticleNeighborhoodProvider() {}
};
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,66 @@
// 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 PX_PARTICLE_SOLVER_TYPE_H
#define PX_PARTICLE_SOLVER_TYPE_H
#include "foundation/PxPreprocessor.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
/**
\deprecated The solver type will be removed in a future version without replacement.
\brief Identifies the solver to use for a particle system.
*/
struct PX_DEPRECATED PxParticleSolverType
{
enum Enum
{
ePBD = 1 << 0 //!< The position based dynamics solver that can handle fluid, granular material, cloth, inflatables etc. See #PxPBDParticleSystem.
};
};
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,47 @@
// 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 PX_PARTICLE_SYSTEM_H
#define PX_PARTICLE_SYSTEM_H
#include "foundation/PxPreprocessor.h"
#include "PxPBDParticleSystem.h"
#if !PX_DOXYGEN
namespace physx
{
/**
\deprecated This typedef only serves for deprecation and will be removed in a future version.
*/
typedef PX_DEPRECATED PxPBDParticleSystem PxParticleSystem;
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,104 @@
// 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 PX_PARTICLE_SYSTEM_FLAG_H
#define PX_PARTICLE_SYSTEM_FLAG_H
#include "foundation/PxFlags.h"
#include "foundation/PxPreprocessor.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Identifies dirty particle buffers that need to be updated in the particle system.
This flag can be used mark the device user buffers that are dirty and need to be written to the particle system.
*/
struct PxParticleBufferFlag
{
enum Enum
{
eNONE = 0, //!< No data specified
eUPDATE_POSITION = 1 << 0, //!< Specifies the position (first 3 floats) and inverse mass (last float) data (array of PxVec4 * number of particles)
eUPDATE_VELOCITY = 1 << 1, //!< Specifies the velocity (first 3 floats) data (array of PxVec4 * number of particles)
eUPDATE_PHASE = 1 << 2, //!< Specifies the per-particle phase flag data (array of PxU32 * number of particles)
eUPDATE_RESTPOSITION = 1 << 3, //!< Specifies the rest position (first 3 floats) data for cloth buffers
eUPDATE_CLOTH = 1 << 5, //!< Specifies the cloth buffer (see PxParticleClothBuffer)
eUPDATE_RIGID = 1 << 6, //!< Specifies the rigid buffer (see PxParticleRigidBuffer)
eUPDATE_DIFFUSE_PARAM = 1 << 7, //!< Specifies the diffuse particle parameter buffer (see PxDiffuseParticleParams)
eUPDATE_ATTACHMENTS = 1 << 8, //!< Specifies the attachments.
eALL =
eUPDATE_POSITION | eUPDATE_VELOCITY | eUPDATE_PHASE | eUPDATE_RESTPOSITION | eUPDATE_CLOTH | eUPDATE_RIGID | eUPDATE_DIFFUSE_PARAM | eUPDATE_ATTACHMENTS
};
};
typedef PxFlags<PxParticleBufferFlag::Enum, PxU32> PxParticleBufferFlags;
/**
\brief A pair of particle buffer unique id and GPU particle system index.
\see PxScene::applyParticleBufferData
\deprecated There is no replacement.
*/
PX_DEPRECATED struct PxGpuParticleBufferIndexPair
{
PxU32 systemIndex; // gpu particle system index
PxU32 bufferIndex; // particle buffer unique id
};
/**
\brief Identifies per-particle behavior for a PxParticleSystem.
See #PxPBDParticleSystem::createPhase().
*/
struct PxParticlePhaseFlag
{
enum Enum
{
eParticlePhaseGroupMask = 0x000fffff, //!< Bits [ 0, 19] represent the particle group for controlling collisions
eParticlePhaseFlagsMask = 0xfff00000, //!< Bits [20, 23] hold flags about how the particle behave
eParticlePhaseSelfCollide = 1 << 20, //!< If set this particle will interact with particles of the same group
eParticlePhaseSelfCollideFilter = 1 << 21, //!< If set this particle will ignore collisions with particles closer than the radius in the rest pose, this flag should not be specified unless valid rest positions have been specified using setRestParticles()
eParticlePhaseFluid = 1 << 22 //!< If set this particle will generate fluid density constraints for its overlapping neighbors
};
};
typedef PxFlags<PxParticlePhaseFlag::Enum, PxU32> PxParticlePhaseFlags;
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,46 @@
// 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 PX_PHYSICS_CONFIG_H
#define PX_PHYSICS_CONFIG_H
/** Configuration include file for PhysX SDK */
#include "common/PxPhysXCommonConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,225 @@
// 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 PX_PHYSICS_API_H
#define PX_PHYSICS_API_H
/**
This is the main include header for the Physics SDK, for users who
want to use a single #include file.
Alternatively, one can instead directly #include a subset of the below files.
*/
// Foundation SDK
#include "foundation/PxAlignedMalloc.h"
#include "foundation/PxAlloca.h"
#include "foundation/PxAllocatorCallback.h"
#include "foundation/PxArray.h"
#include "foundation/PxAssert.h"
#include "foundation/PxAtomic.h"
#include "foundation/PxBasicTemplates.h"
#include "foundation/PxBitAndData.h"
#include "foundation/PxBitMap.h"
#include "foundation/PxBitUtils.h"
#include "foundation/PxBounds3.h"
#include "foundation/PxBroadcast.h"
#include "foundation/PxConstructor.h"
#include "foundation/PxErrorCallback.h"
#include "foundation/PxErrors.h"
#include "foundation/PxFlags.h"
#include "foundation/PxFoundation.h"
#include "foundation/PxFoundationConfig.h"
#include "foundation/PxFPU.h"
#include "foundation/PxHash.h"
#include "foundation/PxHashMap.h"
#include "foundation/PxHashSet.h"
#include "foundation/PxInlineAllocator.h"
#include "foundation/PxInlineArray.h"
#include "foundation/PxIntrinsics.h"
#include "foundation/PxIO.h"
#include "foundation/PxMat33.h"
#include "foundation/PxMat44.h"
#include "foundation/PxMath.h"
#include "foundation/PxMathIntrinsics.h"
#include "foundation/PxMathUtils.h"
#include "foundation/PxMemory.h"
#include "foundation/PxMutex.h"
#include "foundation/PxPhysicsVersion.h"
#include "foundation/PxPlane.h"
#include "foundation/PxPool.h"
#include "foundation/PxPreprocessor.h"
#include "foundation/PxProfiler.h"
#include "foundation/PxQuat.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxSList.h"
#include "foundation/PxSocket.h"
#include "foundation/PxSort.h"
#include "foundation/PxStrideIterator.h"
#include "foundation/PxString.h"
#include "foundation/PxSync.h"
#include "foundation/PxTempAllocator.h"
#include "foundation/PxThread.h"
#include "foundation/PxTime.h"
#include "foundation/PxTransform.h"
#include "foundation/PxUnionCast.h"
#include "foundation/PxUserAllocated.h"
#include "foundation/PxUtilities.h"
#include "foundation/PxVec2.h"
#include "foundation/PxVec3.h"
#include "foundation/PxVec4.h"
#include "foundation/PxVecMath.h"
#include "foundation/PxVecQuat.h"
#include "foundation/PxVecTransform.h"
//Not physics specific utilities and common code
#include "common/PxCoreUtilityTypes.h"
#include "common/PxPhysXCommonConfig.h"
#include "common/PxRenderBuffer.h"
#include "common/PxBase.h"
#include "common/PxTolerancesScale.h"
#include "common/PxTypeInfo.h"
#include "common/PxStringTable.h"
#include "common/PxSerializer.h"
#include "common/PxSerialFramework.h"
#include "common/PxInsertionCallback.h"
//Task Manager
#include "task/PxTask.h"
// Cuda Mananger
#if PX_SUPPORT_GPU_PHYSX
#include "gpu/PxGpu.h"
#endif
//Geometry Library
#include "geometry/PxBoxGeometry.h"
#include "geometry/PxBVH.h"
#include "geometry/PxBVHBuildStrategy.h"
#include "geometry/PxCapsuleGeometry.h"
#include "geometry/PxConvexMesh.h"
#include "geometry/PxConvexMeshGeometry.h"
#include "geometry/PxGeometry.h"
#include "geometry/PxGeometryHelpers.h"
#include "geometry/PxGeometryQuery.h"
#include "geometry/PxHeightField.h"
#include "geometry/PxHeightFieldDesc.h"
#include "geometry/PxHeightFieldFlag.h"
#include "geometry/PxHeightFieldGeometry.h"
#include "geometry/PxHeightFieldSample.h"
#include "geometry/PxMeshQuery.h"
#include "geometry/PxMeshScale.h"
#include "geometry/PxPlaneGeometry.h"
#include "geometry/PxSimpleTriangleMesh.h"
#include "geometry/PxSphereGeometry.h"
#include "geometry/PxTriangle.h"
#include "geometry/PxTriangleMesh.h"
#include "geometry/PxTriangleMeshGeometry.h"
#include "geometry/PxTetrahedron.h"
#include "geometry/PxTetrahedronMesh.h"
#include "geometry/PxTetrahedronMeshGeometry.h"
// PhysX Core SDK
#include "PxActor.h"
#include "PxAggregate.h"
#include "PxArticulationReducedCoordinate.h"
#include "PxArticulationJointReducedCoordinate.h"
#include "PxArticulationLink.h"
#include "PxClient.h"
#include "PxConeLimitedConstraint.h"
#include "PxConstraint.h"
#include "PxConstraintDesc.h"
#include "PxContact.h"
#include "PxContactModifyCallback.h"
#include "PxDeformableSurface.h"
#include "PxDeformableSurfaceMaterial.h"
#include "PxDeformableVolume.h"
#include "PxDeformableVolumeMaterial.h"
#include "PxDeletionListener.h"
#include "PxFEMSoftBodyMaterial.h" // deprecated, include PxDeformableVolumeMaterial.h
#include "PxFiltering.h"
#include "PxForceMode.h"
#include "PxLockedData.h"
#include "PxMaterial.h"
#include "PxParticleBuffer.h"
#include "PxParticleSystem.h"
#include "PxPBDParticleSystem.h"
#include "PxPBDMaterial.h"
#include "PxPhysics.h"
#include "PxPhysXConfig.h"
#include "PxQueryFiltering.h"
#include "PxQueryReport.h"
#include "PxRigidActor.h"
#include "PxRigidBody.h"
#include "PxRigidDynamic.h"
#include "PxRigidStatic.h"
#include "PxScene.h"
#include "PxSceneDesc.h"
#include "PxSceneLock.h"
#include "PxShape.h"
#include "PxSimulationEventCallback.h"
#include "PxSimulationStatistics.h"
#include "PxSoftBody.h" //deprecated, include PxDeformableVolume.h
#include "PxVisualizationParameter.h"
#include "PxPruningStructure.h"
//Character Controller
#include "characterkinematic/PxBoxController.h"
#include "characterkinematic/PxCapsuleController.h"
#include "characterkinematic/PxController.h"
#include "characterkinematic/PxControllerBehavior.h"
#include "characterkinematic/PxControllerManager.h"
#include "characterkinematic/PxControllerObstacles.h"
#include "characterkinematic/PxExtended.h"
//Cooking (data preprocessing)
#include "cooking/Pxc.h"
#include "cooking/PxConvexMeshDesc.h"
#include "cooking/PxCooking.h"
#include "cooking/PxTriangleMeshDesc.h"
#include "cooking/PxBVH33MidphaseDesc.h"
#include "cooking/PxBVH34MidphaseDesc.h"
#include "cooking/PxMidphaseDesc.h"
//Extensions to the SDK
#include "extensions/PxDefaultStreams.h"
#include "extensions/PxExtensionsAPI.h"
//Serialization
#include "extensions/PxSerialization.h"
#include "extensions/PxRepXSerializer.h"
//Vehicle Simulation
#include "vehicle2/PxVehicleAPI.h"
//Connecting the SDK to Visual Debugger
#include "pvd/PxPvdSceneClient.h"
#include "pvd/PxPvd.h"
#include "pvd/PxPvdTransport.h"
#endif

View File

@@ -0,0 +1,67 @@
// 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 PX_PHYSICS_SERIALIZATION_H
#define PX_PHYSICS_SERIALIZATION_H
#include "common/PxSerialFramework.h"
#include "PxPhysXConfig.h"
#if !PX_DOXYGEN
/**
\brief Registers physics classes for serialization.
This function is used to implement PxSerialization.createSerializationRegistry() and is not intended to be needed otherwise.
\see PxSerializationRegistry
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterPhysicsSerializers(physx::PxSerializationRegistry& sr);
/**
\brief Unregisters physics classes for serialization.
This function is used in the release implementation of PxSerializationRegistry and in not intended to be used otherwise.
\see PxSerializationRegistry
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxUnregisterPhysicsSerializers(physx::PxSerializationRegistry& sr);
/**
\brief Adds collected objects to PxPhysics.
This function adds all objects contained in the input collection to the PxPhysics instance. This is used after deserializing
the collection, to populate the physics with inplace deserialized objects. This function is used in the implementation of
PxSerialization.createCollectionFromBinary and is not intended to be needed otherwise.
\param[in] collection Objects to add to the PxPhysics instance.
\see PxCollection, PxSerialization.createCollectionFromBinary
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxAddCollectionToPhysics(const physx::PxCollection& collection);
#endif // !PX_DOXYGEN
#endif

View File

@@ -0,0 +1,129 @@
// 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 PX_PRUNING_STRUCTURE_H
#define PX_PRUNING_STRUCTURE_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief A precomputed pruning structure to accelerate scene queries against newly added actors.
The pruning structure can be provided to #PxScene:: addActors() in which case it will get merged
directly into the scene query optimization AABB tree, thus leading to improved performance when
doing queries against the newly added actors. This applies to both static and dynamic actors.
\note PxPruningStructure objects can be added to a collection and get serialized.
\note Adding a PxPruningStructure object to a collection will also add the actors that were used to build the pruning structure.
\note PxPruningStructure must be released before its rigid actors.
\note PxRigidBody objects can be in one PxPruningStructure only.
\note Changing the bounds of PxRigidBody objects assigned to a pruning structure that has not been added to a scene yet will
invalidate the pruning structure. Same happens if shape scene query flags change or shape gets removed from an actor.
\see PxScene::addActors PxCollection
*/
class PxPruningStructure : public PxBase
{
public:
/**
\brief Release this object.
*/
virtual void release() = 0;
/**
\brief Retrieve rigid actors in the pruning structure.
You can retrieve the number of rigid actor pointers by calling #getNbRigidActors()
\param[out] userBuffer The buffer to store the actor pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first actor pointer to be retrieved
\return Number of rigid actor pointers written to the buffer.
\see PxRigidActor
*/
virtual PxU32 getRigidActors(PxRigidActor** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/**
\brief Returns the number of rigid actors in the pruning structure.
You can use #getRigidActors() to retrieve the rigid actor pointers.
\return Number of rigid actors in the pruning structure.
\see PxRigidActor
*/
virtual PxU32 getNbRigidActors() const = 0;
/**
\brief Gets the merge data for static actors
This is mainly called by the PxSceneQuerySystem::merge() function to merge a PxPruningStructure
with the internal data-structures of the scene-query system.
\return Implementation-dependent merge data for static actors.
\see PxSceneQuerySystem::merge()
*/
virtual const void* getStaticMergeData() const = 0;
/**
\brief Gets the merge data for dynamic actors
This is mainly called by the PxSceneQuerySystem::merge() function to merge a PxPruningStructure
with the internal data-structures of the scene-query system.
\return Implementation-dependent merge data for dynamic actors.
\see PxSceneQuerySystem::merge()
*/
virtual const void* getDynamicMergeData() const = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxPruningStructure"; }
protected:
PX_INLINE PxPruningStructure(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxPruningStructure(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
virtual ~PxPruningStructure() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxPruningStructure", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,208 @@
// 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 PX_QUERY_FILTERING_H
#define PX_QUERY_FILTERING_H
#include "PxPhysXConfig.h"
#include "PxFiltering.h"
#include "PxQueryReport.h"
#include "PxClient.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxShape;
class PxRigidActor;
struct PxQueryHit;
/**
\brief Filtering flags for scene queries.
\see PxQueryFilterData.flags
*/
struct PxQueryFlag
{
enum Enum
{
eSTATIC = (1<<0), //!< Traverse static shapes
eDYNAMIC = (1<<1), //!< Traverse dynamic shapes
ePREFILTER = (1<<2), //!< Run the pre-intersection-test filter (see #PxQueryFilterCallback::preFilter())
ePOSTFILTER = (1<<3), //!< Run the post-intersection-test filter (see #PxQueryFilterCallback::postFilter())
eANY_HIT = (1<<4), //!< Abort traversal as soon as any hit is found and return it via callback.block.
//!< Helps query performance. Both eTOUCH and eBLOCK hitTypes are considered hits with this flag.
eNO_BLOCK = (1<<5), //!< All hits are reported as touching. Overrides eBLOCK returned from user filters with eTOUCH.
//!< This is also an optimization hint that may improve query performance.
eBATCH_QUERY_LEGACY_BEHAVIOUR = (1<<6), //!< Run with legacy batch query filter behavior. Raising this flag ensures that
//!< the hardcoded filter equation is neglected. This guarantees that any provided PxQueryFilterCallback
//!< will be utilised, as specified by the ePREFILTER and ePOSTFILTER flags.
eDISABLE_HARDCODED_FILTER = (1<<6), //!< Same as eBATCH_QUERY_LEGACY_BEHAVIOUR, more explicit name making it clearer that this can also be used
//!< with regular/non-batched queries if needed.
eRESERVED = (1<<15) //!< Reserved for internal use
};
};
PX_COMPILE_TIME_ASSERT(PxQueryFlag::eSTATIC==(1<<0));
PX_COMPILE_TIME_ASSERT(PxQueryFlag::eDYNAMIC==(1<<1));
PX_COMPILE_TIME_ASSERT(PxQueryFlag::eBATCH_QUERY_LEGACY_BEHAVIOUR==PxQueryFlag::eDISABLE_HARDCODED_FILTER);
/**
\brief Flags typedef for the set of bits defined in PxQueryFlag.
*/
typedef PxFlags<PxQueryFlag::Enum,PxU16> PxQueryFlags;
PX_FLAGS_OPERATORS(PxQueryFlag::Enum,PxU16)
/**
\brief Classification of scene query hits (intersections).
- eNONE: Returning this hit type means that the hit should not be reported.
- eBLOCK: For all raycast, sweep and overlap queries the nearest eBLOCK type hit will always be returned in PxHitCallback::block member.
- eTOUCH: Whenever a raycast, sweep or overlap query was called with non-zero PxHitCallback::nbTouches and PxHitCallback::touches
parameters, eTOUCH type hits that are closer or same distance (touchDistance <= blockDistance condition)
as the globally nearest eBLOCK type hit, will be reported.
- For example, to record all hits from a raycast query, always return eTOUCH.
All hits in overlap() queries are treated as if the intersection distance were zero.
This means the hits are unsorted and all eTOUCH hits are recorded by the callback even if an eBLOCK overlap hit was encountered.
Even though all overlap() blocking hits have zero length, only one (arbitrary) eBLOCK overlap hit is recorded in PxHitCallback::block.
All overlap() eTOUCH type hits are reported (zero touchDistance <= zero blockDistance condition).
For raycast/sweep/overlap calls with zero touch buffer or PxHitCallback::nbTouches member,
only the closest hit of type eBLOCK is returned. All eTOUCH hits are discarded.
\see PxQueryFilterCallback.preFilter PxQueryFilterCallback.postFilter PxScene.raycast PxScene.sweep PxScene.overlap
*/
struct PxQueryHitType
{
enum Enum
{
eNONE = 0, //!< the query should ignore this shape
eTOUCH = 1, //!< a hit on the shape touches the intersection geometry of the query but does not block it
eBLOCK = 2 //!< a hit on the shape blocks the query (does not block overlap queries)
};
};
/**
\brief Scene query filtering data.
Whenever the scene query intersects a shape, filtering is performed in the following order:
\li For non-batched queries only:<br>If the data field is non-zero, and the bitwise-AND value of data AND the shape's
queryFilterData is zero, the shape is skipped
\li If filter callbacks are enabled in flags field (see #PxQueryFlags) they will get invoked accordingly.
\li If neither #PxQueryFlag::ePREFILTER or #PxQueryFlag::ePOSTFILTER is set, the hit defaults
to type #PxQueryHitType::eBLOCK when the value of PxHitCallback::nbTouches provided with the query is zero and to type
#PxQueryHitType::eTOUCH when PxHitCallback::nbTouches is positive.
\see PxScene.raycast PxScene.sweep PxScene.overlap PxQueryFlag::eANY_HIT
*/
struct PxQueryFilterData
{
/** \brief default constructor */
explicit PX_INLINE PxQueryFilterData() : flags(PxQueryFlag::eDYNAMIC | PxQueryFlag::eSTATIC) {}
/** \brief constructor to set both filter data and filter flags */
explicit PX_INLINE PxQueryFilterData(const PxFilterData& fd, PxQueryFlags f) : data(fd), flags(f) {}
/** \brief constructor to set filter flags only */
explicit PX_INLINE PxQueryFilterData(PxQueryFlags f) : flags(f) {}
PxFilterData data; //!< Filter data associated with the scene query
PxQueryFlags flags; //!< Filter flags (see #PxQueryFlags)
};
/**
\brief Scene query filtering callbacks.
Custom filtering logic for scene query intersection candidates. If an intersection candidate object passes the data based filter
(see #PxQueryFilterData), filtering callbacks are executed if requested (see #PxQueryFilterData.flags)
\li If #PxQueryFlag::ePREFILTER is set, the preFilter function runs before exact intersection tests.
If this function returns #PxQueryHitType::eTOUCH or #PxQueryHitType::eBLOCK, exact testing is performed to
determine the intersection location.
The preFilter function may overwrite the copy of queryFlags it receives as an argument to specify any of #PxHitFlag::eMODIFIABLE_FLAGS
on a per-shape basis. Changes apply only to the shape being filtered, and changes to other flags are ignored.
\li If #PxQueryFlag::ePREFILTER is not set, precise intersection testing is performed using the original query's filterData.flags.
\li If #PxQueryFlag::ePOSTFILTER is set, the postFilter function is called for each intersection to determine the touch/block status.
This overrides any touch/block status previously returned from the preFilter function for this shape.
Filtering calls are not guaranteed to be sorted along the ray or sweep direction.
\see PxScene.raycast PxScene.sweep PxScene.overlap PxQueryFlags PxHitFlags
*/
class PxQueryFilterCallback
{
public:
/**
\brief This filter callback is executed before the exact intersection test if PxQueryFlag::ePREFILTER flag was set.
\param[in] filterData custom filter data specified as the query's filterData.data parameter.
\param[in] shape A shape that has not yet passed the exact intersection test.
\param[in] actor The shape's actor.
\param[in,out] queryFlags scene query flags from the query's function call (only flags from PxHitFlag::eMODIFIABLE_FLAGS bitmask can be modified)
\return the updated type for this hit (see #PxQueryHitType)
*/
virtual PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) = 0;
/**
\brief This filter callback is executed if the exact intersection test returned true and PxQueryFlag::ePOSTFILTER flag was set.
\param[in] filterData custom filter data of the query
\param[in] hit Scene query hit information. faceIndex member is not valid for overlap queries. For sweep and raycast queries the hit information can be cast to #PxSweepHit and #PxRaycastHit respectively.
\param[in] shape Hit shape
\param[in] actor Hit actor
\return the updated hit type for this hit (see #PxQueryHitType)
*/
virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit, const PxShape* shape, const PxRigidActor* actor) = 0;
/**
\brief virtual destructor
*/
virtual ~PxQueryFilterCallback() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,281 @@
// 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 PX_QUERY_REPORT_H
#define PX_QUERY_REPORT_H
#include "foundation/PxVec3.h"
#include "foundation/PxFlags.h"
#include "foundation/PxAssert.h"
#include "geometry/PxGeometryHit.h"
#include "geometry/PxGeometryQueryContext.h"
#include "PxPhysXConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxShape;
class PxRigidActor;
/**
\brief Combines a shape pointer and the actor the shape belongs to into one memory location.
Serves as a base class for PxQueryHit.
\see PxQueryHit
*/
struct PxActorShape
{
PX_INLINE PxActorShape() : actor(NULL), shape(NULL) {}
PX_INLINE PxActorShape(PxRigidActor* a, PxShape* s) : actor(a), shape(s) {}
PxRigidActor* actor;
PxShape* shape;
};
// Extends geom hits with Px object pointers
struct PxRaycastHit : PxGeomRaycastHit, PxActorShape {};
struct PxOverlapHit : PxGeomOverlapHit, PxActorShape {};
struct PxSweepHit : PxGeomSweepHit, PxActorShape {};
/**
\brief Describes query behavior after returning a partial query result via a callback.
If callback returns true, traversal will continue and callback can be issued again.
If callback returns false, traversal will stop, callback will not be issued again.
\see PxHitCallback
*/
typedef bool PxAgain;
/**
\brief This callback class facilitates reporting scene query hits (intersections) to the user.
User overrides the virtual processTouches function to receive hits in (possibly multiple) fixed size blocks.
\note PxHitBuffer derives from this class and is used to receive touching hits in a fixed size buffer.
\note Since the compiler doesn't look in template dependent base classes when looking for non-dependent names
\note with some compilers it will be necessary to use "this->hasBlock" notation to access a parent variable
\note in a child callback class.
\note Pre-made typedef shorthands, such as ::PxRaycastCallback can be used for raycast, overlap and sweep queries.
\see PxHitBuffer PxRaycastHit PxSweepHit PxOverlapHit PxRaycastCallback PxOverlapCallback PxSweepCallback
*/
template<typename HitType>
struct PxHitCallback : PxQueryThreadContext
{
HitType block; //!< Holds the closest blocking hit result for the query. Invalid if hasBlock is false.
bool hasBlock; //!< Set to true if there was a blocking hit during query.
HitType* touches; //!< User specified buffer for touching hits.
/**
\brief Size of the user specified touching hits buffer.
\note If set to 0 all hits will default to PxQueryHitType::eBLOCK, otherwise to PxQueryHitType::eTOUCH
\note Hit type returned from pre-filter overrides this default */
PxU32 maxNbTouches;
/**
\brief Number of touching hits returned by the query. Used with PxHitBuffer.
\note If true (PxAgain) is returned from the callback, nbTouches will be reset to 0. */
PxU32 nbTouches;
/**
\brief Initializes the class with user provided buffer.
\param[in] aTouches Optional buffer for recording PxQueryHitType::eTOUCH type hits.
\param[in] aMaxNbTouches Size of touch buffer.
\note if aTouches is NULL and aMaxNbTouches is 0, only the closest blocking hit will be recorded by the query.
\note If PxQueryFlag::eANY_HIT flag is used as a query parameter, hasBlock will be set to true and blockingHit will be used to receive the result.
\note Both eTOUCH and eBLOCK hits will be registered as hasBlock=true and stored in PxHitCallback.block when eANY_HIT flag is used.
\see PxHitCallback.hasBlock PxHitCallback.block */
PxHitCallback(HitType* aTouches, PxU32 aMaxNbTouches)
: hasBlock(false), touches(aTouches), maxNbTouches(aMaxNbTouches), nbTouches(0)
{}
/**
\brief virtual callback function used to communicate query results to the user.
This callback will always be invoked with #touches as a buffer if #touches was specified as non-NULL.
All reported touch hits are guaranteed to be closer than the closest blocking hit.
\param[in] buffer Callback will report touch hits to the user in this buffer. This pointer will be the same as #touches.
\param[in] nbHits Number of touch hits reported in buffer. This number will not exceed #maxNbTouches.
\note There is a significant performance penalty in case multiple touch callbacks are issued (up to 2x)
\note to avoid the penalty use a bigger buffer so that all touching hits can be reported in a single buffer.
\note If true (again) is returned from the callback, nbTouches will be reset to 0,
\note If false is returned, nbTouched will remain unchanged.
\note By the time processTouches is first called, the globally closest blocking hit is already determined,
\note values of hasBlock and block are final and all touch hits are guaranteed to be closer than the blocking hit.
\note touches and maxNbTouches can be modified inside of processTouches callback.
\return true to continue receiving callbacks in case there are more hits or false to stop.
\see PxAgain PxRaycastHit PxSweepHit PxOverlapHit */
virtual PxAgain processTouches(const HitType* buffer, PxU32 nbHits) = 0;
virtual void finalizeQuery() {} //!< Query finalization callback, called after the last processTouches callback.
virtual ~PxHitCallback() {}
/** \brief Returns true if any blocking or touching hits were encountered during a query. */
PX_FORCE_INLINE bool hasAnyHits() { return (hasBlock || (nbTouches > 0)); }
};
/**
\brief Returns scene query hits (intersections) to the user in a preallocated buffer.
Will clip touch hits to maximum buffer capacity. When clipped, an arbitrary subset of touching hits will be discarded.
Overflow does not trigger warnings or errors. block and hasBlock will be valid in finalizeQuery callback and after query completion.
Touching hits are guaranteed to have closer or same distance ( <= condition) as the globally nearest blocking hit at the time any processTouches()
callback is issued.
\note Pre-made typedef shorthands, such as ::PxRaycastBuffer can be used for raycast, overlap and sweep queries.
\see PxHitCallback
\see PxRaycastBuffer PxOverlapBuffer PxSweepBuffer PxRaycastBufferN PxOverlapBufferN PxSweepBufferN
*/
template<typename HitType>
struct PxHitBuffer : public PxHitCallback<HitType>
{
/**
\brief Initializes the buffer with user memory.
The buffer is initialized with 0 touch hits by default => query will only report a single closest blocking hit.
Use PxQueryFlag::eANY_HIT to tell the query to abort and return any first hit encoutered as blocking.
\param[in] aTouches Optional buffer for recording PxQueryHitType::eTOUCH type hits.
\param[in] aMaxNbTouches Size of touch buffer.
\see PxHitCallback */
PxHitBuffer(HitType* aTouches = NULL, PxU32 aMaxNbTouches = 0) : PxHitCallback<HitType>(aTouches, aMaxNbTouches) {}
/** \brief Computes the number of any hits in this result, blocking or touching. */
PX_INLINE PxU32 getNbAnyHits() const { return getNbTouches() + PxU32(this->hasBlock); }
/** \brief Convenience iterator used to access any hits in this result, blocking or touching. */
PX_INLINE const HitType& getAnyHit(const PxU32 index) const { PX_ASSERT(index < getNbTouches() + PxU32(this->hasBlock));
return index < getNbTouches() ? getTouches()[index] : this->block; }
PX_INLINE PxU32 getNbTouches() const { return this->nbTouches; }
PX_INLINE const HitType* getTouches() const { return this->touches; }
PX_INLINE const HitType& getTouch(const PxU32 index) const { PX_ASSERT(index < getNbTouches()); return getTouches()[index]; }
PX_INLINE PxU32 getMaxNbTouches() const { return this->maxNbTouches; }
virtual ~PxHitBuffer() {}
protected:
// stops after the first callback
virtual PxAgain processTouches(const HitType* buffer, PxU32 nbHits) { PX_UNUSED(buffer); PX_UNUSED(nbHits); return false; }
};
/** \brief Raycast query callback. */
typedef PxHitCallback<PxRaycastHit> PxRaycastCallback;
/** \brief Overlap query callback. */
typedef PxHitCallback<PxOverlapHit> PxOverlapCallback;
/** \brief Sweep query callback. */
typedef PxHitCallback<PxSweepHit> PxSweepCallback;
/** \brief Raycast query buffer. */
typedef PxHitBuffer<PxRaycastHit> PxRaycastBuffer;
/** \brief Overlap query buffer. */
typedef PxHitBuffer<PxOverlapHit> PxOverlapBuffer;
/** \brief Sweep query buffer. */
typedef PxHitBuffer<PxSweepHit> PxSweepBuffer;
/** \brief Returns touching raycast hits to the user in a fixed size array embedded in the buffer class. **/
template <int N>
struct PxRaycastBufferN : public PxHitBuffer<PxRaycastHit>
{
PxRaycastHit hits[N];
PxRaycastBufferN() : PxHitBuffer<PxRaycastHit>(hits, N) {}
};
/** \brief Returns touching overlap hits to the user in a fixed size array embedded in the buffer class. **/
template <int N>
struct PxOverlapBufferN : public PxHitBuffer<PxOverlapHit>
{
PxOverlapHit hits[N];
PxOverlapBufferN() : PxHitBuffer<PxOverlapHit>(hits, N) {}
};
/** \brief Returns touching sweep hits to the user in a fixed size array embedded in the buffer class. **/
template <int N>
struct PxSweepBufferN : public PxHitBuffer<PxSweepHit>
{
PxSweepHit hits[N];
PxSweepBufferN() : PxHitBuffer<PxSweepHit>(hits, N) {}
};
/**
\brief single hit cache for scene queries.
If a cache object is supplied to a scene query, the cached actor/shape pair is checked for intersection first.
\note Filters are not executed for the cached shape.
\note If intersection is found, the hit is treated as blocking.
\note Typically actor and shape from the last PxHitCallback.block query result is used as a cached actor/shape pair.
\note Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking.
\note Cache is only used if no touch buffer was provided, for single nearest blocking hit queries and queries using eANY_HIT flag.
\note if non-zero touch buffer was provided, cache will be ignored
\note It is the user's responsibility to ensure that the shape and actor are valid, so care must be taken
when deleting shapes to invalidate cached references.
The faceIndex field is an additional hint for a mesh or height field which is not currently used.
\see PxScene.raycast
*/
struct PxQueryCache
{
/**
\brief constructor sets to default
*/
PX_INLINE PxQueryCache() : shape(NULL), actor(NULL), faceIndex(0xffffffff) {}
/**
\brief constructor to set properties
*/
PX_INLINE PxQueryCache(PxShape* s, PxU32 findex) : shape(s), actor(NULL), faceIndex(findex) {}
PxShape* shape; //!< Shape to test for intersection first
PxRigidActor* actor; //!< Actor to which the shape belongs
PxU32 faceIndex; //!< Triangle index to test first - NOT CURRENTLY SUPPORTED
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,83 @@
// 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 PX_RESIDUAL_H
#define PX_RESIDUAL_H
#include "PxPhysXConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Structure representing residual values.
This struct holds residual values, typically used in physics simulations to measure error or discrepancy.
*/
struct PxResidual
{
PxReal rmsResidual; //!< Root mean square residual value.
PxReal maxResidual; //!< Maximum residual value.
PxResidual() : rmsResidual(0.0f), maxResidual(0.0f) {}
};
/**
\brief Structure representing residual values
This struct holds residual values for both position and velocity iterations.
*/
struct PxResiduals
{
PxResidual positionIterationResidual; //!< Residual values for position iteration.
PxResidual velocityIterationResidual; //!< Residual values for velocity iteration.
};
typedef PxResiduals PxArticulationResidual;
typedef PxResiduals PxSceneResidual;
/**
\brief Structure representing residual values for a constraint.
This struct holds residual values for both position and velocity iterations specific to a constraint.
*/
struct PxConstraintResidual
{
PxReal positionIterationResidual; //!< Residual value for position iteration.
PxReal velocityIterationResidual; //!< Residual value for velocity iteration.
PxConstraintResidual() : positionIterationResidual(0.0f), velocityIterationResidual(0.0f) {}
};
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,238 @@
// 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 PX_RIGID_ACTOR_H
#define PX_RIGID_ACTOR_H
#include "PxActor.h"
#include "PxShape.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxConstraint;
/**
\brief PxRigidActor represents a base class shared between dynamic and static rigid bodies in the physics SDK.
PxRigidActor objects specify the geometry of the object by defining a set of attached shapes (see #PxShape).
\see PxActor
*/
class PxRigidActor : public PxActor
{
public:
/**
\brief Deletes the rigid actor object.
Also releases any shapes associated with the actor.
Releasing an actor will affect any objects that are connected to the actor (constraint shaders like joints etc.).
Such connected objects will be deleted upon scene deletion, or explicitly by the user by calling release()
on these objects. It is recommended to always remove all objects that reference actors before the actors
themselves are removed. It is not possible to retrieve list of dead connected objects.
<b>Sleeping:</b> This call will awaken any sleeping actors contacting the deleted actor (directly or indirectly).
Calls #PxActor::release() so you might want to check the documentation of that method as well.
\see PxActor::release()
*/
virtual void release() = 0;
/**
\brief Returns the internal actor index.
\warning This is only defined for actors that have been added to a scene.
\return The internal actor index, or 0xffffffff if the actor is not part of a scene.
*/
virtual PxU32 getInternalActorIndex() const = 0;
/************************************************************************************************/
/** \name Global Pose Manipulation
*/
/**
\brief Retrieves the actors world space transform.
The getGlobalPose() method retrieves the actor's current actor space to world space transformation.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\note If this actor is a PxRigidDynamic or PxArticulationLink, this method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\return Global pose of object.
\see PxRigidDynamic.setGlobalPose() PxRigidStatic.setGlobalPose()
*/
virtual PxTransform getGlobalPose() const = 0;
/**
\brief Method for setting an actor's pose in the world.
This method instantaneously changes the actor space to world space transformation.
This method is mainly for dynamic rigid bodies (see #PxRigidDynamic). Calling this method on static actors is
likely to result in a performance penalty, since internal optimization structures for static actors may need to be
recomputed. In addition, moving static actors will not interact correctly with dynamic actors or joints.
To directly control an actor's position and have it correctly interact with dynamic bodies and joints, create a dynamic
body with the PxRigidBodyFlag::eKINEMATIC flag, then use the setKinematicTarget() commands to define its path.
Even when moving dynamic actors, exercise restraint in making use of this method. Where possible, avoid:
\li moving actors into other actors, thus causing overlap (an invalid physical state)
\li moving an actor that is connected by a joint to another away from the other (thus causing joint error)
\note It is not allowed to use this method if the actor is part of a #PxPruningStructure that has not been
added to a scene yet.
\note If this actor is a PxRigidDynamic or PxArticulationLink, this method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
<b>Sleeping:</b> This call wakes dynamic actors if they are sleeping and the autowake parameter is true (default).
\param[in] pose Transformation from the actors local frame to the global frame. <b>Range:</b> rigid body transform.
\param[in] autowake whether to wake the object if it is dynamic. This parameter has no effect for static or kinematic actors. If true and the current wake counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value.
\see getGlobalPose()
*/
virtual void setGlobalPose(const PxTransform& pose, bool autowake = true) = 0;
/************************************************************************************************/
/** \name Shapes
*/
/**
\brief Attach a shape to an actor
This call will increment the reference count of the shape.
\note Mass properties of dynamic rigid actors will not automatically be recomputed
to reflect the new mass distribution implied by the shape. Follow this call with a call to
the PhysX extensions method #PxRigidBodyExt::updateMassAndInertia() to do that.
Attaching a triangle mesh, heightfield or plane geometry shape configured as eSIMULATION_SHAPE is not supported for
non-kinematic PxRigidDynamic instances.
<b>Sleeping:</b> Does <b>NOT</b> wake the actor up automatically.
\param[in] shape the shape to attach.
\return True if success.
*/
virtual bool attachShape(PxShape& shape) = 0;
/**
\brief Detach a shape from an actor.
This will also decrement the reference count of the PxShape, and if the reference count is zero, will cause it to be deleted.
<b>Sleeping:</b> Does <b>NOT</b> wake the actor up automatically.
\param[in] shape the shape to detach.
\param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulationReducedCoordinate and PxRigidActor types.
*/
virtual void detachShape(PxShape& shape, bool wakeOnLostTouch = true) = 0;
/**
\brief Returns the number of shapes assigned to the actor.
You can use #getShapes() to retrieve the shape pointers.
\return Number of shapes associated with this actor.
\see PxShape getShapes()
*/
virtual PxU32 getNbShapes() const = 0;
/**
\brief Retrieve all the shape pointers belonging to the actor.
These are the shapes used by the actor for collision detection.
You can retrieve the number of shape pointers by calling #getNbShapes()
Note: Removing shapes with #PxShape::release() will invalidate the pointer of the released shape.
\param[out] userBuffer The buffer to store the shape pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first shape pointer to be retrieved
\return Number of shape pointers written to the buffer.
\see PxShape getNbShapes() PxShape::release()
*/
virtual PxU32 getShapes(PxShape** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/************************************************************************************************/
/** \name Constraints
*/
/**
\brief Returns the number of constraint shaders attached to the actor.
You can use #getConstraints() to retrieve the constraint shader pointers.
\return Number of constraint shaders attached to this actor.
\see PxConstraint getConstraints()
*/
virtual PxU32 getNbConstraints() const = 0;
/**
\brief Retrieve all the constraint shader pointers belonging to the actor.
You can retrieve the number of constraint shader pointers by calling #getNbConstraints()
Note: Removing constraint shaders with #PxConstraint::release() will invalidate the pointer of the released constraint.
\param[out] userBuffer The buffer to store the constraint shader pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first constraint pointer to be retrieved
\return Number of constraint shader pointers written to the buffer.
\see PxConstraint getNbConstraints() PxConstraint::release()
*/
virtual PxU32 getConstraints(PxConstraint** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
protected:
PX_INLINE PxRigidActor(PxType concreteType, PxBaseFlags baseFlags) : PxActor(concreteType, baseFlags) {}
PX_INLINE PxRigidActor(PxBaseFlags baseFlags) : PxActor(baseFlags) {}
virtual ~PxRigidActor() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxRigidActor", PxActor); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,779 @@
// 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 PX_RIGID_BODY_H
#define PX_RIGID_BODY_H
#include "PxRigidActor.h"
#include "PxForceMode.h"
#include "PxNodeIndex.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Collection of flags describing the behavior of a rigid body.
\see PxRigidBody.setRigidBodyFlag(), PxRigidBody.getRigidBodyFlags()
*/
struct PxRigidBodyFlag
{
enum Enum
{
/**
\brief Enables kinematic mode for the actor.
Kinematic actors are special dynamic actors that are not
influenced by forces (such as gravity), and have no momentum. They are considered to have infinite
mass and can be moved around the world using the setKinematicTarget() method. They will push
regular dynamic actors out of the way. Kinematics will not collide with static or other kinematic objects.
Kinematic actors are great for moving platforms or characters, where direct motion control is desired.
You can not connect Reduced joints to kinematic actors. Lagrange joints work ok if the platform
is moving with a relatively low, uniform velocity.
<b>Sleeping:</b>
\li Setting this flag on a dynamic actor will put the actor to sleep and set the velocities to 0.
\li If this flag gets cleared, the current sleep state of the actor will be kept.
\note kinematic actors are incompatible with CCD so raising this flag will automatically clear eENABLE_CCD
\see PxRigidDynamic.setKinematicTarget()
*/
eKINEMATIC = (1<<0), //!< Enable kinematic mode for the body.
/**
\brief Use the kinematic target transform for scene queries.
If this flag is raised, then scene queries will treat the kinematic target transform as the current pose
of the body (instead of using the actual pose). Without this flag, the kinematic target will only take
effect with respect to scene queries after a simulation step.
\see PxRigidDynamic.setKinematicTarget()
*/
eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES = (1<<1),
/**
\brief Enables swept integration for the actor.
If this flag is raised and CCD is enabled on the scene, then this body will be simulated by the CCD system to ensure that collisions are not missed due to
high-speed motion. Note individual shape pairs still need to enable PxPairFlag::eDETECT_CCD_CONTACT in the collision filtering to enable the CCD to respond to
individual interactions.
\note kinematic actors are incompatible with CCD so this flag will be cleared automatically when raised on a kinematic actor
\note PxConvexCoreGeometry geometry type only supports eENABLE_SPECULATIVE_CCD at the moment. eENABLE_CCD will be ignored
*/
eENABLE_CCD = (1<<2), //!< Enable CCD for the body.
/**
\brief Enabled CCD in swept integration for the actor.
If this flag is raised and CCD is enabled, CCD interactions will simulate friction. By default, friction is disabled in CCD interactions because
CCD friction has been observed to introduce some simulation artifacts. CCD friction was enabled in previous versions of the SDK. Raising this flag will result in behavior
that is a closer match for previous versions of the SDK.
\note This flag requires PxRigidBodyFlag::eENABLE_CCD to be raised to have any effect.
*/
eENABLE_CCD_FRICTION = (1<<3),
/**
\brief Register a rigid body to dynamically adjust contact offset based on velocity. This can be used to achieve a CCD effect.
If both eENABLE_CCD and eENABLE_SPECULATIVE_CCD are set on the same body, then angular motions are handled by speculative
contacts (eENABLE_SPECULATIVE_CCD) while linear motions are handled by sweeps (eENABLE_CCD).
*/
eENABLE_SPECULATIVE_CCD = (1<<4),
/**
\brief Register a rigid body for reporting pose changes by the simulation at an early stage.
Sometimes it might be advantageous to get access to the new pose of a rigid body as early as possible and
not wait until the call to fetchResults() returns. Setting this flag will schedule the rigid body to get reported
in #PxSimulationEventCallback::onAdvance(). Please refer to the documentation of that callback to understand
the behavior and limitations of this functionality.
\see PxSimulationEventCallback::onAdvance()
*/
eENABLE_POSE_INTEGRATION_PREVIEW = (1<<5),
/**
\brief Permit CCD to limit maxContactImpulse. This is useful for use-cases like a destruction system but can cause visual artefacts so is not enabled by default.
*/
eENABLE_CCD_MAX_CONTACT_IMPULSE = (1<<6),
/**
\brief Carries over forces/torques between frames, rather than clearing them
If this flag is raised, forces and torques will carry over between frames. Impulses applied with PxForceMode::eIMPULSE will not be retained.
\note Clearing this flag will retain the accelerations for an additional frame before clearing them. To reset the forces immediately for the next frame,
a call to PxRigidBody::clearForce() / PxRigidBody::clearTorque() is needed.
\see PxRigidBody::addForce(), PxRigidBody::AddTorque(), PxRigidBody::setForceAndTorque(), PxRigidBody::clearForce(), PxRigidBody::clearTorque()
*/
eRETAIN_ACCELERATIONS = (1<<7),
/**
\brief Forces kinematic-kinematic pairs notifications for this actor.
This flag overrides the global scene-level PxPairFilteringMode setting for kinematic actors.
This is equivalent to having PxPairFilteringMode::eKEEP for pairs involving this actor.
A particular use case is when you have a large amount of kinematic actors, but you are only
interested in interactions between a few of them. In this case it is best to use
PxSceneDesc.kineKineFilteringMode = PxPairFilteringMode::eKILL, and then raise the
eFORCE_KINE_KINE_NOTIFICATIONS flag on the small set of kinematic actors that need
notifications.
\note This has no effect if PxRigidBodyFlag::eKINEMATIC is not set.
\warning Changing this flag at runtime will not have an effect until you remove and re-add the actor to the scene.
\see PxPairFilteringMode PxSceneDesc.kineKineFilteringMode
*/
eFORCE_KINE_KINE_NOTIFICATIONS = (1<<8),
/**
\brief Forces static-kinematic pairs notifications for this actor.
Similar to eFORCE_KINE_KINE_NOTIFICATIONS, but for static-kinematic interactions.
\note This has no effect if PxRigidBodyFlag::eKINEMATIC is not set.
\warning Changing this flag at runtime will not have an effect until you remove and re-add the actor to the scene.
\see PxPairFilteringMode PxSceneDesc.staticKineFilteringMode
*/
eFORCE_STATIC_KINE_NOTIFICATIONS = (1<<9),
/**
\brief Enables computation of gyroscopic forces on the rigid body.
*/
eENABLE_GYROSCOPIC_FORCES = (1<<10),
/**
\brief Reserved for internal usage
*/
eRESERVED = (1<<15)
};
};
/**
\brief collection of set bits defined in PxRigidBodyFlag.
\see PxRigidBodyFlag
*/
typedef PxFlags<PxRigidBodyFlag::Enum,PxU16> PxRigidBodyFlags;
PX_FLAGS_OPERATORS(PxRigidBodyFlag::Enum,PxU16)
/**
\brief PxRigidBody is a base class shared between dynamic rigid body objects.
\see PxRigidActor
*/
class PxRigidBody : public PxRigidActor
{
public:
// Runtime modifications
/************************************************************************************************/
/** \name Mass Manipulation
*/
/**
\brief Sets the pose of the center of mass relative to the actor.
\note Changing this transform will not move the actor in the world!
\note Setting an unrealistic center of mass which is a long way from the body can make it difficult for
the SDK to solve constraints. Perhaps leading to instability and jittering bodies.
\note Changing this transform will not update the linear velocity reported by getLinearVelocity() to account
for the shift in center of mass. If the shift should be accounted for, the user should update the velocity
using setLinearVelocity().
<b>Default:</b> the identity transform
\param[in] pose Mass frame offset transform relative to the actor frame. <b>Range:</b> rigid body transform.
\see getCMassLocalPose() getLinearVelocity()
*/
virtual void setCMassLocalPose(const PxTransform& pose) = 0;
/**
\brief Retrieves the center of mass pose relative to the actor frame.
\return The center of mass pose relative to the actor frame.
\see setCMassLocalPose()
*/
virtual PxTransform getCMassLocalPose() const = 0;
/**
\brief Sets the mass of a dynamic actor.
The mass must be non-negative.
setMass() does not update the inertial properties of the body, to change the inertia tensor
use setMassSpaceInertiaTensor() or the PhysX extensions method #PxRigidBodyExt::updateMassAndInertia().
\note A value of 0 is interpreted as infinite mass.
\note Values of 0 are not permitted for instances of PxArticulationLink but are permitted for instances of PxRigidDynamic.
<b>Default:</b> 1.0
<b>Sleeping:</b> Does <b>NOT</b> wake the actor up automatically.
\param[in] mass New mass value for the actor. <b>Range:</b> [0, PX_MAX_F32)
\see getMass() setMassSpaceInertiaTensor()
*/
virtual void setMass(PxReal mass) = 0;
/**
\brief Retrieves the mass of the actor.
\note A value of 0 is interpreted as infinite mass.
\return The mass of this actor.
\see setMass() setMassSpaceInertiaTensor()
*/
virtual PxReal getMass() const = 0;
/**
\brief Retrieves the inverse mass of the actor.
\return The inverse mass of this actor.
\see setMass() setMassSpaceInertiaTensor()
*/
virtual PxReal getInvMass() const = 0;
/**
\brief Sets the inertia tensor, using a parameter specified in mass space coordinates.
Note that such matrices are diagonal -- the passed vector is the diagonal.
If you have a non diagonal world/actor space inertia tensor(3x3 matrix). Then you need to
diagonalize it and set an appropriate mass space transform. See #setCMassLocalPose().
The inertia tensor elements must be non-negative.
\note A value of 0 in an element is interpreted as infinite inertia along that axis.
\note Values of 0 are not permitted for instances of PxArticulationLink but are permitted for instances of PxRigidDynamic.
<b>Default:</b> (1.0, 1.0, 1.0)
<b>Sleeping:</b> Does <b>NOT</b> wake the actor up automatically.
\param[in] m New mass space inertia tensor for the actor.
\see getMassSpaceInertia() setMass() setCMassLocalPose()
*/
virtual void setMassSpaceInertiaTensor(const PxVec3& m) = 0;
/**
\brief Retrieves the diagonal inertia tensor of the actor relative to the mass coordinate frame.
This method retrieves a mass frame inertia vector.
\return The mass space inertia tensor of this actor.
\note A value of 0 in an element is interpreted as infinite inertia along that axis.
\see setMassSpaceInertiaTensor() setMass() setCMassLocalPose()
*/
virtual PxVec3 getMassSpaceInertiaTensor() const = 0;
/**
\brief Retrieves the diagonal inverse inertia tensor of the actor relative to the mass coordinate frame.
This method retrieves a mass frame inverse inertia vector.
\note A value of 0 in an element is interpreted as infinite inertia along that axis.
\return The mass space inverse inertia tensor of this actor.
\see setMassSpaceInertiaTensor() setMass() setCMassLocalPose()
*/
virtual PxVec3 getMassSpaceInvInertiaTensor() const = 0;
/************************************************************************************************/
/** \name Damping
*/
/**
\brief Sets the linear damping coefficient.
Zero represents no damping. The damping coefficient must be nonnegative.
<b>Default:</b> 0.05 for PxArticulationLink, 0.0 for PxRigidDynamic
\param[in] linDamp Linear damping coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see getLinearDamping() setAngularDamping()
*/
virtual void setLinearDamping(PxReal linDamp) = 0;
/**
\brief Retrieves the linear damping coefficient.
\return The linear damping coefficient associated with this actor.
\see setLinearDamping() getAngularDamping()
*/
virtual PxReal getLinearDamping() const = 0;
/**
\brief Sets the angular damping coefficient.
Zero represents no damping.
The angular damping coefficient must be nonnegative.
<b>Default:</b> 0.05
\param[in] angDamp Angular damping coefficient. <b>Range:</b> [0, PX_MAX_F32)
\see getAngularDamping() setLinearDamping()
*/
virtual void setAngularDamping(PxReal angDamp) = 0;
/**
\brief Retrieves the angular damping coefficient.
\return The angular damping coefficient associated with this actor.
\see setAngularDamping() getLinearDamping()
*/
virtual PxReal getAngularDamping() const = 0;
/************************************************************************************************/
/** \name Velocity
*/
/**
\brief Retrieves the linear velocity of an actor.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\note The linear velocity is reported with respect to the rigid body's center of mass and not the actor frame origin.
\return The linear velocity of the actor.
\see PxRigidDynamic.setLinearVelocity() getAngularVelocity()
*/
virtual PxVec3 getLinearVelocity() const = 0;
/**
\brief Retrieves the angular velocity of the actor.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\return The angular velocity of the actor.
\see PxRigidDynamic.setAngularVelocity() getLinearVelocity()
*/
virtual PxVec3 getAngularVelocity() const = 0;
/**
\brief Lets you set the maximum linear velocity permitted for this actor.
With this function, you can set the maximum linear velocity permitted for this rigid body.
Higher linear velocities are clamped to this value.
Note: The linear velocity is clamped to the set value <i>before</i> the solver, which means that
the limit may still be momentarily exceeded.
\note Enforcing the limit introduces momentum into the simulation, causing potentially unphysical behavior.
For articulation links, consider using joint damping and limits instead, which preserve momentum.
<b>Default:</b> 100 * PxTolerancesScale::length /s for PxArticulationLink, 1e^16 lengthUnits/s for PxRigidDynamic
\param[in] maxLinVel Max allowable linear velocity for actor. <b>Range:</b> [0, 1e^16) lengthUnits/s
\see getMaxAngularVelocity()
*/
virtual void setMaxLinearVelocity(PxReal maxLinVel) = 0;
/**
\brief Retrieves the maximum angular velocity permitted for this actor.
\return The maximum allowed angular velocity for this actor.
\see setMaxLinearVelocity
*/
virtual PxReal getMaxLinearVelocity() const = 0;
/**
\brief Lets you set the maximum angular velocity permitted for this actor.
For various internal computations, very quickly rotating actors introduce error
into the simulation, which leads to undesired results.
With this function, you can set the maximum angular velocity permitted for this rigid body.
Higher angular velocities are clamped to this value.
Note: The angular velocity is clamped to the set value <i>before</i> the solver, which means that
the limit may still be momentarily exceeded.
\note Enforcing the limit introduces momentum into the simulation, causing potentially unphysical behavior.
For articulation links, consider using joint damping and limits instead, which preserve momentum.
<b>Default:</b> 50.0 rad/s for PxArticulationLink, 100.0 rad/s for PxRigidDynamic
<b>Range:</b> [0, 1e^16) rad/s
\param[in] maxAngVel Max allowable angular velocity for actor.
\see getMaxAngularVelocity()
*/
virtual void setMaxAngularVelocity(PxReal maxAngVel) = 0;
/**
\brief Retrieves the maximum angular velocity permitted for this actor.
\return The maximum allowed angular velocity for this actor.
\see setMaxAngularVelocity
*/
virtual PxReal getMaxAngularVelocity() const = 0;
/************************************************************************************************/
/** \name Acceleration
*/
/**
\brief Retrieves the linear acceleration of an actor.
For PxArticulationLink objects, this function is always available.
For PxRigidDynamic actors, this function only returns valid results if PxSceneFlag::eENABLE_BODY_ACCELERATIONS is enabled.
If that flag is not enabled, the function returns zero for PxRigidDynamic actors.
\return The linear acceleration of the actor, or zero if PxSceneFlag::eENABLE_BODY_ACCELERATIONS is disabled and the object is a PxRigidDynamic.
\see PxRigidBody.getAngularAcceleration() PxSceneFlag::eENABLE_BODY_ACCELERATIONS
*/
virtual PxVec3 getLinearAcceleration() const = 0;
/**
\brief Retrieves the angular acceleration of an actor.
For PxArticulationLink objects, this function is always available.
For PxRigidDynamic actors, this function only returns valid results if PxSceneFlag::eENABLE_BODY_ACCELERATIONS is enabled.
If that flag is not enabled, the function returns zero for PxRigidDynamic actors.
\return The angular acceleration of the actor, or zero if PxSceneFlag::eENABLE_BODY_ACCELERATIONS is disabled and the object is a PxRigidDynamic.
\see PxRigidBody.getLinearAcceleration() PxSceneFlag::eENABLE_BODY_ACCELERATIONS
*/
virtual PxVec3 getAngularAcceleration() const = 0;
/************************************************************************************************/
/** \name Forces
*/
/**
\brief Applies a force (or impulse) defined in the global coordinate frame to the actor at its center of mass.
<b>This will not induce a torque</b>.
::PxForceMode determines if the force is to be conventional or impulsive.
Each actor has an acceleration and a velocity change accumulator which are directly modified using the modes PxForceMode::eACCELERATION
and PxForceMode::eVELOCITY_CHANGE respectively. The modes PxForceMode::eFORCE and PxForceMode::eIMPULSE also modify these same
accumulators and are just short hand for multiplying the vector parameter by inverse mass and then using PxForceMode::eACCELERATION and
PxForceMode::eVELOCITY_CHANGE respectively.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links.
\note if this is called on an articulation link, only the link is updated, not the entire articulation.
\note see #PxRigidBodyExt::computeVelocityDeltaFromImpulse for details of how to compute the change in linear velocity that
will arise from the application of an impulsive force, where an impulsive force is applied force multiplied by a timestep.
\note Forces will be cleared automatically after they are applied during the next simulation step. If the forces should be retained for
the following steps, PxRigidBodyFlag::eRETAIN_ACCELERATIONS should be raised.
<b>Sleeping:</b> This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the force is non-zero.
\param[in] force Force/Impulse to apply defined in the global frame.
\param[in] mode The mode to use when applying the force/impulse(see #PxForceMode)
\param[in] autowake Specify if the call should wake up the actor if it is currently asleep. If true and the current wake counter value
is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value.
\see PxForceMode addTorque
*/
virtual void addForce(const PxVec3& force, PxForceMode::Enum mode = PxForceMode::eFORCE, bool autowake = true) = 0;
/**
\brief Applies an impulsive torque defined in the global coordinate frame to the actor.
::PxForceMode determines if the torque is to be conventional or impulsive.
Each actor has an angular acceleration and an angular velocity change accumulator which are directly modified using the modes
PxForceMode::eACCELERATION and PxForceMode::eVELOCITY_CHANGE respectively. The modes PxForceMode::eFORCE and PxForceMode::eIMPULSE
also modify these same accumulators and are just short hand for multiplying the vector parameter by inverse inertia and then
using PxForceMode::eACCELERATION and PxForceMode::eVELOCITY_CHANGE respectively.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links.
\note if this called on an articulation link, only the link is updated, not the entire articulation.
\note see #PxRigidBodyExt::computeVelocityDeltaFromImpulse for details of how to compute the change in angular velocity that
will arise from the application of an impulsive torque, where an impulsive torque is an applied torque multiplied by a timestep.
\note Torques will be cleared after they are applied during the next simulation step. If the Torques should be retained for the following
steps, PxRigidBodyFlag::eRETAIN_ACCELERATIONS should be raised.
<b>Sleeping:</b> This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the torque is non-zero.
\param[in] torque Torque to apply defined in the global frame. <b>Range:</b> torque vector
\param[in] mode The mode to use when applying the force/impulse(see #PxForceMode).
\param[in] autowake Specify if the call should wake up the actor if it is currently asleep. If true and the current wake counter value
is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value.
\see PxForceMode addForce()
*/
virtual void addTorque(const PxVec3& torque, PxForceMode::Enum mode = PxForceMode::eFORCE, bool autowake = true) = 0;
/**
\brief Clears the accumulated forces (sets the accumulated force back to zero).
Each actor has an acceleration and a velocity change accumulator which are directly modified using the modes PxForceMode::eACCELERATION
and PxForceMode::eVELOCITY_CHANGE respectively. The modes PxForceMode::eFORCE and PxForceMode::eIMPULSE also modify these same
accumulators (see PxRigidBody::addForce() for details); therefore the effect of calling clearForce(PxForceMode::eFORCE) is equivalent to calling
clearForce(PxForceMode::eACCELERATION), and the effect of calling clearForce(PxForceMode::eIMPULSE) is equivalent to calling
clearForce(PxForceMode::eVELOCITY_CHANGE).
::PxForceMode determines if the cleared force is to be conventional or impulsive.
\note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\param[in] mode The mode to use when clearing the force/impulse(see #PxForceMode)
\see PxForceMode addForce
*/
virtual void clearForce(PxForceMode::Enum mode = PxForceMode::eFORCE) = 0;
/**
\brief Clears the impulsive torque defined in the global coordinate frame to the actor.
::PxForceMode determines if the cleared torque is to be conventional or impulsive.
Each actor has an angular acceleration and a velocity change accumulator which are directly modified using the modes PxForceMode::eACCELERATION
and PxForceMode::eVELOCITY_CHANGE respectively. The modes PxForceMode::eFORCE and PxForceMode::eIMPULSE also modify these same
accumulators (see PxRigidBody::addTorque() for details); therefore the effect of calling clearTorque(PxForceMode::eFORCE) is equivalent to calling
clearTorque(PxForceMode::eACCELERATION), and the effect of calling clearTorque(PxForceMode::eIMPULSE) is equivalent to calling
clearTorque(PxForceMode::eVELOCITY_CHANGE).
\note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\param[in] mode The mode to use when clearing the force/impulse(see #PxForceMode).
\see PxForceMode addTorque
*/
virtual void clearTorque(PxForceMode::Enum mode = PxForceMode::eFORCE) = 0;
/**
\brief Sets the impulsive force and torque defined in the global coordinate frame to the actor.
::PxForceMode determines if the cleared torque is to be conventional or impulsive.
\note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\note Forces and torques will be cleared after they are applied during the next simulation step. If they should be retained for the following
steps, PxRigidBodyFlag::eRETAIN_ACCELERATIONS should be raised.
\see PxForceMode addTorque
*/
virtual void setForceAndTorque(const PxVec3& force, const PxVec3& torque, PxForceMode::Enum mode = PxForceMode::eFORCE) = 0;
/**
\brief Raises or clears a particular rigid body flag.
See the list of flags #PxRigidBodyFlag
<b>Default:</b> no flags are set
<b>Sleeping:</b> Does <b>NOT</b> wake the actor up automatically.
\param[in] flag The PxRigidBody flag to raise(set) or clear. See #PxRigidBodyFlag.
\param[in] value The new boolean value for the flag.
\see PxRigidBodyFlag getRigidBodyFlags()
*/
virtual void setRigidBodyFlag(PxRigidBodyFlag::Enum flag, bool value) = 0;
virtual void setRigidBodyFlags(PxRigidBodyFlags inFlags) = 0;
/**
\brief Reads the PxRigidBody flags.
See the list of flags #PxRigidBodyFlag
\return The values of the PxRigidBody flags.
\see PxRigidBodyFlag setRigidBodyFlag()
*/
virtual PxRigidBodyFlags getRigidBodyFlags() const = 0;
/**
\brief Sets the CCD minimum advance coefficient.
The CCD minimum advance coefficient is a value in the range [0, 1] that is used to control the minimum amount of time a body is integrated when
it has a CCD contact. The actual minimum amount of time that is integrated depends on various properties, including the relative speed and collision shapes
of the bodies involved in the contact. From these properties, a numeric value is calculated that determines the maximum distance (and therefore maximum time)
which these bodies could be integrated forwards that would ensure that these bodies did not pass through each-other. This value is then scaled by CCD minimum advance
coefficient to determine the amount of time that will be consumed in the CCD pass.
<b>Things to consider:</b>
A large value (approaching 1) ensures that the objects will always advance some time. However, larger values increase the chances of objects gently drifting through each-other in
scenes which the constraint solver can't converge, e.g. scenes where an object is being dragged through a wall with a constraint.
A value of 0 ensures that the pair of objects stop at the exact time-of-impact and will not gently drift through each-other. However, with very small/thin objects initially in
contact, this can lead to a large amount of time being dropped and increases the chances of jamming. Jamming occurs when the an object is persistently in contact with an object
such that the time-of-impact is 0, which results in no time being advanced for those objects in that CCD pass.
The chances of jamming can be reduced by increasing the number of CCD mass \see PxSceneDesc.ccdMaxPasses. However, increasing this number increases the CCD overhead.
\param[in] advanceCoefficient The CCD min advance coefficient. <b>Range:</b> [0, 1] <b>Default:</b> 0.15
*/
virtual void setMinCCDAdvanceCoefficient(PxReal advanceCoefficient) = 0;
/**
\brief Gets the CCD minimum advance coefficient.
\return The value of the CCD min advance coefficient.
\see setMinCCDAdvanceCoefficient
*/
virtual PxReal getMinCCDAdvanceCoefficient() const = 0;
/**
\brief Sets the maximum depenetration velocity permitted to be introduced by the solver.
This value controls how much velocity the solver can introduce to correct for penetrations in contacts.
\param[in] biasClamp The maximum velocity to de-penetrate by <b>Range:</b> (0, PX_MAX_F32].
*/
virtual void setMaxDepenetrationVelocity(PxReal biasClamp) = 0;
/**
\brief Returns the maximum depenetration velocity the solver is permitted to introduced.
This value controls how much velocity the solver can introduce to correct for penetrations in contacts.
\return The maximum penetration bias applied by the solver.
*/
virtual PxReal getMaxDepenetrationVelocity() const = 0;
/**
\brief Sets a limit on the impulse that may be applied at a contact. The maximum impulse at a contact between two dynamic or kinematic
bodies will be the minimum of the two limit values. For a collision between a static and a dynamic body, the impulse is limited
by the value for the dynamic body.
\param[in] maxImpulse the maximum contact impulse. <b>Range:</b> [0, PX_MAX_F32] <b>Default:</b> PX_MAX_F32
\see getMaxContactImpulse
*/
virtual void setMaxContactImpulse(PxReal maxImpulse) = 0;
/**
\brief Returns the maximum impulse that may be applied at a contact.
\return The maximum impulse that may be applied at a contact
\see setMaxContactImpulse
*/
virtual PxReal getMaxContactImpulse() const = 0;
/**
\brief Sets a distance scale whereby the angular influence of a contact on the normal constraint in a contact is
zeroed if normal.cross(offset) falls below this tolerance. Rather than acting as an absolute value, this tolerance
is scaled by the ratio rXn.dot(angVel)/normal.dot(linVel) such that contacts that have relatively larger angular velocity
than linear normal velocity (e.g. rolling wheels) achieve larger slop values as the angular velocity increases.
\param[in] slopCoefficient the Slop coefficient. <b>Range:</b> [0, PX_MAX_F32] <b>Default:</b> 0
\see getContactSlopCoefficient
*/
virtual void setContactSlopCoefficient(PxReal slopCoefficient) = 0;
/**
\brief Returns the contact slop coefficient.
\return The contact slop coefficient.
\see setContactSlopCoefficient
*/
virtual PxReal getContactSlopCoefficient() const = 0;
/**
\brief Returns the island node index
\return The island node index.
*/
virtual PxNodeIndex getInternalIslandNodeIndex() const = 0;
protected:
PX_INLINE PxRigidBody(PxType concreteType, PxBaseFlags baseFlags) : PxRigidActor(concreteType, baseFlags) {}
PX_INLINE PxRigidBody(PxBaseFlags baseFlags) : PxRigidActor(baseFlags) {}
virtual ~PxRigidBody() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxRigidBody", PxRigidActor); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,476 @@
// 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 PX_RIGID_DYNAMIC_H
#define PX_RIGID_DYNAMIC_H
#include "PxRigidBody.h"
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Collection of flags providing a mechanism to lock motion along/around a specific axis.
\see PxRigidDynamic.setRigidDynamicLockFlag(), PxRigidBody.getRigidDynamicLockFlags()
*/
struct PxRigidDynamicLockFlag
{
enum Enum
{
eLOCK_LINEAR_X = (1 << 0),
eLOCK_LINEAR_Y = (1 << 1),
eLOCK_LINEAR_Z = (1 << 2),
eLOCK_ANGULAR_X = (1 << 3),
eLOCK_ANGULAR_Y = (1 << 4),
eLOCK_ANGULAR_Z = (1 << 5)
};
};
typedef PxFlags<PxRigidDynamicLockFlag::Enum, PxU8> PxRigidDynamicLockFlags;
PX_FLAGS_OPERATORS(PxRigidDynamicLockFlag::Enum, PxU8)
/**
\brief PxRigidDynamic represents a dynamic rigid simulation object in the physics SDK.
<h3>Creation</h3>
Instances of this class are created by calling #PxPhysics::createRigidDynamic() and deleted with #release().
<h3>Visualizations</h3>
\li #PxVisualizationParameter::eACTOR_AXES
\li #PxVisualizationParameter::eBODY_AXES
\li #PxVisualizationParameter::eBODY_MASS_AXES
\li #PxVisualizationParameter::eBODY_LIN_VELOCITY
\li #PxVisualizationParameter::eBODY_ANG_VELOCITY
\see PxRigidBody PxPhysics.createRigidDynamic() release()
*/
class PxRigidDynamic : public PxRigidBody
{
public:
// Runtime modifications
/************************************************************************************************/
/** \name Kinematic Actors
*/
/**
\brief Moves kinematically controlled dynamic actors through the game world.
You set a dynamic actor to be kinematic using the PxRigidBodyFlag::eKINEMATIC flag
with setRigidBodyFlag().
The move command will result in a velocity that will move the body into
the desired pose. After the move is carried out during a single time step,
the velocity is returned to zero. Thus, you must continuously call
this in every time step for kinematic actors so that they move along a path.
This function simply stores the move destination until the next simulation
step is processed, so consecutive calls will simply overwrite the stored target variable.
The motion is always fully carried out.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
<b>Sleeping:</b> This call wakes the actor if it is sleeping and will set the wake counter to #PxSceneDesc::wakeCounterResetValue.
\param[in] destination The desired pose for the kinematic actor, in the global frame. <b>Range:</b> rigid body transform.
\see getKinematicTarget() PxRigidBodyFlag setRigidBodyFlag()
*/
virtual void setKinematicTarget(const PxTransform& destination) = 0;
/**
\brief Get target pose of a kinematically controlled dynamic actor.
\param[out] target Transform to write the target pose to. Only valid if the method returns true.
\return True if the actor is a kinematically controlled dynamic and the target has been set, else False.
\see setKinematicTarget() PxRigidBodyFlag setRigidBodyFlag()
*/
virtual bool getKinematicTarget(PxTransform& target) const = 0;
/************************************************************************************************/
/** \name Sleeping
*/
/**
\brief Returns true if this body is sleeping.
When an actor does not move for a period of time, it is no longer simulated in order to save time. This state
is called sleeping. However, because the object automatically wakes up when it is either touched by an awake object,
or one of its properties is changed by the user, the entire sleep mechanism should be transparent to the user.
In general, a dynamic rigid actor is guaranteed to be awake if at least one of the following holds:
\li The wake counter is positive (see #setWakeCounter()).
\li The linear or angular velocity is non-zero.
\li A non-zero force or torque has been applied.
If a dynamic rigid actor is sleeping, the following state is guaranteed:
\li The wake counter is zero.
\li The linear and angular velocity is zero.
\li There is no force update pending.
When an actor gets inserted into a scene, it will be considered asleep if all the points above hold, else it will be treated as awake.
If an actor is asleep after the call to PxScene::fetchResults() returns, it is guaranteed that the pose of the actor
was not changed. You can use this information to avoid updating the transforms of associated objects.
\note A kinematic actor is asleep unless a target pose has been set (in which case it will stay awake until two consecutive
simulation steps without a target pose being set have passed). The wake counter will get set to zero or to the reset value
#PxSceneDesc::wakeCounterResetValue in the case where a target pose has been set to be consistent with the definitions above.
\note It is invalid to use this method if the actor has not been added to a scene already.
\note It is not allowed to use this method while the simulation is running.
\return True if the actor is sleeping.
\see isSleeping() wakeUp() putToSleep() getSleepThreshold()
*/
virtual bool isSleeping() const = 0;
/**
\brief Sets the mass-normalized kinetic energy threshold below which an actor may go to sleep.
Actors whose kinetic energy divided by their mass is below this threshold will be candidates for sleeping.
<b>Default:</b> 5e-5f * PxTolerancesScale::speed * PxTolerancesScale::speed
\param[in] threshold Energy below which an actor may go to sleep. <b>Range:</b> [0, PX_MAX_F32)
\see isSleeping() getSleepThreshold() wakeUp() putToSleep() PxTolerancesScale
*/
virtual void setSleepThreshold(PxReal threshold) = 0;
/**
\brief Returns the mass-normalized kinetic energy below which an actor may go to sleep.
\return The energy threshold for sleeping.
\see isSleeping() wakeUp() putToSleep() setSleepThreshold()
*/
virtual PxReal getSleepThreshold() const = 0;
/**
\brief Sets the mass-normalized kinetic energy threshold below which an actor may participate in stabilization.
Actors whose kinetic energy divided by their mass is above this threshold will not participate in stabilization.
This value has no effect if PxSceneFlag::eENABLE_STABILIZATION was not enabled on the PxSceneDesc.
<b>Default:</b> 1e-5f * PxTolerancesScale::speed * PxTolerancesScale::speed
\param[in] threshold Energy below which an actor may participate in stabilization. <b>Range:</b> [0,inf)
\see getStabilizationThreshold() PxSceneFlag::eENABLE_STABILIZATION
*/
virtual void setStabilizationThreshold(PxReal threshold) = 0;
/**
\brief Returns the mass-normalized kinetic energy below which an actor may participate in stabilization.
Actors whose kinetic energy divided by their mass is above this threshold will not participate in stabilization.
\return The energy threshold for participating in stabilization.
\see setStabilizationThreshold() PxSceneFlag::eENABLE_STABILIZATION
*/
virtual PxReal getStabilizationThreshold() const = 0;
/**
\brief Sets the wake counter for the actor.
The wake counter value determines the minimum amount of time until the body can be put to sleep. Please note
that a body will not be put to sleep if the energy is above the specified threshold (see #setSleepThreshold())
or if other awake bodies are touching it.
\note Passing in a positive value will wake the actor up automatically.
\note It is invalid to use this method for kinematic actors since the wake counter for kinematics is defined
based on whether a target pose has been set (see the comment in #isSleeping()).
\note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set.
<b>Default:</b> 0.4 (which corresponds to 20 frames for a time step of 0.02)
\param[in] wakeCounterValue Wake counter value. <b>Range:</b> [0, PX_MAX_F32)
\see isSleeping() getWakeCounter()
*/
virtual void setWakeCounter(PxReal wakeCounterValue) = 0;
/**
\brief Returns the wake counter of the actor.
\note It is not allowed to use this method while the simulation is running.
\return The wake counter of the actor.
\see isSleeping() setWakeCounter()
*/
virtual PxReal getWakeCounter() const = 0;
/**
\brief Wakes up the actor if it is sleeping.
The actor will get woken up and might cause other touching actors to wake up as well during the next simulation step.
\note This will set the wake counter of the actor to the value specified in #PxSceneDesc::wakeCounterResetValue.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\note It is invalid to use this method for kinematic actors since the sleep state for kinematics is defined
based on whether a target pose has been set (see the comment in #isSleeping()).
\see isSleeping() putToSleep()
*/
virtual void wakeUp() = 0;
/**
\brief Forces the actor to sleep.
The actor will stay asleep during the next simulation step if not touched by another non-sleeping actor.
\note Any applied force will be cleared and the velocity and the wake counter of the actor will be set to 0.
\note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set.
\note It is invalid to use this method for kinematic actors since the sleep state for kinematics is defined
based on whether a target pose has been set (see the comment in #isSleeping()).
\see isSleeping() wakeUp()
*/
virtual void putToSleep() = 0;
/************************************************************************************************/
/** \name Lock flags
*/
/**
\brief Reads the PxRigidDynamic lock flags.
See the list of flags #PxRigidDynamicLockFlag
\return The values of the PxRigidDynamic lock flags.
\see PxRigidDynamicLockFlag setRigidDynamicLockFlag()
*/
virtual PxRigidDynamicLockFlags getRigidDynamicLockFlags() const = 0;
/**
\brief Raises or clears a particular PxRigidDynamic lock flag.
See the list of flags #PxRigidDynamicLockFlag
<b>Default:</b> no flags are set
\param[in] flag The PxRigidDynamicLockFlag to raise(set) or clear. See #PxRigidBodyFlag.
\param[in] value The new boolean value for the flag.
\see PxRigidDynamicLockFlag getRigidDynamicLockFlags()
*/
virtual void setRigidDynamicLockFlag(PxRigidDynamicLockFlag::Enum flag, bool value) = 0;
/**
\brief Set all PxRigidDynamic lock flags.
\see setRigidDynamicLockFlag()
*/
virtual void setRigidDynamicLockFlags(PxRigidDynamicLockFlags flags) = 0;
/**
\brief Retrieves the actor's center-of-mass linear velocity.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\note The linear velocity is reported with respect to the actor's center of mass and not the actor frame origin.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\return The actor's center-of-mass linear velocity.
\see PxRigidDynamic.setLinearVelocity() getAngularVelocity()
*/
virtual PxVec3 getLinearVelocity() const = 0;
/**
\brief Sets the actor's center-of-mass linear velocity.
Note that if you continuously set the velocity of an actor yourself,
forces such as gravity or friction will not be able to manifest themselves, because forces directly
influence only the velocity/momentum of an actor.
<b>Default:</b> (0.0, 0.0, 0.0)
<b>Sleeping:</b> This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the
new velocity is non-zero.
\note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\note The linear velocity is applied with respect to the actor's center of mass and not the actor frame origin.
\param[in] linVel New center-of-mass linear velocity of the actor. <b>Range:</b> velocity vector
\param[in] autowake Whether to wake the object up if it is asleep. If true and the current wake counter value is
smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value.
\see getLinearVelocity() setAngularVelocity()
*/
virtual void setLinearVelocity(const PxVec3& linVel, bool autowake = true) = 0;
/**
\brief Retrieves the angular velocity of the actor.
\note It is not allowed to use this method while the simulation is running (except during PxScene::collide(),
in PxContactModifyCallback or in contact report callbacks).
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\return The angular velocity of the actor.
\see PxRigidDynamic.setAngularVelocity() getLinearVelocity()
*/
virtual PxVec3 getAngularVelocity() const = 0;
/**
\brief Sets the angular velocity of the actor.
Note that if you continuously set the angular velocity of an actor yourself,
forces such as friction will not be able to rotate the actor, because forces directly influence only the velocity/momentum.
<b>Default:</b> (0.0, 0.0, 0.0)
<b>Sleeping:</b> This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the
new velocity is non-zero.
\note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set.
\note This method should not be used after the direct GPU API has been enabled and initialized. See #PxDirectGPUAPI for the details.
\param[in] angVel New angular velocity of actor. <b>Range:</b> angular velocity vector
\param[in] autowake Whether to wake the object up if it is asleep. If true and the current wake counter value is
smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value.
\see getAngularVelocity() setLinearVelocity()
*/
virtual void setAngularVelocity(const PxVec3& angVel, bool autowake = true) = 0;
/************************************************************************************************/
/**
\brief Sets the solver iteration counts for the body.
The solver iteration count determines how accurately joints and contacts are resolved.
If you are having trouble with jointed bodies oscillating and behaving erratically, then
setting a higher position iteration count may improve their stability.
If intersecting bodies are being depenetrated too violently, increase the number of velocity
iterations. More velocity iterations will drive the relative exit velocity of the intersecting
objects closer to the correct value given the restitution.
<b>Default:</b> 4 position iterations, 1 velocity iteration
\param[in] minPositionIters Number of position iterations the solver should perform for this body. <b>Range:</b> [1,255]
\param[in] minVelocityIters Number of velocity iterations the solver should perform for this body. <b>Range:</b> [0,255]
\see getSolverIterationCounts()
*/
virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0;
/**
\brief Retrieves the solver iteration counts.
\see setSolverIterationCounts()
*/
virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0;
/**
\brief Retrieves the force threshold for contact reports.
The contact report threshold is a force threshold. If the force between
two actors exceeds this threshold for either of the two actors, a contact report
will be generated according to the contact report threshold flags provided by
the filter shader/callback.
See #PxPairFlag.
The threshold used for a collision between a dynamic actor and the static environment is
the threshold of the dynamic actor, and all contacts with static actors are summed to find
the total normal force.
<b>Default:</b> PX_MAX_F32
\return Force threshold for contact reports.
\see setContactReportThreshold PxPairFlag PxSimulationFilterShader PxSimulationFilterCallback
*/
virtual PxReal getContactReportThreshold() const = 0;
/**
\brief Sets the force threshold for contact reports.
See #getContactReportThreshold().
\param[in] threshold Force threshold for contact reports. <b>Range:</b> [0, PX_MAX_F32)
\see getContactReportThreshold PxPairFlag
*/
virtual void setContactReportThreshold(PxReal threshold) = 0;
/**
\brief Returns the GPU rigid dynamic index.
\note This function only returns valid results if GPU dynamics is enabled.
\return The GPU index, or 0xFFFFFFFF if the actor is not inserted into a PxScene.
\see PxDirectGPUAPI::getRigidDynamicData(), PxDirectGPUAPI::setRigidDynamicData().
*/
virtual PxRigidDynamicGPUIndex getGPUIndex() const = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxRigidDynamic"; }
protected:
PX_INLINE PxRigidDynamic(PxType concreteType, PxBaseFlags baseFlags) : PxRigidBody(concreteType, baseFlags) { }
PX_INLINE PxRigidDynamic(PxBaseFlags baseFlags) : PxRigidBody(baseFlags) {}
virtual ~PxRigidDynamic() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxRigidDynamic", PxRigidBody); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,71 @@
// 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 PX_RIGID_STATIC_H
#define PX_RIGID_STATIC_H
#include "PxPhysXConfig.h"
#include "PxRigidActor.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief PxRigidStatic represents a static rigid body simulation object in the physics SDK.
PxRigidStatic objects are static rigid physics entities. They shall be used to define solid objects which are fixed in the world.
<h3>Creation</h3>
Instances of this class are created by calling #PxPhysics::createRigidStatic() and deleted with #release().
<h3>Visualizations</h3>
\li #PxVisualizationParameter::eACTOR_AXES
\see PxRigidActor PxPhysics.createRigidStatic() release()
*/
class PxRigidStatic : public PxRigidActor
{
public:
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxRigidStatic"; }
protected:
PX_INLINE PxRigidStatic(PxType concreteType, PxBaseFlags baseFlags) : PxRigidActor(concreteType, baseFlags) {}
PX_INLINE PxRigidStatic(PxBaseFlags baseFlags) : PxRigidActor(baseFlags){}
virtual ~PxRigidStatic() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxRigidStatic", PxRigidActor); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,120 @@
// 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 PX_SDF_BUILDER_H
#define PX_SDF_BUILDER_H
#include "cudamanager/PxCudaContext.h"
#include "cudamanager/PxCudaContextManager.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#include "foundation/PxArray.h"
#include "cooking/PxSDFDesc.h"
#include "cudamanager/PxCudaTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Utility class to compute an SDF on the GPU
*/
class PxSDFBuilder
{
public:
/**
\brief Constructs a dense grid SDF for a triangle mesh using the GPU
\param[in] vertices The vertices of the triangle mesh
\param[in] numVertices The number of vertices
\param[in] indices The triangle indices
\param[in] numTriangleIndices The number of triangle indices
\param[in] width The number of samples along the x direction of the resulting SDF volume
\param[in] height The number of samples along the y direction of the resulting SDF volume
\param[in] depth The number of samples along the z direction of the resulting SDF volume
\param[in] minExtents The minimum corner location of the axis aligned box containing the SDF samples
\param[in] maxExtents The maximum corner location of the axis aligned box containing the SDF samples
\param[in] cellCenteredSamples Determines if the sample points are located at the center of a SDF cell or at the lower left (=min) corner of a cell
\param[out] sdf The distance values. Must provide space for width*height*depth distance samples. Negative distance means the sample point is located inside of the triangle mesh
\param[in] stream The cuda stream on which the conversion is processed. If the default stream (0) is used, a temporary stream will be created internally
\return A boolean that indicates whether the SDF creation succeeded
*/
virtual bool buildSDF(const PxVec3* vertices, PxU32 numVertices, const PxU32* indices, PxU32 numTriangleIndices, PxU32 width, PxU32 height, PxU32 depth,
const PxVec3& minExtents, const PxVec3& maxExtents, bool cellCenteredSamples, PxReal* sdf, CUstream stream = 0) = 0;
/**
\brief Constructs a sparse grid SDF for a triangle mesh using the GPU
\param[in] vertices The vertices of the triangle mesh
\param[in] numVertices The number of vertices
\param[in] indices The triangle indices
\param[in] numTriangleIndices The number of triangle indices
\param[in] width The number of samples along the x direction of the resulting SDF volume
\param[in] height The number of samples along the y direction of the resulting SDF volume
\param[in] depth The number of samples along the z direction of the resulting SDF volume
\param[in] minExtents The minimum corner location of the axis aligned box containing the SDF samples
\param[in] maxExtents The maximum corner location of the axis aligned box containing the SDF samples
\param[in] narrowBandThickness The thickness of the narrow band
\param[in] cellsPerSubgrid The number of cells in a sparse subgrid block (full block has mSubgridSize^3 cells and (mSubgridSize+1)^3 samples)
\param[in] bitsPerSubgridPixel Subgrid pixel compression
\param[out] sdfCoarse Used to store the lower resolution, dense backround SDF to provide distance information further away from the mesh's surface
\param[out] sdfSubgridsStartSlots Used to store the subgrids start indices
\param[out] sdfDataSubgrids Used to store the subgrids
\param[out] subgridsMinSdfValue Used to store the minimum sdf value over all subgrids
\param[out] subgridsMaxSdfValue Used to store the maximum sdf value over all subgrids
\param[out] sdfSubgrids3DTexBlockDimX Used to store x dimension of the texture block that stores the subgrids
\param[out] sdfSubgrids3DTexBlockDimY Used to store y dimension of the texture block that stores the subgrids
\param[out] sdfSubgrids3DTexBlockDimZ Used to store z dimension of the texture block that stores the subgrids
\param[in] stream The cuda stream on which the conversion is processed. If the default stream (0) is used, a temporary stream will be created internally
\return A boolean that indicates whether the SDF creation succeeded
*/
virtual bool buildSparseSDF(const PxVec3* vertices, PxU32 numVertices, const PxU32* indices, PxU32 numTriangleIndices, PxU32 width, PxU32 height, PxU32 depth,
const PxVec3& minExtents, const PxVec3& maxExtents, PxReal narrowBandThickness, PxU32 cellsPerSubgrid, PxSdfBitsPerSubgridPixel::Enum bitsPerSubgridPixel,
PxArray<PxReal>& sdfCoarse, PxArray<PxU32>& sdfSubgridsStartSlots, PxArray<PxU8>& sdfDataSubgrids,
PxReal& subgridsMinSdfValue, PxReal& subgridsMaxSdfValue,
PxU32& sdfSubgrids3DTexBlockDimX, PxU32& sdfSubgrids3DTexBlockDimY, PxU32& sdfSubgrids3DTexBlockDimZ, CUstream stream = 0) = 0;
/**
\brief Releases the memory including the this pointer
*/
virtual void release() = 0;
/**
\brief Destructor
*/
virtual ~PxSDFBuilder() { }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

1802
engine/third_party/physx/include/PxScene.h vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
// 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 PX_SCENE_LOCK_H
#define PX_SCENE_LOCK_H
#include "PxPhysXConfig.h"
#include "PxScene.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief RAII wrapper for the PxScene read lock.
Use this class as follows to lock the scene for reading by the current thread
for the duration of the enclosing scope:
PxSceneReadLock lock(sceneRef);
\see PxScene::lockRead(), PxScene::unlockRead(), PxSceneFlag::eREQUIRE_RW_LOCK
*/
class PxSceneReadLock
{
PxSceneReadLock(const PxSceneReadLock&);
PxSceneReadLock& operator=(const PxSceneReadLock&);
public:
/**
\brief Constructor
\param scene The scene to lock for reading
\param file Optional string for debugging purposes
\param line Optional line number for debugging purposes
*/
PxSceneReadLock(PxScene& scene, const char* file=NULL, PxU32 line=0)
: mScene(scene)
{
mScene.lockRead(file, line);
}
~PxSceneReadLock()
{
mScene.unlockRead();
}
private:
PxScene& mScene;
};
/**
\brief RAII wrapper for the PxScene write lock.
Use this class as follows to lock the scene for writing by the current thread
for the duration of the enclosing scope:
PxSceneWriteLock lock(sceneRef);
\see PxScene::lockWrite(), PxScene::unlockWrite(), PxSceneFlag::eREQUIRE_RW_LOCK
*/
class PxSceneWriteLock
{
PxSceneWriteLock(const PxSceneWriteLock&);
PxSceneWriteLock& operator=(const PxSceneWriteLock&);
public:
/**
\brief Constructor
\param scene The scene to lock for writing
\param file Optional string for debugging purposes
\param line Optional line number for debugging purposes
*/
PxSceneWriteLock(PxScene& scene, const char* file=NULL, PxU32 line=0)
: mScene(scene)
{
mScene.lockWrite(file, line);
}
~PxSceneWriteLock()
{
mScene.unlockWrite();
}
private:
PxScene& mScene;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,324 @@
// 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 PX_SCENE_QUERY_DESC_H
#define PX_SCENE_QUERY_DESC_H
#include "PxPhysXConfig.h"
#include "geometry/PxBVHBuildStrategy.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxSceneQuerySystem;
/**
\brief Pruning structure used to accelerate scene queries.
eNONE uses a simple data structure that consumes less memory than the alternatives,
but generally has slower query performance.
eDYNAMIC_AABB_TREE usually provides the fastest queries. However there is a
constant per-frame management cost associated with this structure. How much work should
be done per frame can be tuned via the #PxSceneQueryDesc::dynamicTreeRebuildRateHint
parameter.
eSTATIC_AABB_TREE is typically used for static objects. It is the same as the
dynamic AABB tree, without the per-frame overhead. This can be a good choice for static
objects, if no static objects are added, moved or removed after the scene has been
created. If there is no such guarantee (e.g. when streaming parts of the world in and out),
then the dynamic version is a better choice even for static objects.
*/
struct PxPruningStructureType
{
enum Enum
{
eNONE, //!< Using a simple data structure
eDYNAMIC_AABB_TREE, //!< Using a dynamic AABB tree
eSTATIC_AABB_TREE, //!< Using a static AABB tree
eLAST
};
};
/**
\brief Secondary pruning structure used for newly added objects in dynamic trees.
Dynamic trees (PxPruningStructureType::eDYNAMIC_AABB_TREE) are slowly rebuilt
over several frames. A secondary pruning structure holds and manages objects
added to the scene while this rebuild is in progress.
eNONE ignores newly added objects. This means that for a number of frames (roughly
defined by PxSceneQueryDesc::dynamicTreeRebuildRateHint) newly added objects will
be ignored by scene queries. This can be acceptable when streaming large worlds, e.g.
when the objects added at the boundaries of the game world don't immediately need to be
visible from scene queries (it would be equivalent to streaming that data in a few frames
later). The advantage of this approach is that there is no CPU cost associated with
inserting the new objects in the scene query data structures, and no extra runtime cost
when performing queries.
eBUCKET uses a structure similar to PxPruningStructureType::eNONE. Insertion is fast but
query cost can be high.
eINCREMENTAL uses an incremental AABB-tree, with no direct PxPruningStructureType equivalent.
Query time is fast but insertion cost can be high.
eBVH uses a PxBVH structure. This usually offers the best overall performance.
*/
struct PxDynamicTreeSecondaryPruner
{
enum Enum
{
eNONE, //!< no secondary pruner, new objects aren't visible to SQ for a few frames
eBUCKET , //!< bucket-based secondary pruner, faster updates, slower query time
eINCREMENTAL, //!< incremental-BVH secondary pruner, faster query time, slower updates
eBVH, //!< PxBVH-based secondary pruner, good overall performance
eLAST
};
};
/**
\brief Scene query update mode
This enum controls what work is done when the scene query system is updated. The updates traditionally happen when PxScene::fetchResults
is called. This function then calls PxSceneQuerySystem::finalizeUpdates, where the update mode is used.
fetchResults/finalizeUpdates will sync changed bounds during simulation and update the scene query bounds in pruners, this work is mandatory.
eBUILD_ENABLED_COMMIT_ENABLED does allow to execute the new AABB tree build step during fetchResults/finalizeUpdates, additionally
the pruner commit is called where any changes are applied. During commit PhysX refits the dynamic scene query tree and if a new tree
was built and the build finished the tree is swapped with current AABB tree.
eBUILD_ENABLED_COMMIT_DISABLED does allow to execute the new AABB tree build step during fetchResults/finalizeUpdates. Pruner commit
is not called, this means that refit will then occur during the first scene query following fetchResults/finalizeUpdates, or may be forced
by the method PxScene::flushQueryUpdates() / PxSceneQuerySystemBase::flushUpdates().
eBUILD_DISABLED_COMMIT_DISABLED no further scene query work is executed. The scene queries update needs to be called manually, see
PxScene::sceneQueriesUpdate (see that function's doc for the equivalent PxSceneQuerySystem sequence). It is recommended to call
PxScene::sceneQueriesUpdate right after fetchResults/finalizeUpdates as the pruning structures are not updated.
*/
struct PxSceneQueryUpdateMode
{
enum Enum
{
eBUILD_ENABLED_COMMIT_ENABLED, //!< Both scene query build and commit are executed.
eBUILD_ENABLED_COMMIT_DISABLED, //!< Scene query build only is executed.
eBUILD_DISABLED_COMMIT_DISABLED //!< No work is done, no update of scene queries
};
};
/**
\brief Descriptor class for scene query system. See #PxSceneQuerySystem.
*/
class PxSceneQueryDesc
{
public:
/**
\brief Defines the structure used to store static objects (PxRigidStatic actors).
There are usually a lot more static actors than dynamic actors in a scene, so they are stored
in a separate structure. The idea is that when dynamic actors move each frame, the static structure
remains untouched and does not need updating.
<b>Default:</b> PxPruningStructureType::eDYNAMIC_AABB_TREE
\note Only PxPruningStructureType::eSTATIC_AABB_TREE and PxPruningStructureType::eDYNAMIC_AABB_TREE are allowed here.
\see PxPruningStructureType PxSceneSQSystem.getStaticStructure()
*/
PxPruningStructureType::Enum staticStructure;
/**
\brief Defines the structure used to store dynamic objects (non-PxRigidStatic actors).
<b>Default:</b> PxPruningStructureType::eDYNAMIC_AABB_TREE
\see PxPruningStructureType PxSceneSQSystem.getDynamicStructure()
*/
PxPruningStructureType::Enum dynamicStructure;
/**
\brief Hint for how much work should be done per simulation frame to rebuild the pruning structures.
This parameter gives a hint on the distribution of the workload for rebuilding the dynamic AABB tree
pruning structure #PxPruningStructureType::eDYNAMIC_AABB_TREE. It specifies the desired number of simulation frames
the rebuild process should take. Higher values will decrease the workload per frame but the pruning
structure will get more and more outdated the longer the rebuild takes (which can make
scene queries less efficient).
\note Only used for #PxPruningStructureType::eDYNAMIC_AABB_TREE pruning structures.
\note Both staticStructure & dynamicStructure can use a PxPruningStructureType::eDYNAMIC_AABB_TREE, in which case
this parameter is used for both.
\note This parameter gives only a hint. The rebuild process might still take more or less time depending on the
number of objects involved.
<b>Range:</b> [4, PX_MAX_U32)<br>
<b>Default:</b> 100
\see PxSceneQuerySystemBase.setDynamicTreeRebuildRateHint() PxSceneQuerySystemBase.getDynamicTreeRebuildRateHint()
*/
PxU32 dynamicTreeRebuildRateHint;
/**
\brief Secondary pruner for dynamic tree.
This is used for PxPruningStructureType::eDYNAMIC_AABB_TREE structures, to control how objects added to the system
at runtime are managed.
\note Both staticStructure & dynamicStructure can use a PxPruningStructureType::eDYNAMIC_AABB_TREE, in which case
this parameter is used for both.
<b>Default:</b> PxDynamicTreeSecondaryPruner::eINCREMENTAL
\see PxDynamicTreeSecondaryPruner
*/
PxDynamicTreeSecondaryPruner::Enum dynamicTreeSecondaryPruner;
/**
\brief Build strategy for PxSceneQueryDesc::staticStructure.
This parameter is used to refine / control the build strategy of PxSceneQueryDesc::staticStructure. This is only
used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE.
<b>Default:</b> PxBVHBuildStrategy::eFAST
\see PxBVHBuildStrategy PxSceneQueryDesc::staticStructure
*/
PxBVHBuildStrategy::Enum staticBVHBuildStrategy;
/**
\brief Build strategy for PxSceneQueryDesc::dynamicStructure.
This parameter is used to refine / control the build strategy of PxSceneQueryDesc::dynamicStructure. This is only
used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE.
<b>Default:</b> PxBVHBuildStrategy::eFAST
\see PxBVHBuildStrategy PxSceneQueryDesc::dynamicStructure
*/
PxBVHBuildStrategy::Enum dynamicBVHBuildStrategy;
/**
\brief Number of objects per node for PxSceneQueryDesc::staticStructure.
This parameter is used to refine / control the number of objects per node for PxSceneQueryDesc::staticStructure.
This is only used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE.
This parameter has an impact on how quickly the structure gets built, and on the per-frame cost of maintaining
the structure. Increasing this value gives smaller AABB-trees that use less memory, are faster to build and
update, but it can lead to slower queries.
<b>Default:</b> 4
\see PxSceneQueryDesc::staticStructure
*/
PxU32 staticNbObjectsPerNode;
/**
\brief Number of objects per node for PxSceneQueryDesc::dynamicStructure.
This parameter is used to refine / control the number of objects per node for PxSceneQueryDesc::dynamicStructure.
This is only used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE.
This parameter has an impact on how quickly the structure gets built, and on the per-frame cost of maintaining
the structure. Increasing this value gives smaller AABB-trees that use less memory, are faster to build and
update, but it can lead to slower queries.
<b>Default:</b> 4
\see PxSceneQueryDesc::dynamicStructure
*/
PxU32 dynamicNbObjectsPerNode;
/**
\brief Defines the scene query update mode.
<b>Default:</b> PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED
\see PxSceneQuerySystemBase.setUpdateMode() PxSceneQuerySystemBase.getUpdateMode()
*/
PxSceneQueryUpdateMode::Enum sceneQueryUpdateMode;
public:
/**
\brief constructor sets to default.
*/
PX_INLINE PxSceneQueryDesc();
/**
\brief (re)sets the structure to the default.
*/
PX_INLINE void setToDefault();
/**
\brief Returns true if the descriptor is valid.
\return true if the current settings are valid.
*/
PX_INLINE bool isValid() const;
};
PX_INLINE PxSceneQueryDesc::PxSceneQueryDesc():
staticStructure (PxPruningStructureType::eDYNAMIC_AABB_TREE),
dynamicStructure (PxPruningStructureType::eDYNAMIC_AABB_TREE),
dynamicTreeRebuildRateHint (100),
dynamicTreeSecondaryPruner (PxDynamicTreeSecondaryPruner::eINCREMENTAL),
staticBVHBuildStrategy (PxBVHBuildStrategy::eFAST),
dynamicBVHBuildStrategy (PxBVHBuildStrategy::eFAST),
staticNbObjectsPerNode (4),
dynamicNbObjectsPerNode (4),
sceneQueryUpdateMode (PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED)
{
}
PX_INLINE void PxSceneQueryDesc::setToDefault()
{
*this = PxSceneQueryDesc();
}
PX_INLINE bool PxSceneQueryDesc::isValid() const
{
if(staticStructure!=PxPruningStructureType::eSTATIC_AABB_TREE && staticStructure!=PxPruningStructureType::eDYNAMIC_AABB_TREE)
return false;
if(dynamicTreeRebuildRateHint < 4)
return false;
return true;
}
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,654 @@
// 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 PX_SCENE_QUERY_SYSTEM_H
#define PX_SCENE_QUERY_SYSTEM_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxBitMap.h"
#include "foundation/PxTransform.h"
#include "PxSceneQueryDesc.h"
#include "PxQueryReport.h"
#include "PxQueryFiltering.h"
#include "geometry/PxGeometryQueryFlags.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxBaseTask;
class PxRenderOutput;
class PxGeometry;
class PxRigidActor;
class PxShape;
class PxBVH;
class PxPruningStructure;
class PxBounds3;
/**
\brief Built-in enum for default PxScene pruners
This is passed as a pruner index to various functions in the following APIs.
\see PxSceneQuerySystemBase::forceRebuildDynamicTree PxSceneQuerySystem::preallocate
\see PxSceneQuerySystem::visualize PxSceneQuerySystem::sync PxSceneQuerySystem::prepareSceneQueryBuildStep
*/
enum PxScenePrunerIndex
{
PX_SCENE_PRUNER_STATIC = 0,
PX_SCENE_PRUNER_DYNAMIC = 1,
PX_SCENE_COMPOUND_PRUNER = 0xffffffff
};
/**
\brief Base class for the scene-query system.
Methods defined here are common to both the traditional PxScene API and the PxSceneQuerySystem API.
\see PxScene PxSceneQuerySystem
*/
class PxSceneQuerySystemBase
{
protected:
PxSceneQuerySystemBase() {}
virtual ~PxSceneQuerySystemBase() {}
public:
/** \name Scene Query
*/
//\{
/**
\brief Sets the rebuild rate of the dynamic tree pruning structures.
\param[in] dynamicTreeRebuildRateHint Rebuild rate of the dynamic tree pruning structures.
\see PxSceneQueryDesc.dynamicTreeRebuildRateHint getDynamicTreeRebuildRateHint() forceRebuildDynamicTree()
*/
virtual void setDynamicTreeRebuildRateHint(PxU32 dynamicTreeRebuildRateHint) = 0;
/**
\brief Retrieves the rebuild rate of the dynamic tree pruning structures.
\return The rebuild rate of the dynamic tree pruning structures.
\see PxSceneQueryDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() forceRebuildDynamicTree()
*/
virtual PxU32 getDynamicTreeRebuildRateHint() const = 0;
/**
\brief Forces dynamic trees to be immediately rebuilt.
\param[in] prunerIndex Index of pruner containing the dynamic tree to rebuild
\note PxScene will call this function with the PX_SCENE_PRUNER_STATIC or PX_SCENE_PRUNER_DYNAMIC value.
\see PxSceneQueryDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() getDynamicTreeRebuildRateHint()
*/
virtual void forceRebuildDynamicTree(PxU32 prunerIndex) = 0;
/**
\brief Sets scene query update mode
\param[in] updateMode Scene query update mode.
\see PxSceneQueryUpdateMode::Enum
*/
virtual void setUpdateMode(PxSceneQueryUpdateMode::Enum updateMode) = 0;
/**
\brief Gets scene query update mode
\return Current scene query update mode.
\see PxSceneQueryUpdateMode::Enum
*/
virtual PxSceneQueryUpdateMode::Enum getUpdateMode() const = 0;
/**
\brief Retrieves the system's internal scene query timestamp, increased each time a change to the
static scene query structure is performed.
\return scene query static timestamp
*/
virtual PxU32 getStaticTimestamp() const = 0;
/**
\brief Flushes any changes to the scene query representation.
This method updates the state of the scene query representation to match changes in the scene state.
By default, these changes are buffered until the next query is submitted. Calling this function will not change
the results from scene queries, but can be used to ensure that a query will not perform update work in the course of
its execution.
A thread performing updates will hold a write lock on the query structure, and thus stall other querying threads. In multithread
scenarios it can be useful to explicitly schedule the period where this lock may be held for a significant period, so that
subsequent queries issued from multiple threads will not block.
*/
virtual void flushUpdates() = 0;
/**
\brief Performs a raycast against objects in the scene, returns results in a PxRaycastBuffer object
or via a custom user callback implementation inheriting from PxRaycastCallback.
\note Touching hits are not ordered.
\note Shooting a ray from within an object leads to different results depending on the shape type. Please check the details in user guide article SceneQuery. User can ignore such objects by employing one of the provided filter mechanisms.
\param[in] origin Origin of the ray.
\param[in] unitDir Normalized direction of the ray.
\param[in] distance Length of the ray. Has to be in the [0, inf) range.
\param[out] hitCall Raycast hit buffer or callback object used to report raycast hits.
\param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback.
\param[in] filterData Filtering data passed to the filter shader.
\param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to be blocking.
\param[in] cache Cached hit shape (optional). Ray is tested against cached shape first. If no hit is found the ray gets queried against the scene.
Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit.
Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking.
\param[in] queryFlags Optional flags controlling the query.
\return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified.
\see PxRaycastCallback PxRaycastBuffer PxQueryFilterData PxQueryFilterCallback PxQueryCache PxRaycastHit PxQueryFlag PxQueryFlag::eANY_HIT PxGeometryQueryFlag
*/
virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, const PxReal distance,
PxRaycastCallback& hitCall, PxHitFlags hitFlags = PxHitFlag::eDEFAULT,
const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL,
const PxQueryCache* cache = NULL, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0;
/**
\brief Performs a sweep test against objects in the scene, returns results in a PxSweepBuffer object
or via a custom user callback implementation inheriting from PxSweepCallback.
\note Touching hits are not ordered.
\note If a shape from the scene is already overlapping with the query shape in its starting position,
the hit is returned unless eASSUME_NO_INITIAL_OVERLAP was specified.
\param[in] geometry Geometry of object to sweep (supported types are: box, sphere, capsule, convex core, convex mesh).
\param[in] pose Pose of the sweep object.
\param[in] unitDir Normalized direction of the sweep.
\param[in] distance Sweep distance. Needs to be in [0, inf) range and >0 if eASSUME_NO_INITIAL_OVERLAP was specified. Will be clamped to PX_MAX_SWEEP_DISTANCE.
\param[out] hitCall Sweep hit buffer or callback object used to report sweep hits.
\param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback.
\param[in] filterData Filtering data and simple logic.
\param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to be blocking.
\param[in] cache Cached hit shape (optional). Sweep is performed against cached shape first. If no hit is found the sweep gets queried against the scene.
Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit.
Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking.
\param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal.
Note: ePRECISE_SWEEP doesn't support inflation. Therefore the sweep will be performed with zero inflation.
\param[in] queryFlags Optional flags controlling the query.
\return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified.
\see PxSweepCallback PxSweepBuffer PxQueryFilterData PxQueryFilterCallback PxSweepHit PxQueryCache PxGeometryQueryFlag
*/
virtual bool sweep( const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance,
PxSweepCallback& hitCall, PxHitFlags hitFlags = PxHitFlag::eDEFAULT,
const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL,
const PxQueryCache* cache = NULL, const PxReal inflation = 0.0f, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0;
/**
\brief Performs an overlap test of a given geometry against objects in the scene, returns results in a PxOverlapBuffer object
or via a custom user callback implementation inheriting from PxOverlapCallback.
\note Filtering: returning eBLOCK from user filter for overlap queries will cause a warning (see #PxQueryHitType).
\param[in] geometry Geometry of object to check for overlap (supported types are: box, sphere, capsule, convex core, convex mesh).
\param[in] pose Pose of the object.
\param[out] hitCall Overlap hit buffer or callback object used to report overlap hits.
\param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxQueryFilterCallback
\param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to overlap.
\param[in] cache Cached hit shape (optional). Overlap is performed against cached shape first. If no hit is found the overlap gets queried against the scene.
\param[in] queryFlags Optional flags controlling the query.
Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit.
Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking.
\return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified.
\note eBLOCK should not be returned from user filters for overlap(). Doing so will result in undefined behavior, and a warning will be issued.
\note If the PxQueryFlag::eNO_BLOCK flag is set, the eBLOCK will instead be automatically converted to an eTOUCH and the warning suppressed.
\see PxOverlapCallback PxOverlapBuffer PxHitFlags PxQueryFilterData PxQueryFilterCallback PxGeometryQueryFlag
*/
virtual bool overlap(const PxGeometry& geometry, const PxTransform& pose, PxOverlapCallback& hitCall,
const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL,
const PxQueryCache* cache = NULL, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0;
//\}
};
/**
\brief Traditional SQ system for PxScene.
Methods defined here are only available through the traditional PxScene API.
Thus PxSceneSQSystem effectively captures the scene-query related part of the PxScene API.
\see PxScene PxSceneQuerySystemBase
*/
class PxSceneSQSystem : public PxSceneQuerySystemBase
{
protected:
PxSceneSQSystem() {}
virtual ~PxSceneSQSystem() {}
public:
/** \name Scene Query
*/
//\{
/**
\brief Sets scene query update mode
\param[in] updateMode Scene query update mode.
\see PxSceneQueryUpdateMode::Enum
*/
PX_FORCE_INLINE void setSceneQueryUpdateMode(PxSceneQueryUpdateMode::Enum updateMode) { setUpdateMode(updateMode); }
/**
\brief Gets scene query update mode
\return Current scene query update mode.
\see PxSceneQueryUpdateMode::Enum
*/
PX_FORCE_INLINE PxSceneQueryUpdateMode::Enum getSceneQueryUpdateMode() const { return getUpdateMode(); }
/**
\brief Retrieves the scene's internal scene query timestamp, increased each time a change to the
static scene query structure is performed.
\return scene query static timestamp
*/
PX_FORCE_INLINE PxU32 getSceneQueryStaticTimestamp() const { return getStaticTimestamp(); }
/**
\brief Flushes any changes to the scene query representation.
\see flushUpdates
*/
PX_FORCE_INLINE void flushQueryUpdates() { flushUpdates(); }
/**
\brief Forces dynamic trees to be immediately rebuilt.
\param[in] rebuildStaticStructure True to rebuild the dynamic tree containing static objects
\param[in] rebuildDynamicStructure True to rebuild the dynamic tree containing dynamic objects
\see PxSceneQueryDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() getDynamicTreeRebuildRateHint()
*/
PX_FORCE_INLINE void forceDynamicTreeRebuild(bool rebuildStaticStructure, bool rebuildDynamicStructure)
{
if(rebuildStaticStructure)
forceRebuildDynamicTree(PX_SCENE_PRUNER_STATIC);
if(rebuildDynamicStructure)
forceRebuildDynamicTree(PX_SCENE_PRUNER_DYNAMIC);
}
/**
\brief Return the value of PxSceneQueryDesc::staticStructure that was set when creating the scene with PxPhysics::createScene
\see PxSceneQueryDesc::staticStructure, PxPhysics::createScene
*/
virtual PxPruningStructureType::Enum getStaticStructure() const = 0;
/**
\brief Return the value of PxSceneQueryDesc::dynamicStructure that was set when creating the scene with PxPhysics::createScene
\see PxSceneQueryDesc::dynamicStructure, PxPhysics::createScene
*/
virtual PxPruningStructureType::Enum getDynamicStructure() const = 0;
/**
\brief Executes scene queries update tasks.
This function will refit dirty shapes within the pruner and will execute a task to build a new AABB tree, which is
build on a different thread. The new AABB tree is built based on the dynamic tree rebuild hint rate. Once
the new tree is ready it will be commited in next fetchQueries call, which must be called after.
This function is equivalent to the following PxSceneQuerySystem calls:
Synchronous calls:
- PxSceneQuerySystemBase::flushUpdates()
- handle0 = PxSceneQuerySystem::prepareSceneQueryBuildStep(PX_SCENE_PRUNER_STATIC)
- handle1 = PxSceneQuerySystem::prepareSceneQueryBuildStep(PX_SCENE_PRUNER_DYNAMIC)
Asynchronous calls:
- PxSceneQuerySystem::sceneQueryBuildStep(handle0);
- PxSceneQuerySystem::sceneQueryBuildStep(handle1);
This function is part of the PxSceneSQSystem interface because it uses the PxScene task system under the hood. But
it calls PxSceneQuerySystem functions, which are independent from this system and could be called in a similar
fashion by a separate, possibly user-defined task manager.
\note If PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED is used, it is required to update the scene queries
using this function.
\param[in] completionTask if non-NULL, this task will have its refcount incremented in sceneQueryUpdate(), then
decremented when the scene is ready to have fetchQueries called. So the task will not run until the
application also calls removeReference().
\param[in] controlSimulation if true, the scene controls its PxTaskManager simulation state. Leave
true unless the application is calling the PxTaskManager start/stopSimulation() methods itself.
\see PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED
*/
virtual void sceneQueriesUpdate(PxBaseTask* completionTask = NULL, bool controlSimulation = true) = 0;
/**
\brief This checks to see if the scene queries update has completed.
This does not cause the data available for reading to be updated with the results of the scene queries update, it is simply a status check.
The bool will allow it to either return immediately or block waiting for the condition to be met so that it can return true
\param[in] block When set to true will block until the condition is met.
\return True if the results are available.
\see sceneQueriesUpdate() fetchResults()
*/
virtual bool checkQueries(bool block = false) = 0;
/**
This method must be called after sceneQueriesUpdate. It will wait for the scene queries update to finish. If the user makes an illegal scene queries update call,
the SDK will issue an error message.
If a new AABB tree build finished, then during fetchQueries the current tree within the pruning structure is swapped with the new tree.
\param[in] block When set to true will block until the condition is met, which is tree built task must finish running.
*/
virtual bool fetchQueries(bool block = false) = 0;
//\}
};
typedef PxU32 PxSQCompoundHandle;
typedef PxU32 PxSQPrunerHandle;
typedef void* PxSQBuildStepHandle;
/**
\brief Scene-queries external sub-system for PxScene-based objects.
The default PxScene has hardcoded support for 2 regular pruners + 1 compound pruner, but these interfaces
should work with multiple pruners.
Regular shapes are traditional PhysX shapes that belong to an actor. That actor can be a compound, i.e. it has
more than one shape. *All of these go to the regular pruners*. This is important because it might be misleading:
by default all shapes go to one of the two regular pruners, even shapes that belong to compound actors.
For compound actors, adding all the actor's shapes individually to the SQ system can be costly, since all the
corresponding bounds will always move together and remain close together - that can put a lot of stress on the
code that updates the SQ spatial structures. In these cases it can be more efficient to add the compound's bounds
(i.e. the actor's bounds) to the system, as the first level of a bounds hierarchy. The scene queries would then
be performed against the actor's bounds first, and only visit the shapes' bounds second. This is only useful
for actors that have more than one shape, i.e. compound actors. Such actors added to the SQ system are thus
called "SQ compounds". These objects are managed by the "compound pruner", which is only used when an explicit
SQ compound is added to the SQ system via the addSQCompound call. So in the end one has to distinguish between:
- a "compound shape", which is added to regular pruners as its own individual entity.
- an "SQ compound shape", which is added to the compound pruner as a subpart of an SQ compound actor.
A compound shape has an invalid compound ID, since it does not belong to an SQ compound.
An SQ compound shape has a valid compound ID, that identifies its SQ compound owner.
\see PxScene PxSceneQuerySystemBase
*/
class PxSceneQuerySystem : public PxSceneQuerySystemBase
{
protected:
PxSceneQuerySystem() {}
virtual ~PxSceneQuerySystem() {}
public:
/**
\brief Decrements the reference count of the object and releases it if the new reference count is zero.
*/
virtual void release() = 0;
/**
\brief Acquires a counted reference to this object.
This method increases the reference count of the object by 1. Decrement the reference count by calling release()
*/
virtual void acquireReference() = 0;
/**
\brief Preallocates internal arrays to minimize the amount of reallocations.
The system does not prevent more allocations than given numbers. It is legal to not call this function at all,
or to add more shapes to the system than the preallocated amounts.
\param[in] prunerIndex Index of pruner to preallocate (PX_SCENE_PRUNER_STATIC, PX_SCENE_PRUNER_DYNAMIC or PX_SCENE_COMPOUND_PRUNER when called from PxScene).
\param[in] nbShapes Expected number of (regular) shapes
*/
virtual void preallocate(PxU32 prunerIndex, PxU32 nbShapes) = 0;
/**
\brief Frees internal memory that may not be in-use anymore.
This is an entry point for reclaiming transient memory allocated at some point by the SQ system,
but which wasn't been immediately freed for performance reason. Calling this function might free
some memory, but it might also produce a new set of allocations in the next frame.
*/
virtual void flushMemory() = 0;
/**
\brief Adds a shape to the SQ system.
The same function is used to add either a regular shape, or a SQ compound shape.
\param[in] actor The shape's actor owner
\param[in] shape The shape itself
\param[in] bounds Shape bounds, in world-space for regular shapes, in local-space for SQ compound shapes.
\param[in] transform Shape transform, in world-space for regular shapes, in local-space for SQ compound shapes.
\param[in] compoundHandle Handle of SQ compound owner, or NULL for regular shapes.
\param[in] hasPruningStructure True if the shape is part of a pruning structure. The structure will be merged later, adding the objects will not invalidate the pruner.
\see merge() PxPruningStructure
*/
virtual void addSQShape( const PxRigidActor& actor, const PxShape& shape, const PxBounds3& bounds,
const PxTransform& transform, const PxSQCompoundHandle* compoundHandle=NULL, bool hasPruningStructure=false) = 0;
/**
\brief Removes a shape from the SQ system.
The same function is used to remove either a regular shape, or a SQ compound shape.
\param[in] actor The shape's actor owner
\param[in] shape The shape itself
*/
virtual void removeSQShape(const PxRigidActor& actor, const PxShape& shape) = 0;
/**
\brief Updates a shape in the SQ system.
The same function is used to update either a regular shape, or a SQ compound shape.
The transforms are eager-evaluated, but the bounds are lazy-evaluated. This means that
the updated transform has to be passed to the update function, while the bounds are automatically
recomputed by the system whenever needed.
\param[in] actor The shape's actor owner
\param[in] shape The shape itself
\param[in] transform New shape transform, in world-space for regular shapes, in local-space for SQ compound shapes.
*/
virtual void updateSQShape(const PxRigidActor& actor, const PxShape& shape, const PxTransform& transform) = 0;
/**
\brief Adds a compound to the SQ system.
\param[in] actor The compound actor
\param[in] shapes The compound actor's shapes
\param[in] bvh BVH structure containing the compound's shapes in local space
\param[in] transforms Shape transforms, in local-space
\return SQ compound handle
\see PxBVH PxCooking::createBVH
*/
virtual PxSQCompoundHandle addSQCompound(const PxRigidActor& actor, const PxShape** shapes, const PxBVH& bvh, const PxTransform* transforms) = 0;
/**
\brief Removes a compound from the SQ system.
\param[in] compoundHandle SQ compound handle (returned by addSQCompound)
*/
virtual void removeSQCompound(PxSQCompoundHandle compoundHandle) = 0;
/**
\brief Updates a compound in the SQ system.
The compound structures are immediately updated when the call occurs.
\param[in] compoundHandle SQ compound handle (returned by addSQCompound)
\param[in] compoundTransform New actor/compound transform, in world-space
*/
virtual void updateSQCompound(PxSQCompoundHandle compoundHandle, const PxTransform& compoundTransform) = 0;
/**
\brief Shift the data structures' origin by the specified vector.
Please refer to the notes of the similar function in PxScene.
\param[in] shift Translation vector to shift the origin by.
*/
virtual void shiftOrigin(const PxVec3& shift) = 0;
/**
\brief Visualizes the system's internal data-structures, for debugging purposes.
\param[in] prunerIndex Index of pruner to visualize (PX_SCENE_PRUNER_STATIC, PX_SCENE_PRUNER_DYNAMIC or PX_SCENE_COMPOUND_PRUNER when called from PxScene).
\param[out] out Filled with render output data
\see PxRenderOutput
*/
virtual void visualize(PxU32 prunerIndex, PxRenderOutput& out) const = 0;
/**
\brief Merges a pruning structure with the SQ system's internal pruners.
\param[in] pruningStructure The pruning structure to merge
\see PxPruningStructure
*/
virtual void merge(const PxPruningStructure& pruningStructure) = 0;
/**
\brief Shape to SQ-pruner-handle mapping function.
This function finds and returns the SQ pruner handle associated with a given (actor/shape) couple
that was previously added to the system. This is needed for the sync function.
\param[in] actor The shape's actor owner
\param[in] shape The shape itself
\param[out] prunerIndex Index of pruner the shape belongs to
\return Associated SQ pruner handle.
*/
virtual PxSQPrunerHandle getHandle(const PxRigidActor& actor, const PxShape& shape, PxU32& prunerIndex) const = 0;
/**
\brief Synchronizes the scene-query system with another system that references the same objects.
This function is used when the scene-query objects also exist in another system that can also update them. For example the scene-query objects
(used for raycast, overlap or sweep queries) might be driven by equivalent objects in an external rigid-body simulation engine. In this case
the rigid-body simulation engine computes the new poses and transforms, and passes them to the scene-query system using this function. It is
more efficient than calling updateSQShape on each object individually, since updateSQShape would end up recomputing the bounds already available
in the rigid-body engine.
\param[in] prunerIndex Index of pruner being synched (PX_SCENE_PRUNER_DYNAMIC for regular PhysX usage)
\param[in] handles Handles of updated objects
\param[in] indices Bounds & transforms indices of updated objects, i.e. object handles[i] has bounds[indices[i]] and transforms[indices[i]]
\param[in] bounds Array of bounds for all objects (not only updated bounds)
\param[in] transforms Array of transforms for all objects (not only updated transforms)
\param[in] count Number of updated objects
\param[in] ignoredIndices Optional bitmap of ignored indices, i.e. update is skipped if ignoredIndices[indices[i]] is set.
\see PxBounds3 PxTransform32 PxBitMap
*/
virtual void sync(PxU32 prunerIndex, const PxSQPrunerHandle* handles, const PxU32* indices, const PxBounds3* bounds, const PxTransform32* transforms, PxU32 count, const PxBitMap& ignoredIndices) = 0;
/**
\brief Finalizes updates made to the SQ system.
This function should be called after updates have been made to the SQ system, to fully reflect the changes
inside the internal pruners. In particular it should be called:
- after calls to updateSQShape
- after calls to sync
This function:
- recomputes bounds of manually updated shapes (i.e. either regular or SQ compound shapes modified by updateSQShape)
- updates dynamic pruners (refit operations)
- incrementally rebuilds AABB-trees
The amount of work performed in this function depends on PxSceneQueryUpdateMode.
\see PxSceneQueryUpdateMode updateSQShape() sync()
*/
virtual void finalizeUpdates() = 0;
/**
\brief Prepares asynchronous build step.
This is directly called (synchronously) by PxSceneSQSystem::sceneQueriesUpdate(). See the comments there.
This function is called to let the system execute any necessary synchronous operation before the
asynchronous sceneQueryBuildStep() function is called.
If there is any work to do for the specific pruner, the function returns a pruner-specific handle that
will be passed to the corresponding, asynchronous sceneQueryBuildStep function.
\return A pruner-specific handle that will be sent to sceneQueryBuildStep if there is any work to do, i.e. to execute the corresponding sceneQueryBuildStep() call.
\param[in] prunerIndex Index of pruner being built. (PX_SCENE_PRUNER_STATIC or PX_SCENE_PRUNER_DYNAMIC when called by PxScene).
\return Null if there is no work to do, otherwise a pruner-specific handle.
\see PxSceneSQSystem::sceneQueriesUpdate sceneQueryBuildStep
*/
virtual PxSQBuildStepHandle prepareSceneQueryBuildStep(PxU32 prunerIndex) = 0;
/**
\brief Executes asynchronous build step.
This is directly called (asynchronously) by PxSceneSQSystem::sceneQueriesUpdate(). See the comments there.
This function incrementally builds the internal trees/pruners. It is called asynchronously, i.e. this can be
called from different threads for building multiple trees at the same time.
\param[in] handle Pruner-specific handle previously returned by the prepareSceneQueryBuildStep function.
\see PxSceneSQSystem::sceneQueriesUpdate prepareSceneQueryBuildStep
*/
virtual void sceneQueryBuildStep(PxSQBuildStepHandle handle) = 0;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,613 @@
// 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 PX_SHAPE_H
#define PX_SHAPE_H
#include "PxPhysXConfig.h"
#include "common/PxBase.h"
#include "foundation/PxSimpleTypes.h"
#include "geometry/PxGeometry.h"
#include "geometry/PxGeometryHelpers.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxBoxGeometry;
class PxSphereGeometry;
class PxCapsuleGeometry;
class PxPlaneGeometry;
class PxConvexMeshGeometry;
class PxTriangleMeshGeometry;
class PxTetrahedronMeshGeometry;
class PxHeightFieldGeometry;
class PxParticleSystemGeometry;
class PxRigidActor;
struct PxFilterData;
class PxBaseMaterial;
class PxMaterial;
class PxDeformableSurfaceMaterial;
class PxDeformableVolumeMaterial;
/**
\brief Flags which affect the behavior of PxShapes.
\see PxShape PxShape.setFlag()
*/
struct PxShapeFlag
{
enum Enum
{
/**
\brief The shape will partake in collision in the physical simulation.
\note It is illegal to raise the eSIMULATION_SHAPE and eTRIGGER_SHAPE flags.
In the event that one of these flags is already raised the sdk will reject any
attempt to raise the other. To raise the eSIMULATION_SHAPE first ensure that
eTRIGGER_SHAPE is already lowered.
\note This flag has no effect if simulation is disabled for the corresponding actor (see #PxActorFlag::eDISABLE_SIMULATION).
\see PxSimulationEventCallback.onContact() PxScene.setSimulationEventCallback() PxShape.setFlag(), PxShape.setFlags()
*/
eSIMULATION_SHAPE = (1<<0),
/**
\brief The shape will partake in scene queries (ray casts, overlap tests, sweeps, ...).
*/
eSCENE_QUERY_SHAPE = (1<<1),
/**
\brief The shape is a trigger which can send reports whenever other shapes enter/leave its volume.
\note Triangle meshes and heightfields can not be triggers. Shape creation will fail in these cases.
\note Shapes marked as triggers do not collide with other objects. If an object should act both
as a trigger shape and a collision shape then create a rigid body with two shapes, one being a
trigger shape and the other a collision shape. It is illegal to raise the eTRIGGER_SHAPE and
eSIMULATION_SHAPE flags on a single PxShape instance. In the event that one of these flags is already
raised the sdk will reject any attempt to raise the other. To raise the eTRIGGER_SHAPE flag first
ensure that eSIMULATION_SHAPE flag is already lowered.
\note Trigger shapes will no longer send notification events for interactions with other trigger shapes.
\note Shapes marked as triggers are allowed to participate in scene queries, provided the eSCENE_QUERY_SHAPE flag is set.
\note This flag has no effect if simulation is disabled for the corresponding actor (see #PxActorFlag::eDISABLE_SIMULATION).
\see PxSimulationEventCallback.onTrigger() PxScene.setSimulationEventCallback() PxShape.setFlag(), PxShape.setFlags()
*/
eTRIGGER_SHAPE = (1<<2),
/**
\brief Enable debug renderer for this shape
\see PxScene.getRenderBuffer() PxRenderBuffer PxVisualizationParameter
*/
eVISUALIZATION = (1<<3)
};
};
/**
\brief collection of set bits defined in PxShapeFlag.
\see PxShapeFlag
*/
typedef PxFlags<PxShapeFlag::Enum,PxU8> PxShapeFlags;
PX_FLAGS_OPERATORS(PxShapeFlag::Enum,PxU8)
/**
\brief Abstract class for collision shapes.
Shapes are shared, reference counted objects.
An instance can be created by calling the createShape() method of the PxRigidActor class, or
the createShape() method of the PxPhysics class.
<h3>Visualizations</h3>
\li PxVisualizationParameter::eCOLLISION_AABBS
\li PxVisualizationParameter::eCOLLISION_SHAPES
\li PxVisualizationParameter::eCOLLISION_AXES
\see PxPhysics.createShape() PxRigidActor.createShape() PxBoxGeometry PxSphereGeometry PxCapsuleGeometry PxPlaneGeometry PxConvexMeshGeometry
PxTriangleMeshGeometry PxHeightFieldGeometry
*/
class PxShape : public PxRefCounted
{
public:
/**
\brief Adjust the geometry of the shape.
\note The type of the passed in geometry must match the geometry type of the shape.
\note It is not allowed to change the geometry type of a shape.
\note This function does not guarantee correct/continuous behavior when objects are resting on top of old or new geometry.
\param[in] geometry New geometry of the shape.
\see PxGeometry PxGeometryType getGeometryType()
*/
virtual void setGeometry(const PxGeometry& geometry) = 0;
/**
\brief Retrieve a reference to the shape's geometry.
\warning The returned reference has the same lifetime as the PxShape it comes from.
\return Reference to internal PxGeometry object.
\see PxGeometry PxGeometryType getGeometryType() setGeometry()
*/
virtual const PxGeometry& getGeometry() const = 0;
/**
\brief Retrieves the actor which this shape is associated with.
\return The actor this shape is associated with, if it is an exclusive shape, else NULL
\see PxRigidStatic, PxRigidDynamic, PxArticulationLink
*/
virtual PxRigidActor* getActor() const = 0;
/************************************************************************************************/
/** \name Pose Manipulation
*/
//\{
/**
\brief Sets the pose of the shape in actor space, i.e. relative to the actors to which they are attached.
This transformation is identity by default.
The local pose is an attribute of the shape, and so will apply to all actors to which the shape is attached.
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
<i>Note:</i> Does not automatically update the inertia properties of the owning actor (if applicable); use the
PhysX extensions method #PxRigidBodyExt::updateMassAndInertia() to do this.
<b>Default:</b> the identity transform
\param[in] pose The new transform from the actor frame to the shape frame. <b>Range:</b> rigid body transform
\see getLocalPose()
*/
virtual void setLocalPose(const PxTransform& pose) = 0;
/**
\brief Retrieves the pose of the shape in actor space, i.e. relative to the actor they are owned by.
This transformation is identity by default.
\return Pose of shape relative to the actor's frame.
\see setLocalPose()
*/
virtual PxTransform getLocalPose() const = 0;
//\}
/************************************************************************************************/
/** \name Collision Filtering
*/
//\{
/**
\brief Sets the user definable collision filter data.
<b>Sleeping:</b> Does wake up the actor if the filter data change causes a formerly suppressed
collision pair to be enabled.
<b>Default:</b> (0,0,0,0)
\see getSimulationFilterData()
*/
virtual void setSimulationFilterData(const PxFilterData& data) = 0;
/**
\brief Retrieves the shape's collision filter data.
\see setSimulationFilterData()
*/
virtual PxFilterData getSimulationFilterData() const = 0;
/**
\brief Sets the user definable query filter data.
<b>Default:</b> (0,0,0,0)
\see getQueryFilterData()
*/
virtual void setQueryFilterData(const PxFilterData& data) = 0;
/**
\brief Retrieves the shape's Query filter data.
\see setQueryFilterData()
*/
virtual PxFilterData getQueryFilterData() const = 0;
//\}
/************************************************************************************************/
/**
\brief Assigns material(s) to the shape. Will remove existing materials from the shape.
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
\param[in] materials List of material pointers to assign to the shape. See #PxMaterial
\param[in] materialCount The number of materials provided.
\see PxPhysics.createMaterial() getMaterials()
*/
virtual void setMaterials(PxMaterial*const* materials, PxU16 materialCount) = 0;
/**
\brief Assigns surface deformable material(s) to the shape. Will remove existing materials from the shape.
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
\param[in] materials List of material pointers to assign to the shape. See #PxDeformableSurfaceMaterial
\param[in] materialCount The number of materials provided.
\see PxPhysics.createDeformableSurfaceMaterial() getDeformableSurfaceMaterials()
*/
virtual void setDeformableSurfaceMaterials(PxDeformableSurfaceMaterial*const* materials, PxU16 materialCount) = 0;
/**
\brief Assigns deformable volume material(s) to the shape. Will remove existing materials from the shape.
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
\param[in] materials List of material pointers to assign to the shape. See #PxDeformableVolumeMaterial
\param[in] materialCount The number of materials provided.
\see PxPhysics.createDeformableVolumeMaterial() getDeformableVolumeMaterials()
*/
virtual void setDeformableVolumeMaterials(PxDeformableVolumeMaterial* const* materials, PxU16 materialCount) = 0;
/**
\brief Deprecated
\see setDeformableVolumeMaterials
*/
PX_DEPRECATED PX_FORCE_INLINE void setSoftBodyMaterials(PxDeformableVolumeMaterial* const* materials, PxU16 materialCount)
{
setDeformableVolumeMaterials(materials, materialCount);
}
/**
\brief Returns the number of materials assigned to the shape.
You can use #getMaterials() to retrieve the material pointers.
\return Number of materials associated with this shape.
\see PxMaterial getMaterials()
*/
virtual PxU16 getNbMaterials() const = 0;
/**
\brief Retrieve all the material pointers associated with the shape.
You can retrieve the number of material pointers by calling #getNbMaterials()
Note: The returned data may contain invalid pointers if you release materials using #PxMaterial::release().
\param[out] userBuffer The buffer to store the material pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first material pointer to be retrieved
\return Number of material pointers written to the buffer.
\see PxMaterial getNbMaterials() PxMaterial::release()
*/
virtual PxU32 getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/**
\brief Retrieve all the surface deformable material pointers associated with the shape.
You can retrieve the number of material pointers by calling #getNbMaterials()
Note: The returned data may contain invalid pointers if you release materials using #PxMaterial::release().
\param[out] userBuffer The buffer to store the material pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first material pointer to be retrieved
\return Number of material pointers written to the buffer.
\see PxDeformableSurfaceMaterial getNbMaterials() PxMaterial::release()
*/
virtual PxU32 getDeformableSurfaceMaterials(PxDeformableSurfaceMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief Retrieve all the deformable volume material pointers associated with the shape.
You can retrieve the number of material pointers by calling #getNbMaterials()
Note: The returned data may contain invalid pointers if you release materials using #PxMaterial::release().
\param[out] userBuffer The buffer to store the material pointers.
\param[in] bufferSize Size of provided user buffer.
\param[in] startIndex Index of first material pointer to be retrieved
\return Number of material pointers written to the buffer.
\see PxDeformableVolumeMaterial getNbMaterials() PxMaterial::release()
*/
virtual PxU32 getDeformableVolumeMaterials(PxDeformableVolumeMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0;
/**
\brief Deprecated
\see getDeformableVolumeMaterials
*/
PX_DEPRECATED PX_FORCE_INLINE PxU32 getSoftBodyMaterials(PxDeformableVolumeMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const
{
return getDeformableVolumeMaterials(userBuffer, bufferSize, startIndex);
}
/**
\brief Retrieve material from given triangle index.
The input index is the internal triangle index as used inside the SDK. This is the index
returned to users by various SDK functions such as raycasts.
This function is only useful for triangle meshes or heightfields, which have per-triangle
materials. For other shapes or SDF triangle meshes, the function returns the single material
associated with the shape, regardless of the index.
\param[in] faceIndex The internal triangle index whose material you want to retrieve.
\return Material from input triangle
\note If faceIndex value of 0xFFFFffff is passed as an input for mesh and heightfield shapes, this function will issue a warning and return NULL.
\note Scene queries set the value of PxQueryHit::faceIndex to 0xFFFFffff whenever it is undefined or does not apply.
\see PxMaterial getNbMaterials() PxMaterial::release()
*/
virtual PxBaseMaterial* getMaterialFromInternalFaceIndex(PxU32 faceIndex) const = 0;
/**
\brief Sets the contact offset.
Shapes whose distance is less than the sum of their contactOffset values will generate contacts. The contact offset must be positive and
greater than the rest offset. Having a contactOffset greater than than the restOffset allows the collision detection system to
predictively enforce the contact constraint even when the objects are slightly separated. This prevents jitter that would occur
if the constraint were enforced only when shapes were within the rest distance.
<b>Default:</b> 0.02f * PxTolerancesScale::length
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
\param[in] contactOffset <b>Range:</b> [maximum(0,restOffset), PX_MAX_F32)
\see getContactOffset PxTolerancesScale setRestOffset
*/
virtual void setContactOffset(PxReal contactOffset) = 0;
/**
\brief Retrieves the contact offset.
\return The contact offset of the shape.
\see setContactOffset()
*/
virtual PxReal getContactOffset() const = 0;
/**
\brief Sets the rest offset.
Two shapes will come to rest at a distance equal to the sum of their restOffset values. If the restOffset is 0, they should converge to touching
exactly. Having a restOffset greater than zero is useful to have objects slide smoothly, so that they do not get hung up on irregularities of
each others' surfaces.
<b>Default:</b> 0.0f
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
\param[in] restOffset <b>Range:</b> (-PX_MAX_F32, contactOffset)
\see getRestOffset setContactOffset
*/
virtual void setRestOffset(PxReal restOffset) = 0;
/**
\brief Retrieves the rest offset.
\return The rest offset of the shape.
\see setRestOffset()
*/
virtual PxReal getRestOffset() const = 0;
/**
\brief Sets the density used to interact with fluids.
To be physically accurate, the density of a rigid body should be computed as its mass divided by its volume. To
simplify tuning the interaction of fluid and rigid bodies, the density for fluid can differ from the real density. This
allows to create floating bodies, even if they are supposed to sink with their mass and volume.
<b>Default:</b> 800.0f
\param[in] densityForFluid <b>Range:</b> (0, PX_MAX_F32)
\see getDensityForFluid
*/
virtual void setDensityForFluid(PxReal densityForFluid) = 0;
/**
\brief Retrieves the density used to interact with fluids.
\return The density of the body when interacting with fluid.
\see setDensityForFluid()
*/
virtual PxReal getDensityForFluid() const = 0;
/**
\brief Sets torsional patch radius.
This defines the radius of the contact patch used to apply torsional friction. If the radius is 0 (and minTorsionalPatchRadius
is 0 too, see #setMinTorsionalPatchRadius), no torsional friction will be applied. If the radius is > 0, some torsional friction
will be applied. This is proportional to the penetration depth so, if the shapes are separated or penetration is zero, no
torsional friction will be applied. It is used to approximate rotational friction introduced by the compression of contacting surfaces.
\note Will only be active, if the friction patch has a single anchor point only. This is for example the case, if a contact patch
has a single contact point.
\note Only supported in combination with solver type PxSolverType::eTGS.
<b>Default:</b> 0.0
\param[in] radius <b>Range:</b> [0, PX_MAX_F32)
*/
virtual void setTorsionalPatchRadius(PxReal radius) = 0;
/**
\brief Gets torsional patch radius.
See #setTorsionalPatchRadius for more info.
\return The torsional patch radius of the shape.
*/
virtual PxReal getTorsionalPatchRadius() const = 0;
/**
\brief Sets minimum torsional patch radius.
This defines the minimum radius of the contact patch used to apply torsional friction. If the radius is 0, the amount of torsional friction
that will be applied will be entirely dependent on the value of torsionalPatchRadius.
If the radius is > 0, some torsional friction will be applied regardless of the value of torsionalPatchRadius or the amount of penetration.
\note Will only be active in certain cases, see #setTorsionalPatchRadius for details.
<b>Default:</b> 0.0
\param[in] radius <b>Range:</b> [0, PX_MAX_F32)
*/
virtual void setMinTorsionalPatchRadius(PxReal radius) = 0;
/**
\brief Gets minimum torsional patch radius.
See #setMinTorsionalPatchRadius for more info.
\return The minimum torsional patch radius of the shape.
*/
virtual PxReal getMinTorsionalPatchRadius() const = 0;
/**
\brief Returns the GPU shape index.
\note This function only returns valid results if GPU dynamics is enabled.
\return The GPU index, or 0xFFFFFFFF if the shape is not attached to a PxActor that is inserted into a PxScene.
\see PxDirectGPUAPI::evaluateSDFDistances().
*/
virtual PxShapeGPUIndex getGPUIndex() const = 0;
/************************************************************************************************/
/**
\brief Sets shape flags
<b>Sleeping:</b> Does <b>NOT</b> wake the associated actor up automatically.
\param[in] flag The shape flag to enable/disable. See #PxShapeFlag.
\param[in] value True to set the flag. False to clear the flag specified in flag.
<b>Default:</b> PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eSCENE_QUERY_SHAPE
\see PxShapeFlag getFlags()
*/
virtual void setFlag(PxShapeFlag::Enum flag, bool value) = 0;
/**
\brief Sets shape flags
\see PxShapeFlag getFlags()
*/
virtual void setFlags(PxShapeFlags inFlags) = 0;
/**
\brief Retrieves shape flags.
\return The values of the shape flags.
\see PxShapeFlag setFlag()
*/
virtual PxShapeFlags getFlags() const = 0;
/**
\brief Returns true if the shape is exclusive to an actor.
\see PxPhysics::createShape()
*/
virtual bool isExclusive() const = 0;
/**
\brief Sets a name string for the object that can be retrieved with #getName().
This is for debugging and is not used by the SDK.
The string is not copied by the SDK, only the pointer is stored.
<b>Default:</b> NULL
\param[in] name The name string to set the objects name to.
\see getName()
*/
virtual void setName(const char* name) = 0;
/**
\brief retrieves the name string set with setName().
\return The name associated with the shape.
\see setName()
*/
virtual const char* getName() const = 0;
virtual const char* getConcreteTypeName() const PX_OVERRIDE PX_FINAL { return "PxShape"; }
/************************************************************************************************/
void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object.
protected:
PX_INLINE PxShape(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {}
PX_INLINE PxShape(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags), userData(NULL) {}
virtual ~PxShape() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxShape", PxRefCounted); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,963 @@
// 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 PX_SIMULATION_EVENT_CALLBACK_H
#define PX_SIMULATION_EVENT_CALLBACK_H
#include "foundation/PxVec3.h"
#include "foundation/PxTransform.h"
#include "foundation/PxMemory.h"
#include "PxPhysXConfig.h"
#include "PxFiltering.h"
#include "PxContact.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxShape;
class PxActor;
class PxRigidActor;
class PxRigidBody;
class PxConstraint;
/**
\brief Extra data item types for contact pairs.
\see PxContactPairExtraDataItem.type
*/
struct PxContactPairExtraDataType
{
enum Enum
{
ePRE_SOLVER_VELOCITY, //!< see #PxContactPairVelocity
ePOST_SOLVER_VELOCITY, //!< see #PxContactPairVelocity
eCONTACT_EVENT_POSE, //!< see #PxContactPairPose
eCONTACT_PAIR_INDEX //!< see #PxContactPairIndex
};
};
/**
\brief Base class for items in the extra data stream of contact pairs
\see PxContactPairHeader.extraDataStream
*/
struct PxContactPairExtraDataItem
{
public:
PX_FORCE_INLINE PxContactPairExtraDataItem() {}
/**
\brief The type of the extra data stream item
*/
PxU8 type;
};
/**
\brief Velocities of the contact pair rigid bodies
This struct is shared by multiple types of extra data items. The #type field allows to distinguish between them:
\li PxContactPairExtraDataType::ePRE_SOLVER_VELOCITY: see #PxPairFlag::ePRE_SOLVER_VELOCITY
\li PxContactPairExtraDataType::ePOST_SOLVER_VELOCITY: see #PxPairFlag::ePOST_SOLVER_VELOCITY
\note For static rigid bodies, the velocities will be set to zero.
\see PxContactPairHeader.extraDataStream
*/
struct PxContactPairVelocity : public PxContactPairExtraDataItem
{
public:
PX_FORCE_INLINE PxContactPairVelocity() {}
/**
\brief The linear velocity of the rigid bodies
*/
PxVec3 linearVelocity[2];
/**
\brief The angular velocity of the rigid bodies
*/
PxVec3 angularVelocity[2];
};
/**
\brief World space actor poses of the contact pair rigid bodies
\see PxContactPairHeader.extraDataStream PxPairFlag::eCONTACT_EVENT_POSE
*/
struct PxContactPairPose : public PxContactPairExtraDataItem
{
public:
PX_FORCE_INLINE PxContactPairPose() {}
/**
\brief The world space pose of the rigid bodies
*/
PxTransform globalPose[2];
};
/**
\brief Marker for the beginning of a new item set in the extra data stream.
If CCD with multiple passes is enabled, then a fast moving object might bounce on and off the same
object multiple times. Also, different shapes of the same actor might gain and lose contact with an other
object over multiple passes. This marker allows to separate the extra data items for each collision case, as well as
distinguish the shape pair reports of different CCD passes.
Example:
Let us assume that an actor a0 with shapes s0_0 and s0_1 hits another actor a1 with shape s1.
First s0_0 will hit s1, then a0 will slightly rotate and s0_1 will hit s1 while s0_0 will lose contact with s1.
Furthermore, let us say that contact event pose information is requested as extra data.
The extra data stream will look like this:
PxContactPairIndexA | PxContactPairPoseA | PxContactPairIndexB | PxContactPairPoseB
The corresponding array of PxContactPair events (see #PxSimulationEventCallback.onContact()) will look like this:
PxContactPair(touch_found: s0_0, s1) | PxContactPair(touch_lost: s0_0, s1) | PxContactPair(touch_found: s0_1, s1)
The #index of PxContactPairIndexA will point to the first entry in the PxContactPair array, for PxContactPairIndexB,
#index will point to the third entry.
\see PxContactPairHeader.extraDataStream
*/
struct PxContactPairIndex : public PxContactPairExtraDataItem
{
public:
PX_FORCE_INLINE PxContactPairIndex() {}
/**
\brief The next item set in the extra data stream refers to the contact pairs starting at #index in the reported PxContactPair array.
*/
PxU16 index;
};
/**
\brief A class to iterate over a contact pair extra data stream.
\see PxContactPairHeader.extraDataStream
*/
struct PxContactPairExtraDataIterator
{
/**
\brief Constructor
\param[in] stream Pointer to the start of the stream.
\param[in] size Size of the stream in bytes.
*/
PX_FORCE_INLINE PxContactPairExtraDataIterator(const PxU8* stream, PxU32 size)
: currPtr(stream), endPtr(stream + size), contactPairIndex(0)
{
clearDataPtrs();
}
/**
\brief Advances the iterator to next set of extra data items.
The contact pair extra data stream contains sets of items as requested by the corresponding #PxPairFlag flags
#PxPairFlag::ePRE_SOLVER_VELOCITY, #PxPairFlag::ePOST_SOLVER_VELOCITY, #PxPairFlag::eCONTACT_EVENT_POSE. A set can contain one
item of each plus the PxContactPairIndex item. This method parses the stream and points the iterator
member variables to the corresponding items of the current set, if they are available. If CCD is not enabled,
you should only get one set of items. If CCD with multiple passes is enabled, you might get more than one item
set.
\note Even though contact pair extra data is requested per shape pair, you will not get an item set per shape pair
but one per actor pair. If, for example, an actor has two shapes and both collide with another actor, then
there will only be one item set (since it applies to both shape pairs).
\return True if there was another set of extra data items in the stream, else false.
\see PxContactPairVelocity PxContactPairPose PxContactPairIndex
*/
PX_INLINE bool nextItemSet()
{
clearDataPtrs();
bool foundEntry = false;
bool endOfItemSet = false;
while ((currPtr < endPtr) && (!endOfItemSet))
{
const PxContactPairExtraDataItem* edItem = reinterpret_cast<const PxContactPairExtraDataItem*>(currPtr);
PxU8 type = edItem->type;
switch(type)
{
case PxContactPairExtraDataType::ePRE_SOLVER_VELOCITY:
{
PX_ASSERT(!preSolverVelocity);
preSolverVelocity = static_cast<const PxContactPairVelocity*>(edItem);
currPtr += sizeof(PxContactPairVelocity);
foundEntry = true;
}
break;
case PxContactPairExtraDataType::ePOST_SOLVER_VELOCITY:
{
postSolverVelocity = static_cast<const PxContactPairVelocity*>(edItem);
currPtr += sizeof(PxContactPairVelocity);
foundEntry = true;
}
break;
case PxContactPairExtraDataType::eCONTACT_EVENT_POSE:
{
eventPose = static_cast<const PxContactPairPose*>(edItem);
currPtr += sizeof(PxContactPairPose);
foundEntry = true;
}
break;
case PxContactPairExtraDataType::eCONTACT_PAIR_INDEX:
{
if (!foundEntry)
{
contactPairIndex = static_cast<const PxContactPairIndex*>(edItem)->index;
currPtr += sizeof(PxContactPairIndex);
foundEntry = true;
}
else
endOfItemSet = true;
}
break;
default:
return foundEntry;
}
}
return foundEntry;
}
private:
/**
\brief Internal helper
*/
PX_FORCE_INLINE void clearDataPtrs()
{
preSolverVelocity = NULL;
postSolverVelocity = NULL;
eventPose = NULL;
}
public:
/**
\brief Current pointer in the stream.
*/
const PxU8* currPtr;
/**
\brief Pointer to the end of the stream.
*/
const PxU8* endPtr;
/**
\brief Pointer to the current pre solver velocity item in the stream. NULL if there is none.
\see PxContactPairVelocity
*/
const PxContactPairVelocity* preSolverVelocity;
/**
\brief Pointer to the current post solver velocity item in the stream. NULL if there is none.
\see PxContactPairVelocity
*/
const PxContactPairVelocity* postSolverVelocity;
/**
\brief Pointer to the current contact event pose item in the stream. NULL if there is none.
\see PxContactPairPose
*/
const PxContactPairPose* eventPose;
/**
\brief The contact pair index of the current item set in the stream.
\see PxContactPairIndex
*/
PxU32 contactPairIndex;
};
/**
\brief Collection of flags providing information on contact report pairs.
\see PxContactPairHeader
*/
struct PxContactPairHeaderFlag
{
enum Enum
{
eREMOVED_ACTOR_0 = (1<<0), //!< The actor with index 0 has been removed from the scene.
eREMOVED_ACTOR_1 = (1<<1) //!< The actor with index 1 has been removed from the scene.
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxContactPairHeaderFlag.
\see PxContactPairHeaderFlag
*/
typedef PxFlags<PxContactPairHeaderFlag::Enum, PxU16> PxContactPairHeaderFlags;
PX_FLAGS_OPERATORS(PxContactPairHeaderFlag::Enum, PxU16)
/**
\brief An Instance of this class is passed to PxSimulationEventCallback.onContact().
\see PxSimulationEventCallback.onContact()
*/
struct PxContactPairHeader
{
public:
PX_INLINE PxContactPairHeader() {}
/**
\brief The two actors of the notification shape pairs.
\note The actor pointers might reference deleted actors. This will be the case if PxPairFlag::eNOTIFY_TOUCH_LOST
or PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST events were requested for the pair and one of the involved actors
gets deleted or removed from the scene. Check the #flags member to see whether that is the case.
Do not dereference a pointer to a deleted actor. The pointer to a deleted actor is only provided
such that user data structures which might depend on the pointer value can be updated.
\see PxActor
*/
PxActor* actors[2];
/**
\brief Stream containing extra data as requested in the PxPairFlag flags of the simulation filter.
This pointer is only valid if any kind of extra data information has been requested for the contact report pair (see #PxPairFlag::ePOST_SOLVER_VELOCITY etc.),
else it will be NULL.
\see PxPairFlag
*/
const PxU8* extraDataStream;
/**
\brief Size of the extra data stream [bytes]
*/
PxU16 extraDataStreamSize;
/**
\brief Additional information on the contact report pair.
\see PxContactPairHeaderFlag
*/
PxContactPairHeaderFlags flags;
/**
\brief pointer to the contact pairs
*/
const struct PxContactPair* pairs;
/**
\brief number of contact pairs
*/
PxU32 nbPairs;
};
/**
\brief Collection of flags providing information on contact report pairs.
\see PxContactPair
*/
struct PxContactPairFlag
{
enum Enum
{
/**
\brief The shape with index 0 has been removed from the actor/scene.
*/
eREMOVED_SHAPE_0 = (1<<0),
/**
\brief The shape with index 1 has been removed from the actor/scene.
*/
eREMOVED_SHAPE_1 = (1<<1),
/**
\brief First actor pair contact.
The provided shape pair marks the first contact between the two actors, no other shape pair has been touching prior to the current simulation frame.
\note: This info is only available if #PxPairFlag::eNOTIFY_TOUCH_FOUND has been declared for the pair.
*/
eACTOR_PAIR_HAS_FIRST_TOUCH = (1<<2),
/**
\brief All contact between the actor pair was lost.
All contact between the two actors has been lost, no shape pairs remain touching after the current simulation frame.
*/
eACTOR_PAIR_LOST_TOUCH = (1<<3),
/**
\brief Internal flag, used by #PxContactPair.extractContacts()
The applied contact impulses are provided for every contact point.
This is the case if #PxPairFlag::eSOLVE_CONTACT has been set for the pair.
*/
eINTERNAL_HAS_IMPULSES = (1<<4),
/**
\brief Internal flag, used by #PxContactPair.extractContacts()
The provided contact point information is flipped with regards to the shapes of the contact pair. This mainly concerns the order of the internal triangle indices.
*/
eINTERNAL_CONTACTS_ARE_FLIPPED = (1<<5)
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxContactPairFlag.
\see PxContactPairFlag
*/
typedef PxFlags<PxContactPairFlag::Enum, PxU16> PxContactPairFlags;
PX_FLAGS_OPERATORS(PxContactPairFlag::Enum, PxU16)
/**
\brief A contact point as used by contact notification
*/
struct PxContactPairPoint
{
/**
\brief The position of the contact point between the shapes, in world space.
*/
PxVec3 position;
/**
\brief The separation of the shapes at the contact point. A negative separation denotes a penetration.
*/
PxReal separation;
/**
\brief The normal of the contacting surfaces at the contact point. The normal direction points from the second shape to the first shape.
*/
PxVec3 normal;
/**
\brief The surface index of shape 0 at the contact point. This is used to identify the surface material.
*/
PxU32 internalFaceIndex0;
/**
\brief The impulse applied at the contact point, in world space. Divide by the simulation time step to get a force value.
*/
PxVec3 impulse;
/**
\brief The surface index of shape 1 at the contact point. This is used to identify the surface material.
*/
PxU32 internalFaceIndex1;
};
/**
\brief A friction anchor as used by contact notification
*/
struct PxContactPairFrictionAnchor
{
/**
\brief The position of the friction anchor in world space.
*/
PxVec3 position;
/**
\brief The impulse applied at the friction anchor, in world space. Divide by the simulation time step to get a force value.
*/
PxVec3 impulse;
};
/**
\brief Contact report pair information.
Instances of this class are passed to PxSimulationEventCallback.onContact(). If contact reports have been requested for a pair of shapes (see #PxPairFlag),
then the corresponding contact information will be provided through this structure.
\see PxSimulationEventCallback.onContact()
*/
struct PxContactPair
{
public:
PX_INLINE PxContactPair() {}
/**
\brief The two shapes that make up the pair.
\note The shape pointers might reference deleted shapes. This will be the case if #PxPairFlag::eNOTIFY_TOUCH_LOST
or #PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST events were requested for the pair and one of the involved shapes
gets deleted. Check the #flags member to see whether that is the case. Do not dereference a pointer to a
deleted shape. The pointer to a deleted shape is only provided such that user data structures which might
depend on the pointer value can be updated.
\see PxShape
*/
PxShape* shapes[2];
/**
\brief Pointer to first patch header in contact stream containing contact patch data
This pointer is only valid if contact point information has been requested for the contact report pair (see #PxPairFlag::eNOTIFY_CONTACT_POINTS).
Use #extractContacts() as a reference for the data layout of the stream.
*/
const PxU8* contactPatches;
/**
\brief Pointer to first contact point in contact stream containing contact data
This pointer is only valid if contact point information has been requested for the contact report pair (see #PxPairFlag::eNOTIFY_CONTACT_POINTS).
Use #extractContacts() as a reference for the data layout of the stream.
*/
const PxU8* contactPoints;
/**
\brief Buffer containing applied impulse data.
This pointer is only valid if contact point information has been requested for the contact report pair (see #PxPairFlag::eNOTIFY_CONTACT_POINTS).
Use #extractContacts() as a reference for the data layout of the stream.
*/
const PxReal* contactImpulses;
/**
\brief Buffer containing contact patches friction information.
*/
const PxU8* frictionPatches;
/**
\brief Size of the contact stream [bytes] including force buffer
*/
PxU32 requiredBufferSize;
/**
\brief Number of contact points stored in the contact stream
*/
PxU8 contactCount;
/**
\brief Number of contact patches stored in the contact stream
*/
PxU8 patchCount;
/**
\brief Size of the contact stream [bytes] not including force buffer
*/
PxU16 contactStreamSize;
/**
\brief Additional information on the contact report pair.
\see PxContactPairFlag
*/
PxContactPairFlags flags;
/**
\brief Flags raised due to the contact.
The events field is a combination of:
<ul>
<li>PxPairFlag::eNOTIFY_TOUCH_FOUND,</li>
<li>PxPairFlag::eNOTIFY_TOUCH_PERSISTS,</li>
<li>PxPairFlag::eNOTIFY_TOUCH_LOST,</li>
<li>PxPairFlag::eNOTIFY_TOUCH_CCD,</li>
<li>PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND,</li>
<li>PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS,</li>
<li>PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST</li>
</ul>
See the documentation of #PxPairFlag for an explanation of each.
\note eNOTIFY_TOUCH_CCD can get raised even if the pair did not request this event. However, in such a case it will only get
raised in combination with one of the other flags to point out that the other event occured during a CCD pass.
\see PxPairFlag
*/
PxPairFlags events;
PxU32 internalData[2]; // For internal use only
/**
\brief Extracts the contact points from the stream and stores them in a convenient format.
\param[out] userBuffer Array of PxContactPairPoint structures to extract the contact points to. The number of contacts for a pair is defined by #contactCount
\param[in] bufferSize Number of PxContactPairPoint structures the provided buffer can store.
\return Number of contact points written to the buffer.
\see PxContactPairPoint
*/
PX_INLINE PxU32 extractContacts(PxContactPairPoint* userBuffer, PxU32 bufferSize) const;
/**
\brief Extracts the friction anchors from the stream and stores them in a convenient format.
\param[out] userBuffer Array of PxContactPairFrictionAnchor structures to extract the friction anchors to.
\param[in] bufferSize Number of PxContactPairFrictionAnchor structures the provided buffer can store.
\return Number of friction anchors written to the buffer.
\see PxContactPairFrictionAnchor
*/
PX_INLINE PxU32 extractFrictionAnchors(PxContactPairFrictionAnchor* userBuffer, PxU32 bufferSize) const;
/**
\brief Helper method to clone the contact pair and copy the contact data stream into a user buffer.
The contact data stream is only accessible during the contact report callback. This helper function provides copy functionality
to buffer the contact stream information such that it can get accessed at a later stage.
\param[out] newPair The contact pair info will get copied to this instance. The contact data stream pointer of the copy will be redirected to the provided user buffer. Use NULL to skip the contact pair copy operation.
\param[out] bufferMemory Memory block to store the contact data stream to. At most #requiredBufferSize bytes will get written to the buffer.
*/
PX_INLINE void bufferContacts(PxContactPair* newPair, PxU8* bufferMemory) const;
PX_INLINE const PxU32* getInternalFaceIndices() const;
};
PX_INLINE PxU32 PxContactPair::extractContacts(PxContactPairPoint* userBuffer, PxU32 bufferSize) const
{
PxU32 nbContacts = 0;
if(contactCount && bufferSize)
{
PxContactStreamIterator iter(contactPatches, contactPoints, getInternalFaceIndices(), patchCount, contactCount);
const PxReal* impulses = contactImpulses;
const PxU32 flippedContacts = (flags & PxContactPairFlag::eINTERNAL_CONTACTS_ARE_FLIPPED);
const PxU32 hasImpulses = (flags & PxContactPairFlag::eINTERNAL_HAS_IMPULSES);
while(iter.hasNextPatch())
{
iter.nextPatch();
while(iter.hasNextContact())
{
iter.nextContact();
PxContactPairPoint& dst = userBuffer[nbContacts];
dst.position = iter.getContactPoint();
dst.separation = iter.getSeparation();
dst.normal = iter.getContactNormal();
if(!flippedContacts)
{
dst.internalFaceIndex0 = iter.getFaceIndex0();
dst.internalFaceIndex1 = iter.getFaceIndex1();
}
else
{
dst.internalFaceIndex0 = iter.getFaceIndex1();
dst.internalFaceIndex1 = iter.getFaceIndex0();
}
if(hasImpulses)
{
const PxReal impulse = impulses[nbContacts];
dst.impulse = dst.normal * impulse;
}
else
dst.impulse = PxVec3(0.0f);
++nbContacts;
if(nbContacts == bufferSize)
return nbContacts;
}
}
}
return nbContacts;
}
PX_INLINE PxU32 PxContactPair::extractFrictionAnchors(PxContactPairFrictionAnchor* userBuffer, PxU32 bufferSize) const
{
PxU32 nbAnchors = 0;
if(bufferSize)
{
PxFrictionAnchorStreamIterator iter(contactPatches, frictionPatches, patchCount);
while(iter.hasNextPatch())
{
iter.nextPatch();
while(iter.hasNextFrictionAnchor())
{
iter.nextFrictionAnchor();
PxContactPairFrictionAnchor& dst = userBuffer[nbAnchors];
dst.position = iter.getPosition();
dst.impulse = iter.getImpulse();
++nbAnchors;
if(nbAnchors == bufferSize)
return nbAnchors;
}
}
}
return nbAnchors;
}
PX_INLINE void PxContactPair::bufferContacts(PxContactPair* newPair, PxU8* bufferMemory) const
{
PxU8* patches = bufferMemory;
PxU8* contacts = NULL;
if(patches)
{
contacts = bufferMemory + patchCount * sizeof(PxContactPatch);
PxMemCopy(patches, contactPatches, sizeof(PxContactPatch)*patchCount);
PxMemCopy(contacts, contactPoints, contactStreamSize - (sizeof(PxContactPatch)*patchCount));
}
if(contactImpulses)
{
PxMemCopy(bufferMemory + ((contactStreamSize + 15) & (~15)), contactImpulses, sizeof(PxReal) * contactCount);
}
if (newPair)
{
*newPair = *this;
newPair->contactPatches = patches;
newPair->contactPoints = contacts;
}
}
PX_INLINE const PxU32* PxContactPair::getInternalFaceIndices() const
{
return reinterpret_cast<const PxU32*>(contactImpulses + contactCount);
}
/**
\brief Collection of flags providing information on trigger report pairs.
\see PxTriggerPair
*/
struct PxTriggerPairFlag
{
enum Enum
{
eREMOVED_SHAPE_TRIGGER = (1<<0), //!< The trigger shape has been removed from the actor/scene.
eREMOVED_SHAPE_OTHER = (1<<1), //!< The shape causing the trigger event has been removed from the actor/scene.
eNEXT_FREE = (1<<2) //!< For internal use only.
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxTriggerPairFlag.
\see PxTriggerPairFlag
*/
typedef PxFlags<PxTriggerPairFlag::Enum, PxU8> PxTriggerPairFlags;
PX_FLAGS_OPERATORS(PxTriggerPairFlag::Enum, PxU8)
/**
\brief Descriptor for a trigger pair.
An array of these structs gets passed to the PxSimulationEventCallback::onTrigger() report.
\note The shape pointers might reference deleted shapes. This will be the case if #PxPairFlag::eNOTIFY_TOUCH_LOST
events were requested for the pair and one of the involved shapes gets deleted. Check the #flags member to see
whether that is the case. Do not dereference a pointer to a deleted shape. The pointer to a deleted shape is
only provided such that user data structures which might depend on the pointer value can be updated.
\see PxSimulationEventCallback.onTrigger()
*/
struct PxTriggerPair
{
PX_INLINE PxTriggerPair() {}
PxShape* triggerShape; //!< The shape that has been marked as a trigger.
PxActor* triggerActor; //!< The actor to which triggerShape is attached
PxShape* otherShape; //!< The shape causing the trigger event. \deprecated (see #PxSimulationEventCallback::onTrigger()) If collision between trigger shapes is enabled, then this member might point to a trigger shape as well.
PxActor* otherActor; //!< The actor to which otherShape is attached
PxPairFlag::Enum status; //!< Type of trigger event (eNOTIFY_TOUCH_FOUND or eNOTIFY_TOUCH_LOST). eNOTIFY_TOUCH_PERSISTS events are not supported.
PxTriggerPairFlags flags; //!< Additional information on the pair (see #PxTriggerPairFlag)
};
/**
\brief Descriptor for a broken constraint.
An array of these structs gets passed to the PxSimulationEventCallback::onConstraintBreak() report.
\see PxConstraint PxSimulationEventCallback.onConstraintBreak()
*/
struct PxConstraintInfo
{
PX_INLINE PxConstraintInfo() {}
PX_INLINE PxConstraintInfo(PxConstraint* c, void* extRef, PxU32 t) : constraint(c), externalReference(extRef), type(t) {}
PxConstraint* constraint; //!< The broken constraint.
void* externalReference; //!< The external object which owns the constraint (see #PxConstraintConnector::getExternalReference())
PxU32 type; //!< Unique type ID of the external object. Allows to cast the provided external reference to the appropriate type
};
/**
\brief An interface class that the user can implement in order to receive simulation events.
With the exception of onAdvance(), the events get sent during the call to either #PxScene::fetchResults() or
#PxScene::flushSimulation() with sendPendingReports=true. onAdvance() gets called while the simulation
is running (that is between PxScene::simulate() or PxScene::advance() and PxScene::fetchResults()).
\note SDK state should not be modified from within the callbacks. In particular objects should not
be created or destroyed. If state modification is needed then the changes should be stored to a buffer
and performed after the simulation step.
<b>Threading:</b> With the exception of onAdvance(), it is not necessary to make these callbacks thread safe as
they will only be called in the context of the user thread.
\see PxScene.setSimulationEventCallback() PxScene.getSimulationEventCallback()
*/
class PxSimulationEventCallback
{
public:
/**
\brief This is called when a breakable constraint breaks.
\note The user should not release the constraint shader inside this call!
\note No event will get reported if the constraint breaks but gets deleted while the time step is still being simulated.
\param[in] constraints - The constraints which have been broken.
\param[in] count - The number of constraints
\see PxConstraint PxConstraintDesc.linearBreakForce PxConstraintDesc.angularBreakForce
*/
virtual void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) = 0;
/**
\brief This is called with the actors which have just been woken up.
\note Only supported by rigid bodies yet.
\note Only called on actors for which the PxActorFlag eSEND_SLEEP_NOTIFIES has been set.
\note Only the latest sleep state transition happening between fetchResults() of the previous frame and fetchResults() of the current frame
will get reported. For example, let us assume actor A is awake, then A->putToSleep() gets called, then later A->wakeUp() gets called.
At the next simulate/fetchResults() step only an onWake() event will get triggered because that was the last transition.
\note If an actor gets newly added to a scene with properties such that it is awake and the sleep state does not get changed by
the user or simulation, then an onWake() event will get sent at the next simulate/fetchResults() step.
\param[in] actors - The actors which just woke up.
\param[in] count - The number of actors
\see PxScene.setSimulationEventCallback() PxSceneDesc.simulationEventCallback PxActorFlag PxActor.setActorFlag()
*/
virtual void onWake(PxActor** actors, PxU32 count) = 0;
/**
\brief This is called with the actors which have just been put to sleep.
\note Only supported by rigid bodies yet.
\note Only called on actors for which the PxActorFlag eSEND_SLEEP_NOTIFIES has been set.
\note Only the latest sleep state transition happening between fetchResults() of the previous frame and fetchResults() of the current frame
will get reported. For example, let us assume actor A is asleep, then A->wakeUp() gets called, then later A->putToSleep() gets called.
At the next simulate/fetchResults() step only an onSleep() event will get triggered because that was the last transition (assuming the simulation
does not wake the actor up).
\note If an actor gets newly added to a scene with properties such that it is asleep and the sleep state does not get changed by
the user or simulation, then an onSleep() event will get sent at the next simulate/fetchResults() step.
\param[in] actors - The actors which have just been put to sleep.
\param[in] count - The number of actors
\see PxScene.setSimulationEventCallback() PxSceneDesc.simulationEventCallback PxActorFlag PxActor.setActorFlag()
*/
virtual void onSleep(PxActor** actors, PxU32 count) = 0;
/**
\brief This is called when certain contact events occur.
The method will be called for a pair of actors if one of the colliding shape pairs requested contact notification.
You request which events are reported using the filter shader/callback mechanism (see #PxSimulationFilterShader,
#PxSimulationFilterCallback, #PxPairFlag).
Do not keep references to the passed objects, as they will be
invalid after this function returns.
\param[in] pairHeader Information on the two actors whose shapes triggered a contact report.
\param[in] pairs The contact pairs of two actors for which contact reports have been requested. See #PxContactPair.
\param[in] nbPairs The number of provided contact pairs.
\see PxScene.setSimulationEventCallback() PxSceneDesc.simulationEventCallback PxContactPair PxPairFlag PxSimulationFilterShader PxSimulationFilterCallback
*/
virtual void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs) = 0;
/**
\brief This is called with the current trigger pair events.
Shapes which have been marked as triggers using PxShapeFlag::eTRIGGER_SHAPE will send events
according to the pair flag specification in the filter shader (see #PxPairFlag, #PxSimulationFilterShader).
\note Trigger shapes will no longer send notification events for interactions with other trigger shapes.
\param[in] pairs - The trigger pair events.
\param[in] count - The number of trigger pair events.
\see PxScene.setSimulationEventCallback() PxSceneDesc.simulationEventCallback PxPairFlag PxSimulationFilterShader PxShapeFlag PxShape.setFlag()
*/
virtual void onTrigger(PxTriggerPair* pairs, PxU32 count) = 0;
/**
\brief Provides early access to the new pose of moving rigid bodies.
When this call occurs, rigid bodies having the #PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW
flag set, were moved by the simulation and their new poses can be accessed through the provided buffers.
\note The provided buffers are valid and can be read until the next call to #PxScene::simulate() or #PxScene::collide().
\note This callback gets triggered while the simulation is running. If the provided rigid body references are used to
read properties of the object, then the callback has to guarantee no other thread is writing to the same body at the same
time.
\note The code in this callback should be lightweight as it can block the simulation, that is, the
#PxScene::fetchResults() call.
\param[in] bodyBuffer The rigid bodies that moved and requested early pose reporting.
\param[in] poseBuffer The integrated rigid body poses of the bodies listed in bodyBuffer.
\param[in] count The number of entries in the provided buffers.
\see PxScene.setSimulationEventCallback() PxSceneDesc.simulationEventCallback PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW
*/
virtual void onAdvance(const PxRigidBody*const* bodyBuffer, const PxTransform* poseBuffer, const PxU32 count) = 0;
virtual ~PxSimulationEventCallback() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,499 @@
// 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 PX_SIMULATION_STATISTICS_H
#define PX_SIMULATION_STATISTICS_H
#include "foundation/PxAssert.h"
#include "PxPhysXConfig.h"
#include "foundation/PxSimpleTypes.h"
#include "geometry/PxGeometry.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Structure used to retrieve actual sizes/counts for the configuration parameters provided in PxGpuDynamicsMemoryConfig.
\note All the values in this structure are reported as the maximum over the lifetime of a PxScene.
\see PxScene::getSimulationStatistics(), PxSimulationStatistics, PxSceneDesc::PxGpuDynamicsMemoryConfig
*/
struct PxGpuDynamicsMemoryConfigStatistics
{
PxU64 tempBufferCapacity; //!< actual size needed (bytes) for PxGpuDynamicsMemoryConfig::tempBufferCapacity.
PxU32 rigidContactCount; //!< actual number of rigid contacts needed - see PxGpuDynamicsMemoryConfig::maxRigidContactCount.
PxU32 rigidPatchCount; //!< actual number of rigid contact patches needed - see PxGpuDynamicsMemoryConfig::maxRigidPatchCount.
PxU32 foundLostPairs; //!< actual number of lost/found pairs needed - see PxGpuDynamicsMemoryConfig::foundLostPairsCapacity.
PxU32 foundLostAggregatePairs; //!< actual number of lost/found aggregate pairs needed - see PxGpuDynamicsMemoryConfig::foundLostAggregatePairsCapacity.
PxU32 totalAggregatePairs; //!< actual number of aggregate pairs needed - see PxGpuDynamicsMemoryConfig::totalAggregatePairsCapacity.
PxU32 deformableSurfaceContacts; //!< actual number of deformable surface contacts needed - see PxGpuDynamicsMemoryConfig::maxDeformableSurfaceContacts.
PxU32 deformableVolumeContacts; //!< actual number of deformable volume contact needed - see PxGpuDynamicsMemoryConfig::maxDeformableVolumeContacts.
PxU32 softbodyContacts; //!< deprecated, use deformableVolumeContacts.
PxU32 particleContacts; //!< actual number of particle contacts needed - see PxGpuDynamicsMemoryConfig::maxParticleContacts.
PxU32 collisionStackSize; //!< actual size (bytes) needed for the collision stack - see PxGpuDynamicsMemoryConfig::collisionStackSize.
PxGpuDynamicsMemoryConfigStatistics() :
tempBufferCapacity (0),
rigidContactCount (0),
rigidPatchCount (0),
foundLostPairs (0),
foundLostAggregatePairs (0),
totalAggregatePairs (0),
deformableSurfaceContacts (0),
deformableVolumeContacts (0),
softbodyContacts (0), // deprecated
particleContacts (0),
collisionStackSize (0)
{ }
};
/**
\brief Class used to retrieve statistics for a simulation step.
\see PxScene::getSimulationStatistics()
*/
class PxSimulationStatistics
{
public:
/**
\brief Different types of rigid body collision pair statistics.
\see getRbPairStats
*/
enum RbPairStatsType
{
/**
\brief Shape pairs processed as discrete contact pairs for the current simulation step.
*/
eDISCRETE_CONTACT_PAIRS,
/**
\brief Shape pairs processed as swept integration pairs for the current simulation step.
\note Counts the pairs for which special CCD (continuous collision detection) work was actually done and NOT the number of pairs which were configured for CCD.
Furthermore, there can be multiple CCD passes and all processed pairs of all passes are summed up, hence the number can be larger than the amount of pairs which have been configured for CCD.
\see PxPairFlag::eDETECT_CCD_CONTACT,
*/
eCCD_PAIRS,
/**
\brief Shape pairs processed with user contact modification enabled for the current simulation step.
\see PxContactModifyCallback
*/
eMODIFIED_CONTACT_PAIRS,
/**
\brief Trigger shape pairs processed for the current simulation step.
\see PxShapeFlag::eTRIGGER_SHAPE
*/
eTRIGGER_PAIRS
};
//objects:
/**
\brief Number of active PxConstraint objects (joints etc.) for the current simulation step.
*/
PxU32 nbActiveConstraints;
/**
\brief Number of active dynamic bodies for the current simulation step.
\note Does not include active kinematic bodies
*/
PxU32 nbActiveDynamicBodies;
/**
\brief Number of active kinematic bodies for the current simulation step.
\note Kinematic deactivation occurs at the end of the frame after the last call to PxRigidDynamic::setKinematicTarget() was called so kinematics that are
deactivated in a given frame will be included by this counter.
*/
PxU32 nbActiveKinematicBodies;
/**
\brief Number of static bodies for the current simulation step.
*/
PxU32 nbStaticBodies;
/**
\brief Number of dynamic bodies for the current simulation step.
\note Includes inactive bodies and articulation links
\note Does not include kinematic bodies
*/
PxU32 nbDynamicBodies;
/**
\brief Number of kinematic bodies for the current simulation step.
\note Includes inactive bodies
*/
PxU32 nbKinematicBodies;
/**
\brief Number of shapes of each geometry type.
*/
PxU32 nbShapes[PxGeometryType::eGEOMETRY_COUNT];
/**
\brief Number of aggregates in the scene.
*/
PxU32 nbAggregates;
/**
\brief Number of articulations in the scene.
*/
PxU32 nbArticulations;
//solver:
/**
\brief The number of 1D axis constraints(joints+contact) present in the current simulation step.
*/
PxU32 nbAxisSolverConstraints;
/**
\brief The size (in bytes) of the compressed contact stream in the current simulation step
*/
PxU32 compressedContactSize;
/**
\brief The total required size (in bytes) of the contact constraints in the current simulation step
*/
PxU32 requiredContactConstraintMemory;
/**
\brief The peak amount of memory (in bytes) that was allocated for constraints (this includes joints) in the current simulation step
*/
PxU32 peakConstraintMemory;
//broadphase:
/**
\brief Get number of broadphase volumes added for the current simulation step.
\return Number of broadphase volumes added.
*/
PX_FORCE_INLINE PxU32 getNbBroadPhaseAdds() const
{
return nbBroadPhaseAdds;
}
/**
\brief Get number of broadphase volumes removed for the current simulation step.
\return Number of broadphase volumes removed.
*/
PX_FORCE_INLINE PxU32 getNbBroadPhaseRemoves() const
{
return nbBroadPhaseRemoves;
}
//collisions:
/**
\brief Get number of shape collision pairs of a certain type processed for the current simulation step.
There is an entry for each geometry pair type.
\note entry[i][j] = entry[j][i], hence, if you want the sum of all pair
types, you need to discard the symmetric entries
\param[in] pairType The type of pair for which to get information
\param[in] g0 The geometry type of one pair object
\param[in] g1 The geometry type of the other pair object
\return Number of processed pairs of the specified geometry types.
*/
PxU32 getRbPairStats(RbPairStatsType pairType, PxGeometryType::Enum g0, PxGeometryType::Enum g1) const
{
PX_ASSERT_WITH_MESSAGE( (pairType >= eDISCRETE_CONTACT_PAIRS) &&
(pairType <= eTRIGGER_PAIRS),
"Invalid pairType in PxSimulationStatistics::getRbPairStats");
if (g0 >= PxGeometryType::eGEOMETRY_COUNT || g1 >= PxGeometryType::eGEOMETRY_COUNT)
{
PX_ASSERT(false);
return 0;
}
PxU32 nbPairs = 0;
switch(pairType)
{
case eDISCRETE_CONTACT_PAIRS:
nbPairs = nbDiscreteContactPairs[g0][g1];
break;
case eCCD_PAIRS:
nbPairs = nbCCDPairs[g0][g1];
break;
case eMODIFIED_CONTACT_PAIRS:
nbPairs = nbModifiedContactPairs[g0][g1];
break;
case eTRIGGER_PAIRS:
nbPairs = nbTriggerPairs[g0][g1];
break;
}
return nbPairs;
}
/**
\brief Total number of (non CCD) pairs reaching narrow phase
*/
PxU32 nbDiscreteContactPairsTotal;
/**
\brief Total number of (non CCD) pairs for which contacts are successfully cached (<=nbDiscreteContactPairsTotal)
\note This includes pairs for which no contacts are generated, it still counts as a cache hit.
*/
PxU32 nbDiscreteContactPairsWithCacheHits;
/**
\brief Total number of (non CCD) pairs for which at least 1 contact was generated (<=nbDiscreteContactPairsTotal)
*/
PxU32 nbDiscreteContactPairsWithContacts;
/**
\brief Number of new pairs found by BP this frame
*/
PxU32 nbNewPairs;
/**
\brief Number of lost pairs from BP this frame
*/
PxU32 nbLostPairs;
/**
\brief Number of new touches found by NP this frame
*/
PxU32 nbNewTouches;
/**
\brief Number of lost touches from NP this frame
*/
PxU32 nbLostTouches;
/**
\brief Number of partitions used by the solver this frame
*/
PxU32 nbPartitions;
/**
\brief GPU device memory in bytes allocated for particle state accessible through API
*/
PxU64 gpuMemParticles;
/**
\brief GPU device memory in bytes allocated for deformable surface state accessible through API
*/
PxU64 gpuMemDeformableSurfaces;
/**
\brief GPU device memory in bytes allocated for deformable volume state accessible through API
*/
PxU64 gpuMemDeformableVolumes;
/**
\brief Deprecated
\see gpuMemDeformableVolumes
*/
PX_DEPRECATED PxU64 gpuMemSoftBodies;
/**
\brief GPU device memory in bytes allocated for internal heap allocation
*/
PxU64 gpuMemHeap;
/**
\brief GPU device heap memory used for broad phase in bytes
*/
PxU64 gpuMemHeapBroadPhase;
/**
\brief GPU device heap memory used for narrow phase in bytes
*/
PxU64 gpuMemHeapNarrowPhase;
/**
\brief GPU device heap memory used for solver in bytes
*/
PxU64 gpuMemHeapSolver;
/**
\brief GPU device heap memory used for articulations in bytes
*/
PxU64 gpuMemHeapArticulation;
/**
\brief GPU device heap memory used for simulation pipeline in bytes
*/
PxU64 gpuMemHeapSimulation;
/**
\brief GPU device heap memory used for articulations in the simulation pipeline in bytes
*/
PxU64 gpuMemHeapSimulationArticulation;
/**
\brief GPU device heap memory used for particles in the simulation pipeline in bytes
*/
PxU64 gpuMemHeapSimulationParticles;
/**
\brief GPU device heap memory used for deformable surfaces in the simulation pipeline in bytes
*/
PxU64 gpuMemHeapSimulationDeformableSurface;
/**
\brief GPU device heap memory used for deformable volumes in the simulation pipeline in bytes
*/
PxU64 gpuMemHeapSimulationDeformableVolume;
/**
\brief Deprecated
\see gpuMemHeapSimulationDeformableVolume
*/
PX_DEPRECATED PxU64 gpuMemHeapSimulationSoftBody;
/**
\brief GPU device heap memory used for shared buffers in the particles pipeline in bytes
*/
PxU64 gpuMemHeapParticles;
/**
\brief GPU device heap memory used for shared buffers in the deformable surface pipeline in bytes
*/
PxU64 gpuMemHeapDeformableSurfaces;
/**
\brief GPU device heap memory used for shared buffers in the deformable volume pipeline in bytes
*/
PxU64 gpuMemHeapDeformableVolumes;
/**
\brief Deprecated
\see gpuMemHeapDeformableVolumes
*/
PX_DEPRECATED PxU64 gpuMemHeapSoftBodies;
/**
\brief GPU device heap memory not covered by other stats in bytes
*/
PxU64 gpuMemHeapOther;
/**
\brief Structure containing statistics about actual count/sizes used for the configuration parameters in PxGpuDynamicsMemoryConfig
*/
PxGpuDynamicsMemoryConfigStatistics gpuDynamicsMemoryConfigStatistics;
PxSimulationStatistics() :
nbActiveConstraints (0),
nbActiveDynamicBodies (0),
nbActiveKinematicBodies (0),
nbStaticBodies (0),
nbDynamicBodies (0),
nbKinematicBodies (0),
nbAggregates (0),
nbArticulations (0),
nbAxisSolverConstraints (0),
compressedContactSize (0),
requiredContactConstraintMemory (0),
peakConstraintMemory (0),
nbDiscreteContactPairsTotal (0),
nbDiscreteContactPairsWithCacheHits (0),
nbDiscreteContactPairsWithContacts (0),
nbNewPairs (0),
nbLostPairs (0),
nbNewTouches (0),
nbLostTouches (0),
nbPartitions (0),
gpuMemParticles (0),
gpuMemDeformableSurfaces (0),
gpuMemDeformableVolumes (0),
gpuMemSoftBodies (0), // deprecated
gpuMemHeap (0),
gpuMemHeapBroadPhase (0),
gpuMemHeapNarrowPhase (0),
gpuMemHeapSolver (0),
gpuMemHeapArticulation (0),
gpuMemHeapSimulation (0),
gpuMemHeapSimulationArticulation (0),
gpuMemHeapSimulationParticles (0),
gpuMemHeapSimulationDeformableSurface (0),
gpuMemHeapSimulationDeformableVolume (0),
gpuMemHeapSimulationSoftBody (0), // deprecated
gpuMemHeapParticles (0),
gpuMemHeapDeformableSurfaces (0),
gpuMemHeapDeformableVolumes (0),
gpuMemHeapSoftBodies (0), // deprecated
gpuMemHeapOther (0)
{
nbBroadPhaseAdds = 0;
nbBroadPhaseRemoves = 0;
for(PxU32 i=0; i < PxGeometryType::eGEOMETRY_COUNT; i++)
{
for(PxU32 j=0; j < PxGeometryType::eGEOMETRY_COUNT; j++)
{
nbDiscreteContactPairs[i][j] = 0;
nbModifiedContactPairs[i][j] = 0;
nbCCDPairs[i][j] = 0;
nbTriggerPairs[i][j] = 0;
}
}
for(PxU32 i=0; i < PxGeometryType::eGEOMETRY_COUNT; i++)
{
nbShapes[i] = 0;
}
}
//
// We advise to not access these members directly. Use the provided accessor methods instead.
//
//broadphase:
PxU32 nbBroadPhaseAdds;
PxU32 nbBroadPhaseRemoves;
//collisions:
PxU32 nbDiscreteContactPairs[PxGeometryType::eGEOMETRY_COUNT][PxGeometryType::eGEOMETRY_COUNT];
PxU32 nbCCDPairs[PxGeometryType::eGEOMETRY_COUNT][PxGeometryType::eGEOMETRY_COUNT];
PxU32 nbModifiedContactPairs[PxGeometryType::eGEOMETRY_COUNT][PxGeometryType::eGEOMETRY_COUNT];
PxU32 nbTriggerPairs[PxGeometryType::eGEOMETRY_COUNT][PxGeometryType::eGEOMETRY_COUNT];
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,186 @@
// 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 PX_SMOOTHING_H
#define PX_SMOOTHING_H
#include "cudamanager/PxCudaContext.h"
#include "cudamanager/PxCudaContextManager.h"
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxVec4.h"
#include "PxParticleSystem.h"
#include "foundation/PxArray.h"
#include "PxParticleGpu.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_SUPPORT_GPU_PHYSX
class PxgKernelLauncher;
class PxParticleNeighborhoodProvider;
/**
\brief Ccomputes smoothed positions for a particle system to improve rendering quality
*/
class PxSmoothedPositionGenerator
{
public:
/**
\brief Schedules the compuation of smoothed positions on the specified cuda stream
\param[in] gpuParticleSystem A gpu pointer to access particle system data
\param[in] numParticles The number of particles
\param[in] stream The stream on which the cuda call gets scheduled
*/
virtual void generateSmoothedPositions(PxGpuParticleSystem* gpuParticleSystem, PxU32 numParticles, CUstream stream) = 0;
/**
\brief Schedules the compuation of smoothed positions on the specified cuda stream
\param[in] particlePositionsGpu A gpu pointer containing the particle positions
\param[in] neighborhoodProvider A neighborhood provider object that supports fast neighborhood queries
\param[in] numParticles The number of particles
\param[in] particleContactOffset The particle contact offset
\param[in] stream The stream on which the cuda call gets scheduled
*/
virtual void generateSmoothedPositions(PxVec4* particlePositionsGpu, PxParticleNeighborhoodProvider& neighborhoodProvider, PxU32 numParticles, PxReal particleContactOffset, CUstream stream) = 0;
/**
\brief Set a host buffer that holds the smoothed position data after the timestep completed
\param[in] smoothedPositions A host buffer with memory for all particles already allocated
*/
virtual void setResultBufferHost(PxVec4* smoothedPositions) = 0;
/**
\brief Set a device buffer that holds the smoothed position data after the timestep completed
\param[in] smoothedPositions A device buffer with memory for all particles already allocated
*/
virtual void setResultBufferDevice(PxVec4* smoothedPositions) = 0;
/**
\brief Sets the intensity of the position smoothing effect
\param[in] smoothingStrenght The strength of the smoothing effect
*/
virtual void setSmoothing(float smoothingStrenght) = 0;
/**
\brief Gets the maximal number of particles
\return The maximal number of particles
*/
virtual PxU32 getMaxParticles() const = 0;
/**
\brief Sets the maximal number of particles
\param[in] maxParticles The maximal number of particles
*/
virtual void setMaxParticles(PxU32 maxParticles) = 0;
/**
\brief Gets the device pointer for the smoothed positions. Only available after calling setResultBufferHost or setResultBufferDevice
\return The device pointer for the smoothed positions
*/
virtual PxVec4* getSmoothedPositionsDevicePointer() const = 0;
/**
\brief Enables or disables the smoothed position generator
\param[in] enabled The boolean to set the generator to enabled or disabled
*/
virtual void setEnabled(bool enabled) = 0;
/**
\brief Allows to query if the smoothed position generator is enabled
\return True if enabled, false otherwise
*/
virtual bool isEnabled() const = 0;
/**
\brief Releases the instance and its data
*/
virtual void release() = 0;
/**
\brief Destructor
*/
virtual ~PxSmoothedPositionGenerator() {}
};
/**
\brief Default implementation of a particle system callback to trigger smoothed position calculations. A call to fetchResultsParticleSystem() on the
PxScene will synchronize the work such that the caller knows that the post solve task completed.
*/
class PxSmoothedPositionCallback : public PxParticleSystemCallback
{
public:
/**
\brief Initializes the smoothing callback
\param[in] smoothedPositionGenerator The smoothed position generator
*/
void initialize(PxSmoothedPositionGenerator* smoothedPositionGenerator)
{
mSmoothedPositionGenerator = smoothedPositionGenerator;
}
virtual void onPostSolve(const PxGpuMirroredPointer<PxGpuParticleSystem>& gpuParticleSystem, CUstream stream)
{
if (mSmoothedPositionGenerator)
{
mSmoothedPositionGenerator->generateSmoothedPositions(gpuParticleSystem.mDevicePtr, gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream);
}
}
virtual void onBegin(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
virtual void onAdvance(const PxGpuMirroredPointer<PxGpuParticleSystem>& /*gpuParticleSystem*/, CUstream /*stream*/) { }
private:
PxSmoothedPositionGenerator* mSmoothedPositionGenerator;
};
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,105 @@
// 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 PX_SOFT_BODY_H
#define PX_SOFT_BODY_H
#include "PxDeformableVolume.h"
#include "PxDeformableVolumeFlag.h"
#include "PxFEMParameter.h"
#include "PxSoftBodyFlag.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning(disable : 4435)
#endif
/**
\brief Deprecated
\see PX_MAX_NB_DEFORMABLE_VOLUME_TET
*/
#define PX_MAX_NB_SOFTBODY_TET PX_MAX_NB_DEFORMABLE_VOLUME_TET
/**
\brief Deprecated
\see PX_MAX_NB_DEFORMABLE_VOLUME
*/
#define PX_MAX_NB_SOFTBODY PX_MAX_NB_DEFORMABLE_VOLUME
/**
\brief Deprecated
\see PxDeformableVolumeFlag
*/
typedef PX_DEPRECATED PxDeformableVolumeFlag PxSoftBodyFlag;
/**
\brief Deprecated
\see PxDeformableVolumeFlags
*/
typedef PX_DEPRECATED PxDeformableVolumeFlags PxSoftBodyFlags;
/**
\brief Deprecated
\see PxDeformableVolume
*/
typedef PX_DEPRECATED PxDeformableVolume PxSoftBody;
/**
\brief Deprecated
\see PxConfigureDeformableVolumeKinematicTarget
*/
PX_DEPRECATED PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4 PxConfigureSoftBodyKinematicTarget(const PxVec4& target, bool isActive)
{
return PxConfigureDeformableVolumeKinematicTarget(target, isActive);
}
/**
\brief Deprecated
\see PxConfigureDeformableVolumeKinematicTarget
*/
PX_DEPRECATED PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4 PxConfigureSoftBodyKinematicTarget(const PxVec3& target, bool isActive)
{
return PxConfigureDeformableVolumeKinematicTarget(PxVec4(target, 0.0f), isActive);
}
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,80 @@
// 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 PX_SOFT_BODY_FLAG_H
#define PX_SOFT_BODY_FLAG_H
#include "PxDeformableVolumeFlag.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Deprecated
\see PxDeformableVolumeDataFlag
*/
typedef PX_DEPRECATED PxDeformableVolumeDataFlag PxSoftBodyDataFlag;
/**
\brief Deprecated
\see PxDeformableVolumeDataFlags
*/
typedef PX_DEPRECATED PxDeformableVolumeDataFlags PxSoftBodyDataFlags;
/**
\brief These flags determine what data is read or written when using PxScene::copySoftBodyData()
or PxScene::applySoftBodyData.
\see PxScene::copySoftBodyData, PxScene::applySoftBodyData
\deprecated There is no direct replacement. The data is exposed in the PxSoftBody interface, accessible directly from GPU.
There is no replacement for eTET_REST_POSES, as the data is constant and can be derived from the input collision mesh.
*/
PX_DEPRECATED class PxSoftBodyGpuDataFlag
{
public:
enum Enum
{
eTET_INDICES = 0, //!< The collision mesh tetrahedron indices (quadruples of int32)
eTET_REST_POSES = 1, //!< The collision mesh tetrahedron rest poses (float 3x3 matrices)
eTET_ROTATIONS = 2, //!< The collision mesh tetrahedron orientations (quaternions, quadruples of float)
eTET_POSITION_INV_MASS = 3, //!< The collision mesh vertex positions and their inverted mass in the 4th component (quadruples of float)
eSIM_TET_INDICES = 4, //!< The simulation mesh tetrahedron indices (quadruples of int32)
eSIM_TET_ROTATIONS = 5, //!< The simulation mesh tetrahedron orientations (quaternions, quadruples of float)
eSIM_VELOCITY_INV_MASS = 6, //!< The simulation mesh vertex velocities and their inverted mass in the 4th component (quadruples of float)
eSIM_POSITION_INV_MASS = 7 //!< The simulation mesh vertex positions and their inverted mass in the 4th component (quadruples of float)
};
};
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,116 @@
// 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 PX_SPARSE_GRID_PARAMS_H
#define PX_SPARSE_GRID_PARAMS_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxMath.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Parameters to define the sparse grid settings like grid spacing, maximal number of subgrids etc.
*/
struct PxSparseGridParams
{
/**
\brief Default constructor.
*/
PX_INLINE PxSparseGridParams()
{
maxNumSubgrids = 512;
subgridSizeX = 32;
subgridSizeY = 32;
subgridSizeZ = 32;
gridSpacing = 0.2f;
haloSize = 1;
}
/**
\brief Copy constructor.
*/
PX_CUDA_CALLABLE PX_INLINE PxSparseGridParams(const PxSparseGridParams& params)
{
maxNumSubgrids = params.maxNumSubgrids;
subgridSizeX = params.subgridSizeX;
subgridSizeY = params.subgridSizeY;
subgridSizeZ = params.subgridSizeZ;
gridSpacing = params.gridSpacing;
haloSize = params.haloSize;
}
PX_CUDA_CALLABLE PX_INLINE PxU32 getNumCellsPerSubgrid() const
{
return subgridSizeX * subgridSizeY * subgridSizeZ;
}
PX_CUDA_CALLABLE PX_INLINE PxReal getSqrt3dx() const
{
return PxSqrt(3.0f) * gridSpacing;
}
/**
\brief (re)sets the structure to the default.
*/
PX_INLINE void setToDefault()
{
*this = PxSparseGridParams();
}
/**
\brief Assignment operator
*/
PX_INLINE void operator = (const PxSparseGridParams& params)
{
maxNumSubgrids = params.maxNumSubgrids;
subgridSizeX = params.subgridSizeX;
subgridSizeY = params.subgridSizeY;
subgridSizeZ = params.subgridSizeZ;
gridSpacing = params.gridSpacing;
haloSize = params.haloSize;
}
PxU32 maxNumSubgrids; //!< Maximum number of subgrids
PxReal gridSpacing; //!< Grid spacing for the grid
PxU16 subgridSizeX; //!< Subgrid resolution in x dimension (must be an even number)
PxU16 subgridSizeY; //!< Subgrid resolution in y dimension (must be an even number)
PxU16 subgridSizeZ; //!< Subgrid resolution in z dimension (must be an even number)
PxU16 haloSize; //!< Number of halo cell layers around every subgrid cell. Only 0 and 1 are valid values
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,271 @@
// 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 PX_VISUALIZATION_PARAMETER_H
#define PX_VISUALIZATION_PARAMETER_H
#include "foundation/PxPreprocessor.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/*
NOTE: Parameters should NOT be conditionally compiled out. Even if a particular feature is not available.
Otherwise the parameter values get shifted about and the numeric values change per platform. This causes problems
when trying to serialize parameters.
New parameters should also be added to the end of the list for this reason. Also make sure to update
eNUM_VALUES, which should be one higher than the maximum value in the enum.
*/
/**
\brief Debug visualization parameters.
#PxVisualizationParameter::eSCALE is the master switch for enabling visualization, please read the corresponding documentation
for further details.
\see PxScene.setVisualizationParameter() PxScene.getVisualizationParameter() PxScene.getRenderBuffer()
*/
struct PxVisualizationParameter
{
enum Enum
{
/* RigidBody-related parameters */
/**
\brief This overall visualization scale gets multiplied with the individual scales. Setting to zero ignores all visualizations. Default is 0.
The below settings permit the debug visualization of various simulation properties.
The setting is either zero, in which case the property is not drawn. Otherwise it is a scaling factor
that determines the size of the visualization widgets.
Only objects for which visualization is turned on using setFlag(eVISUALIZATION) are visualized (see #PxActorFlag::eVISUALIZATION, #PxShapeFlag::eVISUALIZATION, ...).
Default is 0.
Notes:
- to see any visualization, you have to set PxVisualizationParameter::eSCALE to nonzero first.
- the scale factor has been introduced because it's difficult (if not impossible) to come up with a
good scale for 3D vectors. Normals are normalized and their length is always 1. But it doesn't mean
we should render a line of length 1. Depending on your objects/scene, this might be completely invisible
or extremely huge. That's why the scale factor is here, to let you tune the length until it's ok in
your scene.
- however, things like collision shapes aren't ambiguous. They are clearly defined for example by the
triangles & polygons themselves, and there's no point in scaling that. So the visualization widgets
are only scaled when it makes sense.
<b>Range:</b> [0, PX_MAX_F32)<br>
<b>Default:</b> 0
*/
eSCALE,
/**
\brief Visualize the world axes.
*/
eWORLD_AXES,
/* Body visualizations */
/**
\brief Visualize a bodies axes.
\see PxActor.globalPose PxActor
*/
eBODY_AXES,
/**
\brief Visualize a body's mass axes.
This visualization is also useful for visualizing the sleep state of bodies. Sleeping bodies are drawn in
black, while awake bodies are drawn in white. If the body is sleeping and part of a sleeping group, it is
drawn in red.
\see PxBodyDesc.massLocalPose PxActor
*/
eBODY_MASS_AXES,
/**
\brief Visualize the bodies linear velocity.
\see PxBodyDesc.linearVelocity PxActor
*/
eBODY_LIN_VELOCITY,
/**
\brief Visualize the bodies angular velocity.
\see PxBodyDesc.angularVelocity PxActor
*/
eBODY_ANG_VELOCITY,
/* Contact visualisations */
/**
\brief Visualize contact points. Will enable contact information.
*/
eCONTACT_POINT,
/**
\brief Visualize contact normals. Will enable contact information.
*/
eCONTACT_NORMAL,
/**
\brief Visualize contact errors. Will enable contact information.
*/
eCONTACT_ERROR,
/**
\brief Visualize Contact impulses. Will enable contact information.
*/
eCONTACT_IMPULSE,
/**
\brief Visualize Contact forces. Will enable contact information.
\deprecated Use eCONTACT_IMPULSE instead.
*/
eCONTACT_FORCE PX_DEPRECATED = eCONTACT_IMPULSE,
/**
\brief Visualize friction points. Will enable contact information.
*/
eFRICTION_POINT,
/**
\brief Visualize friction normals. Will enable contact information.
*/
eFRICTION_NORMAL,
/**
\brief Visualize friction impulses. Will enable contact information.
*/
eFRICTION_IMPULSE,
/**
\brief Visualize actor axes.
\see PxRigidStatic PxRigidDynamic PxArticulationLink
*/
eACTOR_AXES,
/**
\brief Visualize bounds (AABBs in world space)
*/
eCOLLISION_AABBS,
/**
\brief Shape visualization
\see PxShape
*/
eCOLLISION_SHAPES,
/**
\brief Shape axis visualization
\see PxShape
*/
eCOLLISION_AXES,
/**
\brief Compound visualization (compound AABBs in world space)
*/
eCOLLISION_COMPOUNDS,
/**
\brief Mesh & convex face normals
\see PxTriangleMesh PxConvexMesh
*/
eCOLLISION_FNORMALS,
/**
\brief Active edges for meshes
\see PxTriangleMesh
*/
eCOLLISION_EDGES,
/**
\brief Static pruning structures
*/
eCOLLISION_STATIC,
/**
\brief Dynamic pruning structures
*/
eCOLLISION_DYNAMIC,
/**
\brief Joint local axes
*/
eJOINT_LOCAL_FRAMES,
/**
\brief Joint limits
*/
eJOINT_LIMITS,
/**
\brief Visualize culling box
*/
eCULL_BOX,
/**
\brief MBP regions
*/
eMBP_REGIONS,
/**
\brief Renders the simulation mesh instead of the collision mesh (only available for tetmeshes)
Deformable visualization is currently not supported.
*/
eSIMULATION_MESH,
/**
\brief Renders the SDF of a mesh instead of the collision mesh (only available for triangle meshes with SDFs)
*/
eSDF,
/**
\brief This is not a parameter, it just records the current number of parameters (as maximum(PxVisualizationParameter)+1) for use in loops.
*/
eNUM_VALUES,
eFORCE_DWORD = 0x7fffffff
};
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,223 @@
// 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 PX_BOX_CONTROLLER_H
#define PX_BOX_CONTROLLER_H
#include "characterkinematic/PxController.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Descriptor for a box character controller.
\see PxBoxController PxControllerDesc
*/
class PxBoxControllerDesc : public PxControllerDesc
{
public:
/**
\brief constructor sets to default.
*/
PX_INLINE PxBoxControllerDesc();
PX_INLINE virtual ~PxBoxControllerDesc() {}
/**
\brief copy constructor.
*/
PX_INLINE PxBoxControllerDesc(const PxBoxControllerDesc&);
/**
\brief assignment operator.
*/
PX_INLINE PxBoxControllerDesc& operator=(const PxBoxControllerDesc&);
/**
\brief (re)sets the structure to the default.
*/
PX_INLINE virtual void setToDefault();
/**
\brief returns true if the current settings are valid
\return True if the descriptor is valid.
*/
PX_INLINE virtual bool isValid() const;
/**
\brief Half height
<b>Default:</b> 1.0
*/
PxF32 halfHeight; // Half-height in the "up" direction
/**
\brief Half side extent
<b>Default:</b> 0.5
*/
PxF32 halfSideExtent; // Half-extent in the "side" direction
/**
\brief Half forward extent
<b>Default:</b> 0.5
*/
PxF32 halfForwardExtent; // Half-extent in the "forward" direction
protected:
PX_INLINE void copy(const PxBoxControllerDesc&);
};
PX_INLINE PxBoxControllerDesc::PxBoxControllerDesc() :
PxControllerDesc (PxControllerShapeType::eBOX),
halfHeight (1.0f),
halfSideExtent (0.5f),
halfForwardExtent (0.5f)
{
}
PX_INLINE PxBoxControllerDesc::PxBoxControllerDesc(const PxBoxControllerDesc& other) : PxControllerDesc(other)
{
copy(other);
}
PX_INLINE PxBoxControllerDesc& PxBoxControllerDesc::operator=(const PxBoxControllerDesc& other)
{
PxControllerDesc::operator=(other);
copy(other);
return *this;
}
PX_INLINE void PxBoxControllerDesc::copy(const PxBoxControllerDesc& other)
{
halfHeight = other.halfHeight;
halfSideExtent = other.halfSideExtent;
halfForwardExtent = other.halfForwardExtent;
}
PX_INLINE void PxBoxControllerDesc::setToDefault()
{
*this = PxBoxControllerDesc();
}
PX_INLINE bool PxBoxControllerDesc::isValid() const
{
if(!PxControllerDesc::isValid()) return false;
if(halfHeight<=0.0f) return false;
if(halfSideExtent<=0.0f) return false;
if(halfForwardExtent<=0.0f) return false;
if(stepOffset>2.0f*halfHeight) return false; // Prevents obvious mistakes
return true;
}
/**
\brief Box character controller.
\see PxBoxControllerDesc PxController
*/
class PxBoxController : public PxController
{
public:
/**
\brief Gets controller's half height.
\return The half height of the controller.
\see PxBoxControllerDesc.halfHeight setHalfHeight()
*/
virtual PxF32 getHalfHeight() const = 0;
/**
\brief Gets controller's half side extent.
\return The half side extent of the controller.
\see PxBoxControllerDesc.halfSideExtent setHalfSideExtent()
*/
virtual PxF32 getHalfSideExtent() const = 0;
/**
\brief Gets controller's half forward extent.
\return The half forward extent of the controller.
\see PxBoxControllerDesc.halfForwardExtent setHalfForwardExtent()
*/
virtual PxF32 getHalfForwardExtent() const = 0;
/**
\brief Sets controller's half height.
\warning this doesn't check for collisions.
\param[in] halfHeight The new half height for the controller.
\return Currently always true.
\see PxBoxControllerDesc.halfHeight getHalfHeight()
*/
virtual bool setHalfHeight(PxF32 halfHeight) = 0;
/**
\brief Sets controller's half side extent.
\warning this doesn't check for collisions.
\param[in] halfSideExtent The new half side extent for the controller.
\return Currently always true.
\see PxBoxControllerDesc.halfSideExtent getHalfSideExtent()
*/
virtual bool setHalfSideExtent(PxF32 halfSideExtent) = 0;
/**
\brief Sets controller's half forward extent.
\warning this doesn't check for collisions.
\param[in] halfForwardExtent The new half forward extent for the controller.
\return Currently always true.
\see PxBoxControllerDesc.halfForwardExtent getHalfForwardExtent()
*/
virtual bool setHalfForwardExtent(PxF32 halfForwardExtent) = 0;
protected:
PX_INLINE PxBoxController() {}
virtual ~PxBoxController() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,244 @@
// 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 PX_CAPSULE_CONTROLLER_H
#define PX_CAPSULE_CONTROLLER_H
#include "characterkinematic/PxController.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
struct PxCapsuleClimbingMode
{
enum Enum
{
eEASY, //!< Standard mode, let the capsule climb over surfaces according to impact normal
eCONSTRAINED, //!< Constrained mode, try to limit climbing according to the step offset
eLAST
};
};
/**
\brief A descriptor for a capsule character controller.
\see PxCapsuleController PxControllerDesc
*/
class PxCapsuleControllerDesc : public PxControllerDesc
{
public:
/**
\brief constructor sets to default.
*/
PX_INLINE PxCapsuleControllerDesc ();
PX_INLINE virtual ~PxCapsuleControllerDesc () {}
/**
\brief copy constructor.
*/
PX_INLINE PxCapsuleControllerDesc(const PxCapsuleControllerDesc&);
/**
\brief assignment operator.
*/
PX_INLINE PxCapsuleControllerDesc& operator=(const PxCapsuleControllerDesc&);
/**
\brief (re)sets the structure to the default.
*/
PX_INLINE virtual void setToDefault();
/**
\brief returns true if the current settings are valid
\return True if the descriptor is valid.
*/
PX_INLINE virtual bool isValid() const;
/**
\brief The radius of the capsule
<b>Default:</b> 0.0
\see PxCapsuleController
*/
PxF32 radius;
/**
\brief The height of the controller
<b>Default:</b> 0.0
\see PxCapsuleController
*/
PxF32 height;
/**
\brief The climbing mode
<b>Default:</b> PxCapsuleClimbingMode::eEASY
\see PxCapsuleController
*/
PxCapsuleClimbingMode::Enum climbingMode;
protected:
PX_INLINE void copy(const PxCapsuleControllerDesc&);
};
PX_INLINE PxCapsuleControllerDesc::PxCapsuleControllerDesc () : PxControllerDesc(PxControllerShapeType::eCAPSULE)
{
radius = height = 0.0f;
climbingMode = PxCapsuleClimbingMode::eEASY;
}
PX_INLINE PxCapsuleControllerDesc::PxCapsuleControllerDesc(const PxCapsuleControllerDesc& other) : PxControllerDesc(other)
{
copy(other);
}
PX_INLINE PxCapsuleControllerDesc& PxCapsuleControllerDesc::operator=(const PxCapsuleControllerDesc& other)
{
PxControllerDesc::operator=(other);
copy(other);
return *this;
}
PX_INLINE void PxCapsuleControllerDesc::copy(const PxCapsuleControllerDesc& other)
{
radius = other.radius;
height = other.height;
climbingMode = other.climbingMode;
}
PX_INLINE void PxCapsuleControllerDesc::setToDefault()
{
*this = PxCapsuleControllerDesc();
}
PX_INLINE bool PxCapsuleControllerDesc::isValid() const
{
if(!PxControllerDesc::isValid()) return false;
if(radius<=0.0f) return false;
if(height<=0.0f) return false;
if(stepOffset>height+radius*2.0f) return false; // Prevents obvious mistakes
return true;
}
/**
\brief A capsule character controller.
The capsule is defined as a position, a vertical height, and a radius.
The height is the distance between the two sphere centers at the end of the capsule.
In other words:
p = pos (returned by controller)<br>
h = height<br>
r = radius<br>
p = center of capsule<br>
top sphere center = p.y + h*0.5<br>
bottom sphere center = p.y - h*0.5<br>
top capsule point = p.y + h*0.5 + r<br>
bottom capsule point = p.y - h*0.5 - r<br>
*/
class PxCapsuleController : public PxController
{
public:
/**
\brief Gets controller's radius.
\return The radius of the controller.
\see PxCapsuleControllerDesc.radius setRadius()
*/
virtual PxF32 getRadius() const = 0;
/**
\brief Sets controller's radius.
\warning this doesn't check for collisions.
\param[in] radius The new radius for the controller.
\return Currently always true.
\see PxCapsuleControllerDesc.radius getRadius()
*/
virtual bool setRadius(PxF32 radius) = 0;
/**
\brief Gets controller's height.
\return The height of the capsule controller.
\see PxCapsuleControllerDesc.height setHeight()
*/
virtual PxF32 getHeight() const = 0;
/**
\brief Resets controller's height.
\warning this doesn't check for collisions.
\param[in] height The new height for the controller.
\return Currently always true.
\see PxCapsuleControllerDesc.height getHeight()
*/
virtual bool setHeight(PxF32 height) = 0;
/**
\brief Gets controller's climbing mode.
\return The capsule controller's climbing mode.
\see PxCapsuleControllerDesc.climbingMode setClimbingMode()
*/
virtual PxCapsuleClimbingMode::Enum getClimbingMode() const = 0;
/**
\brief Sets controller's climbing mode.
\param[in] mode The capsule controller's climbing mode.
\see PxCapsuleControllerDesc.climbingMode getClimbingMode()
*/
virtual bool setClimbingMode(PxCapsuleClimbingMode::Enum mode) = 0;
protected:
PX_INLINE PxCapsuleController() {}
virtual ~PxCapsuleController() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,926 @@
// 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 PX_CONTROLLER_H
#define PX_CONTROLLER_H
#include "characterkinematic/PxExtended.h"
#include "characterkinematic/PxControllerObstacles.h"
#include "PxQueryFiltering.h"
#include "foundation/PxErrorCallback.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief The type of controller, eg box, sphere or capsule.
*/
struct PxControllerShapeType
{
enum Enum
{
/**
\brief A box controller.
\see PxBoxController PxBoxControllerDesc
*/
eBOX,
/**
\brief A capsule controller
\see PxCapsuleController PxCapsuleControllerDesc
*/
eCAPSULE,
eFORCE_DWORD = 0x7fffffff
};
};
class PxShape;
class PxScene;
class PxController;
class PxRigidDynamic;
class PxMaterial;
struct PxFilterData;
class PxQueryFilterCallback;
class PxControllerBehaviorCallback;
class PxObstacleContext;
class PxObstacle;
/**
\brief specifies how a CCT interacts with non-walkable parts.
This is only used when slopeLimit is non zero. It is currently enabled for static actors only, and not supported for spheres or capsules.
*/
struct PxControllerNonWalkableMode
{
enum Enum
{
ePREVENT_CLIMBING, //!< Stops character from climbing up non-walkable slopes, but doesn't move it otherwise
ePREVENT_CLIMBING_AND_FORCE_SLIDING //!< Stops character from climbing up non-walkable slopes, and forces it to slide down those slopes
};
};
/**
\brief specifies which sides a character is colliding with.
*/
struct PxControllerCollisionFlag
{
enum Enum
{
eCOLLISION_SIDES = (1<<0), //!< Character is colliding to the sides.
eCOLLISION_UP = (1<<1), //!< Character has collision above.
eCOLLISION_DOWN = (1<<2) //!< Character has collision below.
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxControllerCollisionFlag.
\see PxControllerCollisionFlag
*/
typedef PxFlags<PxControllerCollisionFlag::Enum, PxU8> PxControllerCollisionFlags;
PX_FLAGS_OPERATORS(PxControllerCollisionFlag::Enum, PxU8)
/**
\brief Describes a controller's internal state.
*/
struct PxControllerState
{
PxVec3 deltaXP; //!< delta position vector for the object the CCT is standing/riding on. Not always match the CCT delta when variable timesteps are used.
PxShape* touchedShape; //!< Shape on which the CCT is standing
PxRigidActor* touchedActor; //!< Actor owning 'touchedShape'
PxObstacleHandle touchedObstacleHandle; // Obstacle on which the CCT is standing
PxU32 collisionFlags; //!< Last known collision flags (PxControllerCollisionFlag)
bool standOnAnotherCCT; //!< Are we standing on another CCT?
bool standOnObstacle; //!< Are we standing on a user-defined obstacle?
bool isMovingUp; //!< is CCT moving up or not? (i.e. explicit jumping)
};
/**
\brief Describes a controller's internal statistics.
*/
struct PxControllerStats
{
PxU16 nbIterations;
PxU16 nbFullUpdates;
PxU16 nbPartialUpdates;
PxU16 nbTessellation;
};
/**
\brief Describes a generic CCT hit.
*/
struct PxControllerHit
{
PxController* controller; //!< Current controller
PxExtendedVec3 worldPos; //!< Contact position in world space
PxVec3 worldNormal; //!< Contact normal in world space
PxVec3 dir; //!< Motion direction
PxF32 length; //!< Motion length
};
/**
\brief Describes a hit between a CCT and a shape. Passed to onShapeHit()
\see PxUserControllerHitReport.onShapeHit()
*/
struct PxControllerShapeHit : public PxControllerHit
{
PxShape* shape; //!< Touched shape
PxRigidActor* actor; //!< Touched actor
PxU32 triangleIndex; //!< touched triangle index (only for meshes/heightfields)
};
/**
\brief Describes a hit between a CCT and another CCT. Passed to onControllerHit().
\see PxUserControllerHitReport.onControllerHit()
*/
struct PxControllersHit : public PxControllerHit
{
PxController* other; //!< Touched controller
};
/**
\brief Describes a hit between a CCT and a user-defined obstacle. Passed to onObstacleHit().
\see PxUserControllerHitReport.onObstacleHit() PxObstacleContext
*/
struct PxControllerObstacleHit : public PxControllerHit
{
const void* userData;
};
/**
\brief User callback class for character controller events.
\note Character controller hit reports are only generated when move is called.
\see PxControllerDesc.callback
*/
class PxUserControllerHitReport
{
public:
/**
\brief Called when current controller hits a shape.
This is called when the CCT moves and hits a shape. This will not be called when a moving shape hits a non-moving CCT.
\param[in] hit Provides information about the hit.
\see PxControllerShapeHit
*/
virtual void onShapeHit(const PxControllerShapeHit& hit) = 0;
/**
\brief Called when current controller hits another controller.
\param[in] hit Provides information about the hit.
\see PxControllersHit
*/
virtual void onControllerHit(const PxControllersHit& hit) = 0;
/**
\brief Called when current controller hits a user-defined obstacle.
\param[in] hit Provides information about the hit.
\see PxControllerObstacleHit PxObstacleContext
*/
virtual void onObstacleHit(const PxControllerObstacleHit& hit) = 0;
protected:
virtual ~PxUserControllerHitReport(){}
};
/**
\brief Dedicated filtering callback for CCT vs CCT.
This controls collisions between CCTs (one CCT vs anoter CCT).
To make each CCT collide against all other CCTs, just return true - or simply avoid defining a callback.
To make each CCT freely go through all other CCTs, just return false.
Otherwise create a custom filtering logic in this callback.
\see PxControllerFilters
*/
class PxControllerFilterCallback
{
public:
virtual ~PxControllerFilterCallback(){}
/**
\brief Filtering method for CCT-vs-CCT.
\param[in] a First CCT
\param[in] b Second CCT
\return true to keep the pair, false to filter it out
*/
virtual bool filter(const PxController& a, const PxController& b) = 0;
};
/**
\brief Filtering data for "move" call.
This class contains all filtering-related parameters for the PxController::move() call.
Collisions between a CCT and the world are filtered using the mFilterData, mFilterCallback and mFilterFlags
members. These parameters are internally passed to PxScene::overlap() to find objects touched by the CCT.
Please refer to the PxScene::overlap() documentation for details.
Collisions between a CCT and another CCT are filtered using the mCCTFilterCallback member. If this filter
callback is not defined, none of the CCT-vs-CCT collisions are filtered, and each CCT will collide against
all other CCTs.
\note PxQueryFlag::eANY_HIT and PxQueryFlag::eNO_BLOCK are ignored in mFilterFlags.
\see PxController.move() PxControllerFilterCallback
*/
class PxControllerFilters
{
public:
PX_INLINE PxControllerFilters(const PxFilterData* filterData=NULL, PxQueryFilterCallback* cb=NULL, PxControllerFilterCallback* cctFilterCb=NULL) :
mFilterData (filterData),
mFilterCallback (cb),
mFilterFlags (PxQueryFlag::eSTATIC|PxQueryFlag::eDYNAMIC|PxQueryFlag::ePREFILTER),
mCCTFilterCallback (cctFilterCb)
{}
// CCT-vs-shapes:
const PxFilterData* mFilterData; //!< Data for internal PxQueryFilterData structure. Passed to PxScene::overlap() call.
//!< This can be NULL, in which case a default PxFilterData is used.
PxQueryFilterCallback* mFilterCallback; //!< Custom filter logic (can be NULL). Passed to PxScene::overlap() call.
PxQueryFlags mFilterFlags; //!< Flags for internal PxQueryFilterData structure. Passed to PxScene::overlap() call.
// CCT-vs-CCT:
PxControllerFilterCallback* mCCTFilterCallback; //!< CCT-vs-CCT filter callback. If NULL, all CCT-vs-CCT collisions are kept.
};
/**
\brief Descriptor class for a character controller.
\see PxBoxController PxCapsuleController
*/
class PxControllerDesc
{
public:
/**
\brief returns true if the current settings are valid
\return True if the descriptor is valid.
*/
PX_INLINE virtual bool isValid() const;
/**
\brief Returns the character controller type
\return The controllers type.
\see PxControllerType PxCapsuleControllerDesc PxBoxControllerDesc
*/
PX_INLINE PxControllerShapeType::Enum getType() const { return mType; }
/**
\brief The position of the character
\note The character's initial position must be such that it does not overlap the static geometry.
<b>Default:</b> Zero
*/
PxExtendedVec3 position;
/**
\brief Specifies the 'up' direction
In order to provide stepping functionality the SDK must be informed about the up direction.
<b>Default:</b> (0, 1, 0)
*/
PxVec3 upDirection;
/**
\brief The maximum slope which the character can walk up.
In general it is desirable to limit where the character can walk, in particular it is unrealistic
for the character to be able to climb arbitary slopes.
The limit is expressed as the cosine of desired limit angle. A value of 0 disables this feature.
\warning It is currently enabled for static actors only (not for dynamic/kinematic actors), and not supported for spheres or capsules.
<b>Default:</b> 0.707
\see upDirection invisibleWallHeight maxJumpHeight
*/
PxF32 slopeLimit;
/**
\brief Height of invisible walls created around non-walkable triangles
The library can automatically create invisible walls around non-walkable triangles defined
by the 'slopeLimit' parameter. This defines the height of those walls. If it is 0.0, then
no extra triangles are created.
<b>Default:</b> 0.0
\see upDirection slopeLimit maxJumpHeight
*/
PxF32 invisibleWallHeight;
/**
\brief Maximum height a jumping character can reach
This is only used if invisible walls are created ('invisibleWallHeight' is non zero).
When a character jumps, the non-walkable triangles he might fly over are not found
by the collision queries (since the character's bounding volume does not touch them).
Thus those non-walkable triangles do not create invisible walls, and it is possible
for a jumping character to land on a non-walkable triangle, while he wouldn't have
reached that place by just walking.
The 'maxJumpHeight' variable is used to extend the size of the collision volume
downward. This way, all the non-walkable triangles are properly found by the collision
queries and it becomes impossible to 'jump over' invisible walls.
If the character in your game can not jump, it is safe to use 0.0 here. Otherwise it
is best to keep this value as small as possible, since a larger collision volume
means more triangles to process.
<b>Default:</b> 0.0
\see upDirection slopeLimit invisibleWallHeight
*/
PxF32 maxJumpHeight;
/**
\brief The contact offset used by the controller.
Specifies a skin around the object within which contacts will be generated.
Use it to avoid numerical precision issues.
This is dependant on the scale of the users world, but should be a small, positive
non zero value.
<b>Default:</b> 0.1
*/
PxF32 contactOffset;
/**
\brief Defines the maximum height of an obstacle which the character can climb.
A small value will mean that the character gets stuck and cannot walk up stairs etc,
a value which is too large will mean that the character can climb over unrealistically
high obstacles.
<b>Default:</b> 0.5
\see upDirection
*/
PxF32 stepOffset;
/**
\brief Density of underlying kinematic actor
The CCT creates a PhysX's kinematic actor under the hood. This controls its density.
<b>Default:</b> 10.0
*/
PxF32 density;
/**
\brief Scale coefficient for underlying kinematic actor
The CCT creates a PhysX's kinematic actor under the hood. This controls its scale factor.
This should be a number a bit smaller than 1.0.
This scale factor affects how the character interacts with dynamic rigid bodies around it (e.g. pushing them, etc).
With a scale factor < 1, the underlying kinematic actor will not touch surrounding rigid bodies - they will
only interact with the character controller's shapes (capsules or boxes), and users will have full control
over the interactions (i.e. they will have to push the objects with explicit forces themselves).
With a scale factor >=1, the underlying kinematic actor will touch and push surrounding rigid bodies based
on PhysX's computations, as if there would be no character controller involved. This works fine except
when you push objects into a wall. PhysX has no control over kinematic actors (since they are kinematic)
so they would freely push dynamic objects into walls, and make them tunnel / explode / behave badly.
With a smaller kinematic actor however, the character controller's swept shape touches dynamic rigid bodies
first, and can apply forces to them to move them away (or not, depending on what the gameplay needs).
Meanwhile the character controller's swept shape itself is stopped by these dynamic bodies.
Setting the scale factor to 1 could still work, but it is unreliable. Depending on FPU accuracy you could
end up with either the CCT's volume or the underlying kinematic actor touching the dynamic bodies first,
and this could change from one moment to the next.
<b>Default:</b> 0.8
*/
PxF32 scaleCoeff;
/**
\brief Cached volume growth
Amount of space around the controller we cache to improve performance. This is a scale factor
that should be higher than 1.0f but not too big, ideally lower than 2.0f.
<b>Default:</b> 1.5
*/
PxF32 volumeGrowth;
/**
\brief Specifies a user report callback.
This report callback is called when the character collides with shapes and other characters.
Setting this to NULL disables the callback.
<b>Default:</b> NULL
\see PxUserControllerHitReport
*/
PxUserControllerHitReport* reportCallback;
/**
\brief Specifies a user behavior callback.
This behavior callback is called to customize the controller's behavior w.r.t. touched shapes.
Setting this to NULL disables the callback.
<b>Default:</b> NULL
\see PxControllerBehaviorCallback
*/
PxControllerBehaviorCallback* behaviorCallback;
/**
\brief The non-walkable mode controls if a character controller slides or not on a non-walkable part.
This is only used when slopeLimit is non zero.
<b>Default:</b> PxControllerNonWalkableMode::ePREVENT_CLIMBING
\see PxControllerNonWalkableMode
*/
PxControllerNonWalkableMode::Enum nonWalkableMode;
/**
\brief The material for the actor associated with the controller.
The controller internally creates a rigid body actor. This parameter specifies the material of the actor.
<b>Default:</b> NULL
\see PxMaterial
*/
PxMaterial* material;
/**
\brief Use a deletion listener to get informed about released objects and clear internal caches if needed.
If a character controller registers a deletion listener, it will get informed about released objects. That allows the
controller to invalidate cached data that connects to a released object. If a deletion listener is not
registered, PxController::invalidateCache has to be called manually after objects have been released.
\see PxController::invalidateCache
<b>Default:</b> true
*/
bool registerDeletionListener;
/**
\brief Client ID for associated actor.
\see PxClientID PxActor::setOwnerClient
<b>Default:</b> PX_DEFAULT_CLIENT
*/
PxClientID clientID;
/**
\brief User specified data associated with the controller.
<b>Default:</b> NULL
*/
void* userData;
protected:
const PxControllerShapeType::Enum mType; //!< The type of the controller. This gets set by the derived class' ctor, the user should not have to change it.
/**
\brief constructor sets to default.
*/
PX_INLINE PxControllerDesc(PxControllerShapeType::Enum);
PX_INLINE virtual ~PxControllerDesc();
/**
\brief copy constructor.
*/
PX_INLINE PxControllerDesc(const PxControllerDesc&);
/**
\brief assignment operator.
*/
PX_INLINE PxControllerDesc& operator=(const PxControllerDesc&);
PX_INLINE void copy(const PxControllerDesc&);
};
PX_INLINE PxControllerDesc::PxControllerDesc(PxControllerShapeType::Enum t) :
position (PxExtended(0.0), PxExtended(0.0), PxExtended(0.0)),
upDirection (0.0f, 1.0f, 0.0f),
slopeLimit (0.707f),
invisibleWallHeight (0.0f),
maxJumpHeight (0.0f),
contactOffset (0.1f),
stepOffset (0.5f),
density (10.0f),
scaleCoeff (0.8f),
volumeGrowth (1.5f),
reportCallback (NULL),
behaviorCallback (NULL),
nonWalkableMode (PxControllerNonWalkableMode::ePREVENT_CLIMBING),
material (NULL),
registerDeletionListener (true),
clientID (PX_DEFAULT_CLIENT),
userData (NULL),
mType (t)
{
}
PX_INLINE PxControllerDesc::PxControllerDesc(const PxControllerDesc& other) : mType(other.mType)
{
copy(other);
}
PX_INLINE PxControllerDesc& PxControllerDesc::operator=(const PxControllerDesc& other)
{
copy(other);
return *this;
}
PX_INLINE void PxControllerDesc::copy(const PxControllerDesc& other)
{
upDirection = other.upDirection;
slopeLimit = other.slopeLimit;
contactOffset = other.contactOffset;
stepOffset = other.stepOffset;
density = other.density;
scaleCoeff = other.scaleCoeff;
volumeGrowth = other.volumeGrowth;
reportCallback = other.reportCallback;
behaviorCallback = other.behaviorCallback;
userData = other.userData;
nonWalkableMode = other.nonWalkableMode;
position.x = other.position.x;
position.y = other.position.y;
position.z = other.position.z;
material = other.material;
invisibleWallHeight = other.invisibleWallHeight;
maxJumpHeight = other.maxJumpHeight;
registerDeletionListener = other.registerDeletionListener;
clientID = other.clientID;
}
PX_INLINE PxControllerDesc::~PxControllerDesc()
{
}
PX_INLINE bool PxControllerDesc::isValid() const
{
if( mType!=PxControllerShapeType::eBOX
&& mType!=PxControllerShapeType::eCAPSULE)
return false;
if(scaleCoeff<0.0f)
return false;
if(volumeGrowth<1.0f)
return false;
if(density<0.0f)
return false;
if(slopeLimit<0.0f)
return false;
if(stepOffset<0.0f)
return false;
if(contactOffset<=0.0f)
return false;
if(!material)
return false;
if(!toVec3(position).isFinite())
return false; //the float version needs to be finite otherwise actor creation will fail.
return true;
}
/**
\brief Base class for character controllers.
\see PxCapsuleController PxBoxController
*/
class PxController
{
public:
/**
\brief Return the type of controller
\see PxControllerType
*/
virtual PxControllerShapeType::Enum getType() const = 0;
/**
\brief Releases the controller.
*/
virtual void release() = 0;
/**
\brief Moves the character using a "collide-and-slide" algorithm.
\param[in] disp Displacement vector
\param[in] minDist The minimum travelled distance to consider. If travelled distance is smaller, the character doesn't move.
This is used to stop the recursive motion algorithm when remaining distance to travel is small.
\param[in] elapsedTime Time elapsed since last call
\param[in] filters User-defined filters for this move
\param[in] obstacles Potential additional obstacles the CCT should collide with.
\return Collision flags, collection of ::PxControllerCollisionFlags
*/
virtual PxControllerCollisionFlags move(const PxVec3& disp, PxF32 minDist, PxF32 elapsedTime, const PxControllerFilters& filters, const PxObstacleContext* obstacles=NULL) = 0;
/**
\brief Sets controller's position.
The position controlled by this function is the center of the collision shape.
\warning This is a 'teleport' function, it doesn't check for collisions.
\warning The character's position must be such that it does not overlap the static geometry.
To move the character under normal conditions use the #move() function.
\param[in] position The new (center) positon for the controller.
\return Currently always returns true.
\see PxControllerDesc.position getPosition() getFootPosition() setFootPosition() move()
*/
virtual bool setPosition(const PxExtendedVec3& position) = 0;
/**
\brief Retrieve the raw position of the controller.
The position retrieved by this function is the center of the collision shape. To retrieve the bottom position of the shape,
a.k.a. the foot position, use the getFootPosition() function.
The position is updated by calls to move(). Calling this method without calling
move() will return the last position or the initial position of the controller.
\return The controller's center position
\see PxControllerDesc.position setPosition() getFootPosition() setFootPosition() move()
*/
virtual const PxExtendedVec3& getPosition() const = 0;
/**
\brief Set controller's foot position.
The position controlled by this function is the bottom of the collision shape, a.k.a. the foot position.
\note The foot position takes the contact offset into account
\warning This is a 'teleport' function, it doesn't check for collisions.
To move the character under normal conditions use the #move() function.
\param[in] position The new (bottom) positon for the controller.
\return Currently always returns true.
\see PxControllerDesc.position setPosition() getPosition() getFootPosition() move()
*/
virtual bool setFootPosition(const PxExtendedVec3& position) = 0;
/**
\brief Retrieve the "foot" position of the controller, i.e. the position of the bottom of the CCT's shape.
\note The foot position takes the contact offset into account
\return The controller's foot position
\see PxControllerDesc.position setPosition() getPosition() setFootPosition() move()
*/
virtual PxExtendedVec3 getFootPosition() const = 0;
/**
\brief Get the rigid body actor associated with this controller (see PhysX documentation).
The behavior upon manually altering this actor is undefined, you should primarily
use it for reading const properties.
\return the actor associated with the controller.
*/
virtual PxRigidDynamic* getActor() const = 0;
/**
\brief The step height.
\param[in] offset The new step offset for the controller.
\see PxControllerDesc.stepOffset
*/
virtual void setStepOffset(const PxF32 offset) =0;
/**
\brief Retrieve the step height.
\return The step offset for the controller.
\see setStepOffset()
*/
virtual PxF32 getStepOffset() const =0;
/**
\brief Sets the non-walkable mode for the CCT.
\param[in] flag The new value of the non-walkable mode.
\see PxControllerNonWalkableMode
*/
virtual void setNonWalkableMode(PxControllerNonWalkableMode::Enum flag) = 0;
/**
\brief Retrieves the non-walkable mode for the CCT.
\return The current non-walkable mode.
\see PxControllerNonWalkableMode
*/
virtual PxControllerNonWalkableMode::Enum getNonWalkableMode() const = 0;
/**
\brief Retrieve the contact offset.
\return The contact offset for the controller.
\see PxControllerDesc.contactOffset
*/
virtual PxF32 getContactOffset() const =0;
/**
\brief Sets the contact offset.
\param[in] offset The contact offset for the controller.
\see PxControllerDesc.contactOffset
*/
virtual void setContactOffset(PxF32 offset) =0;
/**
\brief Retrieve the 'up' direction.
\return The up direction for the controller.
\see PxControllerDesc.upDirection
*/
virtual PxVec3 getUpDirection() const =0;
/**
\brief Sets the 'up' direction.
\param[in] up The up direction for the controller.
\see PxControllerDesc.upDirection
*/
virtual void setUpDirection(const PxVec3& up) =0;
/**
\brief Retrieve the slope limit.
\return The slope limit for the controller.
\see PxControllerDesc.slopeLimit
*/
virtual PxF32 getSlopeLimit() const =0;
/**
\brief Sets the slope limit.
\note This feature can not be enabled at runtime, i.e. if the slope limit is zero when creating the CCT
(which disables the feature) then changing the slope limit at runtime will not have any effect, and the call
will be ignored.
\param[in] slopeLimit The slope limit for the controller.
\see PxControllerDesc.slopeLimit
*/
virtual void setSlopeLimit(PxF32 slopeLimit) =0;
/**
\brief Flushes internal geometry cache.
The character controller uses caching in order to speed up collision testing. The cache is
automatically flushed when a change to static objects is detected in the scene. For example when a
static shape is added, updated, or removed from the scene, the cache is automatically invalidated.
However there may be situations that cannot be automatically detected, and those require manual
invalidation of the cache. Currently the user must call this when the filtering behavior changes (the
PxControllerFilters parameter of the PxController::move call). While the controller in principle
could detect a change in these parameters, it cannot detect a change in the behavior of the filtering
function.
\see PxController.move
*/
virtual void invalidateCache() = 0;
/**
\brief Retrieve the scene associated with the controller.
\return The physics scene
*/
virtual PxScene* getScene() = 0;
/**
\brief Returns the user data associated with this controller.
\return The user pointer associated with the controller.
\see PxControllerDesc.userData
*/
virtual void* getUserData() const = 0;
/**
\brief Sets the user data associated with this controller.
\param[in] userData The user pointer associated with the controller.
\see PxControllerDesc.userData
*/
virtual void setUserData(void* userData) = 0;
/**
\brief Returns information about the controller's internal state.
\param[out] state The controller's internal state
\see PxControllerState
*/
virtual void getState(PxControllerState& state) const = 0;
/**
\brief Returns the controller's internal statistics.
\param[out] stats The controller's internal statistics
\see PxControllerStats
*/
virtual void getStats(PxControllerStats& stats) const = 0;
/**
\brief Resizes the controller.
This function attempts to resize the controller to a given size, while making sure the bottom
position of the controller remains constant. In other words the function modifies both the
height and the (center) position of the controller. This is a helper function that can be used
to implement a 'crouch' functionality for example.
\param[in] height Desired controller's height
*/
virtual void resize(PxReal height) = 0;
protected:
PX_INLINE PxController() {}
virtual ~PxController() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,125 @@
// 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 PX_CONTROLLER_BEHAVIOR_H
#define PX_CONTROLLER_BEHAVIOR_H
#include "PxFiltering.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxShape;
class PxObstacle;
class PxController;
/**
\brief specifies controller behavior
*/
struct PxControllerBehaviorFlag
{
enum Enum
{
eCCT_CAN_RIDE_ON_OBJECT = (1<<0), //!< Controller can ride on touched object (i.e. when this touched object is moving horizontally). \note The CCT vs. CCT case is not supported.
eCCT_SLIDE = (1<<1), //!< Controller should slide on touched object
eCCT_USER_DEFINED_RIDE = (1<<2) //!< Disable all code dealing with controllers riding on objects, let users define it outside of the SDK.
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxControllerBehaviorFlag.
\see PxControllerBehaviorFlag
*/
typedef PxFlags<PxControllerBehaviorFlag::Enum, PxU8> PxControllerBehaviorFlags;
PX_FLAGS_OPERATORS(PxControllerBehaviorFlag::Enum, PxU8)
/**
\brief User behavior callback.
This behavior callback is called to customize the controller's behavior w.r.t. touched shapes.
*/
class PxControllerBehaviorCallback
{
public:
/**
\brief Retrieve behavior flags for a shape.
When the CCT touches a shape, the CCT's behavior w.r.t. this shape can be customized by users.
This function retrieves the desired PxControllerBehaviorFlag flags capturing the desired behavior.
\param[in] shape The shape the CCT is currently touching
\param[in] actor The actor owning the shape
\return Desired behavior flags for the given shape
\see PxControllerBehaviorFlag
*/
virtual PxControllerBehaviorFlags getBehaviorFlags(const PxShape& shape, const PxActor& actor) = 0;
/**
\brief Retrieve behavior flags for a controller.
When the CCT touches a controller, the CCT's behavior w.r.t. this controller can be customized by users.
This function retrieves the desired PxControllerBehaviorFlag flags capturing the desired behavior.
\note The flag PxControllerBehaviorFlag::eCCT_CAN_RIDE_ON_OBJECT is not supported.
\param[in] controller The controller the CCT is currently touching
\return Desired behavior flags for the given controller
\see PxControllerBehaviorFlag
*/
virtual PxControllerBehaviorFlags getBehaviorFlags(const PxController& controller) = 0;
/**
\brief Retrieve behavior flags for an obstacle.
When the CCT touches an obstacle, the CCT's behavior w.r.t. this obstacle can be customized by users.
This function retrieves the desired PxControllerBehaviorFlag flags capturing the desired behavior.
\param[in] obstacle The obstacle the CCT is currently touching
\return Desired behavior flags for the given obstacle
\see PxControllerBehaviorFlag
*/
virtual PxControllerBehaviorFlags getBehaviorFlags(const PxObstacle& obstacle) = 0;
protected:
virtual ~PxControllerBehaviorCallback(){}
};
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,296 @@
// 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 PX_CONTROLLER_MANAGER_H
#define PX_CONTROLLER_MANAGER_H
#include "PxPhysXConfig.h"
#include "foundation/PxFlags.h"
#include "foundation/PxErrorCallback.h"
#include "common/PxRenderBuffer.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxPhysics;
class PxScene;
class PxController;
class PxControllerDesc;
class PxObstacleContext;
class PxControllerFilterCallback;
/**
\brief specifies debug-rendering flags
*/
struct PxControllerDebugRenderFlag
{
enum Enum
{
eTEMPORAL_BV = (1<<0), //!< Temporal bounding volume around controllers
eCACHED_BV = (1<<1), //!< Cached bounding volume around controllers
eOBSTACLES = (1<<2), //!< User-defined obstacles
eNONE = 0,
eALL = 0xffffffff
};
};
/**
\brief Bitfield that contains a set of raised flags defined in PxControllerDebugRenderFlag.
\see PxControllerDebugRenderFlag
*/
typedef PxFlags<PxControllerDebugRenderFlag::Enum, PxU32> PxControllerDebugRenderFlags;
PX_FLAGS_OPERATORS(PxControllerDebugRenderFlag::Enum, PxU32)
/**
\brief Manages an array of character controllers.
\see PxController PxBoxController PxCapsuleController
*/
class PxControllerManager
{
public:
/**
\brief Releases the controller manager.
\note This will release all associated controllers and obstacle contexts.
\note This function is required to be called to release foundation usage.
*/
virtual void release() = 0;
/**
\brief Returns the scene the manager is adding the controllers to.
\return The associated physics scene.
*/
virtual PxScene& getScene() const = 0;
/**
\brief Returns the number of controllers that are being managed.
\return The number of controllers.
*/
virtual PxU32 getNbControllers() const = 0;
/**
\brief Retrieve one of the controllers in the manager.
\param index the index of the controller to return
\return The controller with the specified index.
*/
virtual PxController* getController(PxU32 index) = 0;
/**
\brief Creates a new character controller.
\param[in] desc The controllers descriptor
\return The new controller
\see PxController PxController.release() PxControllerDesc
*/
virtual PxController* createController(const PxControllerDesc& desc) = 0;
/**
\brief Releases all the controllers that are being managed.
*/
virtual void purgeControllers() = 0;
/**
\brief Retrieves debug data.
\return The render buffer filled with debug-render data
\see PxControllerManager.setDebugRenderingFlags()
*/
virtual PxRenderBuffer& getRenderBuffer() = 0;
/**
\brief Sets debug rendering flags
\param[in] flags The debug rendering flags (combination of PxControllerDebugRenderFlags)
\see PxControllerManager.getRenderBuffer() PxControllerDebugRenderFlags
*/
virtual void setDebugRenderingFlags(PxControllerDebugRenderFlags flags) = 0;
/**
\brief Returns the number of obstacle contexts that are being managed.
\return The number of obstacle contexts.
*/
virtual PxU32 getNbObstacleContexts() const = 0;
/**
\brief Retrieve one of the obstacle contexts in the manager.
\param index The index of the obstacle context to retrieve.
\return The obstacle context with the specified index.
*/
virtual PxObstacleContext* getObstacleContext(PxU32 index) = 0;
/**
\brief Creates an obstacle context.
\return New obstacle context
\see PxObstacleContext
*/
virtual PxObstacleContext* createObstacleContext() = 0;
/**
\brief Computes character-character interactions.
This function is an optional helper to properly resolve interactions between characters, in case they overlap (which can happen for gameplay reasons, etc).
You should call this once per frame, before your PxController::move() calls. The function will not move the characters directly, but it will
compute overlap information for each character that will be used in the next move() call.
You need to provide a proper time value here so that interactions are resolved in a way that do not depend on the framerate.
If you only have one character in the scene, or if you can guarantee your characters will never overlap, then you do not need to call this function.
\note Releasing the manager will automatically release all the associated obstacle contexts.
\param[in] elapsedTime Elapsed time since last call
\param[in] cctFilterCb Filtering callback for CCT-vs-CCT interactions
*/
virtual void computeInteractions(PxF32 elapsedTime, PxControllerFilterCallback* cctFilterCb=NULL) = 0;
/**
\brief Enables or disables runtime tessellation.
Large triangles can create accuracy issues in the sweep code, which in turn can lead to characters not sliding smoothly
against geometries, or even penetrating them. This feature allows one to reduce those issues by tessellating large
triangles at runtime, before performing sweeps against them. The amount of tessellation is controlled by the 'maxEdgeLength' parameter.
Any triangle with at least one edge length greater than the maxEdgeLength will get recursively tessellated, until resulting triangles are small enough.
This features only applies to triangle meshes, convex meshes, heightfields and boxes.
\param[in] flag True/false to enable/disable runtime tessellation.
\param[in] maxEdgeLength Max edge length allowed before tessellation kicks in.
*/
virtual void setTessellation(bool flag, float maxEdgeLength) = 0;
/**
\brief Enables or disables the overlap recovery module.
The overlap recovery module can be used to depenetrate CCTs from static objects when an overlap is detected. This can happen
in three main cases:
- when the CCT is directly spawned or teleported in another object
- when the CCT algorithm fails due to limited FPU accuracy
- when the "up vector" is modified, making the rotated CCT shape overlap surrounding objects
When activated, the CCT module will automatically try to resolve the penetration, and move the CCT to a safe place where it does
not overlap other objects anymore. This only concerns static objects, dynamic objects are ignored by the recovery module.
When the recovery module is not activated, it is possible for the CCTs to go through static objects. By default, the recovery
module is enabled.
The recovery module currently works with all geometries except heightfields.
\param[in] flag True/false to enable/disable overlap recovery module.
*/
virtual void setOverlapRecoveryModule(bool flag) = 0;
/**
\brief Enables or disables the precise sweeps.
Precise sweeps are more accurate, but also potentially slower than regular sweeps.
By default, precise sweeps are enabled.
\param[in] flag True/false to enable/disable precise sweeps.
*/
virtual void setPreciseSweeps(bool flag) = 0;
/**
\brief Enables or disables vertical sliding against ceilings.
Geometry is seen as "ceilings" when the following condition is met:
dot product(contact normal, up direction)<0.0f
This flag controls whether characters should slide vertically along the geometry in that case.
By default, sliding is allowed.
\param[in] flag True/false to enable/disable sliding.
*/
virtual void setPreventVerticalSlidingAgainstCeiling(bool flag) = 0;
/**
\brief Shift the origin of the character controllers and obstacle objects by the specified vector.
The positions of all character controllers, obstacle objects and the corresponding data structures will get adjusted to reflect the shifted origin location
(the shift vector will get subtracted from all character controller and obstacle object positions).
\note It is the user's responsibility to keep track of the summed total origin shift and adjust all input/output to/from PhysXCharacterKinematic accordingly.
\note This call will not automatically shift the PhysX scene and its objects. You need to call PxScene::shiftOrigin() separately to keep the systems in sync.
\param[in] shift Translation vector to shift the origin by.
*/
virtual void shiftOrigin(const PxVec3& shift) = 0;
protected:
PxControllerManager() {}
virtual ~PxControllerManager() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
/**
\brief Creates the controller manager.
\param[in] scene PhysX scene. You can only create one PxControllerManager per scene.
\param[in] lockingEnabled Enables/disables internal locking.
\return New controller manager, or NULL in case of failure (e.g. when a manager has already been created for that scene)
The character controller is informed by #PxDeletionListener::onRelease() when actors or shapes are released, and updates its internal
caches accordingly. If character controller movement or a call to #PxControllerManager::shiftOrigin() may overlap with actor/shape releases,
internal data structures must be guarded against concurrent access.
Locking guarantees thread safety in such scenarios.
\note locking may result in significant slowdown for release of actors or shapes.
By default, locking is disabled.
*/
PX_C_EXPORT physx::PxControllerManager* PX_CALL_CONV PxCreateControllerManager(physx::PxScene& scene, bool lockingEnabled = false);
#endif

View File

@@ -0,0 +1,186 @@
// 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 PX_CONTROLLER_OBSTACLES_H
#define PX_CONTROLLER_OBSTACLES_H
#include "characterkinematic/PxExtended.h"
#include "geometry/PxGeometry.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxControllerManager;
#define PX_INVALID_OBSTACLE_HANDLE 0xffffffff
/**
\brief Base class for obstacles.
\see PxBoxObstacle PxCapsuleObstacle PxObstacleContext
*/
class PxObstacle
{
protected:
PxObstacle() :
mType (PxGeometryType::eINVALID),
mUserData (NULL),
mPos (0.0, 0.0, 0.0),
mRot (PxQuat(PxIdentity))
{}
PxGeometryType::Enum mType;
public:
PX_FORCE_INLINE PxGeometryType::Enum getType() const { return mType; }
void* mUserData;
PxExtendedVec3 mPos;
PxQuat mRot;
};
/**
\brief A box obstacle.
\see PxObstacle PxCapsuleObstacle PxObstacleContext
*/
class PxBoxObstacle : public PxObstacle
{
public:
PxBoxObstacle() :
mHalfExtents(0.0f)
{ mType = PxGeometryType::eBOX; }
PxVec3 mHalfExtents;
};
/**
\brief A capsule obstacle.
\see PxBoxObstacle PxObstacle PxObstacleContext
*/
class PxCapsuleObstacle : public PxObstacle
{
public:
PxCapsuleObstacle() :
mHalfHeight (0.0f),
mRadius (0.0f)
{ mType = PxGeometryType::eCAPSULE; }
PxReal mHalfHeight;
PxReal mRadius;
};
typedef PxU32 PxObstacleHandle;
/**
\brief Context class for obstacles.
An obstacle context class contains and manages a set of user-defined obstacles.
\see PxBoxObstacle PxCapsuleObstacle PxObstacle
*/
class PxObstacleContext
{
public:
PxObstacleContext() {}
virtual ~PxObstacleContext() {}
/**
\brief Releases the context.
*/
virtual void release() = 0;
/**
\brief Retrieves the controller manager associated with this context.
\return The associated controller manager
*/
virtual PxControllerManager& getControllerManager() const = 0;
/**
\brief Adds an obstacle to the context.
\param [in] obstacle Obstacle data for the new obstacle. The data gets copied.
\return Handle for newly-added obstacle
*/
virtual PxObstacleHandle addObstacle(const PxObstacle& obstacle) = 0;
/**
\brief Removes an obstacle from the context.
\param [in] handle Handle for the obstacle object that needs to be removed.
\return True if success
*/
virtual bool removeObstacle(PxObstacleHandle handle) = 0;
/**
\brief Updates data for an existing obstacle.
\param [in] handle Handle for the obstacle object that needs to be updated.
\param [in] obstacle New obstacle data
\return True if success
*/
virtual bool updateObstacle(PxObstacleHandle handle, const PxObstacle& obstacle) = 0;
/**
\brief Retrieves number of obstacles in the context.
\return Number of obstacles in the context
*/
virtual PxU32 getNbObstacles() const = 0;
/**
\brief Retrieves desired obstacle.
\param [in] i Obstacle index
\return Desired obstacle
*/
virtual const PxObstacle* getObstacle(PxU32 i) const = 0;
/**
\brief Retrieves desired obstacle by given handle.
\param [in] handle Obstacle handle
\return Desired obstacle
*/
virtual const PxObstacle* getObstacleByHandle(PxObstacleHandle handle) const = 0;
};
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,82 @@
// 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 PX_EXTENDED_H
#define PX_EXTENDED_H
// This needs to be included in Foundation just for the debug renderer
#include "PxPhysXConfig.h"
#include "foundation/PxTransform.h"
#include "foundation/PxAssert.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
// This has to be done here since it also changes the top-level "Px" and "Np" APIs
#define PX_BIG_WORLDS
#ifdef PX_BIG_WORLDS
typedef PxVec3d PxExtendedVec3;
typedef double PxExtended;
#define PX_MAX_EXTENDED PX_MAX_F64
PX_FORCE_INLINE PxVec3 toVec3(const PxExtendedVec3& v)
{
return PxVec3(float(v.x), float(v.y), float(v.z));
}
// Computes the single-precision difference between two extended-precision points
PX_INLINE PxVec3 diff(const PxExtendedVec3& p1, const PxExtendedVec3& p0)
{
return PxVec3(float(p1.x - p0.x), float(p1.y - p0.y), float(p1.z - p0.z));
}
#else
typedef PxVec3 PxExtendedVec3;
typedef float PxExtended;
#define PX_MAX_EXTENDED PX_MAX_F32
PX_FORCE_INLINE PxVec3 toVec3(const PxExtendedVec3& v)
{
return v;
}
// Computes the single-precision difference between two extended-precision points
PX_INLINE PxVec3 diff(const PxExtendedVec3& p1, const PxExtendedVec3& p0)
{
return p1 - p0;
}
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,92 @@
// 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 PX_COLLISION_DEFS_H
#define PX_COLLISION_DEFS_H
#include "PxPhysXConfig.h"
#include "foundation/PxSimpleTypes.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief A callback class to allocate memory to cache information used in contact generation.
*/
class PxCacheAllocator
{
public:
/**
\brief Allocates cache data for contact generation. This data is stored inside PxCache objects.
The application can retain and provide this information for future contact generation passes
for a given pair to improve contact generation performance. It is the application's responsibility
to release this memory appropriately. If the memory is released, the application must ensure that
this memory is no longer referenced by any PxCache objects passed to PxGenerateContacts.
\param byteSize [in] size of the allocation in bytes
\return the newly-allocated memory. The returned address must be 16-byte aligned.
\see PxCache, PxGenerateContacts
*/
virtual PxU8* allocateCacheData(const PxU32 byteSize) = 0;
virtual ~PxCacheAllocator() {}
};
/**
\brief A structure to cache contact information produced by low-level contact generation functions.
*/
struct PxCache
{
PxU8* mCachedData; //!< Cached data pointer. Allocated via PxCacheAllocator
PxU16 mCachedSize; //!< The total size of the cached data
PxU8 mPairData; //!< Pair data information used and cached internally by some contact generation functions to accelerate performance.
PxU8 mManifoldFlags; //!< Manifold flags used to identify the format the cached data is stored in.
PX_FORCE_INLINE PxCache() : mCachedData(NULL), mCachedSize(0), mPairData(0), mManifoldFlags(0)
{
}
PX_FORCE_INLINE void reset()
{
mCachedData = NULL;
mCachedSize = 0;
mPairData = 0;
mManifoldFlags = 0;
}
};
#if !PX_DOXYGEN
}
#endif
#endif

View File

@@ -0,0 +1,236 @@
// 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 PX_BASE_H
#define PX_BASE_H
#include "foundation/PxFlags.h"
#include "foundation/PxString.h"
#include "foundation/PxFoundation.h"
#include "common/PxSerialFramework.h"
#include "common/PxCollection.h"
#include "common/PxTypeInfo.h"
#include "foundation/PxAssert.h"
#define PX_IS_KIND_OF(query, classname, baseclass) \
PX_ASSERT(query != NULL); \
if(query == NULL) \
{ \
PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "isKindOf called with invalid string"); \
return false; \
} \
return !Pxstrcmp(classname, query) || baseclass::isKindOf(query)
#if !PX_DOXYGEN
namespace physx
{
#endif
typedef PxU16 PxType;
/**
\brief Flags for PxBase.
*/
struct PxBaseFlag
{
enum Enum
{
eOWNS_MEMORY = (1<<0),
eIS_RELEASABLE = (1<<1)
};
};
typedef PxFlags<PxBaseFlag::Enum, PxU16> PxBaseFlags;
PX_FLAGS_OPERATORS(PxBaseFlag::Enum, PxU16)
/**
\brief Base class for objects that can be members of a PxCollection.
All PxBase sub-classes can be serialized.
\see PxCollection
*/
class PxBase
{
public:
/**
\brief Releases the PxBase instance, please check documentation of release in derived class.
*/
virtual void release() = 0;
/**
\brief Returns string name of dynamic type.
\return Class name of most derived type of this object.
*/
virtual const char* getConcreteTypeName() const = 0;
/* brief Implements dynamic cast functionality.
Example use:
if(actor->is<PxRigidDynamic>()) {...}
\return A pointer to the specified type if object matches, otherwise NULL
*/
template<class T> T* is() { return typeMatch<T>() ? static_cast<T*>(this) : NULL; }
/* brief Implements dynamic cast functionality for const objects.
Example use:
if(actor->is<PxRigidDynamic>()) {...}
\return A pointer to the specified type if object matches, otherwise NULL
*/
template<class T> const T* is() const { return typeMatch<T>() ? static_cast<const T*>(this) : NULL; }
/**
\brief Returns concrete type of object.
\return PxConcreteType::Enum of serialized object
\see PxConcreteType
*/
PX_FORCE_INLINE PxType getConcreteType() const { return mConcreteType; }
/**
\brief Set PxBaseFlag
\param[in] flag The flag to be set
\param[in] value The flags new value
*/
PX_FORCE_INLINE void setBaseFlag(PxBaseFlag::Enum flag, bool value) { mBaseFlags = value ? mBaseFlags|flag : mBaseFlags&~flag; }
/**
\brief Set PxBaseFlags
\param[in] inFlags The flags to be set
\see PxBaseFlags
*/
PX_FORCE_INLINE void setBaseFlags(PxBaseFlags inFlags) { mBaseFlags = inFlags; }
/**
\brief Returns PxBaseFlags
\return PxBaseFlags
\see PxBaseFlags
*/
PX_FORCE_INLINE PxBaseFlags getBaseFlags() const { return mBaseFlags; }
/**
\brief Whether the object is subordinate.
A class is subordinate, if it can only be instantiated in the context of another class.
\return Whether the class is subordinate
\see PxSerialization::isSerializable
*/
virtual bool isReleasable() const { return mBaseFlags & PxBaseFlag::eIS_RELEASABLE; }
protected:
/**
\brief Constructor setting concrete type and base flags.
*/
PX_INLINE PxBase(PxType concreteType, PxBaseFlags baseFlags)
: mConcreteType(concreteType), mBaseFlags(baseFlags), mBuiltInRefCount(1) {}
/**
\brief Deserialization constructor setting base flags.
*/
PX_INLINE PxBase(PxBaseFlags baseFlags) : mBaseFlags(baseFlags)
{
PX_ASSERT(mBuiltInRefCount == 1);
}
/**
\brief Destructor.
*/
virtual ~PxBase() {}
/**
\brief Returns whether a given type name matches with the type of this instance
*/
virtual bool isKindOf(const char* superClass) const { return !Pxstrcmp(superClass, "PxBase"); }
template<class T> bool typeMatch() const
{
return PxU32(PxTypeInfo<T>::eFastTypeId)!=PxU32(PxConcreteType::eUNDEFINED) ?
PxU32(getConcreteType()) == PxU32(PxTypeInfo<T>::eFastTypeId) : isKindOf(PxTypeInfo<T>::name());
}
protected:
PxType mConcreteType; // concrete type identifier - see PxConcreteType.
PxBaseFlags mBaseFlags; // internal flags
PxU32 mBuiltInRefCount;
};
/**
\brief Base class for ref-counted objects.
*/
class PxRefCounted : public PxBase
{
public:
/**
\brief Decrements the reference count of the object and releases it if the new reference count is zero.
*/
virtual void release() = 0;
/**
\brief Returns the reference count of the object.
At creation, the reference count of the object is 1. Every other object referencing this object increments the
count by 1. When the reference count reaches 0, and only then, the object gets destroyed automatically.
\return the current reference count.
*/
virtual PxU32 getReferenceCount() const = 0;
/**
\brief Acquires a counted reference to this object.
This method increases the reference count of the object by 1. Decrement the reference count by calling release()
*/
virtual void acquireReference() = 0;
protected:
virtual void onRefCountZero() { delete this; }
PX_INLINE PxRefCounted(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {}
PX_INLINE PxRefCounted(PxBaseFlags baseFlags) : PxBase(baseFlags) {}
virtual ~PxRefCounted() {}
virtual bool isKindOf(const char* name) const { PX_IS_KIND_OF(name, "PxRefCounted", PxBase); }
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,273 @@
// 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 PX_COLLECTION_H
#define PX_COLLECTION_H
#include "common/PxSerialFramework.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
class PxBase;
/**
\brief Collection class for serialization.
A collection is a set of PxBase objects. PxBase objects can be added to the collection
regardless of other objects they depend on. Objects may be named using PxSerialObjectId values in order
to resolve dependencies between objects of different collections.
Serialization and deserialization only work through collections.
A scene is typically serialized using the following steps:
-# create a serialization registry
-# create a collection for scene objects
-# complete the scene objects (adds all dependent objects, e.g. meshes)
-# serialize collection
-# release collection
-# release serialization registry
For example the code may look like this:
\code
PxPhysics* physics; // The physics
PxScene* scene; // The physics scene
SerialStream s; // The user-defined stream doing the actual write to disk
PxSerializationRegistry* registry = PxSerialization::createSerializationRegistry(*physics); // step 1)
PxCollection* collection = PxSerialization::createCollection(*scene); // step 2)
PxSerialization::complete(*collection, *registry); // step 3)
PxSerialization::serializeCollectionToBinary(s, *collection, *registry); // step 4)
collection->release(); // step 5)
registry->release(); // step 6)
\endcode
A scene is typically deserialized using the following steps:
-# load a serialized collection into memory
-# create a serialization registry
-# create a collection by passing the serialized memory block
-# add collected objects to scene
-# release collection
-# release serialization registry
For example the code may look like this:
\code
PxPhysics* physics; // The physics
PxScene* scene; // The physics scene
void* memory128; // a 128-byte aligned buffer previously loaded from disk by the user - step 1)
PxSerializationRegistry* registry = PxSerialization::createSerializationRegistry(*physics); // step 2)
PxCollection* collection = PxSerialization::createCollectionFromBinary(memory128, *registry); // step 3)
scene->addCollection(*collection); // step 4)
collection->release(); // step 5)
registry->release(); // step 6)
\endcode
\see PxBase, PxCreateCollection()
*/
class PxCollection
{
public:
/**
\brief Adds a PxBase object to the collection.
Adds a PxBase object to the collection. Optionally a PxSerialObjectId can be provided
in order to resolve dependencies between collections. A PxSerialObjectId value of PX_SERIAL_OBJECT_ID_INVALID
means the object remains without id. Objects can be added regardless of other objects they require. If the object
is already in the collection, the ID will be set if it was PX_SERIAL_OBJECT_ID_INVALID previously, otherwise the
operation fails.
\param[in] object Object to be added to the collection
\param[in] id Optional PxSerialObjectId id
*/
virtual void add(PxBase& object, PxSerialObjectId id = PX_SERIAL_OBJECT_ID_INVALID) = 0;
/**
\brief Removes a PxBase member object from the collection.
Object needs to be contained by the collection.
\param[in] object PxBase object to be removed
*/
virtual void remove(PxBase& object) = 0;
/**
\brief Returns whether the collection contains a certain PxBase object.
\param[in] object PxBase object
\return Whether object is contained.
*/
virtual bool contains(PxBase& object) const = 0;
/**
\brief Adds an id to a member PxBase object.
If the object is already associated with an id within the collection, the id is replaced.
May only be called for objects that are members of the collection. The id needs to be unique
within the collection.
\param[in] object Member PxBase object
\param[in] id PxSerialObjectId id to be given to the object
*/
virtual void addId(PxBase& object, PxSerialObjectId id) = 0;
/**
\brief Removes id from a contained PxBase object.
May only be called for ids that are associated with an object in the collection.
\param[in] id PxSerialObjectId value
*/
virtual void removeId(PxSerialObjectId id) = 0;
/**
\brief Adds all PxBase objects and their ids of collection to this collection.
PxBase objects already in this collection are ignored. Object ids need to be conflict
free, i.e. the same object may not have two different ids within the two collections.
\param[in] collection Collection to be added
*/
virtual void add(PxCollection& collection) = 0;
/**
\brief Removes all PxBase objects of collection from this collection.
PxBase objects not present in this collection are ignored. Ids of objects
which are removed are also removed.
\param[in] collection Collection to be removed
*/
virtual void remove(PxCollection& collection) = 0;
/**
\brief Gets number of PxBase objects in this collection.
\return Number of objects in this collection
*/
virtual PxU32 getNbObjects() const = 0;
/**
\brief Gets the PxBase object of this collection given its index.
\param[in] index PxBase index in [0, getNbObjects())
\return PxBase object at index index
*/
virtual PxBase& getObject(PxU32 index) const = 0;
/**
\brief Copies member PxBase pointers to a user specified buffer.
\param[out] userBuffer Array of PxBase pointers
\param[in] bufferSize Capacity of userBuffer
\param[in] startIndex Offset into list of member PxBase objects
\return number of members PxBase objects that have been written to the userBuffer
*/
virtual PxU32 getObjects(PxBase** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/**
\brief Looks for a PxBase object given a PxSerialObjectId value.
If there is no PxBase object in the collection with the given id, NULL is returned.
\param[in] id PxSerialObjectId value to look for
\return PxBase object with the given id value or NULL
*/
virtual PxBase* find(PxSerialObjectId id) const = 0;
/**
\brief Gets number of PxSerialObjectId names in this collection.
\return Number of PxSerialObjectId names in this collection
*/
virtual PxU32 getNbIds() const = 0;
/**
\brief Copies member PxSerialObjectId values to a user specified buffer.
\param[out] userBuffer Array of PxSerialObjectId values
\param[in] bufferSize Capacity of userBuffer
\param[in] startIndex Offset into list of member PxSerialObjectId values
\return number of members PxSerialObjectId values that have been written to the userBuffer
*/
virtual PxU32 getIds(PxSerialObjectId* userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0;
/**
\brief Gets the PxSerialObjectId name of a PxBase object within the collection.
The PxBase object needs to be a member of the collection.
\param[in] object PxBase object to get id for
\return PxSerialObjectId name of the object or PX_SERIAL_OBJECT_ID_INVALID if the object is unnamed
*/
virtual PxSerialObjectId getId(const PxBase& object) const = 0;
/**
\brief Deletes a collection object.
This function only deletes the collection object, i.e. the container class. It doesn't delete objects
that are part of the collection.
\see PxCreateCollection()
*/
virtual void release() = 0;
protected:
PxCollection() {}
virtual ~PxCollection() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
/**
\brief Creates a collection object.
Objects can only be serialized or deserialized through a collection.
For serialization, users must add objects to the collection and serialize the collection as a whole.
For deserialization, the system gives back a collection of deserialized objects to users.
\return The new collection object.
\see PxCollection, PxCollection::release()
*/
PX_C_EXPORT PX_PHYSX_COMMON_API physx::PxCollection* PX_CALL_CONV PxCreateCollection();
#endif

View File

@@ -0,0 +1,242 @@
// 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 PX_CORE_UTILITY_TYPES_H
#define PX_CORE_UTILITY_TYPES_H
#include "foundation/PxAssert.h"
#include "foundation/PxMemory.h"
#include "foundation/PxIO.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
struct PxBoundedData
{
/**
\brief The offset in bytes between consecutive samples in the data.
<b>Default:</b> 0
*/
const void* data;
PxU32 stride;
PxU32 count;
PxBoundedData() : data( NULL ), stride(0), count(0) {}
PxBoundedData(void* data_, PxU32 stride_ = 0, PxU32 count_ = 0)
: data(data_)
, stride(stride_)
, count(count_)
{
}
template<typename TDataType>
PX_INLINE const TDataType& at( PxU32 idx ) const
{
PxU32 theStride( stride );
if ( theStride == 0 )
theStride = sizeof( TDataType );
PxU32 offset( theStride * idx );
return *(reinterpret_cast<const TDataType*>( reinterpret_cast< const PxU8* >( data ) + offset ));
}
};
typedef PX_DEPRECATED PxBoundedData PxStridedData;
template<typename TDataType>
struct PxTypedBoundedData
{
TDataType* data;
PxU32 stride;
PxU32 count;
PxTypedBoundedData()
: data(NULL)
, stride(0)
, count(0)
{
}
PxTypedBoundedData(TDataType* data_, PxU32 stride_ = 0, PxU32 count_ = 0)
: data(data_)
, stride(stride_)
, count(count_)
{
}
PX_CUDA_CALLABLE PX_INLINE const TDataType& at(PxU32 idx) const
{
PxU32 theStride(stride);
if (theStride == 0)
theStride = sizeof(TDataType);
PxU32 offset(theStride * idx);
return *(reinterpret_cast<const TDataType*>(reinterpret_cast<const PxU8*>(data) + offset));
}
PX_CUDA_CALLABLE PX_INLINE TDataType& atRef(PxU32 idx)
{
PxU32 theStride(stride);
if (theStride == 0)
theStride = sizeof(TDataType);
PxU32 offset(theStride * idx);
return *(reinterpret_cast<TDataType*>(reinterpret_cast<PxU8*>(data) + offset));
}
};
template<typename TDataType>
PX_DEPRECATED struct PxTypedStridedData : public PxTypedBoundedData<TDataType>
{
PxTypedStridedData() : PxTypedBoundedData<TDataType>()
{
}
PxTypedStridedData(TDataType* data_, PxU32 stride_ = 0) : PxTypedBoundedData<TDataType>(data_, stride_)
{
}
};
template<PxU8 TNumBytes>
struct PxPadding
{
PxU8 mPadding[TNumBytes];
PxPadding()
{
for ( PxU8 idx =0; idx < TNumBytes; ++idx )
mPadding[idx] = 0;
}
};
template <PxU32 NB_ELEMENTS> class PxFixedSizeLookupTable
{
public:
PxFixedSizeLookupTable()
: mNbDataPairs(0)
{
}
PxFixedSizeLookupTable(const PxEMPTY) {}
PxFixedSizeLookupTable(const PxReal* dataPairs, const PxU32 numDataPairs)
{
PxMemCopy(mDataPairs,dataPairs,sizeof(PxReal)*2*numDataPairs);
mNbDataPairs=numDataPairs;
}
PxFixedSizeLookupTable(const PxFixedSizeLookupTable& src)
{
PxMemCopy(mDataPairs,src.mDataPairs,sizeof(PxReal)*2*src.mNbDataPairs);
mNbDataPairs=src.mNbDataPairs;
}
~PxFixedSizeLookupTable()
{
}
PxFixedSizeLookupTable& operator=(const PxFixedSizeLookupTable& src)
{
PxMemCopy(mDataPairs,src.mDataPairs,sizeof(PxReal)*2*src.mNbDataPairs);
mNbDataPairs=src.mNbDataPairs;
return *this;
}
PX_FORCE_INLINE void addPair(const PxReal x, const PxReal y)
{
PX_ASSERT(mNbDataPairs<NB_ELEMENTS);
mDataPairs[2*mNbDataPairs+0]=x;
mDataPairs[2*mNbDataPairs+1]=y;
mNbDataPairs++;
}
PX_FORCE_INLINE PxReal getYVal(const PxReal x) const
{
if(0==mNbDataPairs)
{
PX_ASSERT(false);
return 0;
}
if(1==mNbDataPairs || x<getX(0))
{
return getY(0);
}
PxReal x0=getX(0);
PxReal y0=getY(0);
for(PxU32 i=1;i<mNbDataPairs;i++)
{
const PxReal x1=getX(i);
const PxReal y1=getY(i);
if((x>=x0)&&(x<x1))
{
return (y0+(y1-y0)*(x-x0)/(x1-x0));
}
x0=x1;
y0=y1;
}
PX_ASSERT(x>=getX(mNbDataPairs-1));
return getY(mNbDataPairs-1);
}
PxU32 getNbDataPairs() const {return mNbDataPairs;}
void clear()
{
PxMemSet(mDataPairs, 0, NB_ELEMENTS*2*sizeof(PxReal));
mNbDataPairs = 0;
}
PX_FORCE_INLINE PxReal getX(const PxU32 i) const
{
return mDataPairs[2*i];
}
PX_FORCE_INLINE PxReal getY(const PxU32 i) const
{
return mDataPairs[2*i+1];
}
PxReal mDataPairs[2*NB_ELEMENTS];
PxU32 mNbDataPairs;
PxU32 mPad[3];
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,75 @@
// 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 PX_INSERTION_CALLBACK_H
#define PX_INSERTION_CALLBACK_H
#include "common/PxBase.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Callback interface that permits TriangleMesh, Heightfield, ConvexMesh or BVH to be used
directly without the need to store the cooking results into a stream.
Using this is advised only if real-time cooking is required; using "offline" cooking and
streams is otherwise preferred.
The default PxInsertionCallback implementations must be used. The PxPhysics
default callback can be obtained using the PxPhysics::getPhysicsInsertionCallback().
The PxCooking default callback can be obtained using the PxCooking::getStandaloneInsertionCallback().
\see PxCooking PxPhysics
*/
class PxInsertionCallback
{
public:
PxInsertionCallback() {}
/**
\brief Builds object (TriangleMesh, Heightfield, ConvexMesh or BVH) from given data in PxPhysics.
\param type Object type to build.
\param data Object data
\return PxBase Created object in PxPhysics.
*/
virtual PxBase* buildObjectFromData(PxConcreteType::Enum type, void* data) = 0;
protected:
virtual ~PxInsertionCallback() {}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,126 @@
// 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 PX_PHYSX_COMMON_CONFIG_H
#define PX_PHYSX_COMMON_CONFIG_H
#include "foundation/PxSimpleTypes.h"
//Fills almost all allocated (host and device memory) with 0xcdcdcdcd (=3452816845)
#define PX_STOMP_ALLOCATED_MEMORY 0
/*Disable support for VS2017 prior version 15.5.1 for windows platform, because of a compiler bug:
https://developercommunity.visualstudio.com/content/problem/66047/possible-compiler-bug.html
*/
#if (PX_VC == 15) && PX_WINDOWS && (_MSC_FULL_VER < 191225830)
#error Visual studio 2017 prior to 15.5.1 is not supported because of a compiler bug.
#endif
// define API function declaration (public API only needed because of extensions)
#if defined PX_PHYSX_STATIC_LIB
#define PX_PHYSX_CORE_API
#else
#if PX_WINDOWS_FAMILY
#if defined PX_PHYSX_CORE_EXPORTS
#define PX_PHYSX_CORE_API __declspec(dllexport)
#else
#define PX_PHYSX_CORE_API __declspec(dllimport)
#endif
#elif PX_UNIX_FAMILY
#define PX_PHYSX_CORE_API PX_UNIX_EXPORT
#else
#define PX_PHYSX_CORE_API
#endif
#endif
#if PX_SUPPORT_GPU_PHYSX
// define API function declaration
#if defined PX_PHYSX_GPU_STATIC
#define PX_PHYSX_GPU_API
#else
#if PX_WINDOWS
#if defined PX_PHYSX_GPU_EXPORTS
#define PX_PHYSX_GPU_API __declspec(dllexport)
#else
#define PX_PHYSX_GPU_API __declspec(dllimport)
#endif
#elif PX_UNIX_FAMILY
#define PX_PHYSX_GPU_API PX_UNIX_EXPORT
#else
#define PX_PHYSX_GPU_API
#endif
#endif
#else // PX_SUPPORT_GPU_PHYSX
#define PX_PHYSX_GPU_API
#endif // PX_SUPPORT_GPU_PHYSX
#if defined PX_PHYSX_STATIC_LIB
#define PX_PHYSX_COMMON_API
#else
#if PX_WINDOWS_FAMILY && !PX_CUDA_COMPILER
#if defined PX_PHYSX_COMMON_EXPORTS
#define PX_PHYSX_COMMON_API __declspec(dllexport)
#else
#define PX_PHYSX_COMMON_API __declspec(dllimport)
#endif
#elif PX_UNIX_FAMILY
#define PX_PHYSX_COMMON_API PX_UNIX_EXPORT
#else
#define PX_PHYSX_COMMON_API
#endif
#endif
// PT: typical "invalid" value in various CD algorithms
#define PX_INVALID_U32 0xffffffff
#define PX_INVALID_U16 0xffff
// Changing these parameters requires recompilation of the SDK
// Enable debug visualization
#define PX_ENABLE_DEBUG_VISUALIZATION 1
#define PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION
// Enable simulation statistics generation
#define PX_ENABLE_SIM_STATS 1
#define PX_CATCH_UNDEFINED_ENABLE_SIM_STATS
#if !PX_DOXYGEN
namespace physx
{
#endif
typedef PxU32 PxTriangleID;
typedef PxU16 PxMaterialTableIndex;
typedef PxU16 PxDeformableMaterialTableIndex;
typedef PX_DEPRECATED PxU16 PxFEMMaterialTableIndex;
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,56 @@
// 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.
#ifndef PX_PROFILE_ZONE_H
#define PX_PROFILE_ZONE_H
#include "foundation/PxProfiler.h"
#include "foundation/PxFoundation.h"
#if PX_DEBUG || PX_CHECKED || PX_PROFILE
#define PX_PROFILE_ZONE(x, y) \
physx::PxProfileScoped PX_CONCAT(_scoped, __LINE__)(PxGetProfilerCallback(), x, false, y)
#define PX_PROFILE_START_CROSSTHREAD(x, y) \
if(PxGetProfilerCallback()) \
PxGetProfilerCallback()->zoneStart(x, true, y)
#define PX_PROFILE_STOP_CROSSTHREAD(x, y) \
if(PxGetProfilerCallback()) \
PxGetProfilerCallback()->zoneEnd(NULL, x, true, y)
#define PX_PROFILE_VALUE(x, y, z) \
if(PxGetProfilerCallback()) \
PxGetProfilerCallback()->recordData(x, y, z)
#define PX_PROFILE_FRAME(x, y) \
if(PxGetProfilerCallback()) \
PxGetProfilerCallback()->recordFrame(x, y)
#else
#define PX_PROFILE_ZONE(x, y)
#define PX_PROFILE_START_CROSSTHREAD(x, y)
#define PX_PROFILE_STOP_CROSSTHREAD(x, y)
#define PX_PROFILE_VALUE(x, y, z)
#define PX_PROFILE_FRAME(x, y)
#endif
#endif

View File

@@ -0,0 +1,163 @@
// 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 PX_RENDER_BUFFER_H
#define PX_RENDER_BUFFER_H
#include "common/PxPhysXCommonConfig.h"
#include "foundation/PxVec3.h"
#include "foundation/PxMat33.h"
#include "foundation/PxBounds3.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Default color values used for debug rendering.
*/
struct PxDebugColor
{
enum Enum
{
eARGB_BLACK = 0xff000000,
eARGB_RED = 0xffff0000,
eARGB_GREEN = 0xff00ff00,
eARGB_BLUE = 0xff0000ff,
eARGB_YELLOW = 0xffffff00,
eARGB_MAGENTA = 0xffff00ff,
eARGB_CYAN = 0xff00ffff,
eARGB_WHITE = 0xffffffff,
eARGB_GREY = 0xff808080,
eARGB_DARKRED = 0xff880000,
eARGB_DARKGREEN = 0xff008800,
eARGB_DARKBLUE = 0xff000088
};
};
/**
\brief Used to store a single point and colour for debug rendering.
*/
struct PxDebugPoint
{
PxDebugPoint(const PxVec3& p, const PxU32& c)
: pos(p), color(c) {}
PxVec3 pos;
PxU32 color;
};
/**
\brief Used to store a single line and colour for debug rendering.
*/
struct PxDebugLine
{
PxDebugLine(const PxVec3& p0, const PxVec3& p1, const PxU32& c)
: pos0(p0), color0(c), pos1(p1), color1(c) {}
PxVec3 pos0;
PxU32 color0;
PxVec3 pos1;
PxU32 color1;
};
/**
\brief Used to store a single triangle and colour for debug rendering.
*/
struct PxDebugTriangle
{
PxDebugTriangle(const PxVec3& p0, const PxVec3& p1, const PxVec3& p2, const PxU32& c)
: pos0(p0), color0(c), pos1(p1), color1(c), pos2(p2), color2(c) {}
PxVec3 pos0;
PxU32 color0;
PxVec3 pos1;
PxU32 color1;
PxVec3 pos2;
PxU32 color2;
};
/**
\brief Used to store a text for debug rendering. Doesn't own 'string' array.
*/
struct PxDebugText
{
PxDebugText() : string(0)
{
}
PxDebugText(const PxVec3& pos, const PxReal& sz, const PxU32& clr, const char* str)
: position(pos), size(sz), color(clr), string(str)
{
}
PxVec3 position;
PxReal size;
PxU32 color;
const char* string;
};
/**
\brief Interface for points, lines, triangles, and text buffer.
*/
class PxRenderBuffer
{
public:
virtual ~PxRenderBuffer() {}
virtual PxU32 getNbPoints() const = 0;
virtual const PxDebugPoint* getPoints() const = 0;
virtual void addPoint(const PxDebugPoint& point) = 0;
virtual PxU32 getNbLines() const = 0;
virtual const PxDebugLine* getLines() const = 0;
virtual void addLine(const PxDebugLine& line) = 0;
virtual PxDebugLine* reserveLines(const PxU32 nbLines) = 0;
virtual PxDebugPoint* reservePoints(const PxU32 nbLines) = 0;
virtual PxU32 getNbTriangles() const = 0;
virtual const PxDebugTriangle* getTriangles() const = 0;
virtual void addTriangle(const PxDebugTriangle& triangle) = 0;
virtual void append(const PxRenderBuffer& other) = 0;
virtual void clear() = 0;
virtual void shift(const PxVec3& delta) = 0;
virtual bool empty() const = 0;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,404 @@
// 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 PX_RENDER_OUTPUT_H
#define PX_RENDER_OUTPUT_H
#include "foundation/PxMat44.h"
#include "foundation/PxBasicTemplates.h"
#include "PxRenderBuffer.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if PX_VC
#pragma warning(push)
#pragma warning( disable : 4251 ) // class needs to have dll-interface to be used by clients of class
#endif
/**
Output stream to fill RenderBuffer
*/
class PxRenderOutput
{
public:
enum Primitive
{
POINTS,
LINES,
LINESTRIP,
TRIANGLES,
TRIANGLESTRIP
};
PxRenderOutput(PxRenderBuffer& buffer)
: mPrim(POINTS),
mColor(0),
mVertex0(0.0f),
mVertex1(0.0f),
mVertexCount(0),
mTransform(PxIdentity),
mBuffer(buffer)
{
}
PX_INLINE PxRenderOutput& operator<<(Primitive prim);
PX_INLINE PxRenderOutput& operator<<(PxU32 color) ;
PX_INLINE PxRenderOutput& operator<<(const PxMat44& transform);
PX_INLINE PxRenderOutput& operator<<(const PxTransform& t);
PX_INLINE PxRenderOutput& operator<<(const PxVec3& vertex);
PX_INLINE PxDebugLine* reserveSegments(PxU32 nbSegments);
PX_INLINE PxDebugPoint* reservePoints(PxU32 nbSegments);
PX_INLINE void outputSegment(const PxVec3& v0, const PxVec3& v1);
PX_INLINE PxRenderOutput& outputCapsule(PxF32 radius, PxF32 halfHeight, const PxMat44& absPose);
private:
PxRenderOutput& operator=(const PxRenderOutput&);
Primitive mPrim;
PxU32 mColor;
PxVec3 mVertex0, mVertex1;
PxU32 mVertexCount;
PxMat44 mTransform;
PxRenderBuffer& mBuffer;
};
struct PxDebugBox
{
explicit PxDebugBox(const PxVec3& extents, bool wireframe_ = true)
: minimum(-extents), maximum(extents), wireframe(wireframe_) {}
explicit PxDebugBox(const PxVec3& pos, const PxVec3& extents, bool wireframe_ = true)
: minimum(pos - extents), maximum(pos + extents), wireframe(wireframe_) {}
explicit PxDebugBox(const PxBounds3& bounds, bool wireframe_ = true)
: minimum(bounds.minimum), maximum(bounds.maximum), wireframe(wireframe_) {}
PxVec3 minimum, maximum;
bool wireframe;
};
PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugBox& box)
{
if (box.wireframe)
{
out << PxRenderOutput::LINESTRIP;
out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z);
out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z);
out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z);
out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z);
out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z);
out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z);
out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z);
out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z);
out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z);
out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z);
out << PxRenderOutput::LINES;
out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z);
out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z);
out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z);
out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z);
out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z);
out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z);
}
else
{
out << PxRenderOutput::TRIANGLESTRIP;
out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); // 0
out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); // 2
out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); // 1
out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z); // 3
out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); // 7
out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); // 2
out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); // 6
out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); // 0
out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); // 4
out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); // 1
out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z); // 5
out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); // 7
out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); // 4
out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); // 6
}
return out;
}
struct PxDebugArrow
{
PxDebugArrow(const PxVec3& pos, const PxVec3& vec)
: base(pos), tip(pos + vec), headLength(vec.magnitude()*0.15f) {}
PxDebugArrow(const PxVec3& pos, const PxVec3& vec, PxReal headLength_)
: base(pos), tip(pos + vec), headLength(headLength_) {}
PxVec3 base, tip;
PxReal headLength;
};
PX_FORCE_INLINE void normalToTangents(const PxVec3& normal, PxVec3& tangent0, PxVec3& tangent1)
{
tangent0 = PxAbs(normal.x) < 0.70710678f ? PxVec3(0, -normal.z, normal.y) : PxVec3(-normal.y, normal.x, 0);
tangent0.normalize();
tangent1 = normal.cross(tangent0);
}
PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArrow& arrow)
{
PxVec3 t0 = arrow.tip - arrow.base, t1, t2;
t0.normalize();
normalToTangents(t0, t1, t2);
const PxReal tipAngle = 0.25f;
t1 *= arrow.headLength * tipAngle;
t2 *= arrow.headLength * tipAngle * PxSqrt(3.0f);
PxVec3 headBase = arrow.tip - t0 * arrow.headLength;
out << PxRenderOutput::LINES;
out << arrow.base << arrow.tip;
out << PxRenderOutput::TRIANGLESTRIP;
out << arrow.tip;
out << headBase + t1 + t1;
out << headBase - t1 - t2;
out << headBase - t1 + t2;
out << arrow.tip;
out << headBase + t1 + t1;
return out;
}
struct PxDebugBasis
{
PxDebugBasis(const PxVec3& ext, PxU32 cX = PxU32(PxDebugColor::eARGB_RED),
PxU32 cY = PxU32(PxDebugColor::eARGB_GREEN), PxU32 cZ = PxU32(PxDebugColor::eARGB_BLUE))
: extends(ext), colorX(cX), colorY(cY), colorZ(cZ) {}
PxVec3 extends;
PxU32 colorX, colorY, colorZ;
};
PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugBasis& basis)
{
const PxReal headLength = basis.extends.magnitude() * 0.15f;
out << basis.colorX << PxDebugArrow(PxVec3(0.0f), PxVec3(basis.extends.x, 0, 0), headLength);
out << basis.colorY << PxDebugArrow(PxVec3(0.0f), PxVec3(0, basis.extends.y, 0), headLength);
out << basis.colorZ << PxDebugArrow(PxVec3(0.0f), PxVec3(0, 0, basis.extends.z), headLength);
return out;
}
struct PxDebugCircle
{
PxDebugCircle(PxU32 s, PxReal r)
: nSegments(s), radius(r) {}
PxU32 nSegments;
PxReal radius;
};
PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugCircle& circle)
{
const PxF32 step = PxTwoPi / PxF32(circle.nSegments);
PxF32 angle = 0;
out << PxRenderOutput::LINESTRIP;
for (PxU32 i = 0; i < circle.nSegments; i++, angle += step)
out << PxVec3(circle.radius * PxSin(angle), circle.radius * PxCos(angle), 0);
out << PxVec3(0, circle.radius, 0);
return out;
}
struct PxDebugArc
{
PxDebugArc(PxU32 s, PxReal r, PxReal minAng, PxReal maxAng)
: nSegments(s), radius(r), minAngle(minAng), maxAngle(maxAng) {}
PxU32 nSegments;
PxReal radius;
PxReal minAngle, maxAngle;
};
PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArc& arc)
{
const PxF32 step = (arc.maxAngle - arc.minAngle) / PxF32(arc.nSegments);
PxF32 angle = arc.minAngle;
out << PxRenderOutput::LINESTRIP;
for (PxU32 i = 0; i < arc.nSegments; i++, angle += step)
out << PxVec3(arc.radius * PxSin(angle), arc.radius * PxCos(angle), 0);
out << PxVec3(arc.radius * PxSin(arc.maxAngle), arc.radius * PxCos(arc.maxAngle), 0);
return out;
}
PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(Primitive prim)
{
mPrim = prim;
mVertexCount = 0;
return *this;
}
PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(PxU32 color)
{
mColor = color;
return *this;
}
PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxMat44& transform)
{
mTransform = transform;
return *this;
}
PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxTransform& t)
{
mTransform = PxMat44(t);
return *this;
}
PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxVec3& vertexIn)
{
// apply transformation
const PxVec3 vertex = mTransform.transform(vertexIn);
++mVertexCount;
// add primitive to render buffer
switch (mPrim)
{
case POINTS:
mBuffer.addPoint(PxDebugPoint(vertex, mColor)); break;
case LINES:
if (mVertexCount == 2)
{
mBuffer.addLine(PxDebugLine(mVertex0, vertex, mColor));
mVertexCount = 0;
}
break;
case LINESTRIP:
if (mVertexCount >= 2)
mBuffer.addLine(PxDebugLine(mVertex0, vertex, mColor));
break;
case TRIANGLES:
if (mVertexCount == 3)
{
mBuffer.addTriangle(PxDebugTriangle(mVertex1, mVertex0, vertex, mColor));
mVertexCount = 0;
}
break;
case TRIANGLESTRIP:
if (mVertexCount >= 3)
mBuffer.addTriangle(PxDebugTriangle(
(mVertexCount & 0x1) ? mVertex0 : mVertex1,
(mVertexCount & 0x1) ? mVertex1 : mVertex0, vertex, mColor));
break;
}
// cache the last 2 vertices (for strips)
if (1 < mVertexCount)
{
mVertex1 = mVertex0;
mVertex0 = vertex;
}
else
{
mVertex0 = vertex;
}
return *this;
}
PX_INLINE PxDebugLine* PxRenderOutput::reserveSegments(PxU32 nbSegments)
{
return mBuffer.reserveLines(nbSegments);
}
PX_INLINE PxDebugPoint* PxRenderOutput::reservePoints(PxU32 nbPoints)
{
return mBuffer.reservePoints(nbPoints);
}
// PT: using the operators is just too slow.
PX_INLINE void PxRenderOutput::outputSegment(const PxVec3& v0, const PxVec3& v1)
{
PxDebugLine* segment = mBuffer.reserveLines(1);
segment->pos0 = v0;
segment->pos1 = v1;
segment->color0 = segment->color1 = mColor;
}
PX_INLINE PxRenderOutput& PxRenderOutput::outputCapsule(PxF32 radius, PxF32 halfHeight, const PxMat44& absPose)
{
PxRenderOutput& out = *this;
const PxVec3 vleft2(-halfHeight, 0.0f, 0.0f);
PxMat44 left2 = absPose;
left2.column3 += PxVec4(left2.rotate(vleft2), 0.0f);
out << left2 << PxDebugArc(100, radius, PxPi, PxTwoPi);
PxMat44 rotPose = left2;
PxSwap(rotPose.column1, rotPose.column2);
rotPose.column1 = -rotPose.column1;
out << rotPose << PxDebugArc(100, radius, PxPi, PxTwoPi);
PxSwap(rotPose.column0, rotPose.column2);
rotPose.column0 = -rotPose.column0;
out << rotPose << PxDebugCircle(100, radius);
const PxVec3 vright2(halfHeight, 0.0f, 0.0f);
PxMat44 right2 = absPose;
right2.column3 += PxVec4(right2.rotate(vright2), 0.0f);
out << right2 << PxDebugArc(100, radius, 0.0f, PxPi);
rotPose = right2;
PxSwap(rotPose.column1, rotPose.column2);
rotPose.column1 = -rotPose.column1;
out << rotPose << PxDebugArc(100, radius, 0.0f, PxPi);
PxSwap(rotPose.column0, rotPose.column2);
rotPose.column0 = -rotPose.column0;
out << rotPose << PxDebugCircle(100, radius);
out << absPose;
out.outputSegment(absPose.transform(PxVec3(-halfHeight, radius, 0)),
absPose.transform(PxVec3(halfHeight, radius, 0)));
out.outputSegment(absPose.transform(PxVec3(-halfHeight, -radius, 0)),
absPose.transform(PxVec3(halfHeight, -radius, 0)));
out.outputSegment(absPose.transform(PxVec3(-halfHeight, 0, radius)),
absPose.transform(PxVec3(halfHeight, 0, radius)));
out.outputSegment(absPose.transform(PxVec3(-halfHeight, 0, -radius)),
absPose.transform(PxVec3(halfHeight, 0, -radius)));
return *this;
}
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,385 @@
// 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 PX_SERIAL_FRAMEWORK_H
#define PX_SERIAL_FRAMEWORK_H
#include "common/PxPhysXCommonConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
#if !PX_DOXYGEN // need to exclude, confuses api doc build about duplicate declaration
typedef PxU16 PxType;
#endif
class PxBase;
class PxSerializationContext;
class PxRepXSerializer;
class PxSerializer;
class PxPhysics;
class PxCollection;
class PxOutputStream;
//! Default serialization alignment
#define PX_SERIAL_ALIGN 16
//! Serialized input data must be aligned to this value
#define PX_SERIAL_FILE_ALIGN 128
//! PxSerialObjectId value for objects that do not have an ID
#define PX_SERIAL_OBJECT_ID_INVALID 0
//! ID type for PxBase objects in a PxCollection
typedef PxU64 PxSerialObjectId;
//! Bit to mark pointer type references, \see PxDeserializationContext
#define PX_SERIAL_REF_KIND_PTR_TYPE_BIT (1u<<31)
//! Reference kind value for PxBase objects
#define PX_SERIAL_REF_KIND_PXBASE (0 | PX_SERIAL_REF_KIND_PTR_TYPE_BIT)
//! Reference kind value for material indices
#define PX_SERIAL_REF_KIND_MATERIAL_IDX (1)
//! Used to fix multi-byte characters warning from gcc for situations like: PxU32 foo = 'CCTS';
#define PX_MAKE_FOURCC(a, b, c, d) ( (a) | ((b)<<8) | ((c)<<16) | ((d)<<24) )
/**
\brief Callback class used to process PxBase objects.
\see PxSerializer::requires
*/
class PxProcessPxBaseCallback
{
public:
virtual ~PxProcessPxBaseCallback() {}
virtual void process(PxBase&) = 0;
};
/**
\brief Binary serialization context class.
This class is used to register reference values and write object
and object extra data during serialization.
It is mainly used by the serialization framework. Except for custom
serializable types, users should not have to worry about it.
\see PxDeserializationContext
*/
class PxSerializationContext
{
public:
/**
\brief Registers a reference value corresponding to a PxBase object.
This method is assumed to be called in the implementation of PxSerializer::registerReferences for serialized
references that need to be resolved on deserialization.
A reference needs to be associated with exactly one PxBase object in either the collection or the
external references collection.
Different kinds of references are supported and need to be specified. In the most common case
(PX_SERIAL_REF_KIND_PXBASE) the PxBase object matches the reference value (which is the pointer
to the PxBase object). Integer references maybe registered as well (used for internal material
indices with PX_SERIAL_REF_KIND_MATERIAL_IDX). Other kinds could be added with the restriction that
for pointer types the kind value needs to be marked with the PX_SERIAL_REF_KIND_PTR_TYPE_BIT.
\param[in] base PxBase object associated with the reference
\param[in] kind What kind of reference this is (PX_SERIAL_REF_KIND_PXBASE, PX_SERIAL_REF_KIND_MATERIAL_IDX or custom kind)
\param[in] reference Value of reference
\see PxDeserializationContext::resolveReference, PX_SERIAL_REF_KIND_PXBASE, PX_SERIAL_REF_KIND_MATERIAL_IDX, PxSerializer::registerReferences
*/
virtual void registerReference(PxBase& base, PxU32 kind, size_t reference) = 0;
/**
\brief Returns the collection that is being serialized.
*/
virtual const PxCollection& getCollection() const = 0;
/**
\brief Serializes object data and object extra data.
This function is assumed to be called within the implementation of PxSerializer::exportData and PxSerializer::exportExtraData.
\see PxSerializer::exportData, PxSerializer::exportExtraData, PxSerializer::createObject, PxDeserializationContext::readExtraData
*/
virtual void writeData(const void* data, PxU32 size) = 0;
/**
\brief Aligns the serialized data.
This function is assumed to be called within the implementation of PxSerializer::exportData and PxSerializer::exportExtraData.
\see PxSerializer::exportData, PxSerializer::exportExtraData, PxDeserializationContext::alignExtraData
*/
virtual void alignData(PxU32 alignment = PX_SERIAL_ALIGN) = 0;
/**
\brief Helper function to write a name to the extraData if serialization is configured to save names.
This function is assumed to be called within the implementation of PxSerializer::exportExtraData.
\see PxSerialization::serializeCollectionToBinary, PxDeserializationContext::readName
*/
virtual void writeName(const char* name) = 0;
protected:
PxSerializationContext() {}
virtual ~PxSerializationContext() {}
};
/**
\brief Binary deserialization context class.
This class is used to resolve references and access extra data during deserialization.
It is mainly used by the serialization framework. Except for custom
serializable types, users should not have to worry about it.
\see PxSerializationContext
*/
class PxDeserializationContext
{
public:
/**
\brief Retrieves a pointer to a deserialized PxBase object given a corresponding deserialized reference value
This method is assumed to be called in the implementation of PxSerializer::createObject in order
to update reference values on deserialization.
To update a PxBase reference the corresponding deserialized pointer value needs to be provided in order to retrieve
the location of the corresponding deserialized PxBase object. (PxDeserializationContext::translatePxBase simplifies
this common case).
For other kinds of references the reverence values need to be updated by deduction given the corresponding PxBase instance.
\param[in] kind What kind of reference this is (PX_SERIAL_REF_KIND_PXBASE, PX_SERIAL_REF_KIND_MATERIAL_IDX or custom kind)
\param[in] reference Deserialized reference value
\return PxBase object associated with the reference value
\see PxSerializationContext::registerReference, PX_SERIAL_REF_KIND_PXBASE, PX_SERIAL_REF_KIND_MATERIAL_IDX, translatePxBase
*/
virtual PxBase* resolveReference(PxU32 kind, size_t reference) const = 0;
/**
\brief Helper function to update PxBase pointer on deserialization
\see resolveReference, PX_SERIAL_REF_KIND_PXBASE
*/
template<typename T>
void translatePxBase(T*& base) { if (base) { base = static_cast<T*>(resolveReference(PX_SERIAL_REF_KIND_PXBASE, size_t(base))); } }
/**
\brief Helper function to read a name from the extra data during deserialization.
This function is assumed to be called within the implementation of PxSerializer::createObject.
\see PxSerializationContext::writeName
*/
PX_INLINE void readName(const char*& name)
{
PxU32 len = *reinterpret_cast<PxU32*>(mExtraDataAddress);
mExtraDataAddress += sizeof(len);
name = len ? reinterpret_cast<const char*>(mExtraDataAddress) : NULL;
mExtraDataAddress += len;
}
/**
\brief Function to read extra data during deserialization.
This function is assumed to be called within the implementation of PxSerializer::createObject.
\see PxSerializationContext::writeData, PxSerializer::createObject
*/
template<typename T>
PX_INLINE T* readExtraData(PxU32 count=1)
{
T* data = reinterpret_cast<T*>(mExtraDataAddress);
mExtraDataAddress += sizeof(T)*count;
return data;
}
/**
\brief Function to read extra data during deserialization optionally aligning the extra data stream before reading.
This function is assumed to be called within the implementation of PxSerializer::createObject.
\see PxSerializationContext::writeData, PxDeserializationContext::alignExtraData, PxSerializer::createObject
*/
template<typename T, PxU32 alignment>
PX_INLINE T* readExtraData(PxU32 count=1)
{
alignExtraData(alignment);
return readExtraData<T>(count);
}
/**
\brief Function to align the extra data stream to a power of 2 alignment
This function is assumed to be called within the implementation of PxSerializer::createObject.
\see PxSerializationContext::alignData, PxSerializer::createObject
*/
PX_INLINE void alignExtraData(PxU32 alignment = PX_SERIAL_ALIGN)
{
size_t addr = size_t(mExtraDataAddress);
addr = (addr+alignment-1)&~size_t(alignment-1);
mExtraDataAddress = reinterpret_cast<PxU8*>(addr);
}
protected:
PxDeserializationContext() {}
virtual ~PxDeserializationContext() {}
PxU8* mExtraDataAddress;
};
/**
\brief Class serving as a registry for XML (RepX) and binary serializable types.
In order to serialize and deserialize objects the application needs
to maintain an instance of this class. It can be created with
PxSerialization::createSerializationRegistry() and released with
PxSerializationRegistry::release().
\see PxSerialization::createSerializationRegistry
*/
class PxSerializationRegistry
{
public:
/************************************************************************************************/
/** \name Binary Serialization Functionality
*/
//\{
/**
\brief Register a serializer for a concrete type
\param type PxConcreteType corresponding to the serializer
\param serializer The PxSerializer to be registered
\see PxConcreteType, PxSerializer, PxSerializationRegistry::unregisterSerializer
*/
virtual void registerSerializer(PxType type, PxSerializer& serializer) = 0;
/**
\brief Unregister a serializer for a concrete type, and retrieves the corresponding serializer object.
\param type PxConcreteType for which the serializer should be unregistered
\return Unregistered serializer corresponding to type, NULL for types for which no serializer has been registered.
\see PxConcreteType, PxSerializationRegistry::registerSerializer, PxSerializationRegistry::release
*/
virtual PxSerializer* unregisterSerializer(PxType type) = 0;
/**
\brief Returns PxSerializer corresponding to type
\param type PxConcreteType of the serializer requested.
\return Registered PxSerializer object corresponding to type
\see PxConcreteType
*/
virtual const PxSerializer* getSerializer(PxType type) const = 0;
//\}
/************************************************************************************************/
/** \name RepX (XML) Serialization Functionality
*/
//\{
/**
\brief Register a RepX serializer for a concrete type
\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics.
\param type PxConcreteType corresponding to the RepX serializer
\param serializer The PxRepXSerializer to be registered
\see PxConcreteType, PxRepXSerializer
*/
PX_DEPRECATED virtual void registerRepXSerializer(PxType type, PxRepXSerializer& serializer) = 0;
/**
\brief Unregister a RepX serializer for a concrete type, and retrieves the corresponding serializer object.
\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics.
\param type PxConcreteType for which the RepX serializer should be unregistered
\return Unregistered PxRepxSerializer corresponding to type, NULL for types for which no RepX serializer has been registered.
\see PxConcreteType, PxSerializationRegistry::registerRepXSerializer, PxSerializationRegistry::release
*/
PX_DEPRECATED virtual PxRepXSerializer* unregisterRepXSerializer(PxType type) = 0;
/**
\brief Returns RepX serializer given the corresponding type name
\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics.
\param typeName Name of the type
\return Registered PxRepXSerializer object corresponding to type name
\see PxRepXSerializer, PxTypeInfo, PX_DEFINE_TYPEINFO
*/
PX_DEPRECATED virtual PxRepXSerializer* getRepXSerializer(const char* typeName) const = 0;
//\}
/************************************************************************************************/
/**
\brief Releases PxSerializationRegistry instance.
This unregisters all PhysX and PhysXExtension serializers. Make sure to unregister all custom type
serializers before releasing the PxSerializationRegistry.
\see PxSerializationRegistry::unregisterSerializer, PxSerializationRegistry::unregisterRepXSerializer
*/
virtual void release() = 0;
protected:
virtual ~PxSerializationRegistry(){}
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,259 @@
// 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 PX_SERIALIZER_H
#define PX_SERIALIZER_H
#include "foundation/PxAssert.h"
#include "foundation/PxAllocatorCallback.h"
#include "foundation/PxFoundation.h"
#include "common/PxSerialFramework.h"
#include "common/PxCollection.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Serialization interface class.
PxSerializer is used to extend serializable PxBase classes with serialization functionality. The
interface is structured such that per-class adapter instances can be used as opposed to per-object
adapter instances, avoiding per object allocations. Hence the methods take a reference to PxBase as a parameter.
The PxSerializer interface needs to be implemented for binary or RepX serialization to work on custom
types. If only RepX serialization is needed, some methods can be left empty, as they are only needed
for binary serialization.
A default implementation is available as a template adapter (PxSerializerDefaultAdapter).
\see PxSerializerDefaultAdapter, PX_NEW_SERIALIZER_ADAPTER, PxSerializationRegistry::registerSerializer
*/
class PxSerializer
{
public:
/**********************************************************************************************************************/
/** \name Basics needed for Binary- and RepX-Serialization
*/
//\{
/**
\brief Returns string name of dynamic type.
\return Class name of most derived type of this object.
*/
virtual const char* getConcreteTypeName() const = 0;
/**
\brief Adds required objects to the collection.
This method does not add the required objects recursively, e.g. objects required by required objects.
\see PxCollection, PxSerialization::complete
*/
virtual void requiresObjects(PxBase&, PxProcessPxBaseCallback&) const = 0;
/**
\brief Whether the object is subordinate.
A class is subordinate, if it can only be instantiated in the context of another class.
\return Whether the class is subordinate
\see PxSerialization::isSerializable
*/
virtual bool isSubordinate() const = 0;
//\}
/**********************************************************************************************************************/
/**********************************************************************************************************************/
/** \name Functionality needed for Binary Serialization only
*/
//\{
/**
\brief Exports object's extra data to stream.
*/
virtual void exportExtraData(PxBase&, PxSerializationContext&) const = 0;
/**
\brief Exports object's data to stream.
*/
virtual void exportData(PxBase&, PxSerializationContext&) const = 0;
/**
\brief Register references that the object maintains to other objects.
*/
virtual void registerReferences(PxBase& obj, PxSerializationContext& s) const = 0;
/**
\brief Returns size needed to create the class instance.
\return sizeof class instance.
*/
virtual size_t getClassSize() const = 0;
/**
\brief Create object at a given address, resolve references and import extra data.
\param address Location at which object is created. Address is increased by the size of the created object.
\param context Context for reading external data and resolving references.
\return Created PxBase pointer (needs to be identical to address before increment).
*/
virtual PxBase* createObject(PxU8*& address, PxDeserializationContext& context) const = 0;
//\}
/**********************************************************************************************************************/
virtual ~PxSerializer() {}
};
/**
\brief Default PxSerializer implementation.
*/
template<class T>
class PxSerializerDefaultAdapter : public PxSerializer
{
public:
/************************************************************************************************/
/** \name Basics needed for Binary- and RepX-Serialization
*/
//\{
PxSerializerDefaultAdapter(const char* name) : mTypeName(name){}
virtual const char* getConcreteTypeName() const
{
return mTypeName;
}
virtual void requiresObjects(PxBase& obj, PxProcessPxBaseCallback& c) const
{
T& t = static_cast<T&>(obj);
t.requiresObjects(c);
}
virtual bool isSubordinate() const
{
return false;
}
//\}
/************************************************************************************************/
/** \name Functionality needed for Binary Serialization only
*/
//\{
// object methods
virtual void exportExtraData(PxBase& obj, PxSerializationContext& s) const
{
T& t = static_cast<T&>(obj);
t.exportExtraData(s);
}
virtual void exportData(PxBase& obj, PxSerializationContext& s) const
{
PxAllocatorCallback& allocator = *PxGetAllocatorCallback();
T* copy = reinterpret_cast<T*>(allocator.allocate(sizeof(T), "TmpAllocExportData", PX_FL));
PxMemCopy(copy, &obj, sizeof(T));
copy->preExportDataReset();
s.writeData(copy, sizeof(T));
allocator.deallocate(copy);
}
virtual void registerReferences(PxBase& obj, PxSerializationContext& s) const
{
T& t = static_cast<T&>(obj);
s.registerReference(obj, PX_SERIAL_REF_KIND_PXBASE, size_t(&obj));
struct RequiresCallback : public PxProcessPxBaseCallback
{
RequiresCallback(PxSerializationContext& c) : context(c) {}
RequiresCallback& operator=(RequiresCallback&) { PX_ASSERT(0); return *this; }
void process(physx::PxBase& base)
{
context.registerReference(base, PX_SERIAL_REF_KIND_PXBASE, size_t(&base));
}
PxSerializationContext& context;
};
RequiresCallback callback(s);
t.requiresObjects(callback);
}
// class methods
virtual size_t getClassSize() const
{
return sizeof(T);
}
virtual PxBase* createObject(PxU8*& address, PxDeserializationContext& context) const
{
return T::createObject(address, context);
}
//\}
/************************************************************************************************/
private:
const char* mTypeName;
};
/**
\brief Preprocessor Macro to simplify adapter creation.
Note: that the allocator used for creation needs to match with the one used in PX_DELETE_SERIALIZER_ADAPTER.
*/
#define PX_NEW_SERIALIZER_ADAPTER(x) \
*new( PxGetAllocatorCallback()->allocate(sizeof(PxSerializerDefaultAdapter<x>), \
"PxSerializerDefaultAdapter", PX_FL)) PxSerializerDefaultAdapter<x>(#x)
/**
\brief Preprocessor Macro to simplify adapter deletion.
*/
#define PX_DELETE_SERIALIZER_ADAPTER(x) \
{ PxSerializer* s = x; if (s) { s->~PxSerializer(); PxGetAllocatorCallback()->deallocate(s); } }
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,67 @@
// 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 PX_STRING_TABLE_H
#define PX_STRING_TABLE_H
#include "foundation/PxPreprocessor.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
* \brief a table to manage strings. Strings allocated through this object are expected to be owned by this object.
*/
class PxStringTable
{
protected:
virtual ~PxStringTable(){}
public:
/**
* \brief Allocate a new string.
*
* \param[in] inSrc Source string, null terminated or null.
*
* \return *Always* a valid null terminated string. "" is returned if "" or null is passed in.
*/
virtual const char* allocateStr( const char* inSrc ) = 0;
/**
* Release the string table and all the strings associated with it.
*/
virtual void release() = 0;
};
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,103 @@
// 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 PX_TOLERANCES_SCALE_H
#define PX_TOLERANCES_SCALE_H
#include "common/PxPhysXCommonConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief Class to define the scale at which simulation runs. Most simulation tolerances are
calculated in terms of the values here.
\note if you change the simulation scale, you will probably also wish to change the scene's
default value of gravity, and stable simulation will probably require changes to the scene's
bounceThreshold also.
*/
class PxTolerancesScale
{
public:
/**
\brief The approximate size of objects in the simulation.
For simulating roughly human-sized in metric units, 1 is a good choice.
If simulation is done in centimetres, use 100 instead. This is used to
estimate certain length-related tolerances.
*/
PxReal length;
/**
\brief The typical magnitude of velocities of objects in simulation. This is used to estimate
whether a contact should be treated as bouncing or resting based on its impact velocity,
and a kinetic energy threshold below which the simulation may put objects to sleep.
For normal physical environments, a good choice is the approximate speed of an object falling
under gravity for one second.
*/
PxReal speed;
/**
\brief constructor sets to default
\param[in] defaultLength Default length
\param[in] defaultSpeed Default speed
*/
PX_INLINE explicit PxTolerancesScale(float defaultLength=1.0f, float defaultSpeed=10.0f);
/**
\brief Returns true if the descriptor is valid.
\return true if the current settings are valid (returns always true).
*/
PX_INLINE bool isValid() const;
};
PX_INLINE PxTolerancesScale::PxTolerancesScale(float defaultLength, float defaultSpeed) :
length (defaultLength),
speed (defaultSpeed)
{
}
PX_INLINE bool PxTolerancesScale::isValid() const
{
return length>0.0f;
}
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,156 @@
// 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 PX_TYPE_INFO_H
#define PX_TYPE_INFO_H
#include "common/PxPhysXCommonConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief an enumeration of concrete classes inheriting from PxBase
Enumeration space is reserved for future PhysX core types, PhysXExtensions,
PhysXVehicle and Custom application types.
\see PxBase, PxTypeInfo
*/
struct PxConcreteType
{
enum Enum
{
eUNDEFINED,
eHEIGHTFIELD,
eCONVEX_MESH,
eTRIANGLE_MESH_BVH33 PX_DEPRECATED, //!< \deprecated Will be removed together with deprecated BVH33.
eTRIANGLE_MESH_BVH34,
eTETRAHEDRON_MESH,
eDEFORMABLE_VOLUME_MESH,
eSOFTBODY_MESH PX_DEPRECATED = eDEFORMABLE_VOLUME_MESH, //!< \deprecated
eRIGID_DYNAMIC,
eRIGID_STATIC,
eSHAPE,
eMATERIAL,
eDEFORMABLE_SURFACE_MATERIAL,
eDEFORMABLE_VOLUME_MATERIAL,
eSOFTBODY_MATERIAL PX_DEPRECATED = eDEFORMABLE_VOLUME_MATERIAL, //!< \deprecated
ePBD_MATERIAL,
eCONSTRAINT,
eAGGREGATE,
eARTICULATION_REDUCED_COORDINATE,
eARTICULATION_LINK,
eARTICULATION_JOINT_REDUCED_COORDINATE,
eARTICULATION_SPATIAL_TENDON,
eARTICULATION_FIXED_TENDON,
eARTICULATION_ATTACHMENT,
eARTICULATION_TENDON_JOINT,
eARTICULATION_MIMIC_JOINT,
ePRUNING_STRUCTURE,
eBVH,
eDEFORMABLE_VOLUME,
eSOFT_BODY PX_DEPRECATED = eDEFORMABLE_VOLUME, //!< \deprecated
eDEFORMABLE_VOLUME_STATE,
eSOFT_BODY_STATE PX_DEPRECATED = eDEFORMABLE_VOLUME_STATE, //!< \deprecated
ePBD_PARTICLESYSTEM,
eDEFORMABLE_SURFACE,
eDEFORMABLE_ATTACHMENT,
eDEFORMABLE_ELEMENT_FILTER,
ePARTICLE_BUFFER,
ePARTICLE_DIFFUSE_BUFFER,
ePARTICLE_CLOTH_BUFFER,
ePARTICLE_RIGID_BUFFER,
ePHYSX_CORE_COUNT,
eFIRST_PHYSX_EXTENSION = 256,
eFIRST_VEHICLE_EXTENSION = 512,
eFIRST_USER_EXTENSION = 1024
};
};
/**
\brief a structure containing per-type information for types inheriting from PxBase
\see PxBase, PxConcreteType
*/
template<typename T> struct PxTypeInfo {};
#define PX_DEFINE_TYPEINFO(_name, _fastType) \
class _name; \
template <> struct PxTypeInfo<_name> { static const char* name() { return #_name; } enum { eFastTypeId = _fastType }; };
/* the semantics of the fastType are as follows: an object A can be cast to a type B if B's fastType is defined, and A has the same fastType.
* This implies that B has no concrete subclasses or superclasses.
*/
PX_DEFINE_TYPEINFO(PxBase, PxConcreteType::eUNDEFINED)
PX_DEFINE_TYPEINFO(PxMaterial, PxConcreteType::eMATERIAL)
PX_DEFINE_TYPEINFO(PxDeformableSurfaceMaterial, PxConcreteType::eDEFORMABLE_SURFACE_MATERIAL)
PX_DEFINE_TYPEINFO(PxDeformableVolumeMaterial, PxConcreteType::eDEFORMABLE_VOLUME_MATERIAL)
PX_DEFINE_TYPEINFO(PxPBDMaterial, PxConcreteType::ePBD_MATERIAL)
PX_DEFINE_TYPEINFO(PxConvexMesh, PxConcreteType::eCONVEX_MESH)
PX_DEFINE_TYPEINFO(PxTriangleMesh, PxConcreteType::eUNDEFINED)
PX_DEFINE_TYPEINFO(PxBVH33TriangleMesh, PxConcreteType::eTRIANGLE_MESH_BVH33)
PX_DEFINE_TYPEINFO(PxBVH34TriangleMesh, PxConcreteType::eTRIANGLE_MESH_BVH34)
PX_DEFINE_TYPEINFO(PxTetrahedronMesh, PxConcreteType::eTETRAHEDRON_MESH)
PX_DEFINE_TYPEINFO(PxHeightField, PxConcreteType::eHEIGHTFIELD)
PX_DEFINE_TYPEINFO(PxActor, PxConcreteType::eUNDEFINED)
PX_DEFINE_TYPEINFO(PxRigidActor, PxConcreteType::eUNDEFINED)
PX_DEFINE_TYPEINFO(PxRigidBody, PxConcreteType::eUNDEFINED)
PX_DEFINE_TYPEINFO(PxRigidDynamic, PxConcreteType::eRIGID_DYNAMIC)
PX_DEFINE_TYPEINFO(PxRigidStatic, PxConcreteType::eRIGID_STATIC)
PX_DEFINE_TYPEINFO(PxArticulationLink, PxConcreteType::eARTICULATION_LINK)
PX_DEFINE_TYPEINFO(PxArticulationJointReducedCoordinate, PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE)
PX_DEFINE_TYPEINFO(PxArticulationReducedCoordinate, PxConcreteType::eARTICULATION_REDUCED_COORDINATE)
PX_DEFINE_TYPEINFO(PxAggregate, PxConcreteType::eAGGREGATE)
PX_DEFINE_TYPEINFO(PxConstraint, PxConcreteType::eCONSTRAINT)
PX_DEFINE_TYPEINFO(PxShape, PxConcreteType::eSHAPE)
PX_DEFINE_TYPEINFO(PxPruningStructure, PxConcreteType::ePRUNING_STRUCTURE)
PX_DEFINE_TYPEINFO(PxPBDParticleSystem, PxConcreteType::ePBD_PARTICLESYSTEM)
PX_DEFINE_TYPEINFO(PxDeformableSurface, PxConcreteType::eDEFORMABLE_SURFACE)
PX_DEFINE_TYPEINFO(PxDeformableVolume, PxConcreteType::eDEFORMABLE_VOLUME)
PX_DEFINE_TYPEINFO(PxDeformableAttachment, PxConcreteType::eDEFORMABLE_ATTACHMENT)
PX_DEFINE_TYPEINFO(PxDeformableElementFilter, PxConcreteType::eDEFORMABLE_ELEMENT_FILTER)
PX_DEFINE_TYPEINFO(PxParticleBuffer, PxConcreteType::ePARTICLE_BUFFER)
PX_DEFINE_TYPEINFO(PxParticleAndDiffuseBuffer, PxConcreteType::ePARTICLE_DIFFUSE_BUFFER)
PX_DEFINE_TYPEINFO(PxParticleClothBuffer, PxConcreteType::ePARTICLE_CLOTH_BUFFER)
PX_DEFINE_TYPEINFO(PxParticleRigidBuffer, PxConcreteType::ePARTICLE_RIGID_BUFFER)
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

View File

@@ -0,0 +1,96 @@
// 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 PX_WINDOWS_DELAY_LOAD_HOOK_H
#define PX_WINDOWS_DELAY_LOAD_HOOK_H
#include "foundation/PxPreprocessor.h"
#include "common/PxPhysXCommonConfig.h"
#if !PX_DOXYGEN
namespace physx
{
#endif
/**
\brief PxDelayLoadHook
This is a helper class for delay loading the PhysXCommon dll and PhysXFoundation dll.
If a PhysXCommon dll or PhysXFoundation dll with a non-default file name needs to be loaded,
PxDelayLoadHook can be sub-classed to provide the custom filenames.
Once the names are set, the instance must be set for use by PhysX.dll using PxSetPhysXDelayLoadHook(),
PhysXCooking.dll using PxSetPhysXCookingDelayLoadHook() or by PhysXCommon.dll using PxSetPhysXCommonDelayLoadHook().
\see PxSetPhysXDelayLoadHook(), PxSetPhysXCookingDelayLoadHook(), PxSetPhysXCommonDelayLoadHook()
*/
class PxDelayLoadHook
{
public:
PxDelayLoadHook() {}
virtual ~PxDelayLoadHook() {}
virtual const char* getPhysXFoundationDllName() const = 0;
virtual const char* getPhysXCommonDllName() const = 0;
protected:
private:
};
/**
\brief Sets delay load hook instance for PhysX dll.
\param[in] hook Delay load hook.
\see PxDelayLoadHook
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxSetPhysXDelayLoadHook(const physx::PxDelayLoadHook* hook);
/**
\brief Sets delay load hook instance for PhysXCooking dll.
\param[in] hook Delay load hook.
\see PxDelayLoadHook
*/
PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxSetPhysXCookingDelayLoadHook(const physx::PxDelayLoadHook* hook);
/**
\brief Sets delay load hook instance for PhysXCommon dll.
\param[in] hook Delay load hook.
\see PxDelayLoadHook
*/
PX_C_EXPORT PX_PHYSX_COMMON_API void PX_CALL_CONV PxSetPhysXCommonDelayLoadHook(const physx::PxDelayLoadHook* hook);
#if !PX_DOXYGEN
} // namespace physx
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More