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,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 DY_ARTICULATION_CORE_H
#define DY_ARTICULATION_CORE_H
#include "PxArticulationReducedCoordinate.h"
namespace physx
{
namespace Dy
{
struct ArticulationCore
{
// PX_SERIALIZATION
ArticulationCore(const PxEMPTY) : flags(PxEmpty) {}
ArticulationCore() {}
//~PX_SERIALIZATION
PxU16 solverIterationCounts; //KS - made a U16 so that it matches PxsRigidCore
PxArticulationFlags flags;
PxReal sleepThreshold;
PxReal freezeThreshold;
PxReal wakeCounter;
PxU32 gpuRemapIndex;
};
}
}
#endif

View File

@@ -0,0 +1,278 @@
// 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 DY_ARTICULATION_JOINT_CORE_H
#define DY_ARTICULATION_JOINT_CORE_H
#include "DyArticulationCore.h"
#include "solver/PxSolverDefs.h"
#include "PxArticulationJointReducedCoordinate.h"
#include "CmSpatialVector.h"
namespace physx
{
namespace Dy
{
// PT: avoid some multiplies when immediately normalizing a rotated vector
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 rotateAndNormalize(const PxQuat& q, const PxVec3& v)
{
const float vx = v.x;
const float vy = v.y;
const float vz = v.z;
const float x = q.x;
const float y = q.y;
const float z = q.z;
const float w = q.w;
const float w2 = w * w - 0.5f;
const float dot2 = (x * vx + y * vy + z * vz);
const PxVec3 rotated( (vx * w2 + (y * vz - z * vy) * w + x * dot2),
(vy * w2 + (z * vx - x * vz) * w + y * dot2),
(vz * w2 + (x * vy - y * vx) * w + z * dot2));
return rotated.getNormalized();
}
class ArticulationJointCoreData;
PX_ALIGN_PREFIX(16)
struct ArticulationJointCore
{
public:
// PX_SERIALIZATION
ArticulationJointCore(const PxEMPTY&) : drives{ PxArticulationDrive(PxEmpty),
PxArticulationDrive(PxEmpty),
PxArticulationDrive(PxEmpty),
PxArticulationDrive(PxEmpty),
PxArticulationDrive(PxEmpty),
PxArticulationDrive(PxEmpty) }, jCalcUpdateFrames(false)
{
PX_COMPILE_TIME_ASSERT(sizeof(PxArticulationMotions) == sizeof(PxU8));
}
//~PX_SERIALIZATION
ArticulationJointCore(const PxTransform& parentFrame, const PxTransform& childFrame)
{
//PxMarkSerializedMemory(this, sizeof(ArticulationJointCore));
init(parentFrame, childFrame);
}
// PT: these ones don't update the dirty flags
PX_FORCE_INLINE void setLimit(PxArticulationAxis::Enum axis, const PxArticulationLimit& limit) { limits[axis] = limit; }
PX_FORCE_INLINE void setDrive(PxArticulationAxis::Enum axis, const PxArticulationDrive& drive) { drives[axis] = drive; }
PX_FORCE_INLINE void setJointType(PxArticulationJointType::Enum type) { jointType = PxU8(type); }
PX_FORCE_INLINE void setMaxJointVelocity(const PxReal maxJointV) {
for(PxU32 i = 0; i < PxArticulationAxis::eCOUNT; i++)
{
maxJointVelocity[i] = maxJointV;
}
}
PX_FORCE_INLINE void setMaxJointVelocity(PxArticulationAxis::Enum axis, const PxReal maxJointV) {
maxJointVelocity[axis] = maxJointV;
}
PX_FORCE_INLINE void setFrictionCoefficient(const PxReal coefficient) { frictionCoefficient = coefficient; }
PX_FORCE_INLINE void setFrictionParams(PxArticulationAxis::Enum axis, const PxJointFrictionParams& jointFrictionParams)
{
frictionParams[axis] = jointFrictionParams;
}
void init(const PxTransform& parentFrame, const PxTransform& childFrame)
{
PX_ASSERT(parentFrame.isValid());
PX_ASSERT(childFrame.isValid());
parentPose = parentFrame;
childPose = childFrame;
jointOffset = 0;
jCalcUpdateFrames = true;
setFrictionCoefficient(0.05f);
setMaxJointVelocity(100.0f);
setJointType(PxArticulationJointType::eUNDEFINED);
for(PxU32 i=0; i<PxArticulationAxis::eCOUNT; i++)
{
setLimit(PxArticulationAxis::Enum(i), PxArticulationLimit(0.0f, 0.0f));
setDrive(PxArticulationAxis::Enum(i), PxArticulationDrive(0.0f, 0.0f, 0.0f, PxArticulationDriveType::eNONE));
setFrictionParams(PxArticulationAxis::Enum(i), PxJointFrictionParams(0.0f, 0.0f, 0.0f));
setFrictionParams(PxArticulationAxis::Enum(i), PxJointFrictionParams(0.0f, 0.0f, 0.0f));
targetP[i] = 0.0f;
targetV[i] = 0.0f;
armature[i] = 0.0f;
jointPos[i] = 0.0f;
jointVel[i] = 0.0f;
dofIds[i] = 0xff;
invDofIds[i] = 0xff;
motion[i] = PxArticulationMotion::eLOCKED;
}
}
PX_CUDA_CALLABLE void setJointFrame(Cm::UnAlignedSpatialVector* motionMatrix,
const Cm::UnAlignedSpatialVector* jointAxis,
PxQuat& relativeQuat,
const PxU32 dofs)
{
if (jCalcUpdateFrames)
{
relativeQuat = (childPose.q * (parentPose.q.getConjugate())).getNormalized();
computeMotionMatrix(motionMatrix, jointAxis, dofs);
jCalcUpdateFrames = false;
}
}
PX_CUDA_CALLABLE PX_FORCE_INLINE void computeMotionMatrix(Cm::UnAlignedSpatialVector* motionMatrix,
const Cm::UnAlignedSpatialVector* jointAxis,
const PxU32 dofs)
{
const PxVec3 childOffset = -childPose.p;
switch (jointType)
{
case PxArticulationJointType::ePRISMATIC:
{
const Cm::UnAlignedSpatialVector& jJointAxis = jointAxis[0];
const PxVec3 u = rotateAndNormalize(childPose.q, jJointAxis.bottom);
motionMatrix[0] = Cm::UnAlignedSpatialVector(PxVec3(0.0f), u);
PX_ASSERT(dofs == 1);
break;
}
case PxArticulationJointType::eREVOLUTE:
case PxArticulationJointType::eREVOLUTE_UNWRAPPED:
{
const Cm::UnAlignedSpatialVector& jJointAxis = jointAxis[0];
const PxVec3 u = rotateAndNormalize(childPose.q, jJointAxis.top);
const PxVec3 uXd = u.cross(childOffset);
motionMatrix[0] = Cm::UnAlignedSpatialVector(u, uXd);
break;
}
case PxArticulationJointType::eSPHERICAL:
{
for (PxU32 ind = 0; ind < dofs; ++ind)
{
const Cm::UnAlignedSpatialVector& jJointAxis = jointAxis[ind];
const PxVec3 u = rotateAndNormalize(childPose.q, jJointAxis.top);
const PxVec3 uXd = u.cross(childOffset);
motionMatrix[ind] = Cm::UnAlignedSpatialVector(u, uXd);
}
break;
}
case PxArticulationJointType::eFIX:
{
PX_ASSERT(dofs == 0);
break;
}
default:
break;
}
}
PX_CUDA_CALLABLE PX_FORCE_INLINE void operator=(ArticulationJointCore& other)
{
parentPose = other.parentPose;
childPose = other.childPose;
//KS - temp place to put reduced coordinate limit and drive values
for(PxU32 i=0; i<PxArticulationAxis::eCOUNT; i++)
{
limits[i] = other.limits[i];
drives[i] = other.drives[i];
targetP[i] = other.targetP[i];
targetV[i] = other.targetV[i];
armature[i] = other.armature[i];
frictionParams[i] = other.frictionParams[i];
maxJointVelocity[i] = other.maxJointVelocity[i];
jointPos[i] = other.jointPos[i];
jointVel[i] = other.jointVel[i];
dofIds[i] = other.dofIds[i];
invDofIds[i] = other.invDofIds[i];
motion[i] = other.motion[i];
}
frictionCoefficient = other.frictionCoefficient;
jointOffset = other.jointOffset;
jCalcUpdateFrames = other.jCalcUpdateFrames;
jointType = other.jointType;
}
PX_FORCE_INLINE void setParentPose(const PxTransform& t) { parentPose = t; jCalcUpdateFrames = true; }
PX_FORCE_INLINE void setChildPose(const PxTransform& t) { childPose = t; jCalcUpdateFrames = true; }
PX_FORCE_INLINE void setMotion(PxArticulationAxis::Enum axis, PxArticulationMotion::Enum m) { motion[axis] = PxU8(m);}
PX_FORCE_INLINE void setTargetP(PxArticulationAxis::Enum axis, PxReal value) { targetP[axis] = value; }
PX_FORCE_INLINE void setTargetV(PxArticulationAxis::Enum axis, PxReal value) { targetV[axis] = value; }
PX_FORCE_INLINE void setArmature(PxArticulationAxis::Enum axis, PxReal value) { armature[axis] = value;}
// attachment points, don't change the order, otherwise it will break GPU code
PxTransform parentPose; //28 28
PxTransform childPose; //28 56
//KS - temp place to put reduced coordinate limit and drive values
PxArticulationLimit limits[PxArticulationAxis::eCOUNT]; //48 104
PxArticulationDrive drives[PxArticulationAxis::eCOUNT]; //96 200
PxReal targetP[PxArticulationAxis::eCOUNT]; //24 224
PxReal targetV[PxArticulationAxis::eCOUNT]; //24 248
PxReal armature[PxArticulationAxis::eCOUNT]; //24 272
PxReal jointPos[PxArticulationAxis::eCOUNT]; //24 296
PxReal jointVel[PxArticulationAxis::eCOUNT]; //24 320
PxReal frictionCoefficient; //4 324
PxJointFrictionParams frictionParams[PxArticulationAxis::eCOUNT]; //72 396
PxReal maxJointVelocity[PxArticulationAxis::eCOUNT]; // 24 420
//this is the dof offset for the joint in the cache.
PxU32 jointOffset; //4 424
PxU8 dofIds[PxArticulationAxis::eCOUNT]; //6 430
PxU8 motion[PxArticulationAxis::eCOUNT]; //6 436
PxU8 invDofIds[PxArticulationAxis::eCOUNT]; //6 442
bool jCalcUpdateFrames; //1 443
PxU8 jointType; //1 444
PxReal padding[1]; //4 ````448
}PX_ALIGN_SUFFIX(16);
}
}
#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 PXD_ARTICULATION_MIMIC_JOINT_CORE_H
#define PXD_ARTICULATION_MIMIC_JOINT_CORE_H
#include "foundation/PxSimpleTypes.h"
namespace physx
{
namespace Dy
{
struct ArticulationMimicJointCore
{
PxU32 linkA;
PxU32 axisA; //PxArticulationAxis::Enum
PxU32 linkB;
PxU32 axisB; //PxArticulationAxis::Enum
PxReal gearRatio;
PxReal offset;
PxReal naturalFrequency;
PxReal dampingRatio;
};
PX_COMPILE_TIME_ASSERT(32 == sizeof(ArticulationMimicJointCore));
}//namespace Dy
}//namespace physx
#endif //PXD_ARTICULATION_MIMIC_JOINT_CORE_H

