
Hi,
I tested the engine by stacking up 50 boxes, and discovered that in this situation, the boxes always collapse unless you increase the update frequency.
So, as an experiment, I tried writing an RK4 integration method that I hoped would improve the results. It didn't seem to make much difference. Maybe numerical error isn't what's causing the problem with stacked boxes, but I thought I'd post my code and see
if I'm doing something wrong.
This is from Body.IntegratePosition(float dt):
//Integrating position:
//dp.X = bodylinearVelocity.X * dt; //CHANGED
//dp.Y = bodylinearVelocity.Y * dt; //CHANGED
RK4(force.Y * inverseMass, dt, bodylinearVelocity.Y, position.Y, out position.Y); //CHANGED
RK4(force.X * inverseMass, dt, bodylinearVelocity.X, position.X, out position.X); //CHANGED
previousPosition = position;
//INLINE: Vector2.Add(ref previousPosition, ref dp, out position); //CHANGED
linearVelocityBias.X = 0;
linearVelocityBias.Y = 0;
bodyAngularVelocity = angularVelocity + angularVelocityBias;
//rotationChange = bodyAngularVelocity * dt; //CHANGED
RK4(inverseMomentOfInertia * torque, dt, bodyAngularVelocity, rotation, out rotation); //CHANGED
previousRotation = rotation;
//rotation = previousRotation + rotationChange; //CHANGED
//etc...
And this is the RK4 method itself:
//Works where where yp = ypp * t, in other words, where y'(t) is linear and depends only on t.
//example: RK4(acceleration, dt, initialVelocity, initialPosition, out newPosition)
float d6 = 1 / 6f;
private void RK4(float ypp, float dt, float yp0, float y0, out float y1)
{
float halfdt = dt * 0.5f;
float k1 = yp0;
float k2 = (halfdt * ypp) + yp0;
float k3 = k2;
float k4 = (dt * ypp) + yp0;
float dy = (dt * d6) * (k1 + 2*k2 + 2*k3 + k4);
y1 = y0 + dy;
}

