// 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 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 mTendonJoints; Cm::IDPool mIDPool; PxU32 mIndex; }; }//namespace Dy }//namespace physx #endif