public void Iterate()
{
float dvx, dvy, dvz;
dvx = body2.linearVelocity.X - body1.linearVelocity.X;
dvy = body2.linearVelocity.Y - body1.linearVelocity.Y;
dvz = body2.linearVelocity.Z - body1.linearVelocity.Z;
if (!body1IsMassPoint)
{
dvx = dvx - (body1.angularVelocity.Y * relativePos1.Z) + (body1.angularVelocity.Z * relativePos1.Y);
dvy = dvy - (body1.angularVelocity.Z * relativePos1.X) + (body1.angularVelocity.X * relativePos1.Z);
dvz = dvz - (body1.angularVelocity.X * relativePos1.Y) + (body1.angularVelocity.Y * relativePos1.X);
}
if (!body2IsMassPoint)
{
dvx = dvx + (body2.angularVelocity.Y * relativePos2.Z) - (body2.angularVelocity.Z * relativePos2.Y);
dvy = dvy + (body2.angularVelocity.Z * relativePos2.X) - (body2.angularVelocity.X * relativePos2.Z);
dvz = dvz + (body2.angularVelocity.X * relativePos2.Y) - (body2.angularVelocity.Y * relativePos2.X);
}
// this gets us some performance
if (dvx * dvx + dvy * dvy + dvz * dvz < settings.minVelocity * settings.minVelocity)
{ return; }
float vn = normal.X * dvx + normal.Y * dvy + normal.Z * dvz;
float normalImpulse = massNormal * (-vn + restitutionBias);
float oldNormalImpulse = accumulatedNormalImpulse;
accumulatedNormalImpulse = oldNormalImpulse + normalImpulse;
if (accumulatedNormalImpulse < 0.0f) accumulatedNormalImpulse = 0.0f;
normalImpulse = accumulatedNormalImpulse - oldNormalImpulse;
float vt = dvx * tangent.X + dvy * tangent.Y + dvz * tangent.Z;
float maxTangentImpulse = friction * accumulatedNormalImpulse;
float tangentImpulse = massTangent * (-vt);
float oldTangentImpulse = accumulatedTangentImpulse;
accumulatedTangentImpulse = oldTangentImpulse + tangentImpulse;
if (accumulatedTangentImpulse < -maxTangentImpulse) accumulatedTangentImpulse = -maxTangentImpulse;
else if (accumulatedTangentImpulse > maxTangentImpulse) accumulatedTangentImpulse = maxTangentImpulse;
tangentImpulse = accumulatedTangentImpulse - oldTangentImpulse;
// Apply contact impulse
JVector impulse;
impulse.X = normal.X * normalImpulse + tangent.X * tangentImpulse;
impulse.Y = normal.Y * normalImpulse + tangent.Y * tangentImpulse;
impulse.Z = normal.Z * normalImpulse + tangent.Z * tangentImpulse;
if (!body1.isStatic)
{
body1.linearVelocity.X -= (impulse.X * body1.inverseMass);
body1.linearVelocity.Y -= (impulse.Y * body1.inverseMass);
body1.linearVelocity.Z -= (impulse.Z * body1.inverseMass);
if (!body1IsMassPoint)
{
float num0, num1, num2;
num0 = relativePos1.Y * impulse.Z - relativePos1.Z * impulse.Y;
num1 = relativePos1.Z * impulse.X - relativePos1.X * impulse.Z;
num2 = relativePos1.X * impulse.Y - relativePos1.Y * impulse.X;
float num3 =
(((num0 * body1.invInertiaWorld.M11) +
(num1 * body1.invInertiaWorld.M21)) +
(num2 * body1.invInertiaWorld.M31));
float num4 =
(((num0 * body1.invInertiaWorld.M12) +
(num1 * body1.invInertiaWorld.M22)) +
(num2 * body1.invInertiaWorld.M32));
float num5 =
(((num0 * body1.invInertiaWorld.M13) +
(num1 * body1.invInertiaWorld.M23)) +
(num2 * body1.invInertiaWorld.M33));
body1.angularVelocity.X -= num3;
body1.angularVelocity.Y -= num4;
body1.angularVelocity.Z -= num5;
}
}
if (!body2.isStatic)
{
body2.linearVelocity.X += (impulse.X * body2.inverseMass);
body2.linearVelocity.Y += (impulse.Y * body2.inverseMass);
body2.linearVelocity.Z += (impulse.Z * body2.inverseMass);
if (!body2IsMassPoint)
{
float num0, num1, num2;
num0 = relativePos2.Y * impulse.Z - relativePos2.Z * impulse.Y;
num1 = relativePos2.Z * impulse.X - relativePos2.X * impulse.Z;
num2 = relativePos2.X * impulse.Y - relativePos2.Y * impulse.X;
float num3 =
(((num0 * body2.invInertiaWorld.M11) +
(num1 * body2.invInertiaWorld.M21)) +
(num2 * body2.invInertiaWorld.M31));
float num4 =
(((num0 * body2.invInertiaWorld.M12) +
(num1 * body2.invInertiaWorld.M22)) +
(num2 * body2.invInertiaWorld.M32));
float num5 =
(((num0 * body2.invInertiaWorld.M13) +
(num1 * body2.invInertiaWorld.M23)) +
(num2 * body2.invInertiaWorld.M33));
body2.angularVelocity.X += num3;
body2.angularVelocity.Y += num4;
body2.angularVelocity.Z += num5;
}
}
}