here is teh code that calculate teh impulse.
see if you undernad it
- Code: Select all
void dgBody::AddImpulse (const dgVector& pointDeltaVeloc, const dgVector& pointPosit)
{
dgInt32 i;
dgInt32 j;
dgMatrix tmpMatrix;
tmpMatrix[0][0] = m_invMass[0] * m_matrix[0][0];
tmpMatrix[0][1] = m_invMass[1] * m_matrix[1][0];
tmpMatrix[0][2] = m_invMass[2] * m_matrix[2][0];
tmpMatrix[0][3] = dgFloat32 (0.0f);
tmpMatrix[1][0] = m_invMass[0] * m_matrix[0][1];
tmpMatrix[1][1] = m_invMass[1] * m_matrix[1][1];
tmpMatrix[1][2] = m_invMass[2] * m_matrix[2][1];
tmpMatrix[1][3] = dgFloat32 (0.0f);
tmpMatrix[2][0] = m_invMass[0] * m_matrix[0][2];
tmpMatrix[2][1] = m_invMass[1] * m_matrix[1][2];
tmpMatrix[2][2] = m_invMass[2] * m_matrix[2][2];
tmpMatrix[2][3] = dgFloat32 (0.0f);
tmpMatrix[3][0] = dgFloat32 (0.0f);
tmpMatrix[3][1] = dgFloat32 (0.0f);
tmpMatrix[3][2] = dgFloat32 (0.0f);
tmpMatrix[3][3] = dgFloat32 (1.0f);
dgMatrix invInertia (tmpMatrix * m_matrix);
// get contact matrix
dgMatrix tmp;
//dgVector globalContact (pointPosit - m_matrix.m_posit);
dgVector globalContact (pointPosit - m_globalCentreOfMass);
//globalContact[0] = dgFloat32 (0.0f);
//globalContact[1] = dgFloat32 (0.0f);
//globalContact[2] = dgFloat32 (0.0f);
tmp[0][0] = dgFloat32 (0.0f);
tmp[0][1] = + globalContact[2];
tmp[0][2] = - globalContact[1];
tmp[0][3] = dgFloat32 (0.0f);
tmp[1][0] = -globalContact[2];
tmp[1][1] = dgFloat32 (0.0f);
tmp[1][2] = +globalContact[0];
tmp[1][3] = dgFloat32 (0.0f);
tmp[2][0] = +globalContact[1];
tmp[2][1] = -globalContact[0];
tmp[2][2] = dgFloat32 (0.0f);
tmp[2][3] = dgFloat32 (0.0f);
tmp[3][0] = dgFloat32 (0.0f);
tmp[3][1] = dgFloat32 (0.0f);
tmp[3][2] = dgFloat32 (0.0f);
tmp[3][3] = dgFloat32 (1.0f);
dgMatrix contactMatrix (tmp * invInertia * tmp);
for (i = 0; i < 3; i ++) {
for (j = 0; j < 3; j ++) {
contactMatrix[i][j] *= -dgFloat32 (1.0f);
}
}
contactMatrix[0][0] += m_invMass.m_w;
contactMatrix[1][1] += m_invMass.m_w;
contactMatrix[2][2] += m_invMass.m_w;
contactMatrix = contactMatrix.Symetric3by3Inverse ();
// change of momentum
dgVector changeOfMomentum (contactMatrix.RotateVector (pointDeltaVeloc));
dgVector dv (changeOfMomentum.Scale (m_invMass.m_w));
dgVector dw (invInertia.RotateVector (globalContact * changeOfMomentum));
m_veloc += dv;
m_omega += dw;
m_sleeping = false;
m_equilibrium = false;
Unfreeze ();
}
basically gine a point on teh body in global space, and a chenge of velocity at tha point, teh funtion add the nessesary velocity and angula velocity to teh body,
to make sure the velocity at tehe point of interest is chnage by the desire amount.
basically all you need to do is calculate teh velocity at teh point you want
v = v_origin + cross ((p - origin) , omega))
if you wan to mak ethe velocity zero, the negate V
v = v.Scale (-1)
the call you version of the function above.
you can write your own flavor becasue as you can see the newton version only work for one point, and also modify some of the internal states of the body,
and you may not want that.
if you want to change more than one opoint at a time, you can use it a loop cycling over the points for few ietration utim all the point get the desires velocity with it some smal tolerance.
also if you are goin to use it for changing the velocity of more than one point
you can separate it in two
the first part calculate the inertia matrix and is common to all ieration since the position and orienation do no change when teh velocity is changes
dgMatrix tmpMatrix;
tmpMatrix[0][0] = m_invMass[0] * m_matrix[0][0];
tmpMatrix[0][1] = m_invMass[1] * m_matrix[1][0];
tmpMatrix[0][2] = m_invMass[2] * m_matrix[2][0];
tmpMatrix[0][3] = dgFloat32 (0.0f);
tmpMatrix[1][0] = m_invMass[0] * m_matrix[0][1];
tmpMatrix[1][1] = m_invMass[1] * m_matrix[1][1];
tmpMatrix[1][2] = m_invMass[2] * m_matrix[2][1];
tmpMatrix[1][3] = dgFloat32 (0.0f);
tmpMatrix[2][0] = m_invMass[0] * m_matrix[0][2];
tmpMatrix[2][1] = m_invMass[1] * m_matrix[1][2];
tmpMatrix[2][2] = m_invMass[2] * m_matrix[2][2];
tmpMatrix[2][3] = dgFloat32 (0.0f);
tmpMatrix[3][0] = dgFloat32 (0.0f);
tmpMatrix[3][1] = dgFloat32 (0.0f);
tmpMatrix[3][2] = dgFloat32 (0.0f);
tmpMatrix[3][3] = dgFloat32 (1.0f);
dgMatrix invInertia (tmpMatrix * m_matrix);
the rest goies in the loop and you can iterate as many time as you wnat.