function update(game: Game, entity: Entity) {
let transform = game.World.Transform[entity];
let rigid_body = game.World.RigidBody[entity];
let collide = game.World.Collide[rigid_body.ColliderId];
if (rigid_body.Kind === RigidKind.Dynamic) {
rigid_body.IsGrounded = false;
let has_collision = false;
for (let i = 0; i < collide.Collisions.length; i++) {
let collision = collide.Collisions[i];
if (game.World.Signature[collision.Other] & Has.RigidBody) {
has_collision = true;
add(transform.Translation, transform.Translation, collision.Hit);
game.World.Signature[entity] |= Has.Dirty;
let other_body = game.World.RigidBody[collision.Other];
switch (other_body.Kind) {
case RigidKind.Static:
normalize(a, collision.Hit);
scale(a, a, -2 * dot(rigid_body.VelocityLinear, a));
add(rigid_body.VelocityResolved, rigid_body.VelocityLinear, a);
break;
case RigidKind.Dynamic:
case RigidKind.Kinematic:
copy(rigid_body.VelocityResolved, other_body.VelocityLinear);
break;
}
scale(
rigid_body.VelocityResolved,
rigid_body.VelocityResolved,
rigid_body.Bounciness
);
if (collision.Hit[1] > 0 && rigid_body.VelocityResolved[1] < 1) {
rigid_body.VelocityResolved[1] = 0;
rigid_body.IsGrounded = true;
}
}
}
if (!has_collision) {
copy(rigid_body.VelocityResolved, rigid_body.VelocityLinear);
}
}
}