View File

@@ -0,0 +1,192 @@
// 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 PXD_ARTICULATION_TENDON_H
#define PXD_ARTICULATION_TENDON_H
#include "foundation/PxVec3.h"
#include "foundation/PxQuat.h"
#include "foundation/PxTransform.h"
#include "foundation/PxVecMath.h"
#include "foundation/PxUtilities.h"
#include "CmUtils.h"
#include "CmIDPool.h"
#include "solver/PxSolverDefs.h"
namespace physx
{
namespace Dy
{
typedef PxU64 ArticulationAttachmentBitField;
#define DY_ARTICULATION_ATTACHMENT_NONE 0xffffffff
struct ArticulationAttachment
{
PxVec3 relativeOffset; //relative offset to the link
PxReal lowLimit;
PxReal highLimit;
PxReal restLength;
PxReal coefficient;
PxU32 parent; //parent index
PxU32 myInd;
PxU32 mConstraintInd;
PxU16 linkInd;
PxU16 childCount;
ArticulationAttachmentBitField children;
};
class ArticulationTendon
{
public:
ArticulationTendon() : mStiffness(0.f), mDamping(0.f), mOffset(0.f), mLimitStiffness(0.f)
{
}
PxReal mStiffness;
PxReal mDamping;
PxReal mOffset;
PxReal mLimitStiffness;
};
class ArticulationSpatialTendon : public ArticulationTendon
{
public:
ArticulationSpatialTendon()
{
mAttachments.reserve(64);
mAttachments.forceSize_Unsafe(64);
}
PX_FORCE_INLINE ArticulationAttachment* getAttachments() { return mAttachments.begin(); }
PX_FORCE_INLINE ArticulationAttachment& getAttachment(const PxU32 index) { return mAttachments[index]; }
PX_FORCE_INLINE PxU32 getNumAttachments() { return mIDPool.getNumUsedID(); }
PX_FORCE_INLINE PxU32 getNewID()
{
const PxU32 index = mIDPool.getNewID();
if (mAttachments.capacity() <= index)
{
mAttachments.resize(index * 2 + 1);
}
return index;
}
PX_FORCE_INLINE void freeID(const PxU32 index)
{
mIDPool.freeID(index);
}
PX_FORCE_INLINE PxU32 getTendonIndex() { return mIndex; }
PX_FORCE_INLINE void setTendonIndex(const PxU32 index) { mIndex = index; }
private:
PxArray<ArticulationAttachment> mAttachments;
Cm::IDPool mIDPool;
PxU32 mIndex;
};
class ArticulationTendonJoint
{
public:
PxU16 axis;
PxU16 startJointOffset;
PxReal coefficient;
PxReal recipCoefficient;
PxU32 mConstraintInd;
PxU32 parent; //parent index
PxU16 linkInd;
PxU16 childCount;
ArticulationAttachmentBitField children;
};
class ArticulationFixedTendon : public ArticulationTendon
{
public:
ArticulationFixedTendon() :mLowLimit(PX_MAX_F32), mHighLimit(-PX_MAX_F32), mRestLength(0.f)
{
mTendonJoints.reserve(64);
mTendonJoints.forceSize_Unsafe(64);
}
PX_FORCE_INLINE ArticulationTendonJoint* getTendonJoints() { return mTendonJoints.begin(); }
PX_FORCE_INLINE ArticulationTendonJoint& getTendonJoint(const PxU32 index) { return mTendonJoints[index]; }
PX_FORCE_INLINE PxU32 getNumJoints() { return mIDPool.getNumUsedID(); }
PX_FORCE_INLINE PxU32 getNewID()
{
const PxU32 index = mIDPool.getNewID();
if (mTendonJoints.capacity() <= index)
{
mTendonJoints.resize(index * 2 + 1);
}
return index;
}
PX_FORCE_INLINE void freeID(const PxU32 index)
{
mIDPool.freeID(index);
}
PX_FORCE_INLINE PxU32 getTendonIndex() { return mIndex; }
PX_FORCE_INLINE void setTendonIndex(const PxU32 index) { mIndex = index; }
PxReal mLowLimit;
PxReal mHighLimit;
PxReal mRestLength;
PxReal mError;
private:
PxArray<ArticulationTendonJoint> mTendonJoints;
Cm::IDPool mIDPool;
PxU32 mIndex;
};
}//namespace Dy
}//namespace physx
#endif

View File

