void btHingeConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) { ///the regular (virtual) implementation getInfo2 already performs 'testLimit' during getInfo1, so we need to do it now testLimit(transA,transB); getInfo2Internal(info,transA,transB,angVelA,angVelB); }
void btHingeConstraint::getInfo1(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; info->nub = 0; } else { info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular info->nub = 1; //prepare constraint testLimit(); if(getSolveLimit() || getEnableAngularMotor()) { info->m_numConstraintRows++; // limit 3rd anguar as well info->nub--; } } }
void btHingeConstraint::getInfo1(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; info->nub = 0; } else { info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular info->nub = 1; //always add the row, to avoid computation (data is not available yet) //prepare constraint testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); if(getSolveLimit() || getEnableAngularMotor()) { info->m_numConstraintRows++; // limit 3rd anguar as well info->nub--; } } }
void btHingeConstraint::buildJacobian() { if (m_useSolveConstraintObsolete) { m_appliedImpulse = btScalar(0.); m_accMotorImpulse = btScalar(0.); if (!m_angularOnly) { btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); btVector3 relPos = pivotBInW - pivotAInW; btVector3 normal[3]; if (relPos.length2() > SIMD_EPSILON) { normal[0] = relPos.normalized(); } else { normal[0].setValue(btScalar(1.0),0,0); } btPlaneSpace1(normal[0], normal[1], normal[2]); for (int i=0;i<3;i++) { new (&m_jac[i]) btJacobianEntry( m_rbA.getCenterOfMassTransform().getBasis().transpose(), m_rbB.getCenterOfMassTransform().getBasis().transpose(), pivotAInW - m_rbA.getCenterOfMassPosition(), pivotBInW - m_rbB.getCenterOfMassPosition(), normal[i], m_rbA.getInvInertiaDiagLocal(), m_rbA.getInvMass(), m_rbB.getInvInertiaDiagLocal(), m_rbB.getInvMass()); } } //calculate two perpendicular jointAxis, orthogonal to hingeAxis //these two jointAxis require equal angular velocities for both bodies //this is unused for now, it's a todo btVector3 jointAxis0local; btVector3 jointAxis1local; btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); new (&m_jacAng[0]) btJacobianEntry(jointAxis0, m_rbA.getCenterOfMassTransform().getBasis().transpose(), m_rbB.getCenterOfMassTransform().getBasis().transpose(), m_rbA.getInvInertiaDiagLocal(), m_rbB.getInvInertiaDiagLocal()); new (&m_jacAng[1]) btJacobianEntry(jointAxis1, m_rbA.getCenterOfMassTransform().getBasis().transpose(), m_rbB.getCenterOfMassTransform().getBasis().transpose(), m_rbA.getInvInertiaDiagLocal(), m_rbB.getInvInertiaDiagLocal()); new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, m_rbA.getCenterOfMassTransform().getBasis().transpose(), m_rbB.getCenterOfMassTransform().getBasis().transpose(), m_rbA.getInvInertiaDiagLocal(), m_rbB.getInvInertiaDiagLocal()); // clear accumulator m_accLimitImpulse = btScalar(0.); // test angular limit testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); //Compute K = J*W*J' for hinge axis btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + getRigidBodyB().computeAngularImpulseDenominator(axisA)); } }