in Box2D/Dynamics/Joints/b2GearJoint.cpp [131:233]
void b2GearJoint::InitVelocityConstraints(const b2SolverData& data)
{
m_indexA = m_bodyA->m_islandIndex;
m_indexB = m_bodyB->m_islandIndex;
m_indexC = m_bodyC->m_islandIndex;
m_indexD = m_bodyD->m_islandIndex;
m_lcA = m_bodyA->m_sweep.localCenter;
m_lcB = m_bodyB->m_sweep.localCenter;
m_lcC = m_bodyC->m_sweep.localCenter;
m_lcD = m_bodyD->m_sweep.localCenter;
m_mA = m_bodyA->m_invMass;
m_mB = m_bodyB->m_invMass;
m_mC = m_bodyC->m_invMass;
m_mD = m_bodyD->m_invMass;
m_iA = m_bodyA->m_invI;
m_iB = m_bodyB->m_invI;
m_iC = m_bodyC->m_invI;
m_iD = m_bodyD->m_invI;
float32 aA = data.positions[m_indexA].a;
b2Vec2 vA = data.velocities[m_indexA].v;
float32 wA = data.velocities[m_indexA].w;
float32 aB = data.positions[m_indexB].a;
b2Vec2 vB = data.velocities[m_indexB].v;
float32 wB = data.velocities[m_indexB].w;
float32 aC = data.positions[m_indexC].a;
b2Vec2 vC = data.velocities[m_indexC].v;
float32 wC = data.velocities[m_indexC].w;
float32 aD = data.positions[m_indexD].a;
b2Vec2 vD = data.velocities[m_indexD].v;
float32 wD = data.velocities[m_indexD].w;
b2Rot qA(aA), qB(aB), qC(aC), qD(aD);
m_mass = 0.0f;
if (m_typeA == e_revoluteJoint)
{
m_JvAC.SetZero();
m_JwA = 1.0f;
m_JwC = 1.0f;
m_mass += m_iA + m_iC;
}
else
{
b2Vec2 u = b2Mul(qC, m_localAxisC);
b2Vec2 rC = b2Mul(qC, m_localAnchorC - m_lcC);
b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_lcA);
m_JvAC = u;
m_JwC = b2Cross(rC, u);
m_JwA = b2Cross(rA, u);
m_mass += m_mC + m_mA + m_iC * m_JwC * m_JwC + m_iA * m_JwA * m_JwA;
}
if (m_typeB == e_revoluteJoint)
{
m_JvBD.SetZero();
m_JwB = m_ratio;
m_JwD = m_ratio;
m_mass += m_ratio * m_ratio * (m_iB + m_iD);
}
else
{
b2Vec2 u = b2Mul(qD, m_localAxisD);
b2Vec2 rD = b2Mul(qD, m_localAnchorD - m_lcD);
b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_lcB);
m_JvBD = m_ratio * u;
m_JwD = m_ratio * b2Cross(rD, u);
m_JwB = m_ratio * b2Cross(rB, u);
m_mass += m_ratio * m_ratio * (m_mD + m_mB) + m_iD * m_JwD * m_JwD + m_iB * m_JwB * m_JwB;
}
// Compute effective mass.
m_mass = m_mass > 0.0f ? 1.0f / m_mass : 0.0f;
if (data.step.warmStarting)
{
vA += (m_mA * m_impulse) * m_JvAC;
wA += m_iA * m_impulse * m_JwA;
vB += (m_mB * m_impulse) * m_JvBD;
wB += m_iB * m_impulse * m_JwB;
vC -= (m_mC * m_impulse) * m_JvAC;
wC -= m_iC * m_impulse * m_JwC;
vD -= (m_mD * m_impulse) * m_JvBD;
wD -= m_iD * m_impulse * m_JwD;
}
else
{
m_impulse = 0.0f;
}
data.velocities[m_indexA].v = vA;
data.velocities[m_indexA].w = wA;
data.velocities[m_indexB].v = vB;
data.velocities[m_indexB].w = wB;
data.velocities[m_indexC].v = vC;
data.velocities[m_indexC].w = wC;
data.velocities[m_indexD].v = vD;
data.velocities[m_indexD].w = wD;
}