@@ -0,0 +1,85 @@
// 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 DY_CONSTRAINT_H
#define DY_CONSTRAINT_H
#include "foundation/PxVec3.h"
#include "foundation/PxTransform.h"
#include "PxvConfig.h"
#include "PxvDynamics.h"
#include "PxConstraint.h"
#include "DyConstraintWriteBack.h"
namespace physx
{
class PxsRigidBody;
namespace Dy
{
#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
PX_ALIGN_PREFIX(16)
struct Constraint
{
public:
PxReal linBreakForce;
PxReal angBreakForce;
PxU16 constantBlockSize;
PxU16 flags;
PxConstraintSolverPrep solverPrep;
void* constantBlock;
PxsRigidBody* body0;
PxsRigidBody* body1;
PxsBodyCore* bodyCore0;
PxsBodyCore* bodyCore1;
PxU32 index;
PxReal minResponseThreshold;
}
PX_ALIGN_SUFFIX(16);
#if PX_VC
#pragma warning(pop)
#endif
#if !PX_P64_FAMILY
PX_COMPILE_TIME_ASSERT(48==sizeof(Constraint));
#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 DY_CONSTRAINT_WRITE_BACK_H
#define DY_CONSTRAINT_WRITE_BACK_H
#include "foundation/PxVec3.h"
#include "PxvConfig.h"
#include "PxvDynamics.h"
namespace physx
{
namespace Dy
{
PX_ALIGN_PREFIX(16)
struct ConstraintWriteback
{
void initialize()
{
linearImpulse = PxVec3(0);
angularImpulse = PxVec3(0);
residualPosIter = 0.0f;
residual = 0.0f;
}
PxVec3 linearImpulse;
private:
union
{
PxU32 broken;
PxReal residualPosIter;
};
public:
PxVec3 angularImpulse;
PxReal residual;
PX_FORCE_INLINE PxU32 setBit(PxU32 value, PxU32 bitLocation, bool bitState)
{
if (bitState)
return value | (1 << bitLocation);
else
return value & (~(1 << bitLocation));
}
PX_FORCE_INLINE bool isBroken() const { return broken & PX_SIGN_BITMASK; }
PX_FORCE_INLINE PxReal getPositionIterationResidual() const { return PxAbs(residualPosIter); }
PX_FORCE_INLINE void setCombined(bool isBroken, PxReal positionIterationResidual)
{
residualPosIter = positionIterationResidual;
broken = setBit(broken, 31, isBroken);
}
}
PX_ALIGN_SUFFIX(16);
}
}
#endif

View File

@@ -0,0 +1,367 @@
// 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 DY_CONTEXT_H
#define DY_CONTEXT_H
#include "PxSceneDesc.h"
#include "DyThresholdTable.h"
#include "PxcNpThreadContext.h"
#include "PxsSimulationController.h"
#include "DyConstraintWriteBack.h"
#include "foundation/PxAllocator.h"
#include "foundation/PxUserAllocated.h"
#include "PxsRigidBody.h"
#include "DyResidualAccumulator.h"
namespace physx
{
class PxcNpMemBlockPool;
namespace Cm
{
class FlushPool;
}
namespace IG
{
class SimpleIslandManager;
}
class PxcScratchAllocator;
struct PxvSimStats;
class PxTaskManager;
class PxsContactManager;
struct PxsContactManagerOutputCounts;
class PxvNphaseImplementationContext;
namespace Dy
{
class Context : public PxUserAllocated
{
PX_NOCOPY(Context)
public:
// PT: TODO: consider making all of these public at this point
// PT: please avoid useless comments like "returns Blah" for a function called "getBlah".
PX_FORCE_INLINE PxReal getMaxBiasCoefficient() const { return mMaxBiasCoefficient; }
PX_FORCE_INLINE void setMaxBiasCoefficient(PxReal coeff) { mMaxBiasCoefficient = coeff; }
PX_FORCE_INLINE PxReal getCorrelationDistance() const { return mCorrelationDistance; }
PX_FORCE_INLINE void setCorrelationDistance(PxReal f) { mCorrelationDistance = f; }
PX_FORCE_INLINE PxReal getBounceThreshold() const { return mBounceThreshold; }
PX_FORCE_INLINE void setBounceThreshold(PxReal f) { mBounceThreshold = f; }
PX_FORCE_INLINE PxReal getFrictionOffsetThreshold() const { return mFrictionOffsetThreshold; }
PX_FORCE_INLINE void setFrictionOffsetThreshold(PxReal offset) { mFrictionOffsetThreshold = offset; }
PX_FORCE_INLINE PxReal getCCDSeparationThreshold() const { return mCCDSeparationThreshold; }
PX_FORCE_INLINE void setCCDSeparationThreshold(PxReal offset) { mCCDSeparationThreshold = offset; }
PX_FORCE_INLINE PxU32 getSolverBatchSize() const { return mSolverBatchSize; }
PX_FORCE_INLINE void setSolverBatchSize(PxU32 f) { mSolverBatchSize = f; }
PX_FORCE_INLINE PxU32 getSolverArticBatchSize() const { return mSolverArticBatchSize; }
PX_FORCE_INLINE void setSolverArticBatchSize(PxU32 f) { mSolverArticBatchSize = f; }
PX_FORCE_INLINE PxReal getDt() const { return mDt; }
PX_FORCE_INLINE void setDt(const PxReal dt) { mDt = dt; }
// PT: TODO: we have a setDt function but it doesn't set the inverse dt, what's the story here?
PX_FORCE_INLINE PxReal getInvDt() const { return mInvDt; }
//Forces any cached body state to be updated!
PX_FORCE_INLINE void setStateDirty(bool dirty) { mBodyStateDirty = dirty; }
PX_FORCE_INLINE bool isStateDirty() const { return mBodyStateDirty; }
// Returns the maximum solver constraint size in this island in bytes.
PX_FORCE_INLINE PxU32 getMaxSolverConstraintSize() const { return mMaxSolverConstraintSize; }
PX_FORCE_INLINE PxReal getLengthScale() const { return mLengthScale; }
PX_FORCE_INLINE const PxVec3& getGravity() const { return mGravity; }
PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; }
PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; }
PX_FORCE_INLINE ThresholdStream& getForceChangedThresholdStream() { return *mForceChangedThresholdStream; }
PX_FORCE_INLINE ThresholdTable& getThresholdTable() { return mThresholdTable; }
void createThresholdStream(PxVirtualAllocatorCallback& callback) { PX_ASSERT(!mThresholdStream); mThresholdStream = PX_NEW(ThresholdStream)(callback); }
void createForceChangeThresholdStream(PxVirtualAllocatorCallback& callback) { PX_ASSERT(!mForceChangedThresholdStream); mForceChangedThresholdStream = PX_NEW(ThresholdStream)(callback); }
PX_FORCE_INLINE PxcDataStreamPool& getContactStreamPool() { return mContactStreamPool; }
PX_FORCE_INLINE PxcDataStreamPool& getPatchStreamPool() { return mPatchStreamPool; }
PX_FORCE_INLINE PxcDataStreamPool& getForceStreamPool() { return mForceStreamPool; }
PX_FORCE_INLINE PxPinnedArray<Dy::ConstraintWriteback>& getConstraintWriteBackPool() { return mConstraintWriteBackPool; }
PX_FORCE_INLINE PxcDataStreamPool& getFrictionPatchStreamPool() { return mFrictionPatchStreamPool; }
PX_FORCE_INLINE PxPinnedArray<PxReal>& getConstraintPositionIterResidualPoolGpu() { return mConstraintPositionIterResidualPoolGpu; }
//Reports the sum of squared errors of the delta Force corrections. Geometric error was not possible because a compliant contact might have penetration (=geometric error) but can still be solved perfectly
PX_FORCE_INLINE PxReal getContactError() const { return (mContactErrorVelIter ? mContactErrorVelIter->mErrorSumOfSquares : 0.0f) + (mArticulationContactErrorVelIter.size() ? mArticulationContactErrorVelIter[0].mErrorSumOfSquares : 0.0f); }
PX_FORCE_INLINE PxU32 getContactErrorCounter() const { return (mContactErrorVelIter ? mContactErrorVelIter->mCounter : 0u) + (mArticulationContactErrorVelIter.size() ? mArticulationContactErrorVelIter[0].mCounter : 0u); }
PX_FORCE_INLINE PxReal getMaxContactError() const { return PxMax(mContactErrorVelIter ? mContactErrorVelIter->mMaxError : 0.0f, mArticulationContactErrorVelIter.size() ? mArticulationContactErrorVelIter[0].mMaxError : 0.0f); }
PX_FORCE_INLINE PxReal getContactErrorPosIter() const { return (mContactErrorPosIter ? mContactErrorPosIter->mErrorSumOfSquares : 0.0f) + (mArticulationContactErrorPosIter.size() ? mArticulationContactErrorPosIter[0].mErrorSumOfSquares : 0.0f); }
PX_FORCE_INLINE PxU32 getContactErrorCounterPosIter() const { return (mContactErrorPosIter ? mContactErrorPosIter->mCounter : 0u) + (mArticulationContactErrorPosIter.size() ? mArticulationContactErrorPosIter[0].mCounter : 0u); }
PX_FORCE_INLINE PxReal getMaxContactErrorPosIter() const { return PxMax(mContactErrorPosIter ? mContactErrorPosIter->mMaxError : 0.0f, mArticulationContactErrorPosIter.size() ? mArticulationContactErrorPosIter[0].mMaxError : 0.0f); }
PX_FORCE_INLINE bool isResidualReportingEnabled() const { return mIsResidualReportingEnabled; }
/**
\brief Destroys this dynamics context
*/
virtual void destroy() = 0;
/**
\brief The entry point for the constraint solver.
\param[in] dt The simulation time-step
\param[in] continuation The continuation task for the solver
\param[in] processLostTouchTask The task that processes lost touches
This method is called after the island generation has completed. Its main responsibilities are:
(1) Reserving the solver body pools
(2) Initializing the static and kinematic solver bodies, which are shared resources between islands.
(3) Construct the solver task chains for each island
Each island is solved as an independent solver task chain. In addition, large islands may be solved using multiple parallel tasks.
Island solving is asynchronous. Once all islands have been solved, the continuation task will be called.
*/
virtual void update( Cm::FlushPool& flushPool, PxBaseTask* continuation, PxBaseTask* postPartitioningTask, PxBaseTask* processLostTouchTask,
PxvNphaseImplementationContext* nPhaseContext, PxU32 maxPatchesPerCM, PxU32 maxArticulationLinks, PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap) = 0;
virtual void updatePostPartitioning(PxBaseTask* /*processLostTouchTask*/,
PxvNphaseImplementationContext* /*nPhaseContext*/, PxU32 /*maxPatchesPerCM*/, PxU32 /*maxArticulationLinks*/, PxReal /*dt*/, const PxVec3& /*gravity*/, PxBitMapPinned& /*changedHandleMap*/) {}
virtual void processPatches( Cm::FlushPool& /*flushPool*/, PxBaseTask* /*continuation*/,
PxsContactManager** /*lostFoundPatchManagers*/, PxU32 /*nbLostFoundPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/) {}
/**
\brief This method copy gpu solver body data to cpu body core
*/
virtual void updateBodyCore(PxBaseTask* /*continuation*/) {}
/**
\brief Called after update's task chain has completed. This collects the results of the solver together.
This method combines the results of several islands, e.g. constructing scene-level simulation statistics and merging together threshold streams for contact notification.
*/
virtual void mergeResults() = 0;
virtual void setSimulationController(PxsSimulationController* simulationController) = 0;
virtual void getDataStreamBase(void*& /*contactStreamBase*/, void*& /*patchStreamBase*/, void*& /*forceAndIndicesStreamBase*/) {}
virtual PxSolverType::Enum getSolverType() const = 0;
virtual PxsExternalAccelerationProvider& getExternalRigidAccelerations() { return mRigidExternalAccelerations; }
// Only used for Direct GPU API pipeline at the moment.
virtual void setActiveBreakableConstraintCount(PxU32 activeBreakableConstraintCount) { PX_UNUSED(activeBreakableConstraintCount); }
protected:
Context(IG::SimpleIslandManager& islandManager, PxVirtualAllocatorCallback* allocatorCallback,
PxvSimStats& simStats, bool enableStabilization, bool useEnhancedDeterminism,
PxReal maxBiasCoefficient, PxReal lengthScale, PxU64 contextID, bool isResidualReportingEnabled) :
mThresholdStream (NULL),
mForceChangedThresholdStream(NULL),
mIslandManager (islandManager),
mDt (1.0f),
mInvDt (1.0f),
mMaxBiasCoefficient (maxBiasCoefficient),
mEnableStabilization (enableStabilization),
mUseEnhancedDeterminism (useEnhancedDeterminism),
mBounceThreshold (-2.0f),
mLengthScale (lengthScale),
mSolverBatchSize (32),
mConstraintWriteBackPool (PxVirtualAllocator(allocatorCallback)),
mConstraintPositionIterResidualPoolGpu(PxVirtualAllocator(allocatorCallback)),
mIsResidualReportingEnabled(isResidualReportingEnabled),
mContactErrorPosIter (NULL),
mContactErrorVelIter (NULL),
mArticulationContactErrorVelIter(PxVirtualAllocator(allocatorCallback)),
mArticulationContactErrorPosIter(PxVirtualAllocator(allocatorCallback)),
mSimStats (simStats),
mContextID (contextID),
mBodyStateDirty(false),
mTotalContactError ()
{
}
virtual ~Context()
{
PX_DELETE(mThresholdStream);
PX_DELETE(mForceChangedThresholdStream);
}
ThresholdStream* mThresholdStream;
ThresholdStream* mForceChangedThresholdStream;
ThresholdTable mThresholdTable;
IG::SimpleIslandManager& mIslandManager;
PxsSimulationController* mSimulationController;
/**
\brief Time-step.
*/
PxReal mDt;
/**
\brief 1/time-step.
*/
PxReal mInvDt;
PxReal mMaxBiasCoefficient;
const bool mEnableStabilization;
const bool mUseEnhancedDeterminism;
PxVec3 mGravity;
/**
\brief max solver constraint size
*/
PxU32 mMaxSolverConstraintSize;
/**
\brief Threshold controlling the relative velocity at which the solver transitions between restitution and bias for solving normal contact constraint.
*/
PxReal mBounceThreshold;
/**
\brief Threshold controlling whether friction anchors are constructed or not. If the separation is above mFrictionOffsetThreshold, the contact will not be considered to become a friction anchor
*/
PxReal mFrictionOffsetThreshold;
/**
\brief Threshold controlling whether distant contacts are processed using bias, restitution or a combination of the two. This only has effect on pairs involving bodies that have enabled speculative CCD simulation mode.
*/
PxReal mCCDSeparationThreshold;
/**
\brief Threshold for controlling friction correlation
*/
PxReal mCorrelationDistance;
/**
\brief The length scale from PxTolerancesScale::length.
*/
PxReal mLengthScale;
/**
\brief The minimum size of an island to generate a solver task chain.
*/
PxU32 mSolverBatchSize;
/**
\brief The minimum number of articulations required to generate a solver task chain.
*/
PxU32 mSolverArticBatchSize;
/**
\brief Structure to encapsulate contact stream allocations. Used by GPU solver to reference pre-allocated pinned host memory
*/
PxcDataStreamPool mContactStreamPool;
/**
\brief Struct to encapsulate the contact patch stream allocations. Used by GPU solver to reference pre-allocated pinned host memory
*/
PxcDataStreamPool mPatchStreamPool;
/**
\brief Structure to encapsulate force stream allocations. Used by GPU solver to reference pre-allocated pinned host memory for force reports.
*/
PxcDataStreamPool mForceStreamPool;
/**
\brief Struct to encapsulate the friction patch stream allocations. Used by GPU solver to reference pre-allocated pinned host memory
*/
PxcDataStreamPool mFrictionPatchStreamPool;
/**
\brief Structure to encapsulate constraint write back allocations. Used by GPU/CPU solver to reference pre-allocated pinned host memory for breakable joint reports.
*/
PxPinnedArray<Dy::ConstraintWriteback> mConstraintWriteBackPool;
/**
\brief Buffer that contains only the joint residuals for the gpu solver, cpu solver residuals take a different code path
*/
PxPinnedArray<PxReal> mConstraintPositionIterResidualPoolGpu;
/**
\brief Indicates if solver residuals should get computed and reported
*/
bool mIsResidualReportingEnabled;
/**
\brief Pointer to contact error data during the last position iteration (can point to memory owned by the GPU solver context that is copied to the host asynchronously)
*/
Dy::ErrorAccumulator* mContactErrorPosIter;
/**
\brief Pointer to contact error data during the last velocity iteration (can point to memory owned by the GPU solver context that is copied to the host asynchronously)
*/
Dy::ErrorAccumulator* mContactErrorVelIter;
/**
\brief Contains the articulation contact error during the last velocity iteration. Has size 1 if articulations are present in the scene. Pinned host memory for fast device to host copies.
*/
PxPinnedArray<Dy::ErrorAccumulator> mArticulationContactErrorVelIter;
/**
\brief Contains the articulation contact error during the last position iteration. Has size 1 if articulations are present in the scene. Pinned host memory for fast device to host copies.
*/
PxPinnedArray<Dy::ErrorAccumulator> mArticulationContactErrorPosIter;
PxvSimStats& mSimStats;
const PxU64 mContextID;
PxsExternalAccelerationProvider mRigidExternalAccelerations;
bool mBodyStateDirty;
Dy::ErrorAccumulatorEx mTotalContactError;
};
Context* createDynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool,
PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager,
IG::SimpleIslandManager& islandManager, PxU64 contextID, bool enableStabilization, bool useEnhancedDeterminism,
PxReal maxBiasCoefficient, bool frictionEveryIteration, PxReal lengthScale, bool isResidualReportingEnabled);
Context* createTGSDynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool,
PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager,
IG::SimpleIslandManager& islandManager, PxU64 contextID, bool enableStabilization, bool useEnhancedDeterminism, PxReal lengthScale,
bool externalForcesEveryTgsIterationEnabled, bool isResidualReportingEnabled);
}
}
#endif

