121 constraintRow.m_orgConstraint =
this;
122 constraintRow.m_orgDofIndex = row;
124 constraintRow.m_multiBodyA = m_bodyA;
125 constraintRow.m_multiBodyB =
m_bodyB;
127 const btVector3 dummy(0, 0, 0);
129 btScalar rel_vel =
fillMultiBodyConstraint(constraintRow, data,
jacobianA(row),
jacobianB(row), dummy, dummy, dummy, dummy, posError,
infoGlobal, 0, m_maxAppliedImpulse);
134 switch (m_bodyA->getLink(
m_linkA).m_jointType)
138 constraintRow.m_contactNormal1.setZero();
139 constraintRow.m_contactNormal2.setZero();
140 btVector3 revoluteAxisInWorld = direction *
quatRotate(m_bodyA->getLink(
m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(
m_linkA).m_axes[0].m_topVec);
141 constraintRow.m_relpos1CrossNormal = revoluteAxisInWorld;
142 constraintRow.m_relpos2CrossNormal = -revoluteAxisInWorld;
148 btVector3 prismaticAxisInWorld = direction *
quatRotate(m_bodyA->getLink(
m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(
m_linkA).m_axes[0].m_bottomVec);
149 constraintRow.m_contactNormal1 = prismaticAxisInWorld;
150 constraintRow.m_contactNormal2 = -prismaticAxisInWorld;
151 constraintRow.m_relpos1CrossNormal.setZero();
152 constraintRow.m_relpos2CrossNormal.setZero();
167 if (!
infoGlobal.m_splitImpulse || (penetration >
infoGlobal.m_splitImpulsePenetrationThreshold))
174 velocityError = -penetration /
infoGlobal.m_timeStep;
178 positionalError = -penetration * erp /
infoGlobal.m_timeStep;
181 btScalar penetrationImpulse = positionalError * constraintRow.m_jacDiagABInv;
182 btScalar velocityImpulse = velocityError * constraintRow.m_jacDiagABInv;
183 if (!
infoGlobal.m_splitImpulse || (penetration >
infoGlobal.m_splitImpulsePenetrationThreshold))
186 constraintRow.m_rhs = penetrationImpulse + velocityImpulse;
187 constraintRow.m_rhsPenetration = 0.f;
192 constraintRow.m_rhs = velocityImpulse;
193 constraintRow.m_rhsPenetration = penetrationImpulse;
@ MULTIBODY_CONSTRAINT_LIMIT
btScalar getPosition(int row) const
void setPosition(int row, btScalar pos)
btScalar * jacobianB(int row)
void allocateJacobiansMultiDof()
btScalar fillMultiBodyConstraint(btMultiBodySolverConstraint &solverConstraint, btMultiBodyJacobianData &data, btScalar *jacOrgA, btScalar *jacOrgB, const btVector3 &constraintNormalAng, const btVector3 &constraintNormalLin, const btVector3 &posAworld, const btVector3 &posBworld, btScalar posError, const btContactSolverInfo &infoGlobal, btScalar lowerLimit, btScalar upperLimit, bool angConstraint=false, btScalar relaxation=1.f, bool isFriction=false, btScalar desiredVelocity=0, btScalar cfmSlip=0)
btScalar * jacobianA(int row)
btMultiBodySolverConstraint
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
const btMultibodyLink & getLink(int index) const
virtual int getIslandIdB() const
virtual void finalizeMultiDof()
virtual int getIslandIdA() const
virtual ~btMultiBodyJointLimitConstraint()
virtual void createConstraintRows(btMultiBodyConstraintArray &constraintRows, btMultiBodyJacobianData &data, const btContactSolverInfo &infoGlobal)
btMultiBodyJointLimitConstraint(btMultiBody *body, int link, btScalar lower, btScalar upper)
This file was written by Erwin Coumans.