revert to using euler integration
This commit is contained in:
parent
8177754821
commit
a0600fc419
@ -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
|
||||||
|
|||||||
@ -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 */
|
||||||
|
|||||||
24
src/game.c
24
src/game.c
@ -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 */
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user