View File

@@ -0,0 +1,86 @@
// 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 DY_DEFORMABLE_BODY_CORE_H
#define DY_DEFORMABLE_BODY_CORE_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxTransform.h"
#include "foundation/PxArray.h"
namespace physx
{
namespace Dy
{
struct DeformableBodyCore
{
public:
//PxFEMParameters
PxReal linearDamping;
PxReal settlingThreshold;
PxReal sleepThreshold;
PxReal settlingDamping;
PxReal selfCollisionFilterDistance;
PxReal selfCollisionStressTolerance;
//~PxFEMParameters
PxReal maxLinearVelocity;
PxReal maxPenetrationBias;
PxU16 solverIterationCounts; //vel iters are in low word and pos iters in high word.
PxArray<PxU16> materialHandles;
PxReal wakeCounter;
PxDeformableBodyFlags bodyFlags;
PxActorFlags actorFlags;
bool dirty;
DeformableBodyCore()
//PxFEMParameters, same defaults as deprecated PxFEMParameters
: linearDamping(0.05f)
, settlingThreshold(0.1f)
, sleepThreshold(0.05f)
, settlingDamping(10.f)
, selfCollisionFilterDistance(0.1f)
, selfCollisionStressTolerance(0.9f)
//~PxFEMParameters
, maxLinearVelocity(PX_MAX_REAL) // see Sc::BodyCore::BodyCore
, maxPenetrationBias(-1e32f) // see PxsBodyCore::init
, solverIterationCounts(0)
, wakeCounter(0)
, bodyFlags(0)
, actorFlags(0)
, dirty(false)
{
}
};
} // namespace Dy
} // namespace physx
#endif // DY_DEFORMABLE_CORE_H

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.
#ifndef DY_DEFORMABLE_SURFACE_H
#define DY_DEFORMABLE_SURFACE_H
#include "foundation/PxSimpleTypes.h"
#include "DyDeformableSurfaceCore.h"
#include "PxvGeometry.h"
namespace physx
{
namespace Sc
{
class DeformableSurfaceSim;
}
namespace Dy
{
typedef size_t DeformableSurfaceHandle;
struct DeformableSurfaceCore;
class DeformableSurface
{
PX_NOCOPY(DeformableSurface)
public:
DeformableSurface(Sc::DeformableSurfaceSim* sim, Dy::DeformableSurfaceCore& core) :
mSim(sim), mCore(core), mElementId(0xffffffff), mGpuRemapId(0xffffffff)
{}
~DeformableSurface() {}
PX_FORCE_INLINE void setGpuRemapId(const PxU32 remapId)
{
mGpuRemapId = remapId;
PxTriangleMeshGeometryLL& geom = mShapeCore->mGeometry.get<PxTriangleMeshGeometryLL>();
geom.materialsLL.gpuRemapId = remapId;
}
PX_FORCE_INLINE PxTriangleMesh* getTriangleMesh()
{
PxTriangleMeshGeometryLL& geom = mShapeCore->mGeometry.get<PxTriangleMeshGeometryLL>();
return geom.triangleMesh;
}
PX_FORCE_INLINE PxU32 getGpuRemapId() { return mGpuRemapId; }
PX_FORCE_INLINE void setElementId(const PxU32 elementId) { mElementId = elementId; }
PX_FORCE_INLINE PxU32 getElementId() { return mElementId; }
PX_FORCE_INLINE PxsShapeCore& getShapeCore() { return *mShapeCore; }
PX_FORCE_INLINE void setShapeCore(PxsShapeCore* shapeCore) { mShapeCore = shapeCore; }
PX_FORCE_INLINE Sc::DeformableSurfaceSim* getSim() const { return mSim; }
PX_FORCE_INLINE const DeformableSurfaceCore& getCore() const { return mCore; }
PX_FORCE_INLINE DeformableSurfaceCore& getCore() { return mCore; }
PX_FORCE_INLINE PxU16 getIterationCounts() const { return mCore.solverIterationCounts; }
void addAttachmentHandle(PxU32 handle);
void removeAttachmentHandle(PxU32 handle);
PxArray<PxU32> mAttachmentHandles;
PxArray<PxU32> mSurfaceSurfaceAttachments;
private:
Sc::DeformableSurfaceSim* mSim;
DeformableSurfaceCore& mCore;
PxsShapeCore* mShapeCore;
PxU32 mElementId; //this is used for the bound array, contactDist
PxU32 mGpuRemapId;
};
PX_FORCE_INLINE DeformableSurface* getDeformableSurface(DeformableSurfaceHandle handle)
{
return reinterpret_cast<DeformableSurface*>(handle);
}
PX_FORCE_INLINE void DeformableSurface::addAttachmentHandle(PxU32 handle)
{
mAttachmentHandles.pushBack(handle);
}
PX_FORCE_INLINE void DeformableSurface::removeAttachmentHandle(PxU32 handle)
{
for (PxU32 i = 0; i < mAttachmentHandles.size(); ++i)
{
if (mAttachmentHandles[i] == handle)
{
mAttachmentHandles.replaceWithLast(i);
}
}
}
} // namespace Dy
} // namespace physx
#endif // DY_DEFORMABLE_SURFACE_H

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.
#ifndef DY_DEFORMABLE_SURFACE_CORE_H
#define DY_DEFORMABLE_SURFACE_CORE_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxTransform.h"
#include "foundation/PxVec4.h"
#include "foundation/PxArray.h"
#include "PxDeformableSurface.h"
#include "PxDeformableSurfaceFlag.h"
#include "DyDeformableBodyCore.h"
namespace physx
{
namespace Dy
{
struct DeformableSurfaceCore : public DeformableBodyCore
{
public:
// number of collision pair updates per timestep. Collision pair is updated at least once per timestep and increasing the frequency provides better collision pairs.
PxU32 nbCollisionPairUpdatesPerTimestep;
// number of collision substeps in each sub-timestep. Collision constraints can be applied multiple times in each sub-timestep.
PxU32 nbCollisionSubsteps;
//device - managed by PhysX
PxVec4* positionInvMass;
PxVec4* velocity;
PxVec4* restPosition;
PxDeformableSurfaceDataFlags dirtyFlags;
PxDeformableSurfaceFlags surfaceFlags;
DeformableSurfaceCore()
: nbCollisionPairUpdatesPerTimestep(0)
, nbCollisionSubsteps(1)
, positionInvMass(NULL)
, velocity(NULL)
, restPosition(NULL)
, dirtyFlags(0)
, surfaceFlags(0)
{
}
};
} // namespace Dy
} // namespace physx
#endif // DY_DEFORMABLE_SURFACE_CORE_H

