The two linear constraints are that the translation between frames A and B must be zero in local directions y and z. As time derivative, I get
p * (vA - vB) + ((wB_t - wA_t) x p) * omegaA + ((wB_R * fB_t) x p) * (omegaA - omegaB) = 0
vA, vB, omegaA, omegaB: velocities
p: local direction y/z in world coordinates
wA_t, wB_t: translational part of world transforms
wB_R: rotational part of world transforms
fB_t: translational part of constraint frame (i.e., wB_R * fB_t is the vector from slider origin to rigid body B in world coordinates)
Now the current implementation ignores the last term, which is only possible if omegaA = omegaB, and it replaces omegaA by a weighted sum of omegaA and omegaB (weighted by mass), which again requires omegaA = omegaB.
I replaced this code
Code: Select all
btVector3 tmp = c.cross(p);
for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i];
for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i];
tmp = c.cross(q);
for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i];
for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i];
Code: Select all
btVector3 b = bodyB_trans.getBasis() * m_frameInB.getOrigin();
btVector3 a = b + c;
btVector3 tmpa = a.cross(p);
btVector3 tmpb = b.cross(p);
for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpa[i];
for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpb[i];
tmpa = a.cross(q);
tmpb = b.cross(q);
for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = tmpa[i];
for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = -tmpb[i];
What consideration is behind the use of the weighted mean of omegaA and omegaB? This could be integrated in my fix for the directions perpendicular to the slider axis, but I would like to know why this is better than the straightforward formula.