step method
Advances the simulation by dt seconds, in collisionSteps passes
(one per 1/60 s is plenty). Characters move in moveCharacter, before
it.
Implementation
@override
void step(double dt, {int collisionSteps = 1}) {
if (_disposed || dt <= 0) return;
steps++;
lastStep = dt;
final all = bodies.values.toList(growable: false);
for (final b in all) {
if (!b.awake) continue;
if (b.type == BodyType3D.kinematic) {
final target = b._kinematicTarget;
if (target != null) {
b.position.setFrom(target);
b._kinematicTarget = null;
} else {
b.position.addScaled(b.linearVelocity, dt);
}
// A sensor makes no contact, so it wakes nothing (Jolt wakes bodies
// only as it makes contacts).
if (collisions && !b.isSensor && b.linearVelocity.lengthSquared > 0) {
_wakeTouched(b, all);
}
// Still for long enough, it sleeps, as in Jolt.
if (b.allowSleeping &&
target == null &&
b.linearVelocity.lengthSquared < 0.05 * 0.05) {
if (++b._restSteps > _sleepSteps) _fallAsleep(b);
} else {
b._restSteps = 0;
}
continue;
}
if (b.type != BodyType3D.dynamic) continue;
final v = b.linearVelocity;
// Moving before this step's gravity: at rest, it wakes nothing.
final moving = v.lengthSquared >= 0.05 * 0.05;
v.addScaled(_gravity, b.gravityFactor * dt);
v.addScaled(b.force, dt / b.mass);
b.force.setZero();
b.torque.setZero();
v.scale(math.max(0.0, 1 - b.linearDamping * dt));
b.position.addScaled(v, dt);
if (collisions) _resolve(b, all, wake: moving);
if (b.allowSleeping && v.lengthSquared < 0.05 * 0.05) {
if (++b._restSteps > _sleepSteps) _fallAsleep(b);
} else {
b._restSteps = 0;
}
}
if (collisions) _findContacts(all);
}