View File

@@ -0,0 +1,161 @@
// 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 DY_DEFORMABLE_VOLUME_H
#define DY_DEFORMABLE_VOLUME_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxPinnedArray.h"
#include "DyDeformableVolumeCore.h"
#include "PxvGeometry.h"
namespace physx
{
namespace Sc
{
class DeformableVolumeSim;
}
namespace Dy
{
typedef size_t DeformableVolumeHandle;
struct DeformableVolumeCore;
struct VolumeVolumeFilter { PxU64 a; PxU64 b; };
typedef PxPinnedArray<VolumeVolumeFilter> VolumeVolumeFilterArray;
class DeformableVolume
{
PX_NOCOPY(DeformableVolume)
public:
DeformableVolume(Sc::DeformableVolumeSim* sim, Dy::DeformableVolumeCore& core) :
mVolumeVolumeFilterPairs(NULL), mSim(sim), mCore(core), mElementId(0xffffffff), mGpuRemapId(0xffffffff)
{
mFilterDirty = false;
mFilterInDirtyList = false;
mDirtyVolumeForFilterPairs = NULL;
mVolumeVolumeFilterPairs = NULL;
}
~DeformableVolume()
{
if (mDirtyVolumeForFilterPairs)
{
Dy::DeformableVolume** dirtySoftBodies = mDirtyVolumeForFilterPairs->begin();
const PxU32 size = mDirtyVolumeForFilterPairs->size();
for (PxU32 i = 0; i < size; ++i)
{
if (dirtySoftBodies[i] == this)
{
dirtySoftBodies[i] = NULL;
}
}
}
if(mVolumeVolumeFilterPairs)
{
// TODO: Move all Pxg level data into Pxg layer!
mVolumeVolumeFilterPairs->clear();
mVolumeVolumeFilterPairs->shrink();
PX_FREE(mVolumeVolumeFilterPairs);
mVolumeVolumeFilterPairs = NULL;
}
}
PX_FORCE_INLINE void setGpuRemapId(const PxU32 remapId)
{
mGpuRemapId = remapId;
PxTetrahedronMeshGeometryLL& geom = mShapeCore->mGeometry.get<PxTetrahedronMeshGeometryLL>();
geom.materialsLL.gpuRemapId = remapId;
}
PX_FORCE_INLINE PxU32 getGpuRemapId() { return mGpuRemapId; }
PX_FORCE_INLINE void setElementId(const PxU32 elementId) { mElementId = elementId; }
PX_FORCE_INLINE PxU32 getElementId() { return mElementId; }
PX_FORCE_INLINE PxsShapeCore& getShapeCore() { return *mShapeCore; }
PX_FORCE_INLINE void setShapeCore(PxsShapeCore* shapeCore) { mShapeCore = shapeCore; }
PX_FORCE_INLINE void setSimShapeCore(PxTetrahedronMesh* simulationMesh, PxDeformableVolumeAuxData* simulationState)
{
mSimulationMesh = simulationMesh;
mAuxData = simulationState;
}
PX_FORCE_INLINE const PxTetrahedronMesh* getCollisionMesh() const { return mShapeCore->mGeometry.get<PxTetrahedronMeshGeometryLL>().tetrahedronMesh; }
PX_FORCE_INLINE PxTetrahedronMesh* getCollisionMesh() { return mShapeCore->mGeometry.get<PxTetrahedronMeshGeometryLL>().tetrahedronMesh; }
PX_FORCE_INLINE const PxTetrahedronMesh* getSimulationMesh() const { return mSimulationMesh; }
PX_FORCE_INLINE PxTetrahedronMesh* getSimulationMesh() { return mSimulationMesh; }
PX_FORCE_INLINE const PxDeformableVolumeAuxData* getAuxData() const { return mAuxData; }
PX_FORCE_INLINE PxDeformableVolumeAuxData* getAuxData() { return mAuxData; }
PX_FORCE_INLINE Sc::DeformableVolumeSim* getSim() const { return mSim; }
PX_FORCE_INLINE const DeformableVolumeCore& getCore() const { return mCore; }
PX_FORCE_INLINE DeformableVolumeCore& getCore() { return mCore; }
PX_FORCE_INLINE PxU16 getIterationCounts() const { return mCore.solverIterationCounts; }
PX_FORCE_INLINE PxU32 getGpuIndex() const { return mGpuRemapId; }
PxArray<PxU32> mParticleVolumeAttachments;
PxArray<PxU32> mRigidVolumeAttachments;
PxArray<PxU32> mSurfaceVolumeAttachments;
PxArray<PxU32> mVolumeVolumeAttachments;
//TODO: Move all Pxg level data into Pxg layer!
VolumeVolumeFilterArray* mVolumeVolumeFilterPairs;
PxArray <Dy::DeformableVolume*>* mDirtyVolumeForFilterPairs; //pointer to the array of mDirtyDeformableVolumeForFilterPairs in PxgSimulationController.cpp
PxArray<PxU32> mVolumeVolumeAttachmentIdReferences;
bool mFilterDirty;
bool mFilterInDirtyList;
private:
Sc::DeformableVolumeSim* mSim;
DeformableVolumeCore& mCore;
PxsShapeCore* mShapeCore;
PxU32 mElementId; //this is used for the bound array, contactDist
PxU32 mGpuRemapId;
PxTetrahedronMesh* mSimulationMesh;
PxDeformableVolumeAuxData* mAuxData;
};
PX_FORCE_INLINE DeformableVolume* getDeformableVolume(DeformableVolumeHandle handle)
{
return reinterpret_cast<DeformableVolume*>(handle);
}
} // namespace Dy
} // namespace physx
#endif // DY_DEFORMABLE_VOLUME_H

View File

