revert to using euler integration

This commit is contained in:
jacob 2024-09-10 14:14:56 -05:00
parent 8177754821
commit a0600fc419
5 changed files with 18 additions and 21 deletions

View File

@ -16,7 +16,6 @@ READONLY struct entity _g_entity_nil = {
.local_xform = XFORM_IDENT_NOCAST, .local_xform = XFORM_IDENT_NOCAST,
.cached_global_xform = XFORM_IDENT_NOCAST, .cached_global_xform = XFORM_IDENT_NOCAST,
.cached_global_xform_dirty = false, .cached_global_xform_dirty = false,
.verlet_xform = XFORM_IDENT_NOCAST,
.mass_unscaled = 1, .mass_unscaled = 1,
.sprite_local_xform = XFORM_IDENT_NOCAST, .sprite_local_xform = XFORM_IDENT_NOCAST,
.sprite_tint = COLOR_WHITE .sprite_tint = COLOR_WHITE
@ -27,7 +26,6 @@ GLOBAL READONLY struct entity g_entity_default = {
.local_xform = XFORM_IDENT_NOCAST, .local_xform = XFORM_IDENT_NOCAST,
.cached_global_xform = XFORM_IDENT_NOCAST, .cached_global_xform = XFORM_IDENT_NOCAST,
.cached_global_xform_dirty = true, .cached_global_xform_dirty = true,
.verlet_xform = XFORM_IDENT_NOCAST,
.mass_unscaled = 1, .mass_unscaled = 1,
.sprite_local_xform = XFORM_IDENT_NOCAST, .sprite_local_xform = XFORM_IDENT_NOCAST,
.sprite_tint = COLOR_WHITE .sprite_tint = COLOR_WHITE

View File

@ -148,8 +148,8 @@ struct entity {
f32 mass_unscaled; /* Mass of entity in kg before any transformations */ f32 mass_unscaled; /* Mass of entity in kg before any transformations */
f32 ground_friction; f32 ground_friction;
/* Xform of the entity from the previous frame (used to calculate velocity) */ struct v2 linear_velocity; /* m/s */
struct xform verlet_xform; //f32 angular_velocity; /* rad/s */
/* ====================================================================== */ /* ====================================================================== */
/* Impulse */ /* Impulse */

View File

@ -105,7 +105,6 @@ INTERNAL void activate_now(struct entity *ent)
{ {
entity_enable_prop(ent, ENTITY_PROP_ACTIVE); entity_enable_prop(ent, ENTITY_PROP_ACTIVE);
ent->activation_tick = G.tick.tick_id; ent->activation_tick = G.tick.tick_id;
ent->verlet_xform = entity_get_xform(ent);
++ent->continuity_gen; ++ent->continuity_gen;
} }
@ -596,9 +595,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
if (ent->ground_friction != 0) { if (ent->ground_friction != 0) {
struct xform verlet_xform = ent->verlet_xform; struct v2 linear_velocity = ent->linear_velocity;
struct xform xf = entity_get_xform(ent);
struct v2 linear_velocity = v2_div(v2_sub(xf.og, verlet_xform.og), dt);
if (!v2_eq(linear_velocity, V2(0, 0))) { if (!v2_eq(linear_velocity, V2(0, 0))) {
/* FIXME: Incorrect behavior at low FPS & low entity density */ /* FIXME: Incorrect behavior at low FPS & low entity density */
@ -612,6 +609,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
activate_now(force); activate_now(force);
} else { } else {
/* If linear_velocity is below clamp_epsilon, stop entity movement. */ /* If linear_velocity is below clamp_epsilon, stop entity movement. */
struct xform xf = entity_get_xform(ent);
f32 mass = ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); f32 mass = ent->mass_unscaled * math_fabs(xform_get_determinant(xf));
struct entity *impulse = entity_alloc(ent); struct entity *impulse = entity_alloc(ent);
entity_enable_prop(impulse, ENTITY_PROP_IMPULSE); entity_enable_prop(impulse, ENTITY_PROP_IMPULSE);
@ -635,25 +633,24 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
f32 mass = ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); f32 mass = ent->mass_unscaled * math_fabs(xform_get_determinant(xf));
/* Determine acceleration from forces and impulses */ /* Determine acceleration from forces and impulses */
struct v2 acceleration = V2(0, 0); struct v2 tick_acceleration = V2(0, 0);
for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) { for (struct entity *child = entity_from_handle(store, ent->first); child->valid; child = entity_from_handle(store, child->next)) {
if (entity_has_prop(child, ENTITY_PROP_IMPULSE)) { if (entity_has_prop(child, ENTITY_PROP_IMPULSE)) {
acceleration = v2_add(acceleration, child->force); tick_acceleration = v2_add(tick_acceleration, child->force);
entity_enable_prop(child, ENTITY_PROP_RELEASE); entity_enable_prop(child, ENTITY_PROP_RELEASE);
} else if (entity_has_prop(child, ENTITY_PROP_FORCE)) { } else if (entity_has_prop(child, ENTITY_PROP_FORCE)) {
acceleration = v2_add(acceleration, v2_mul(child->force, dt)); tick_acceleration = v2_add(tick_acceleration, v2_mul(child->force, dt));
entity_enable_prop(child, ENTITY_PROP_RELEASE); entity_enable_prop(child, ENTITY_PROP_RELEASE);
} }
} }
acceleration = v2_div(acceleration, mass); tick_acceleration = v2_div(tick_acceleration, mass);
/* Verlet integration */
struct v2 tick_velocity = v2_sub(xf.og, ent->verlet_xform.og);
tick_velocity = v2_add(tick_velocity, v2_mul(acceleration, dt));
ent->verlet_xform = xf;
/* Integrate */
struct v2 tick_velocity = v2_mul(ent->linear_velocity, dt);
tick_velocity = v2_add(tick_velocity, v2_mul(tick_acceleration, dt));
xf.og = v2_add(xf.og, tick_velocity); xf.og = v2_add(xf.og, tick_velocity);
ent->predicted_xform = xf; ent->predicted_xform = xf;
ent->linear_velocity = v2_div(tick_velocity, dt);
} }
/* ========================== * /* ========================== *
@ -882,7 +879,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(velocity) + PI / 2); struct xform xf = XFORM_TRS(.t = pos, .r = v2_angle(velocity) + PI / 2);
entity_set_xform(ent, xf); entity_set_xform(ent, xf);
ent->verlet_xform = xf;
entity_enable_prop(ent, ENTITY_PROP_PHYSICAL); entity_enable_prop(ent, ENTITY_PROP_PHYSICAL);
/* Create impulse */ /* Create impulse */

View File

@ -286,7 +286,7 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
/* Insert point into prototype */ /* Insert point into prototype */
/* FIXME: Preserve winding order */ /* FIXME: Preserve winding order */
arena_push(scratch.arena, struct v2); arena_push(scratch.arena, struct gjk_menkowski_point);
++proto_count; ++proto_count;
for (u32 i = proto_count - 1; i > pen_pe_index; --i) { for (u32 i = proto_count - 1; i > pen_pe_index; --i) {
u32 shift_from = (i > 0) ? i - 1 : proto_count - 1; u32 shift_from = (i > 0) ? i - 1 : proto_count - 1;
@ -685,7 +685,7 @@ struct gjk_extended_result gjk_extended(struct v2_array shape0, struct v2_array
/* Insert point into prototype */ /* Insert point into prototype */
/* FIXME: Preserve winding order */ /* FIXME: Preserve winding order */
arena_push(scratch.arena, struct v2); arena_push(scratch.arena, struct gjk_menkowski_point);
++proto_count; ++proto_count;
for (u32 i = proto_count - 1; i > pen_pe_index; --i) { for (u32 i = proto_count - 1; i > pen_pe_index; --i) {
u32 shift_from = (i > 0) ? i - 1 : proto_count - 1; u32 shift_from = (i > 0) ? i - 1 : proto_count - 1;

View File

@ -393,7 +393,7 @@ INTERNAL void debug_draw_movement(struct entity *ent)
u32 color_vel = RGBA_32_F(1, 0.5, 0, 1); u32 color_vel = RGBA_32_F(1, 0.5, 0, 1);
struct xform xf = entity_get_xform(ent); struct xform xf = entity_get_xform(ent);
struct v2 velocity = v2_div(v2_sub(xf.og, ent->verlet_xform.og), G.world.dt); struct v2 velocity = ent->linear_velocity;
struct v2 pos = xform_mul_v2(G.world_view, xf.og); struct v2 pos = xform_mul_v2(G.world_view, xf.og);
struct v2 vel_ray = xform_basis_mul_v2(G.world_view, velocity); struct v2 vel_ray = xform_basis_mul_v2(G.world_view, velocity);
@ -498,6 +498,9 @@ INTERNAL void user_update(void)
e->control_move_force = math_lerp(e0->control_move_force, e1->control_move_force, tick_blend); e->control_move_force = math_lerp(e0->control_move_force, e1->control_move_force, tick_blend);
e->linear_velocity = v2_lerp(e0->linear_velocity, e1->linear_velocity, tick_blend);
e->angular_velocity = math_lerp(e0->angular_velocity, e1->angular_velocity, tick_blend);
e->control.move = v2_lerp(e0->control.move, e1->control.move, tick_blend); e->control.move = v2_lerp(e0->control.move, e1->control.move, tick_blend);
e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, tick_blend); e->control.focus = v2_lerp(e0->control.focus, e1->control.focus, tick_blend);