| 1 | // |
| 2 | // Redistribution and use in source and binary forms, with or without |
| 3 | // modification, are permitted provided that the following conditions |
| 4 | // are met: |
| 5 | // * Redistributions of source code must retain the above copyright |
| 6 | // notice, this list of conditions and the following disclaimer. |
| 7 | // * Redistributions in binary form must reproduce the above copyright |
| 8 | // notice, this list of conditions and the following disclaimer in the |
| 9 | // documentation and/or other materials provided with the distribution. |
| 10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
| 11 | // contributors may be used to endorse or promote products derived |
| 12 | // from this software without specific prior written permission. |
| 13 | // |
| 14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
| 15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| 18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 | // |
| 26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
| 27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
| 28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
| 29 | |
| 30 | |
| 31 | #ifndef PXD_FEATHERSTONE_ARTICULATION_H |
| 32 | #define PXD_FEATHERSTONE_ARTICULATION_H |
| 33 | |
| 34 | #include "foundation/PxVec3.h" |
| 35 | #include "foundation/PxQuat.h" |
| 36 | #include "foundation/PxTransform.h" |
| 37 | #include "PsVecMath.h" |
| 38 | #include "CmUtils.h" |
| 39 | #include "PxArticulationJoint.h" |
| 40 | #include "DyVArticulation.h" |
| 41 | #include "DyFeatherstoneArticulationUtils.h" |
| 42 | #include "DyFeatherstoneArticulationJointData.h" |
| 43 | #include "solver/PxSolverDefs.h" |
| 44 | |
| 45 | #ifndef FEATHERSTONE_DEBUG |
| 46 | #define FEATHERSTONE_DEBUG 0 |
| 47 | #endif |
| 48 | |
| 49 | namespace physx |
| 50 | { |
| 51 | |
| 52 | class PxContactJoint; |
| 53 | //struct PxSolverConstraintDesc; |
| 54 | class PxcConstraintBlockStream; |
| 55 | class PxcScratchAllocator; |
| 56 | class PxsConstraintBlockManager; |
| 57 | struct SolverConstraint1DExtStep; |
| 58 | struct PxSolverConstraintPrepDesc; |
| 59 | struct PxSolverBody; |
| 60 | struct PxSolverBodyData; |
| 61 | class PxConstraintAllocator; |
| 62 | class PxsContactManagerOutputIterator; |
| 63 | |
| 64 | struct PxSolverConstraintDesc; |
| 65 | |
| 66 | namespace Dy |
| 67 | { |
| 68 | //#if PX_VC |
| 69 | //#pragma warning(push) |
| 70 | //#pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. |
| 71 | //#endif |
| 72 | |
| 73 | |
| 74 | //class ArticulationJointCoreData; |
| 75 | class ArticulationLinkData; |
| 76 | struct SpatialSubspaceMatrix; |
| 77 | struct SolverConstraint1DExt; |
| 78 | struct SolverConstraint1DStep; |
| 79 | |
| 80 | class FeatherstoneArticulation; |
| 81 | struct SpatialMatrix; |
| 82 | struct SpatialTransform; |
| 83 | struct Constraint; |
| 84 | class ThreadContext; |
| 85 | |
| 86 | /* struct DyScratchAllocator |
| 87 | { |
| 88 | char* base; |
| 89 | size_t size; |
| 90 | size_t taken; |
| 91 | |
| 92 | DyScratchAllocator(char* p, size_t s) : base(p), size(s), taken(0) {} |
| 93 | |
| 94 | PxU32 round16(PxU32 size_) { return (size_ + 15)&(~15); } |
| 95 | |
| 96 | template<class T> T* alloc(PxU32 count) |
| 97 | { |
| 98 | const PxU32 sizeReq = round16(sizeof(T)*count); |
| 99 | PX_ASSERT((taken+ sizeReq) < size); |
| 100 | T* result = reinterpret_cast<T*>(base + taken); |
| 101 | taken += sizeReq; |
| 102 | return result; |
| 103 | } |
| 104 | };*/ |
| 105 | |
| 106 | //This stuct is used in TGS |
| 107 | /* class ArticulationTempData |
| 108 | { |
| 109 | public: |
| 110 | Cm::SpatialVectorF mBaseLinkMotionVelocite; |
| 111 | Ps::Array<Cm::SpatialVectorF> mZAForce; |
| 112 | Ps::Array<PxReal> mJointPosition; // joint position |
| 113 | Ps::Array<PxReal> mJointVelocity; // joint velocity |
| 114 | Ps::Array<PxTransform> mLinkTransform; // this is the transform list for links |
| 115 | };*/ |
| 116 | |
| 117 | struct ArticulationInternalConstraint |
| 118 | { |
| 119 | //Common/shared directional info between, frictions and drives |
| 120 | Cm::UnAlignedSpatialVector row0; //24 24 |
| 121 | Cm::UnAlignedSpatialVector row1; //24 48 |
| 122 | Cm::UnAlignedSpatialVector deltaVA; //24 72 |
| 123 | Cm::UnAlignedSpatialVector deltaVB; //24 96 |
| 124 | //Response information |
| 125 | PxReal recipResponse; //4 100 |
| 126 | PxReal response; //4 104 |
| 127 | //Joint limit values |
| 128 | PxReal lowLimit; //4 108 |
| 129 | PxReal highLimit; //4 112 |
| 130 | PxReal lowImpulse; //4 116 changed |
| 131 | PxReal highImpulse; //4 120 changed |
| 132 | PxReal erp; //4 124 |
| 133 | //Joint spring drive info |
| 134 | PxReal driveTargetVel; //4 128 |
| 135 | PxReal driveBiasCoefficient; //4 132 |
| 136 | PxReal driveTarget; //4 136 |
| 137 | PxReal driveVelMultiplier; //4 140 |
| 138 | PxReal driveBackPropagateScale; //4 144 |
| 139 | PxReal driveImpulseMultiplier; //4 148 |
| 140 | PxReal maxDriveForce; //4 152 |
| 141 | PxReal driveForce; //4 156 |
| 142 | |
| 143 | PxReal maxFrictionForce; //4 160 |
| 144 | PxReal frictionForce; //4 164 |
| 145 | PxReal frictionForceCoefficient; //4 168 |
| 146 | |
| 147 | bool isLinearConstraint; //1 169 |
| 148 | PxU8 padding[7]; //11 176 |
| 149 | }; |
| 150 | |
| 151 | struct ArticulationInternalLockedAxis |
| 152 | { |
| 153 | //How much an impulse will effect angular velocity |
| 154 | Cm::UnAlignedSpatialVector deltaVA; //24 24 |
| 155 | Cm::UnAlignedSpatialVector deltaVB; //24 48 |
| 156 | //Jacobian axis that is locked |
| 157 | PxVec3 axis; //12 60 |
| 158 | //Response information |
| 159 | PxReal recipResponse; //4 64 |
| 160 | //Initial error |
| 161 | PxReal error; //4 68 |
| 162 | //Bias scale |
| 163 | PxReal biasScale; //4 72 |
| 164 | |
| 165 | PxU32 pad[2]; //4 80 |
| 166 | }; |
| 167 | |
| 168 | class ArticulationData |
| 169 | { |
| 170 | public: |
| 171 | |
| 172 | ArticulationData() : |
| 173 | mLinksData(NULL), mJointData(NULL), mJointTranData(NULL), |
| 174 | mDt(0.f), mDofs(0xffffffff), mLocks(0), mDataDirty(true) |
| 175 | { |
| 176 | mRootPreMotionVelocity = Cm::SpatialVectorF::Zero(); |
| 177 | } |
| 178 | |
| 179 | ~ArticulationData(); |
| 180 | |
| 181 | PX_FORCE_INLINE void init(); |
| 182 | void resizeLinkData(const PxU32 linkCount); |
| 183 | void resizeJointData(const PxU32 dofs); |
| 184 | |
| 185 | PX_FORCE_INLINE PxReal* getJointAccelerations() { return mJointAcceleration.begin(); } |
| 186 | PX_FORCE_INLINE const PxReal* getJointAccelerations() const { return mJointAcceleration.begin(); } |
| 187 | PX_FORCE_INLINE PxReal* getJointVelocities() { return mJointVelocity.begin(); } |
| 188 | PX_FORCE_INLINE const PxReal* getJointVelocities() const { return mJointVelocity.begin(); } |
| 189 | PX_FORCE_INLINE PxReal* getJointDeltaVelocities() { return mJointDeltaVelocity.begin(); } |
| 190 | PX_FORCE_INLINE const PxReal* getJointDeltaVelocities() const { return mJointDeltaVelocity.begin(); } |
| 191 | PX_FORCE_INLINE PxReal* getJointPositions() { return mJointPosition.begin(); } |
| 192 | PX_FORCE_INLINE const PxReal* getJointPositions() const { return mJointPosition.begin(); } |
| 193 | PX_FORCE_INLINE PxReal* getJointForces() { return mJointForce.begin(); } |
| 194 | PX_FORCE_INLINE const PxReal* getJointForces() const { return mJointForce.begin(); } |
| 195 | //PX_FORCE_INLINE PxReal* getJointFrictionForces() { return mJointFrictionForce.begin(); } |
| 196 | |
| 197 | PX_FORCE_INLINE ArticulationInternalConstraint& getInternalConstraint(const PxU32 dofId) { return mInternalConstraints[dofId]; } |
| 198 | PX_FORCE_INLINE const ArticulationInternalConstraint& getInternalConstraint(const PxU32 dofId) const { return mInternalConstraints[dofId]; } |
| 199 | |
| 200 | PX_FORCE_INLINE ArticulationInternalLockedAxis& getInternalLocks(const PxU32 dofId) { return mInternalLockedAxes[dofId]; } |
| 201 | PX_FORCE_INLINE const ArticulationInternalLockedAxis& getInternalLocks(const PxU32 dofId) const { return mInternalLockedAxes[dofId]; } |
| 202 | |
| 203 | PX_FORCE_INLINE Cm::SpatialVectorF* getMotionVelocities() { return mMotionVelocities.begin(); } |
| 204 | PX_FORCE_INLINE Cm::SpatialVectorF* getMotionAccelerations() { return mMotionAccelerations.begin(); } |
| 205 | PX_FORCE_INLINE const Cm::SpatialVectorF* getMotionAccelerations() const { return mMotionAccelerations.begin(); } |
| 206 | PX_FORCE_INLINE Cm::SpatialVectorF* getCorioliseVectors() { return mCorioliseVectors.begin(); } |
| 207 | PX_FORCE_INLINE Cm::SpatialVectorF* getSpatialZAVectors() { return mZAForces.begin(); } |
| 208 | PX_FORCE_INLINE Cm::SpatialVectorF* getTransmittedForces() { return mJointTransmittedForce.begin(); } |
| 209 | |
| 210 | PX_FORCE_INLINE Cm::SpatialVectorF* getPosIterMotionVelocities() { return mPosIterMotionVelocities.begin(); } |
| 211 | PX_FORCE_INLINE PxReal* getPosIterJointDeltaVelocities() { return mPosIterJointDeltaVelocities.begin(); } |
| 212 | |
| 213 | PX_FORCE_INLINE Cm::SpatialVectorF& getPosIterMotionVelocity(const PxU32 index) { return mPosIterMotionVelocities[index]; } |
| 214 | PX_FORCE_INLINE const Cm::SpatialVectorF& getMotionVelocity(const PxU32 index) const { return mMotionVelocities[index]; } |
| 215 | PX_FORCE_INLINE const Cm::SpatialVectorF& getMotionAcceleration(const PxU32 index) const { return mMotionAccelerations[index]; } |
| 216 | PX_FORCE_INLINE const Cm::SpatialVectorF& getCorioliseVector(const PxU32 index) const { return mCorioliseVectors[index]; } |
| 217 | PX_FORCE_INLINE const Cm::SpatialVectorF& getSpatialZAVector(const PxU32 index) const { return mZAForces[index]; } |
| 218 | PX_FORCE_INLINE const Cm::SpatialVectorF& getTransmittedForce(const PxU32 index) const { return mJointTransmittedForce[index]; } |
| 219 | |
| 220 | PX_FORCE_INLINE Cm::SpatialVectorF& getMotionVelocity(const PxU32 index) { return mMotionVelocities[index]; } |
| 221 | PX_FORCE_INLINE Cm::SpatialVectorF& getMotionAcceleration(const PxU32 index) { return mMotionAccelerations[index]; } |
| 222 | PX_FORCE_INLINE Cm::SpatialVectorF& getCorioliseVector(const PxU32 index) { return mCorioliseVectors[index]; } |
| 223 | PX_FORCE_INLINE Cm::SpatialVectorF& getSpatialZAVector(const PxU32 index) { return mZAForces[index]; } |
| 224 | PX_FORCE_INLINE Cm::SpatialVectorF& getTransmittedForce(const PxU32 index) { return mJointTransmittedForce[index]; } |
| 225 | |
| 226 | //PX_FORCE_INLINE Dy::SpatialMatrix* getTempSpatialMatrix() { mTempSpatialMatrix.begin(); } |
| 227 | |
| 228 | PX_FORCE_INLINE PxTransform& getPreTransform(const PxU32 index) { return mPreTransform[index]; } |
| 229 | PX_FORCE_INLINE const PxTransform& getPreTransform(const PxU32 index) const { return mPreTransform[index]; } |
| 230 | // PX_FORCE_INLINE void setPreTransform(const PxU32 index, const PxTransform& t){ mPreTransform[index] = t; } |
| 231 | PX_FORCE_INLINE PxTransform* getPreTransform() { return mPreTransform.begin(); } |
| 232 | |
| 233 | PX_FORCE_INLINE const Cm::SpatialVectorF& getDeltaMotionVector(const PxU32 index) const { return mDeltaMotionVector[index]; } |
| 234 | PX_FORCE_INLINE void setDeltaMotionVector(const PxU32 index, const Cm::SpatialVectorF& vec) { mDeltaMotionVector[index] = vec; } |
| 235 | PX_FORCE_INLINE Cm::SpatialVectorF* getDeltaMotionVector() { return mDeltaMotionVector.begin(); } |
| 236 | |
| 237 | PX_FORCE_INLINE ArticulationLink* getLinks() const { return mLinks; } |
| 238 | PX_FORCE_INLINE PxU32 getLinkCount() const { return mLinkCount; } |
| 239 | |
| 240 | PX_FORCE_INLINE ArticulationLink& getLink(PxU32 index) const { return mLinks[index]; } |
| 241 | |
| 242 | PX_FORCE_INLINE ArticulationLinkData* getLinkData() const { return mLinksData; } |
| 243 | ArticulationLinkData& getLinkData(PxU32 index) const; |
| 244 | |
| 245 | PX_FORCE_INLINE ArticulationJointCoreData* getJointData() const { return mJointData; } |
| 246 | PX_FORCE_INLINE ArticulationJointCoreData& getJointData(PxU32 index) const { return mJointData[index]; } |
| 247 | |
| 248 | PX_FORCE_INLINE ArticulationJointTargetData* getJointTranData() const { return mJointTranData; } |
| 249 | PX_FORCE_INLINE ArticulationJointTargetData& getJointTranData(PxU32 index) const { return mJointTranData[index]; } |
| 250 | // PT: PX-1399 |
| 251 | PX_FORCE_INLINE PxArticulationFlags getArticulationFlags() const { return *mFlags; } |
| 252 | |
| 253 | PX_FORCE_INLINE Cm::SpatialVector* getExternalAccelerations() { return mExternalAcceleration; } |
| 254 | |
| 255 | PX_FORCE_INLINE PxU32 getSolverDataSize() const { return mSolverDataSize; } |
| 256 | PX_FORCE_INLINE Cm::SpatialVector& getExternalAcceleration(const PxU32 linkID) { return mExternalAcceleration[linkID]; } |
| 257 | |
| 258 | PX_FORCE_INLINE PxReal getDt() const { return mDt; } |
| 259 | PX_FORCE_INLINE void setDt(const PxReal dt) { mDt = dt; } |
| 260 | |
| 261 | PX_FORCE_INLINE bool getDataDirty() const { return mDataDirty; } |
| 262 | PX_FORCE_INLINE void setDataDirty(const bool dirty) { mDataDirty = dirty; } |
| 263 | |
| 264 | PX_FORCE_INLINE PxU32 getDofs() const { return mDofs; } |
| 265 | PX_FORCE_INLINE void setDofs(const PxU32 dof) { mDofs = dof; } |
| 266 | |
| 267 | PX_FORCE_INLINE PxU32 getLocks() const { return mLocks; } |
| 268 | PX_FORCE_INLINE void setLocks(const PxU32 locks) { mLocks = locks; } |
| 269 | |
| 270 | PX_FORCE_INLINE FeatherstoneArticulation* getArticulation() { return mArticulation; } |
| 271 | PX_FORCE_INLINE void setArticulation(FeatherstoneArticulation* articulation) { mArticulation = articulation; } |
| 272 | |
| 273 | PX_FORCE_INLINE const SpatialMatrix& getBaseInvSpatialArticulatedInertiaW() const { return mBaseInvSpatialArticulatedInertiaW; } |
| 274 | |
| 275 | PX_FORCE_INLINE PxTransform* getAccumulatedPoses() { return mAccumulatedPoses.begin(); } |
| 276 | PX_FORCE_INLINE const PxTransform* getAccumulatedPoses() const { return mAccumulatedPoses.begin(); } |
| 277 | |
| 278 | PX_FORCE_INLINE SpatialImpulseResponseMatrix* getImpulseResponseMatrixWorld() { return mResponseMatrixW.begin(); } |
| 279 | |
| 280 | PX_FORCE_INLINE const SpatialImpulseResponseMatrix* getImpulseResponseMatrixWorld() const { return mResponseMatrixW.begin(); } |
| 281 | |
| 282 | PX_FORCE_INLINE const SpatialMatrix& getWorldSpatialArticulatedInertia(const PxU32 linkID) const { return mWorldSpatialArticulatedInertia[linkID]; } |
| 283 | |
| 284 | |
| 285 | PX_FORCE_INLINE const InvStIs& getInvStIs(const PxU32 linkID) const { return mInvStIs[linkID]; } |
| 286 | |
| 287 | PX_FORCE_INLINE const SpatialSubspaceMatrix& getMotionMatrix(const PxU32 linkID) const { return mMotionMatrix[linkID]; } |
| 288 | PX_FORCE_INLINE const SpatialSubspaceMatrix& getWorldMotionMatrix(const PxU32 linkID) const { return mWorldMotionMatrix[linkID]; } |
| 289 | |
| 290 | PX_FORCE_INLINE const IsInvD& getWorldIsInvD(const PxU32 linkID) const { return mIsInvDW[linkID]; } |
| 291 | |
| 292 | private: |
| 293 | Cm::SpatialVectorF mRootPreMotionVelocity; |
| 294 | Ps::Array<PxReal> mJointAcceleration; // joint acceleration |
| 295 | Ps::Array<PxReal> mJointVelocity; // joint velocity |
| 296 | Ps::Array<PxReal> mJointDeltaVelocity; // joint velocity change due to contacts |
| 297 | Ps::Array<PxReal> mJointPosition; // joint position |
| 298 | Ps::Array<PxReal> mJointForce; // joint force |
| 299 | //Ps::Array<PxReal> mJointFrictionForce; // joint friction force |
| 300 | |
| 301 | Ps::Array<PxReal> mPosIterJointDeltaVelocities; //joint delta velocity after postion iternation before velocity iteration |
| 302 | Ps::Array<Cm::SpatialVectorF> mPosIterMotionVelocities; //link motion velocites after position iteration before velocity iteration |
| 303 | Ps::Array<Cm::SpatialVectorF> mMotionVelocities; //link motion velocites |
| 304 | Ps::Array<Cm::SpatialVectorF> mMotionAccelerations; //link motion accelerations |
| 305 | Ps::Array<Cm::SpatialVectorF> mCorioliseVectors; //link coriolise vector |
| 306 | Ps::Array<Cm::SpatialVectorF> mZAForces; //link spatial zero acceleration force/ spatial articulated force |
| 307 | Ps::Array<Cm::SpatialVectorF> mJointTransmittedForce; |
| 308 | Ps::Array<ArticulationInternalConstraint> mInternalConstraints; |
| 309 | Ps::Array<ArticulationInternalLockedAxis> mInternalLockedAxes; |
| 310 | |
| 311 | Ps::Array<Cm::SpatialVectorF> mDeltaMotionVector; //this is for TGS solver |
| 312 | Ps::Array<PxTransform> mPreTransform; //this is the previous transform list for links |
| 313 | Ps::Array<SpatialImpulseResponseMatrix> mResponseMatrixW; |
| 314 | Ps::Array<SpatialMatrix> mWorldSpatialArticulatedInertia; |
| 315 | Ps::Array<InvStIs> mInvStIs; |
| 316 | Ps::Array<SpatialSubspaceMatrix> mMotionMatrix; |
| 317 | Ps::Array<SpatialSubspaceMatrix> mWorldMotionMatrix; |
| 318 | Ps::Array<IsInvD> mIsInvDW; |
| 319 | |
| 320 | Ps::Array<PxU32> mNbStaticConstraints; |
| 321 | Ps::Array<PxU32> mStaticConstraintStartIndex; |
| 322 | |
| 323 | Ps::Array<PxQuat> mRelativeQuat; |
| 324 | |
| 325 | |
| 326 | //Ps::Array<SpatialMatrix> mTempSpatialMatrix; |
| 327 | |
| 328 | ArticulationLink* mLinks; |
| 329 | PxU32 mLinkCount; |
| 330 | ArticulationLinkData* mLinksData; |
| 331 | ArticulationJointCoreData* mJointData; |
| 332 | ArticulationJointTargetData* mJointTranData; |
| 333 | PxReal mDt; |
| 334 | PxU32 mDofs; |
| 335 | PxU32 mLocks; |
| 336 | const PxArticulationFlags* mFlags; // PT: PX-1399 |
| 337 | Cm::SpatialVector* mExternalAcceleration; |
| 338 | PxU32 mSolverDataSize; |
| 339 | bool mDataDirty; //this means we need to call commonInit() |
| 340 | bool mJointDirty; //this means joint delta velocity has been changed by contacts so we need to update joint velocity/joint acceleration |
| 341 | FeatherstoneArticulation* mArticulation; |
| 342 | |
| 343 | Ps::Array<PxTransform> mAccumulatedPoses; |
| 344 | Ps::Array<PxQuat> mDeltaQ; |
| 345 | //PxReal mAccumulatedDt; |
| 346 | |
| 347 | SpatialMatrix mBaseInvSpatialArticulatedInertiaW; |
| 348 | |
| 349 | |
| 350 | |
| 351 | friend class FeatherstoneArticulation; |
| 352 | }; |
| 353 | |
| 354 | void ArticulationData::init() |
| 355 | { |
| 356 | //zero delta motion vector for TGS solver |
| 357 | PxMemZero(dest: getDeltaMotionVector(), count: sizeof(Cm::SpatialVectorF) * mLinkCount); |
| 358 | |
| 359 | //zero joint velocity delta, which will be changed in pxcFsApplyImpulse if there are any contact with links |
| 360 | PxMemZero(dest: getJointDeltaVelocities(), count: sizeof(PxReal) * mDofs); |
| 361 | mJointDirty = false; |
| 362 | } |
| 363 | |
| 364 | struct ScratchData |
| 365 | { |
| 366 | public: |
| 367 | ScratchData() |
| 368 | { |
| 369 | motionVelocities = NULL; |
| 370 | motionAccelerations = NULL; |
| 371 | coriolisVectors = NULL; |
| 372 | spatialZAVectors = NULL; |
| 373 | externalAccels = NULL; |
| 374 | compositeSpatialInertias = NULL; |
| 375 | |
| 376 | jointVelocities = NULL; |
| 377 | jointAccelerations = NULL; |
| 378 | jointForces = NULL; |
| 379 | jointPositions = NULL; |
| 380 | jointFrictionForces = NULL; |
| 381 | } |
| 382 | |
| 383 | Cm::SpatialVectorF* motionVelocities; |
| 384 | Cm::SpatialVectorF* motionAccelerations; |
| 385 | Cm::SpatialVectorF* coriolisVectors; |
| 386 | Cm::SpatialVectorF* spatialZAVectors; |
| 387 | Cm::SpatialVector* externalAccels; |
| 388 | Dy::SpatialMatrix* compositeSpatialInertias; |
| 389 | |
| 390 | PxReal* jointVelocities; |
| 391 | PxReal* jointAccelerations; |
| 392 | PxReal* jointForces; |
| 393 | PxReal* jointPositions; |
| 394 | PxReal* jointFrictionForces; |
| 395 | }; |
| 396 | |
| 397 | #if PX_VC |
| 398 | #pragma warning(push) |
| 399 | #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. |
| 400 | #endif |
| 401 | |
| 402 | //Articulation dirty flag - used to tag which properties of the articulation are dirty. Used only to transfer selected data to the GPU... |
| 403 | struct ArticulationDirtyFlag |
| 404 | { |
| 405 | enum Enum |
| 406 | { |
| 407 | eDIRTY_JOINTS = 1<<0, |
| 408 | eDIRTY_POSITIONS = 1<<1, |
| 409 | eDIRTY_VELOCITIES = 1<<2, |
| 410 | eDIRTY_ACCELERATIONS = 1<<3, |
| 411 | eDIRTY_FORCES = 1<<4, |
| 412 | eDIRTY_ROOT = 1<<5, |
| 413 | eDIRTY_LINKS = 1<<6, |
| 414 | eIN_DIRTY_LIST = 1<<7, |
| 415 | eDIRTY_DOFS = (eDIRTY_POSITIONS | eDIRTY_VELOCITIES | eDIRTY_ACCELERATIONS | eDIRTY_FORCES) |
| 416 | }; |
| 417 | }; |
| 418 | |
| 419 | PX_INLINE void computeArticJacobianAxes(PxVec3 row[3], const PxQuat& qa, const PxQuat& qb) |
| 420 | { |
| 421 | // Compute jacobian matrix for (qa* qb) [[* means conjugate in this expr]] |
| 422 | // d/dt (qa* qb) = 1/2 L(qa*) R(qb) (omega_b - omega_a) |
| 423 | // result is L(qa*) R(qb), where L(q) and R(q) are left/right q multiply matrix |
| 424 | |
| 425 | const PxReal wa = qa.w, wb = qb.w; |
| 426 | const PxVec3 va(qa.x, qa.y, qa.z), vb(qb.x, qb.y, qb.z); |
| 427 | |
| 428 | const PxVec3 c = vb*wa + va*wb; |
| 429 | const PxReal d0 = wa*wb; |
| 430 | const PxReal d1 = va.dot(v: vb); |
| 431 | const PxReal d = d0 - d1; |
| 432 | |
| 433 | row[0] = (va * vb.x + vb * va.x + PxVec3(d, c.z, -c.y)) * 0.5f; |
| 434 | row[1] = (va * vb.y + vb * va.y + PxVec3(-c.z, d, c.x)) * 0.5f; |
| 435 | row[2] = (va * vb.z + vb * va.z + PxVec3(c.y, -c.x, d)) * 0.5f; |
| 436 | |
| 437 | if ((d0 + d1) != 0.0f) // check if relative rotation is 180 degrees which can lead to singular matrix |
| 438 | return; |
| 439 | else |
| 440 | { |
| 441 | row[0].x += PX_EPS_F32; |
| 442 | row[1].y += PX_EPS_F32; |
| 443 | row[2].z += PX_EPS_F32; |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | |
| 448 | PX_ALIGN_PREFIX(64) |
| 449 | class FeatherstoneArticulation : public ArticulationV |
| 450 | { |
| 451 | PX_NOCOPY(FeatherstoneArticulation) |
| 452 | public: |
| 453 | // public interface |
| 454 | |
| 455 | explicit FeatherstoneArticulation(void*); |
| 456 | ~FeatherstoneArticulation(); |
| 457 | |
| 458 | // get data sizes for allocation at higher levels |
| 459 | virtual void getDataSizes(PxU32 linkCount, PxU32& solverDataSize, PxU32& totalSize, PxU32& scratchSize); |
| 460 | |
| 461 | virtual bool resize(const PxU32 linkCount); |
| 462 | |
| 463 | virtual void onUpdateSolverDesc(); |
| 464 | |
| 465 | virtual PxU32 getDofs(); |
| 466 | |
| 467 | virtual PxU32 getDof(const PxU32 linkID); |
| 468 | |
| 469 | virtual bool applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag); |
| 470 | |
| 471 | virtual void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag); |
| 472 | |
| 473 | virtual void packJointData(const PxReal* maximum, PxReal* reduced); |
| 474 | |
| 475 | virtual void unpackJointData(const PxReal* reduced, PxReal* maximum); |
| 476 | |
| 477 | virtual void initializeCommonData(); |
| 478 | |
| 479 | //gravity as input, joint force as output |
| 480 | virtual void getGeneralizedGravityForce(const PxVec3& gravity, PxArticulationCache& cache); |
| 481 | |
| 482 | //joint velocity as input, generalised force(coriolis and centrigugal force) as output |
| 483 | virtual void getCoriolisAndCentrifugalForce(PxArticulationCache& cache); |
| 484 | |
| 485 | //external force as input, joint force as output |
| 486 | virtual void getGeneralizedExternalForce(PxArticulationCache& /*cache*/); |
| 487 | |
| 488 | //joint force as input, joint acceleration as output |
| 489 | virtual void getJointAcceleration(const PxVec3& gravity, PxArticulationCache& cache); |
| 490 | |
| 491 | //joint acceleration as input, joint force as out |
| 492 | virtual void getJointForce(PxArticulationCache& cache); |
| 493 | |
| 494 | virtual void getDenseJacobian(PxArticulationCache& cache, PxU32 & nRows, PxU32 & nCols); |
| 495 | |
| 496 | //These two functions are for closed loop system |
| 497 | void getKMatrix(ArticulationJointCore* loopJoint, const PxU32 parentIndex, const PxU32 childIndex, PxArticulationCache& cache); |
| 498 | |
| 499 | virtual void getCoefficientMatrix(const PxReal dt, const PxU32 linkID, const PxContactJoint* contactJoints, const PxU32 nbContacts, PxArticulationCache& cache); |
| 500 | |
| 501 | virtual void getCoefficientMatrixWithLoopJoints(ArticulationLoopConstraint* lConstraints, const PxU32 nbJoints, PxArticulationCache& cache); |
| 502 | |
| 503 | virtual bool getLambda(ArticulationLoopConstraint* lConstraints, const PxU32 nbJoints, PxArticulationCache& cache, PxArticulationCache& rollBackCache, |
| 504 | const PxReal* jointTorque, const PxVec3& gravity, const PxU32 maxIter); |
| 505 | |
| 506 | virtual void getGeneralizedMassMatrix(PxArticulationCache& cache); |
| 507 | |
| 508 | virtual void getGeneralizedMassMatrixCRB(PxArticulationCache& cache); |
| 509 | |
| 510 | virtual bool storeStaticConstraint(const PxSolverConstraintDesc& desc); |
| 511 | |
| 512 | virtual bool willStoreStaticConstraint() { return true; } |
| 513 | |
| 514 | virtual void teleportRootLink(); |
| 515 | |
| 516 | virtual void getImpulseResponse( |
| 517 | PxU32 linkID, |
| 518 | Cm::SpatialVectorF* Z, |
| 519 | const Cm::SpatialVector& impulse, |
| 520 | Cm::SpatialVector& deltaV) const; |
| 521 | |
| 522 | virtual void getImpulseResponse( |
| 523 | PxU32 linkID, |
| 524 | Cm::SpatialVectorV* /*Z*/, |
| 525 | const Cm::SpatialVectorV& impulse, |
| 526 | Cm::SpatialVectorV& deltaV) const; |
| 527 | |
| 528 | virtual void getImpulseSelfResponse( |
| 529 | PxU32 linkID0, |
| 530 | PxU32 linkID1, |
| 531 | Cm::SpatialVectorF* Z, |
| 532 | const Cm::SpatialVector& impulse0, |
| 533 | const Cm::SpatialVector& impulse1, |
| 534 | Cm::SpatialVector& deltaV0, |
| 535 | Cm::SpatialVector& deltaV1) const; |
| 536 | |
| 537 | virtual Cm::SpatialVectorV getLinkVelocity(const PxU32 linkID) const; |
| 538 | |
| 539 | virtual Cm::SpatialVectorV getLinkMotionVector(const PxU32 linkID) const; |
| 540 | |
| 541 | //this is called by island gen to determine whether the articulation should be awake or sleep |
| 542 | virtual Cm::SpatialVector getMotionVelocity(const PxU32 linkID) const; |
| 543 | |
| 544 | virtual Cm::SpatialVector getMotionAcceleration(const PxU32 linkID) const; |
| 545 | |
| 546 | virtual void fillIndexedManager(const PxU32 linkId, Dy::ArticulationLinkHandle& handle, PxU8& indexType); |
| 547 | |
| 548 | virtual PxReal getLinkMaxPenBias(const PxU32 linkID) const; |
| 549 | |
| 550 | static PxU32 computeUnconstrainedVelocities( |
| 551 | const ArticulationSolverDesc& desc, |
| 552 | PxReal dt, |
| 553 | PxConstraintAllocator& allocator, |
| 554 | PxSolverConstraintDesc* constraintDesc, |
| 555 | PxU32& acCount, |
| 556 | const PxVec3& gravity, PxU64 contextID, |
| 557 | Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); |
| 558 | |
| 559 | static void computeUnconstrainedVelocitiesTGS( |
| 560 | const ArticulationSolverDesc& desc, |
| 561 | PxReal dt, const PxVec3& gravity, |
| 562 | PxU64 contextID, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); |
| 563 | |
| 564 | static PxU32 setupSolverConstraintsTGS(const ArticulationSolverDesc& articDesc, |
| 565 | PxcConstraintBlockStream& stream, |
| 566 | PxSolverConstraintDesc* constraintDesc, |
| 567 | PxReal dt, |
| 568 | PxReal invDt, |
| 569 | PxReal totalDt, |
| 570 | PxU32& acCount, |
| 571 | PxsConstraintBlockManager& constraintBlockManager, |
| 572 | Cm::SpatialVectorF* Z); |
| 573 | |
| 574 | static void saveVelocity(const ArticulationSolverDesc& d, Cm::SpatialVectorF* deltaV); |
| 575 | |
| 576 | static void saveVelocityTGS(const ArticulationSolverDesc& d, PxReal invDtF32); |
| 577 | |
| 578 | static void updateBodies(const ArticulationSolverDesc& desc, PxReal dt); |
| 579 | |
| 580 | static void updateBodiesTGS(const ArticulationSolverDesc& desc, PxReal dt); |
| 581 | |
| 582 | static void updateBodies(FeatherstoneArticulation* articulation, PxReal dt, bool integrateJointPosition); |
| 583 | |
| 584 | static void recordDeltaMotion(const ArticulationSolverDesc& desc, const PxReal dt, Cm::SpatialVectorF* deltaV, const PxReal totalInvDt); |
| 585 | |
| 586 | static void deltaMotionToMotionVelocity(const ArticulationSolverDesc& desc, PxReal invDt); |
| 587 | |
| 588 | virtual void pxcFsApplyImpulse(PxU32 linkID, Ps::aos::Vec3V linear, |
| 589 | Ps::aos::Vec3V angular, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); |
| 590 | |
| 591 | virtual void pxcFsApplyImpulses(PxU32 linkID, const Ps::aos::Vec3V& linear, |
| 592 | const Ps::aos::Vec3V& angular, PxU32 linkID2, const Ps::aos::Vec3V& linear2, |
| 593 | const Ps::aos::Vec3V& angular2, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); |
| 594 | |
| 595 | virtual void pxcFsApplyImpulses(Cm::SpatialVectorF* Z); |
| 596 | |
| 597 | virtual Cm::SpatialVectorV pxcFsGetVelocity(PxU32 linkID); |
| 598 | |
| 599 | virtual void pxcFsGetVelocities(PxU32 linkID, PxU32 linkID1, Cm::SpatialVectorV& v0, Cm::SpatialVectorV& v1); |
| 600 | |
| 601 | virtual Cm::SpatialVectorV pxcFsGetVelocityTGS(PxU32 linkID); |
| 602 | |
| 603 | virtual const PxTransform& getCurrentTransform(PxU32 linkID) const; |
| 604 | |
| 605 | virtual const PxQuat& getDeltaQ(PxU32 linkID) const; |
| 606 | |
| 607 | //Applies a set of N impulses, all in local space and updates the links' motion and joint velocities |
| 608 | void applyImpulses(Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); |
| 609 | void getDeltaV(Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); |
| 610 | |
| 611 | //This method calculate the velocity change due to collision/constraint impulse, record joint velocity and acceleration |
| 612 | static Cm::SpatialVectorF propagateVelocityW(const PxVec3& c2p, const Dy::SpatialMatrix& spatialInertia, |
| 613 | const InvStIs& invStIs, const SpatialSubspaceMatrix& motionMatrix, const Cm::SpatialVectorF& Z, |
| 614 | PxReal* jointVelocity, const Cm::SpatialVectorF& hDeltaV); |
| 615 | |
| 616 | //This method calculate the velocity change due to collision/constraint impulse |
| 617 | static Cm::SpatialVectorF propagateVelocityTestImpulseW(const PxVec3& c2p, const Dy::SpatialMatrix& spatialInertia, const InvStIs& invStIs, |
| 618 | const SpatialSubspaceMatrix& motionMatrix, const Cm::SpatialVectorF& Z, const Cm::SpatialVectorF& hDeltaV); |
| 619 | |
| 620 | |
| 621 | ////This method calculate zero acceration impulse due to test/actual impluse |
| 622 | //static Cm::SpatialVectorF propagateImpulse(const IsInvD& isInvD, const SpatialTransform& childToParent, |
| 623 | // const SpatialSubspaceMatrix& motionMatrix, const Cm::SpatialVectorF& Z); |
| 624 | |
| 625 | static Cm::SpatialVectorF propagateImpulseW(const IsInvD& isInvD, const PxVec3& childToParent, |
| 626 | const SpatialSubspaceMatrix& motionMatrix, const Cm::SpatialVectorF& Z); |
| 627 | |
| 628 | bool applyCacheToDest(ArticulationData& data, PxArticulationCache& cache, |
| 629 | PxReal* jVelocities, PxReal* jAcceleration, PxReal* jPosition, PxReal* jointForce, |
| 630 | const PxArticulationCacheFlags flag); |
| 631 | |
| 632 | PX_FORCE_INLINE ArticulationData& getArticulationData() { return mArticulationData; } |
| 633 | PX_FORCE_INLINE const ArticulationData& getArticulationData() const { return mArticulationData; } |
| 634 | |
| 635 | //void setGpuRemapId(const PxU32 id) { mGpuRemapId = id; } |
| 636 | //PxU32 getGpuRemapId() { return mGpuRemapId; } |
| 637 | |
| 638 | static PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::SpatialVectorF translateSpatialVector(const PxVec3& offset, const Cm::SpatialVectorF& vec) |
| 639 | { |
| 640 | return Cm::SpatialVectorF(vec.top, vec.bottom + offset.cross(v: vec.top)); |
| 641 | } |
| 642 | |
| 643 | static PX_CUDA_CALLABLE PX_FORCE_INLINE Cm::UnAlignedSpatialVector translateSpatialVector(const PxVec3& offset, const Cm::UnAlignedSpatialVector& vec) |
| 644 | { |
| 645 | return Cm::UnAlignedSpatialVector(vec.top, vec.bottom + offset.cross(v: vec.top)); |
| 646 | } |
| 647 | |
| 648 | static PX_FORCE_INLINE PxMat33 constructSkewSymmetricMatrix(const PxVec3 r) |
| 649 | { |
| 650 | return PxMat33(PxVec3(0.0f, r.z, -r.y), |
| 651 | PxVec3(-r.z, 0.0f, r.x), |
| 652 | PxVec3(r.y, -r.x, 0.0f)); |
| 653 | } |
| 654 | |
| 655 | bool raiseGPUDirtyFlag(ArticulationDirtyFlag::Enum flag) |
| 656 | { |
| 657 | bool nothingRaised = !(mGPUDirtyFlags); |
| 658 | mGPUDirtyFlags |= flag; |
| 659 | return nothingRaised; |
| 660 | } |
| 661 | |
| 662 | void clearGPUDirtyFlags() |
| 663 | { |
| 664 | mGPUDirtyFlags = 0; |
| 665 | } |
| 666 | |
| 667 | protected: |
| 668 | void constraintPrep(ArticulationLoopConstraint* lConstraints, const PxU32 nbJoints, |
| 669 | Cm::SpatialVectorF* Z, PxSolverConstraintPrepDesc& prepDesc, PxSolverBody& sBody, |
| 670 | PxSolverBodyData& sBodyData, PxSolverConstraintDesc* desc, PxConstraintAllocator& allocator); |
| 671 | |
| 672 | void updateArticulation(ScratchData& scratchData, |
| 673 | const PxVec3& gravity, |
| 674 | Cm::SpatialVectorF* Z, |
| 675 | Cm::SpatialVectorF* DeltaV); |
| 676 | |
| 677 | void computeUnconstrainedVelocitiesInternal( |
| 678 | const PxVec3& gravity, |
| 679 | Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV); |
| 680 | |
| 681 | //copy joint data from fromJointData to toJointData |
| 682 | void copyJointData(ArticulationData& data, PxReal* toJointData, const PxReal* fromJointData); |
| 683 | |
| 684 | void computeDofs(); |
| 685 | //this function calculates motion subspace matrix(s) for all tree joint |
| 686 | void jcalc(ArticulationData& data, bool forceUpdate = false); |
| 687 | |
| 688 | //this function calculates loop joint constraint subspace matrix(s) and active force |
| 689 | //subspace matrix |
| 690 | void jcalcLoopJointSubspace(ArticulationJointCore* joint, ArticulationJointCoreData& jointDatum, SpatialSubspaceMatrix& T); |
| 691 | |
| 692 | void computeSpatialInertia(ArticulationData& data); |
| 693 | |
| 694 | //compute zero acceleration force |
| 695 | void computeZ(ArticulationData& data, const PxVec3& gravity, ScratchData& scratchData); |
| 696 | |
| 697 | //compute drag force |
| 698 | void computeD(ArticulationData& data, ScratchData& scratchData, |
| 699 | Cm::SpatialVectorF* tZ, Cm::SpatialVectorF* tDeltaV); |
| 700 | |
| 701 | void solveInternalConstraints(const PxReal dt, const PxReal invDt, Cm::SpatialVectorF* impulses, Cm::SpatialVectorF* DeltaV, |
| 702 | bool velocityIteration, bool isTGS, const PxReal elapsedTime); |
| 703 | |
| 704 | Cm::SpatialVectorF solveInternalConstraintRecursive(const PxReal dt, const PxReal invDt, Cm::SpatialVectorF* impulses, Cm::SpatialVectorF* DeltaV, |
| 705 | bool velocityIteration, bool isTGS, const PxReal elapsedTime, const PxU32 linkID, const Cm::SpatialVectorF& parentDeltaV, |
| 706 | PxU32& dofId, PxU32& lockId); |
| 707 | |
| 708 | void writebackInternalConstraints(bool isTGS); |
| 709 | |
| 710 | void concludeInternalConstraints(bool isTGS); |
| 711 | |
| 712 | //compute coriolis force |
| 713 | void computeC(ArticulationData& data, ScratchData& scratchData); |
| 714 | |
| 715 | //compute relative transform child to parent |
| 716 | void computeRelativeTransformC2P(ArticulationData& data); |
| 717 | //compute relative transform child to base |
| 718 | void computeRelativeTransformC2B(ArticulationData& data); |
| 719 | |
| 720 | void computeLinkVelocities(ArticulationData& data, ScratchData& scratchData); |
| 721 | |
| 722 | void initLinks(ArticulationData& data, const PxVec3& gravity, |
| 723 | ScratchData& scratchData, Cm::SpatialVectorF* tZ, Cm::SpatialVectorF* tDeltaV); |
| 724 | |
| 725 | void computeIs(ArticulationLinkData& linkDatum, ArticulationJointCoreData& jointDatum, const PxU32 linkID); |
| 726 | static SpatialMatrix computePropagateSpatialInertia(const PxU8 jointType, ArticulationJointCoreData& jointDatum, |
| 727 | const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, IsInvD& isInvD, |
| 728 | const SpatialSubspaceMatrix& motionMatrix); |
| 729 | |
| 730 | static void transformInertia(const SpatialTransform& sTod, SpatialMatrix& inertia); |
| 731 | |
| 732 | static void translateInertia(const PxMat33& offset, SpatialMatrix& inertia); |
| 733 | |
| 734 | void computeArticulatedSpatialInertia(ArticulationData& data); |
| 735 | |
| 736 | void computeArticulatedResponseMatrix(ArticulationData& data); |
| 737 | |
| 738 | void computeArticulatedSpatialZ(ArticulationData& data, ScratchData& scratchData); |
| 739 | |
| 740 | /*void computeJointAcceleration(ArticulationLinkData& linkDatum, ArticulationJointCoreData& jointDatum, |
| 741 | const Cm::SpatialVectorF& pMotionAcceleration, PxReal* jointAcceleration, const PxU32 linkID);*/ |
| 742 | |
| 743 | void computeJointAccelerationW(ArticulationLinkData& linkDatum, ArticulationJointCoreData& jointDatum, |
| 744 | const Cm::SpatialVectorF& pMotionAcceleration, PxReal* jointAcceleration, const PxU32 linkID); |
| 745 | |
| 746 | //compute joint acceleration, joint velocity and link acceleration, velocity based |
| 747 | //on spatial force and spatial articulated inertia tensor |
| 748 | void computeLinkAcceleration(ArticulationData& data, ScratchData& scratchData); |
| 749 | |
| 750 | //void computeTempLinkAcceleration(ArticulationData& data, ScratchData& scratchData); |
| 751 | void computeJointTransmittedFrictionForce(ArticulationData& data, ScratchData& scratchData, |
| 752 | Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV); |
| 753 | //void computeJointFriction(ArticulationData& data, ScratchData& scratchData); |
| 754 | |
| 755 | //void copyFromBodyCore(); |
| 756 | //void copyToBodyCore(); |
| 757 | void updateBodies(); |
| 758 | |
| 759 | void applyExternalImpulse(ArticulationLink* links, const PxU32 linkCount, const bool fixBase, |
| 760 | ArticulationData& data, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV, const PxReal dt, const PxVec3& gravity, Cm::SpatialVector* acceleration); |
| 761 | |
| 762 | static Cm::SpatialVectorF getDeltaVWithDeltaJV(const bool fixBase, const PxU32 linkID, |
| 763 | const ArticulationData& data, Cm::SpatialVectorF* Z, |
| 764 | PxReal* jointVelocities); |
| 765 | |
| 766 | static Cm::SpatialVectorF getDeltaV(const bool fixBase, const PxU32 linkID, |
| 767 | const ArticulationData& data, Cm::SpatialVectorF* Z); |
| 768 | |
| 769 | //impulse need to be in the linkID space |
| 770 | static void getZ(const PxU32 linkID, const ArticulationData& data, |
| 771 | Cm::SpatialVectorF* Z, const Cm::SpatialVectorF& impulse); |
| 772 | |
| 773 | ////impulse0 and impulse1 are in linkID0 and linkID1 space respectively |
| 774 | //static void getZ( |
| 775 | // const ArticulationData& data, |
| 776 | // Cm::SpatialVectorF* Z, |
| 777 | // PxU32 linkID0_, |
| 778 | // const Cm::SpatialVector& impulse0, |
| 779 | // PxU32 linkID1_, |
| 780 | // const Cm::SpatialVector& impulse1); |
| 781 | |
| 782 | //This method use in impulse self response. The input impulse is in the link space |
| 783 | static Cm::SpatialVectorF getImpulseResponseW( |
| 784 | const PxU32 linkID, |
| 785 | const ArticulationData& data, |
| 786 | const Cm::SpatialVectorF& impulse); |
| 787 | |
| 788 | //This method use in impulse self response. The input impulse is in the link space |
| 789 | static Cm::SpatialVectorF getImpulseResponseWithJ( |
| 790 | const PxU32 linkID, |
| 791 | const bool fixBase, |
| 792 | const ArticulationData& data, |
| 793 | Cm::SpatialVectorF* Z, |
| 794 | const Cm::SpatialVectorF& impulse, |
| 795 | PxReal* jointVelocities); |
| 796 | |
| 797 | void getImpulseSelfResponseInv(const bool fixBase, |
| 798 | PxU32 linkID0, |
| 799 | PxU32 linkID1, |
| 800 | Cm::SpatialVectorF* Z, |
| 801 | const Cm::SpatialVector& impulse0, |
| 802 | const Cm::SpatialVector& impulse1, |
| 803 | Cm::SpatialVector& deltaV0, |
| 804 | Cm::SpatialVector& deltaV1, |
| 805 | PxReal* jointVelocities); |
| 806 | |
| 807 | void getImpulseResponseSlowInv(Dy::ArticulationLink* links, |
| 808 | const ArticulationData& data, |
| 809 | PxU32 linkID0_, |
| 810 | const Cm::SpatialVector& impulse0, |
| 811 | Cm::SpatialVector& deltaV0, |
| 812 | PxU32 linkID1_, |
| 813 | const Cm::SpatialVector& impulse1, |
| 814 | Cm::SpatialVector& deltaV1, |
| 815 | PxReal* jointVelocities); |
| 816 | |
| 817 | Cm::SpatialVectorF getImpulseResponseInv(const bool fixBase, |
| 818 | const PxU32 linkID, Cm::SpatialVectorF* Z, |
| 819 | const Cm::SpatialVector& impulse, |
| 820 | PxReal* jointVelocites); |
| 821 | |
| 822 | void inverseDynamic(ArticulationData& data, const PxVec3& gravity, |
| 823 | ScratchData& scratchData, bool computeCoriolis); |
| 824 | |
| 825 | void inverseDynamicFloatingBase(ArticulationData& data, const PxVec3& gravity, |
| 826 | ScratchData& scratchData, bool computeCoriolis); |
| 827 | |
| 828 | //compute link body force with motion velocity and acceleration |
| 829 | void computeZAForceInv(ArticulationData& data, ScratchData& scratchData); |
| 830 | void initCompositeSpatialInertia(ArticulationData& data, Dy::SpatialMatrix* compositeSpatialInertia); |
| 831 | void computeCompositeSpatialInertiaAndZAForceInv(ArticulationData& data, ScratchData& scratchData); |
| 832 | |
| 833 | void computeRelativeGeneralizedForceInv(ArticulationData& data, ScratchData& scratchData); |
| 834 | |
| 835 | //provided joint velocity and joint acceleartion, compute link acceleration |
| 836 | void computeLinkAccelerationInv(ArticulationData& data, ScratchData& scratchData); |
| 837 | |
| 838 | void computeGeneralizedForceInv(ArticulationData& data, ScratchData& scratchData); |
| 839 | |
| 840 | void calculateMassMatrixColInv(ScratchData& scratchData); |
| 841 | |
| 842 | void calculateHFixBase(PxArticulationCache& cache); |
| 843 | |
| 844 | void calculateHFloatingBase(PxArticulationCache& cache); |
| 845 | |
| 846 | //joint limits |
| 847 | void enforcePrismaticLimits(PxReal* jPosition, ArticulationJointCore* joint); |
| 848 | |
| 849 | public: |
| 850 | static void getImpulseSelfResponse(ArticulationLink* links, |
| 851 | const bool fixBase, |
| 852 | Cm::SpatialVectorF* Z, |
| 853 | const ArticulationData& data, |
| 854 | PxU32 linkID0, |
| 855 | const Cm::SpatialVectorV& impulse0, |
| 856 | Cm::SpatialVectorV& deltaV0, |
| 857 | PxU32 linkID1, |
| 858 | const Cm::SpatialVectorV& impulse1, |
| 859 | Cm::SpatialVectorV& deltaV1); |
| 860 | |
| 861 | static void getImpulseResponseSlow(Dy::ArticulationLink* links, |
| 862 | const ArticulationData& data, |
| 863 | PxU32 linkID0_, |
| 864 | const Cm::SpatialVector& impulse0, |
| 865 | Cm::SpatialVector& deltaV0, |
| 866 | PxU32 linkID1_, |
| 867 | const Cm::SpatialVector& impulse1, |
| 868 | Cm::SpatialVector& deltaV1, |
| 869 | Cm::SpatialVectorF* Z); |
| 870 | |
| 871 | void createHardLimit( |
| 872 | ArticulationLink* links, |
| 873 | const bool fixBase, |
| 874 | Cm::SpatialVectorF* Z, |
| 875 | ArticulationData& data, |
| 876 | PxU32 linkIndex, |
| 877 | SolverConstraint1DExt& s, |
| 878 | const PxVec3& axis, |
| 879 | PxReal err, |
| 880 | PxReal recipDt); |
| 881 | |
| 882 | void createHardLimits( |
| 883 | SolverConstraint1DExt& s0, |
| 884 | SolverConstraint1DExt& s1, |
| 885 | const PxVec3& axis, |
| 886 | PxReal err0, |
| 887 | PxReal err1, |
| 888 | PxReal recipDt, |
| 889 | const Cm::SpatialVectorV& deltaVA, |
| 890 | const Cm::SpatialVectorV& deltaVB, |
| 891 | PxReal recipResponse); |
| 892 | |
| 893 | void createTangentialSpring( |
| 894 | ArticulationLink* links, |
| 895 | const bool fixBase, |
| 896 | Cm::SpatialVectorF* Z, |
| 897 | ArticulationData& data, |
| 898 | PxU32 linkIndex, |
| 899 | SolverConstraint1DExt& s, |
| 900 | const PxVec3& axis, |
| 901 | PxReal stiffness, |
| 902 | PxReal damping, |
| 903 | PxReal dt); |
| 904 | |
| 905 | PxU32 setupSolverConstraints( |
| 906 | ArticulationLink* links, |
| 907 | const PxU32 linkCount, |
| 908 | const bool fixBase, |
| 909 | ArticulationData& data, |
| 910 | Cm::SpatialVectorF* Z, |
| 911 | PxU32& acCount); |
| 912 | |
| 913 | void setupInternalConstraints( |
| 914 | ArticulationLink* links, |
| 915 | const PxU32 linkCount, |
| 916 | const bool fixBase, |
| 917 | ArticulationData& data, |
| 918 | Cm::SpatialVectorF* Z, |
| 919 | PxReal stepDt, |
| 920 | PxReal dt, |
| 921 | PxReal invDt, |
| 922 | PxReal erp, |
| 923 | bool isTGSSolver); |
| 924 | |
| 925 | void setupInternalConstraintsRecursive( |
| 926 | ArticulationLink* links, |
| 927 | const PxU32 linkCount, |
| 928 | const bool fixBase, |
| 929 | ArticulationData& data, |
| 930 | Cm::SpatialVectorF* Z, |
| 931 | const PxReal stepDt, |
| 932 | const PxReal dt, |
| 933 | const PxReal invDt, |
| 934 | const PxReal erp, |
| 935 | const PxReal cfm, |
| 936 | const bool isTGSSolver, |
| 937 | const PxU32 linkID, |
| 938 | const PxReal maxForceScale); |
| 939 | |
| 940 | virtual void prepareStaticConstraints(const PxReal dt, const PxReal invDt, PxsContactManagerOutputIterator& outputs, |
| 941 | Dy::ThreadContext& threadContext, PxReal correlationDist, PxReal bounceThreshold, PxReal frictionOffsetThreshold, PxReal solverOffsetSlop, |
| 942 | PxReal ccdMaxSeparation, PxSolverBodyData* solverBodyData, PxsConstraintBlockManager& blockManager, |
| 943 | Dy::ConstraintWriteback* constraintWritebackPool); |
| 944 | |
| 945 | virtual void prepareStaticConstraintsTGS(const PxReal stepDt, const PxReal totalDt, const PxReal invStepDt, const PxReal invTotalDt, |
| 946 | PxsContactManagerOutputIterator& outputs, Dy::ThreadContext& threadContext, PxReal correlationDist, PxReal bounceThreshold, |
| 947 | PxReal frictionOffsetThreshold, PxTGSSolverBodyData* solverBodyData, |
| 948 | PxTGSSolverBodyTxInertia* txInertia, PxsConstraintBlockManager& blockManager, Dy::ConstraintWriteback* constraintWritebackPool, |
| 949 | const PxU32 nbSubsteps, const PxReal lengthScale); |
| 950 | |
| 951 | void createHardLimitTGS( |
| 952 | SolverConstraint1DExtStep& s, |
| 953 | const PxVec3& axis, |
| 954 | PxReal err, |
| 955 | PxReal recipDt, |
| 956 | const Cm::SpatialVectorV& deltaVA, |
| 957 | const Cm::SpatialVectorV& deltaVB, |
| 958 | PxReal recipResponse); |
| 959 | |
| 960 | void createTangentialSpringTGS( |
| 961 | ArticulationLink* links, |
| 962 | const bool fixBase, |
| 963 | Cm::SpatialVectorF* Z, |
| 964 | ArticulationData& data, |
| 965 | PxU32 linkIndex, |
| 966 | SolverConstraint1DExtStep& s, |
| 967 | const PxVec3& axis, |
| 968 | PxReal stiffness, |
| 969 | PxReal damping, |
| 970 | PxReal dt); |
| 971 | |
| 972 | //integration |
| 973 | void propagateLinksDown(ArticulationData& data, PxReal* jointVelocities, PxReal* jointPositions, |
| 974 | Cm::SpatialVectorF* motionVelocities); |
| 975 | |
| 976 | void updateJointProperties( |
| 977 | const PxReal* jointDeltaVelocities, |
| 978 | const Cm::SpatialVectorF* motionVelocities, |
| 979 | PxReal* jointVelocities, |
| 980 | PxReal* jointAccelerations); |
| 981 | |
| 982 | void recomputeAccelerations(const PxReal dt); |
| 983 | Cm::SpatialVector recomputeAcceleration(const PxU32 linkID, const PxReal dt) const; |
| 984 | |
| 985 | void computeAndEnforceJointPositions(ArticulationData& data, PxReal* jointPositions); |
| 986 | |
| 987 | //update link position based on joint position provided by the cache |
| 988 | void teleportLinks(ArticulationData& data); |
| 989 | |
| 990 | void computeLinkVelocities(ArticulationData& data); |
| 991 | |
| 992 | PxU8* allocateScratchSpatialData(PxcScratchAllocator* allocator, |
| 993 | const PxU32 linkCount, ScratchData& scratchData, bool fallBackToHeap = false); |
| 994 | |
| 995 | // void allocateScratchSpatialData(DyScratchAllocator& allocator, |
| 996 | // const PxU32 linkCount, ScratchData& scratchData); |
| 997 | |
| 998 | //This method calculate the velocity change from parent to child using parent current motion velocity |
| 999 | PxTransform propagateTransform(const PxU32 linkID, ArticulationLink* links, ArticulationJointCoreData& jointDatum, |
| 1000 | Cm::SpatialVectorF* motionVelocities, const PxReal dt, const PxTransform& pBody2World, const PxTransform& currentTransform, |
| 1001 | PxReal* jointVelocity, PxReal* jointDeltaVelocities, PxReal* jointPosition, const SpatialSubspaceMatrix& motionMatrix, |
| 1002 | const SpatialSubspaceMatrix& worldMotionMatrix); |
| 1003 | |
| 1004 | static void updateRootBody(const Cm::SpatialVectorF& motionVelocity, |
| 1005 | const PxTransform& preTransform, ArticulationData& data, const PxReal dt); |
| 1006 | |
| 1007 | ArticulationData mArticulationData; |
| 1008 | |
| 1009 | Ps::Array<char> mScratchMemory; |
| 1010 | bool mHasSphericalJoint; |
| 1011 | |
| 1012 | Ps::Array<PxSolverConstraintDesc> mStaticConstraints; |
| 1013 | //this is the id remap pxgbodysim and pxgariculation. if application delete the articulation, we need to |
| 1014 | //put back this id to the id pool |
| 1015 | //PxU32 mGpuRemapId; |
| 1016 | |
| 1017 | PxU32 mGPUDirtyFlags; |
| 1018 | |
| 1019 | |
| 1020 | |
| 1021 | } PX_ALIGN_SUFFIX(64); |
| 1022 | |
| 1023 | #if PX_VC |
| 1024 | #pragma warning(pop) |
| 1025 | #endif |
| 1026 | |
| 1027 | void PxvRegisterArticulationsReducedCoordinate(); |
| 1028 | |
| 1029 | } //namespace Dy |
| 1030 | |
| 1031 | } |
| 1032 | |
| 1033 | #endif |
| 1034 | |