for (int i = 0; i < numContacts; ++i)
{
Contact c = contacts[i];
Vector2f r1 = new Vector2f(c.position);
r1.sub(b1.getPosition());
Vector2f r2 = new Vector2f(c.position);
r2.sub(b2.getPosition());
// Relative velocity at contact
Vector2f relativeVelocity = new Vector2f(b2.getVelocity());
relativeVelocity.add(MathUtil.cross(b2.getAngularVelocity(), r2));
relativeVelocity.sub(b1.getVelocity());
relativeVelocity.sub(MathUtil.cross(b1.getAngularVelocity(), r1));
// Compute normal impulse with bias.
float vn = relativeVelocity.dot(c.normal);
// bias caculations are now handled seperately hence we only
// handle the real impulse caculations here
//float normalImpulse = c.massNormal * ((c.restitution - vn) + c.bias);
float normalImpulse = c.massNormal * (c.restitution - vn);
// Clamp the accumulated impulse
float oldNormalImpulse = c.accumulatedNormalImpulse;
c.accumulatedNormalImpulse = Math.max(oldNormalImpulse + normalImpulse, 0.0f);
normalImpulse = c.accumulatedNormalImpulse - oldNormalImpulse;
// Apply contact impulse
Vector2f impulse = MathUtil.scale(c.normal, normalImpulse);
b1.adjustVelocity(MathUtil.scale(impulse, -b1.getInvMass()));
b1.adjustAngularVelocity(-(b1.getInvI() * MathUtil.cross(r1, impulse)));
b2.adjustVelocity(MathUtil.scale(impulse, b2.getInvMass()));
b2.adjustAngularVelocity(b2.getInvI() * MathUtil.cross(r2, impulse));
// Compute bias impulse
// NEW STUFF FOR SEPERATING BIAS
relativeVelocity.set(b2.getBiasedVelocity());
relativeVelocity.add(MathUtil.cross(b2.getBiasedAngularVelocity(), r2));
relativeVelocity.sub(b1.getBiasedVelocity());
relativeVelocity.sub(MathUtil.cross(b1.getBiasedAngularVelocity(), r1));
float vnb = relativeVelocity.dot(c.normal);
float biasImpulse = c.massNormal * (-vnb + c.bias);
float oldBiasImpulse = c.biasImpulse;
c.biasImpulse = Math.max(oldBiasImpulse + biasImpulse, 0.0f);
biasImpulse = c.biasImpulse - oldBiasImpulse;
Vector2f Pb = MathUtil.scale(c.normal, biasImpulse);
b1.adjustBiasedVelocity(MathUtil.scale(Pb, -b1.getInvMass()));
b1.adjustBiasedAngularVelocity(-(b1.getInvI() * MathUtil.cross(r1, Pb)));
b2.adjustBiasedVelocity(MathUtil.scale(Pb, b2.getInvMass()));
b2.adjustBiasedAngularVelocity((b2.getInvI() * MathUtil.cross(r2, Pb)));
// END NEW STUFF
//
// Compute friction (tangent) impulse
//
float maxTangentImpulse = friction * c.accumulatedNormalImpulse;
// Relative velocity at contact
relativeVelocity.set(b2.getVelocity());
relativeVelocity.add(MathUtil.cross(b2.getAngularVelocity(), r2));
relativeVelocity.sub(b1.getVelocity());
relativeVelocity.sub(MathUtil.cross(b1.getAngularVelocity(), r1));
Vector2f tangent = MathUtil.cross(c.normal, 1.0f);
float vt = relativeVelocity.dot(tangent);
float tangentImpulse = c.massTangent * (-vt);
// Clamp friction
float oldTangentImpulse = c.accumulatedTangentImpulse;