@@ -0,0 +1,79 @@
// 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 DY_DEFORMABLE_VOLUME_CORE_H
#define DY_DEFORMABLE_VOLUME_CORE_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxTransform.h"
#include "PxDeformableVolume.h"
#include "PxDeformableVolumeFlag.h"
#include "PxsDeformableVolumeMaterialCore.h"
#include "foundation/PxArray.h"
#include "DyDeformableBodyCore.h"
namespace physx
{
namespace Dy
{
struct DeformableVolumeCore : public DeformableBodyCore
{
public:
PxQuat initialRotation;
PxReal freezeThreshold; // not exposed (stabilization threshold)
//device - managed by PhysX
PxVec4* positionInvMass; // collision mesh positions, alloc on attachShape(), dealloc detachShape()
PxVec4* restPosition; // collision mesh rest positions, alloc on attachShape(), dealloc detachShape()
PxVec4* simPositionInvMass; // simulation mesh positions, alloc on attachSimulationMesh(), dealloc detachSimulationMesh()
PxVec4* simVelocity; // simulation mesh velocities, alloc on attachSimulationMesh(), dealloc detachSimulationMesh()
// device - just the pointer, user responsible.
const PxVec4* kinematicTarget;
PxDeformableVolumeDataFlags dirtyFlags;
PxDeformableVolumeFlags volumeFlags;
DeformableVolumeCore()
: initialRotation(PxIdentity)
, freezeThreshold(0.0f)
, positionInvMass(NULL)
, restPosition(NULL)
, simPositionInvMass(NULL)
, simVelocity(NULL)
, kinematicTarget(NULL)
, dirtyFlags(0)
, volumeFlags(0)
{
}
};
} // namespace Dy
} // namespace physx
#endif // DY_DEFORMABLE_VOLUME_CORE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,111 @@
// 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 DY_FEATHERSTONE_ARTICULATION_JOINT_DATA_H
#define DY_FEATHERSTONE_ARTICULATION_JOINT_DATA_H
#include "foundation/PxVec3.h"
#include "foundation/PxQuat.h"
#include "foundation/PxTransform.h"
#include "foundation/PxVecMath.h"
#include "CmUtils.h"
#include "CmSpatialVector.h"
#include "DyVArticulation.h"
#include "DyFeatherstoneArticulationUtils.h"
#include "DyArticulationJointCore.h"
#include <stdio.h>
namespace physx
{
namespace Dy
{
class ArticulationJointCoreData
{
public:
ArticulationJointCoreData() : jointOffset(0xffffffff)
{
}
PX_CUDA_CALLABLE PX_FORCE_INLINE PxU8 countJointDofs(ArticulationJointCore* joint) const
{
PxU8 tDof = 0;
for (PxU32 i = 0; i < DY_MAX_DOF; ++i)
{
if (joint->motion[i] != PxArticulationMotion::eLOCKED)
{
tDof++;
}
}
return tDof;
}
PX_FORCE_INLINE PxU8 configureJointDofs(ArticulationJointCore* joint, Cm::UnAlignedSpatialVector* jointAxis)
{
nbDof = 0;
dofLimitMask = 0;
//KS - no need to zero memory here.
//PxMemZero(jointAxis, sizeof(jointAxis));
for (PxU8 i = 0; i < DY_MAX_DOF; ++i)
{
if (joint->motion[i] != PxArticulationMotion::eLOCKED)
{
Cm::UnAlignedSpatialVector axis = Cm::UnAlignedSpatialVector::Zero();
//axis is in the local space of joint
axis[i] = 1.f;
jointAxis[nbDof] = axis;
joint->invDofIds[i] = nbDof;
joint->dofIds[nbDof] = i;
if (joint->motion[i] == PxArticulationMotion::eLIMITED)
dofLimitMask |= 1 << nbDof;
nbDof++;
}
}
return nbDof;
}
PxU32 jointOffset; //4
//degree of freedom
PxU8 nbDof; //1
PxU8 dofLimitMask; //1
};
}//namespace Dy
}
#endif

File diff suppressed because it is too large Load Diff

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 DY_ISLAND_MANAGER_H
#define DY_ISLAND_MANAGER_H
// PT: low-level-dynamics client helper code for using the low-level island sim
#include "PxsIslandSim.h"
namespace physx
{
class PxsRigidBody;
namespace Dy
{
class FeatherstoneArticulation;
#if PX_SUPPORT_GPU_PHYSX
class DeformableSurface;
class DeformableVolume;
class ParticleSystem;
#endif
}
template <typename T>
struct IGNodeTraits
{
enum {TypeID = IG::Node::eTYPE_COUNT };
};
template <typename T> struct IGNodeTraits<const T> { enum { TypeID = IGNodeTraits<T>::TypeID }; };
template <> struct IGNodeTraits<PxsRigidBody> { enum { TypeID = IG::Node::eRIGID_BODY_TYPE }; };
template <> struct IGNodeTraits<Dy::FeatherstoneArticulation> { enum { TypeID = IG::Node::eARTICULATION_TYPE }; };
#if PX_SUPPORT_GPU_PHYSX
template <> struct IGNodeTraits<Dy::DeformableSurface> { enum { TypeID = IG::Node::eDEFORMABLE_SURFACE_TYPE }; };
template <> struct IGNodeTraits<Dy::DeformableVolume> { enum { TypeID = IG::Node::eDEFORMABLE_VOLUME_TYPE }; };
template <> struct IGNodeTraits<Dy::ParticleSystem> { enum { TypeID = IG::Node::ePARTICLESYSTEM_TYPE }; };
#endif
template<class T>
PX_FORCE_INLINE T* getObjectFromIG(const IG::Node& node)
{
PX_ASSERT(PxU32(node.mType) == PxU32(IGNodeTraits<T>::TypeID));
return reinterpret_cast<T*>(node.mObject);
}
PX_FORCE_INLINE PxsRigidBody* getRigidBodyFromIG(const IG::IslandSim& islandSim, PxNodeIndex nodeIndex)
{
return reinterpret_cast<PxsRigidBody*>(islandSim.getObject(nodeIndex, IG::Node::eRIGID_BODY_TYPE));
}
PX_FORCE_INLINE Dy::FeatherstoneArticulation* getArticulationFromIG(const IG::IslandSim& islandSim, PxNodeIndex nodeIndex)
{
return reinterpret_cast<Dy::FeatherstoneArticulation*>(islandSim.getObject(nodeIndex, IG::Node::eARTICULATION_TYPE));
}
}
#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.
#ifndef PXD_PARTICLESYSTEM_H
#define PXD_PARTICLESYSTEM_H
#include "foundation/PxSimpleTypes.h"
#include "DyParticleSystemCore.h"
#include "PxvGeometry.h"
#define MAX_SPARSEGRID_DIM 1024
#define MIN_SPARSEGRID_ID -512
#define MAX_SPARSEGRID_ID 511
namespace physx
{
namespace Sc
{
class ParticleSystemSim;
}
namespace Dy
{
typedef size_t ParticleSystemHandle;
class ParticleSystemCore;
struct ParticleSystemFlag
{
enum Enum
{
eUPDATE_PARAMS = 1 << 1,
eUPDATE_MATERIAL = 1 << 2,
eUPDATE_PHASE = 1 << 3,
eUPDATE_ACTIVE_PARTICLECOUNT = 1 << 4,
eENABLE_GPU_DATA_SYNC = 1 << 5,
};
};
class ParticleSystem
{
PX_NOCOPY(ParticleSystem)
public:
ParticleSystem(Dy::ParticleSystemCore& core) : mCore(core), mShapeCore(NULL),
mElementId(0xffffffff), mGpuRemapId(0xffffffff)
{
mFlag = 0;
}
~ParticleSystem() {}
PX_FORCE_INLINE void setShapeCore(PxsShapeCore* shapeCore)
{
mShapeCore = shapeCore;
}
PX_FORCE_INLINE void setGpuRemapId(const PxU32 remapId)
{
mGpuRemapId = remapId;
PxParticleSystemGeometryLL& geom = mShapeCore->mGeometry.get<PxParticleSystemGeometryLL>();
geom.materialsLL.gpuRemapId = remapId;
}
PX_FORCE_INLINE PxU32 getGpuRemapId() const { return mGpuRemapId; }
PX_FORCE_INLINE void setElementId(const PxU32 elementId) { mElementId = elementId; }
PX_FORCE_INLINE PxU32 getElementId() { return mElementId; }
PX_FORCE_INLINE ParticleSystemCore& getCore() const { return mCore; }
PX_FORCE_INLINE PxsShapeCore& getShapeCore() { return *mShapeCore; }
PX_FORCE_INLINE PxU16 getIterationCounts() { return mCore.solverIterationCounts; }
PxU32 mFlag;
private:
ParticleSystemCore& mCore;
PxsShapeCore* mShapeCore;
PxU32 mElementId; //this is used for the bound array
PxU32 mGpuRemapId;
};
struct ParticleSystemSolverDesc
{
ParticleSystem* particleSystem;
};
PX_FORCE_INLINE ParticleSystem* getParticleSystem(ParticleSystemHandle handle)
{
return reinterpret_cast<ParticleSystem*>(handle);
}
}
}
#endif

View File

@@ -0,0 +1,122 @@
// 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 DY_PARTICLESYSTEM_CORE_H
#define DY_PARTICLESYSTEM_CORE_H
#include "foundation/PxSimpleTypes.h"
#include "foundation/PxTransform.h"
#include "foundation/PxArray.h"
#include "foundation/PxMemory.h"
#include "PxParticleSystem.h"
#include "PxParticleBuffer.h"
#include "CmIDPool.h"
#include "PxParticleSolverType.h"
#include "PxSparseGridParams.h"
namespace physx
{
class PxsParticleBuffer;
namespace Dy
{
class ParticleSystemCore
{
public:
PxReal sleepThreshold;
PxReal freezeThreshold;
PxReal wakeCounter;
PxU32 gridSizeX;
PxU32 gridSizeY;
PxU32 gridSizeZ;
PxU16 solverIterationCounts;
PxSparseGridParams sparseGridParams;
PxReal restOffset;
PxReal particleContactOffset;
PxReal particleContactOffset_prev;
PxReal solidRestOffset;
PxReal fluidRestOffset;
PxReal fluidRestOffset_prev;
PxReal fluidBoundaryDensityScale;
PxReal maxDepenetrationVelocity;
PxReal maxVelocity;
PxParticleFlags mFlags;
PxParticleLockFlags mLockFlags;
PxVec3 mWind;
PxU32 mMaxNeighborhood;
PxReal mNeighborhoodScale;
PxArray<PxU16> mPhaseGroupToMaterialHandle;
PxArray<PxU16> mUniqueMaterialHandles; //just for reporting
PxU32 getNumUserBuffers() const
{
return mParticleBuffers.size() +
mParticleDiffuseBuffers.size() +
mParticleClothBuffers.size() +
mParticleRigidBuffers.size();
}
//device
PxArray<PxsParticleBuffer*> mParticleBuffers;
PxArray<PxsParticleBuffer*> mParticleDiffuseBuffers;
PxArray<PxsParticleBuffer*> mParticleClothBuffers;
PxArray<PxsParticleBuffer*> mParticleRigidBuffers;
bool mParticleBufferUpdate;
bool mParticleDiffuseBufferUpdate;
bool mParticleClothBufferUpdate;
bool mParticleRigidBufferUpdate;
PxParticleSystemCallback* mCallback;
ParticleSystemCore()
{
PxMemSet(this, 0, sizeof(*this));
mParticleBufferUpdate = false;
mParticleDiffuseBufferUpdate = false;
mParticleClothBufferUpdate = false;
mParticleRigidBufferUpdate = false;
}
};
} // namespace Dy
} // namespace physx
#endif

View File

@@ -0,0 +1,180 @@
// 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 CM_ERROR_ACCUMULATOR_H
#define CM_ERROR_ACCUMULATOR_H
#include "foundation/PxVecMath.h"
#include "foundation/PxArray.h"
namespace physx
{
namespace Dy
{
PX_FORCE_INLINE PX_CUDA_CALLABLE PxReal calculateResidual(PxReal deltaF, PxReal velocityMultiplier)
{
return velocityMultiplier == 0.0f ? 0.0f : deltaF / velocityMultiplier;
}
//Vectorized variant
PX_FORCE_INLINE aos::FloatV calculateResidual(const aos::FloatV& deltaF, const aos::FloatV& velocityMultiplier)
{
aos::BoolV isZero = aos::FIsEq(velocityMultiplier, aos::FZero());
return aos::FSel(isZero, aos::FZero(), aos::FDivFast(deltaF, velocityMultiplier));
}
PX_FORCE_INLINE aos::Vec4V calculateResidualV4(const aos::Vec4V& deltaF, const aos::Vec4V& velocityMultiplier)
{
aos::BoolV isZero = aos::V4IsEq(velocityMultiplier, aos::V4Zero());
return aos::V4Sel(isZero, aos::V4Zero(), aos::V4DivFast(deltaF, velocityMultiplier));
}
struct ErrorAccumulator
{
PxReal mErrorSumOfSquares;
PxI32 mCounter;
PxReal mMaxError;
#if !PX_CUDA_COMPILER
PX_FORCE_INLINE ErrorAccumulator() : mErrorSumOfSquares(0.0f), mCounter(0), mMaxError(0.0f)
{ }
#endif
PX_FORCE_INLINE void combine(ErrorAccumulator& other)
{
mErrorSumOfSquares += other.mErrorSumOfSquares;
mCounter += other.mCounter;
mMaxError = PxMax(mMaxError, other.mMaxError);
}
PX_FORCE_INLINE PX_CUDA_CALLABLE void accumulateErrorLocal(PxReal residual)
{
mErrorSumOfSquares += residual * residual;
++mCounter;
mMaxError = PxMax(mMaxError, PxAbs(residual));
}
PX_FORCE_INLINE PX_CUDA_CALLABLE void accumulateErrorLocal(PxReal deltaF, PxReal velocityMultiplier)
{
PxReal e = calculateResidual(deltaF, velocityMultiplier);
accumulateErrorLocal(e);
}
//For friction constraints
PX_FORCE_INLINE void accumulateErrorLocal(PxReal deltaF0, PxReal deltaF1,
PxReal velocityMultiplier0, PxReal velocityMultiplier1)
{
accumulateErrorLocal(deltaF0, velocityMultiplier0);
accumulateErrorLocal(deltaF1, velocityMultiplier1);
}
PX_FORCE_INLINE void accumulateErrorLocal(const aos::FloatV& deltaF, const aos::FloatV& velocityMultiplier)
{
PxReal e;
aos::FStore(calculateResidual(deltaF, velocityMultiplier), &e);
mErrorSumOfSquares += e * e;
++mCounter;
mMaxError = PxMax(mMaxError, PxAbs(e));
}
PX_FORCE_INLINE void accumulateErrorLocal(const aos::FloatV& deltaF0, const aos::FloatV& deltaF1,
const aos::FloatV& velocityMultiplier0, const aos::FloatV& velocityMultiplier1)
{
accumulateErrorLocal(deltaF0, velocityMultiplier0);
accumulateErrorLocal(deltaF1, velocityMultiplier1);
}
//Vectorized variants
PX_FORCE_INLINE void accumulateErrorLocalV4(const aos::Vec4V& deltaF, const aos::Vec4V& velocityMultiplier)
{
aos::BoolV isZero = aos::V4IsEq(velocityMultiplier, aos::V4Zero());
aos::Vec4V div = aos::V4Sel(isZero, aos::V4Zero(), aos::V4DivFast(deltaF, velocityMultiplier));
aos::FloatV dot = aos::V4Dot(div, div);
PxReal tmp;
aos::FStore(dot, &tmp);
mErrorSumOfSquares += tmp;
PxU32 maskNonZero = ~aos::BGetBitMask(isZero);
mCounter += (maskNonZero & 1) + ((maskNonZero & 2) >> 1) + ((maskNonZero & 4) >> 2) + ((maskNonZero & 8) >> 3);
aos::FloatV maxVal = aos::V4ExtractMax(aos::V4Abs(div));
aos::FStore(maxVal, &tmp);
mMaxError = PxMax(mMaxError, tmp);
}
//For friction constraints
PX_FORCE_INLINE void accumulateErrorLocalV4(const aos::Vec4V& deltaF0, const aos::Vec4V& deltaF1,
const aos::Vec4V& velocityMultiplier0, const aos::Vec4V& velocityMultiplier1)
{
accumulateErrorLocalV4(deltaF0, velocityMultiplier0);
accumulateErrorLocalV4(deltaF1, velocityMultiplier1);
}
PX_FORCE_INLINE PX_CUDA_CALLABLE void reset()
{
mErrorSumOfSquares = 0.0f;
mCounter = 0;
mMaxError = 0.0f;
}
PX_FORCE_INLINE void accumulateErrorGlobal(Dy::ErrorAccumulator& globalAccumulator)
{
globalAccumulator.mErrorSumOfSquares += mErrorSumOfSquares;
globalAccumulator.mCounter += mCounter;
if (mMaxError > globalAccumulator.mMaxError)
{
globalAccumulator.mMaxError = mMaxError;
}
}
};
struct ErrorAccumulatorEx
{
ErrorAccumulator mPositionIterationErrorAccumulator;
ErrorAccumulator mVelocityIterationErrorAccumulator;
PX_FORCE_INLINE void reset()
{
mPositionIterationErrorAccumulator.reset();
mVelocityIterationErrorAccumulator.reset();
}
PX_FORCE_INLINE void combine(ErrorAccumulatorEx& other)
{
mPositionIterationErrorAccumulator.combine(other.mPositionIterationErrorAccumulator);
mVelocityIterationErrorAccumulator.combine(other.mVelocityIterationErrorAccumulator);
}
};
} // namespace Cm
}
#endif

View File

@@ -0,0 +1,40 @@
// 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 DY_SLEEPING_CONFIGURATION_H
#define DY_SLEEPING_CONFIGURATION_H
#define PXD_FREEZE_INTERVAL 1.5f
#define PXD_FREE_EXIT_THRESHOLD 4.f
#define PXD_FREEZE_TOLERANCE 0.25f
#define PXD_SLEEP_DAMPING 0.5f
#define PXD_ACCEL_LOSS 0.9f
#define PXD_FREEZE_SCALE 0.1f
#endif

View File

@@ -0,0 +1,282 @@
// 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 DY_THRESHOLD_TABLE_H
#define DY_THRESHOLD_TABLE_H
#include "foundation/PxPinnedArray.h"
#include "foundation/PxUserAllocated.h"
#include "foundation/PxHash.h"
#include "foundation/PxMemory.h"
#include "PxNodeIndex.h"
namespace physx
{
class PxsRigidBody;
namespace Sc
{
class ShapeInteraction;
}
namespace Dy
{
struct ThresholdStreamElement
{
Sc::ShapeInteraction* shapeInteraction; //4/8 4/8
PxReal normalForce; //4 8/12
PxReal threshold; //4 12/16
PxNodeIndex nodeIndexA; //8 24 This is the unique node index in island gen which corresonding to that body and it is persistent 16 20
PxNodeIndex nodeIndexB; //8 32 This is the unique node index in island gen which corresonding to that body and it is persistent 20 24
PxReal accumulatedForce; //4 36
PxU32 pad; //4 40
PX_CUDA_CALLABLE bool operator <= (const ThresholdStreamElement& otherPair) const
{
return ((nodeIndexA < otherPair.nodeIndexA) ||(nodeIndexA == otherPair.nodeIndexA && nodeIndexB <= otherPair.nodeIndexB));
}
PX_CUDA_CALLABLE bool operator < (const ThresholdStreamElement& otherPair) const
{
return ((nodeIndexA < otherPair.nodeIndexA) || (nodeIndexA == otherPair.nodeIndexA && nodeIndexB < otherPair.nodeIndexB));
}
PX_CUDA_CALLABLE bool operator == (const ThresholdStreamElement& otherPair) const
{
return ((nodeIndexA == otherPair.nodeIndexA && nodeIndexB == otherPair.nodeIndexB));
}
};
typedef PxPinnedArray<ThresholdStreamElement> ThresholdArray;
class ThresholdStream : public ThresholdArray, public PxUserAllocated
{
public:
ThresholdStream(PxVirtualAllocatorCallback& allocatorCallback) : ThresholdArray(PxVirtualAllocator(&allocatorCallback))
{
}
};
class ThresholdTable
{
public:
ThresholdTable()
: mBuffer(NULL),
mHash(NULL),
mHashSize(0),
mHashCapactiy(0),
mPairs(NULL),
mNexts(NULL),
mPairsSize(0),
mPairsCapacity(0)
{
}
~ThresholdTable()
{
PX_FREE(mBuffer);
}
void build(const ThresholdStream& stream);
bool check(const ThresholdStream& stream, const PxU32 nodexIndexA, const PxU32 nodexIndexB, PxReal dt);
bool check(const ThresholdStream& stream, const ThresholdStreamElement& elem, PxU32& thresholdIndex);
//private:
static const PxU32 NO_INDEX = 0xffffffff;
struct Pair
{
PxU32 thresholdStreamIndex;
PxReal accumulatedForce;
//PxU32 next; // hash key & next ptr
};
PxU8* mBuffer;
PxU32* mHash;
PxU32 mHashSize;
PxU32 mHashCapactiy;
Pair* mPairs;
PxU32* mNexts;
PxU32 mPairsSize;
PxU32 mPairsCapacity;
};
namespace
{
static PX_FORCE_INLINE PxU32 computeHashKey(const PxU32 nodeIndexA, const PxU32 nodeIndexB, const PxU32 hashCapacity)
{
return (PxComputeHash(PxU64(nodeIndexA)<<32 | PxU64(nodeIndexB)) % hashCapacity);
}
}
inline bool ThresholdTable::check(const ThresholdStream& stream, const ThresholdStreamElement& elem, PxU32& thresholdIndex)
{
PxU32* PX_RESTRICT hashes = mHash;
PxU32* PX_RESTRICT nextIndices = mNexts;
Pair* PX_RESTRICT pairs = mPairs;
PX_ASSERT(elem.nodeIndexA < elem.nodeIndexB);
PxU32 hashKey = computeHashKey(elem.nodeIndexA.index(), elem.nodeIndexB.index(), mHashSize);
PxU32 pairIndex = hashes[hashKey];
while(NO_INDEX != pairIndex)
{
Pair& pair = pairs[pairIndex];
const PxU32 thresholdStreamIndex = pair.thresholdStreamIndex;
PX_ASSERT(thresholdStreamIndex < stream.size());
const ThresholdStreamElement& otherElement = stream[thresholdStreamIndex];
if(otherElement.nodeIndexA==elem.nodeIndexA && otherElement.nodeIndexB==elem.nodeIndexB && otherElement.shapeInteraction == elem.shapeInteraction)
{
thresholdIndex = thresholdStreamIndex;
return true;
}
pairIndex = nextIndices[pairIndex];
}
thresholdIndex = NO_INDEX;
return false;
}
inline void ThresholdTable::build(const ThresholdStream& stream)
{
//Handle the case of an empty stream.
if(0==stream.size())
{
mPairsSize=0;
mPairsCapacity=0;
mHashSize=0;
mHashCapactiy=0;
PX_FREE(mBuffer);
return;
}
//Realloc/resize if necessary.
const PxU32 pairsCapacity = stream.size();
const PxU32 hashCapacity = pairsCapacity*2+1;
if((pairsCapacity > mPairsCapacity) || (pairsCapacity < (mPairsCapacity >> 2)))
{
PX_FREE(mBuffer);
const PxU32 pairsByteSize = sizeof(Pair)*pairsCapacity;
const PxU32 nextsByteSize = sizeof(PxU32)*pairsCapacity;
const PxU32 hashByteSize = sizeof(PxU32)*hashCapacity;
const PxU32 totalByteSize = pairsByteSize + nextsByteSize + hashByteSize;
mBuffer = reinterpret_cast<PxU8*>(PX_ALLOC(totalByteSize, "PxThresholdStream"));
PxU32 offset = 0;
mPairs = reinterpret_cast<Pair*>(mBuffer + offset);
offset += pairsByteSize;
mNexts = reinterpret_cast<PxU32*>(mBuffer + offset);
offset += nextsByteSize;
mHash = reinterpret_cast<PxU32*>(mBuffer + offset);
offset += hashByteSize;
PX_ASSERT(totalByteSize == offset);
mPairsCapacity = pairsCapacity;
mHashCapactiy = hashCapacity;
}
//Set each entry of the hash table to 0xffffffff
PxMemSet(mHash, 0xff, sizeof(PxU32)*hashCapacity);
//Init the sizes of the pairs array and hash array.
mPairsSize = 0;
mHashSize = hashCapacity;
PxU32* PX_RESTRICT hashes = mHash;
PxU32* PX_RESTRICT nextIndices = mNexts;
Pair* PX_RESTRICT pairs = mPairs;
//Add all the pairs from the stream.
PxU32 pairsSize = 0;
for(PxU32 i = 0; i < pairsCapacity; i++)
{
const ThresholdStreamElement& element = stream[i];
const PxNodeIndex nodeIndexA = element.nodeIndexA;
const PxNodeIndex nodeIndexB = element.nodeIndexB;
const PxF32 force = element.normalForce;
PX_ASSERT(nodeIndexA < nodeIndexB);
const PxU32 hashKey = computeHashKey(nodeIndexA.index(), nodeIndexB.index(), hashCapacity);
//Get the index of the first pair found that resulted in a hash that matched hashKey.
PxU32 prevPairIndex = hashKey;
PxU32 pairIndex = hashes[hashKey];
//Search through all pairs found that resulted in a hash that matched hashKey.
//Search until the exact same body pair is found.
//Increment the accumulated force if the exact same body pair is found.
while(NO_INDEX != pairIndex)
{
Pair& pair = pairs[pairIndex];
const PxU32 thresholdStreamIndex = pair.thresholdStreamIndex;
PX_ASSERT(thresholdStreamIndex < stream.size());
const ThresholdStreamElement& otherElement = stream[thresholdStreamIndex];
if(nodeIndexA == otherElement.nodeIndexA && nodeIndexB==otherElement.nodeIndexB)
{
pair.accumulatedForce += force;
prevPairIndex = NO_INDEX;
pairIndex = NO_INDEX;
break;
}
prevPairIndex = pairIndex;
pairIndex = nextIndices[pairIndex];
}
if(NO_INDEX != prevPairIndex)
{
nextIndices[pairsSize] = hashes[hashKey];
hashes[hashKey] = pairsSize;
Pair& newPair = pairs[pairsSize];
newPair.thresholdStreamIndex = i;
newPair.accumulatedForce = force;
pairsSize++;
}
}
mPairsSize = pairsSize;
}
}
}
#endif

View File

@@ -0,0 +1,134 @@
// 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 DY_V_ARTICULATION_H
#define DY_V_ARTICULATION_H
#include "foundation/PxVec3.h"
#include "foundation/PxQuat.h"
#include "foundation/PxTransform.h"
#include "foundation/PxVecMath.h"
#include "foundation/PxUtilities.h"
#include "CmUtils.h"
#include "CmSpatialVector.h"
#include "foundation/PxMemory.h"
#include "DyArticulationCore.h"
#include "DyArticulationJointCore.h"
#include "DyArticulationMimicJointCore.h"
namespace physx
{
struct PxsBodyCore;
class PxsConstraintBlockManager;
class PxsContactManagerOutputIterator;
struct PxSolverConstraintDesc;
struct PxSolverBodyData;
struct PxTGSSolverBodyData;
struct PxTGSSolverBodyTxInertia;
struct PxSolverConstraintDesc;
namespace Dy
{
struct SpatialSubspaceMatrix;
struct ConstraintWriteback;
class ThreadContext;
static const size_t DY_ARTICULATION_TENDON_MAX_SIZE = 64;
struct Constraint;
class Context;
class ArticulationSpatialTendon;
class ArticulationFixedTendon;
class ArticulationTendonJoint;
typedef PxU64 ArticulationBitField;
struct ArticulationLoopConstraint
{
public:
PxU32 linkIndex0;
PxU32 linkIndex1;
Dy::Constraint* constraint;
};
#define DY_ARTICULATION_LINK_NONE 0xffffffff
struct ArticulationLink
{
PxU32 mPathToRootStartIndex;
PxU32 mChildrenStartIndex;
PxU16 mPathToRootCount;
PxU16 mNumChildren;
PxsBodyCore* bodyCore;
ArticulationJointCore* inboundJoint;
PxU32 parent;
PxReal cfm;
};
class FeatherstoneArticulation;
struct ArticulationSolverDesc
{
void initData(ArticulationCore* core_, const PxArticulationFlags* flags_)
{
articulation = NULL;
links = NULL;
motionVelocity = NULL;
acceleration = NULL;
poses = NULL;
deltaQ = NULL;
core = core_;
flags = flags_;
linkCount = 0;
numInternalConstraints = 0;
}
FeatherstoneArticulation* articulation;
ArticulationLink* links;
Cm::SpatialVectorV* motionVelocity;
Cm::SpatialVector* acceleration;
PxTransform* poses;
PxQuat* deltaQ;
ArticulationCore* core;
const PxArticulationFlags* flags; // PT: PX-1399
PxU8 linkCount;
PxU8 numInternalConstraints;
};
}
}
#endif