This commit is contained in:
jacob 2024-09-26 17:21:51 -05:00
parent 3b21f641ad
commit acbd97aa84
5 changed files with 111 additions and 81 deletions

View File

@ -38,7 +38,7 @@
* E.g: At 1.5, the user thread will render 75ms back in time (if game thread runs at 50FPS) * E.g: At 1.5, the user thread will render 75ms back in time (if game thread runs at 50FPS)
*/ */
#define USER_INTERP_OFFSET_TICK_RATIO 1.1 #define USER_INTERP_OFFSET_TICK_RATIO 1.1
#define USER_INTERP_ENABLED 1 #define USER_INTERP_ENABLED 0
/* ========================== * /* ========================== *
* Settings * Settings

View File

@ -312,6 +312,11 @@ INLINE b32 entity_has_prop(struct entity *ent, enum entity_prop prop)
return !!(ent->props[index] & ((u64)1 << bit)); return !!(ent->props[index] & ((u64)1 << bit));
} }
INLINE b32 entity_is_valid_and_active(struct entity *ent)
{
return ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE);
}
/* ========================== * /* ========================== *
* Entity functions * Entity functions
* ========================== */ * ========================== */

View File

@ -251,24 +251,6 @@ INTERNAL void spawn_test_entities(void)
* TESTING * TESTING
* ========================== */ * ========================== */
INTERNAL void pre_step(void)
{
struct entity_store *store = G.tick.entity_store;
/* TODO: Just do this during create contact manifolds call if both are outside of substep */
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *manifold = &store->entities[entity_index];
if (!(manifold->valid && entity_has_prop(manifold, ENTITY_PROP_ACTIVE))) continue;
if (!entity_has_prop(manifold, ENTITY_PROP_MANIFOLD)) continue;
for (u32 i = 0; i < manifold->num_contacts; ++i) {
struct contact *contact = &manifold->contacts[i];
contact->accumulated_impulse = 0;
}
}
}
INTERNAL void create_contact_manifolds(void) INTERNAL void create_contact_manifolds(void)
@ -284,7 +266,7 @@ INTERNAL void create_contact_manifolds(void)
struct entity *root = G.root; struct entity *root = G.root;
for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) { for (u64 e0_index = 0; e0_index < store->reserved; ++e0_index) {
struct entity *e0 = &store->entities[e0_index]; struct entity *e0 = &store->entities[e0_index];
if (!(e0->valid && entity_has_prop(e0, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(e0)) continue;
if (!entity_has_prop(e0, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(e0, ENTITY_PROP_PHYSICAL)) continue;
/* Calculate entity 0 shape */ /* Calculate entity 0 shape */
@ -305,7 +287,7 @@ INTERNAL void create_contact_manifolds(void)
for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) { for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) {
struct entity *e1 = &store->entities[e1_index]; struct entity *e1 = &store->entities[e1_index];
if (e1 == e0) continue; if (e1 == e0) continue;
if (!(e1->valid && entity_has_prop(e1, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(e1)) continue;
if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue;
/* TODO: Remove this (temporary stop to prevent double-manifold creation) */ /* TODO: Remove this (temporary stop to prevent double-manifold creation) */
@ -332,14 +314,18 @@ INTERNAL void create_contact_manifolds(void)
manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash)); manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash));
} }
struct entity *manifold = entity_nil(); struct entity *manifold = NULL;
struct entity_handle *entry = fixed_dict_get(&dict, manifold_key); struct entity_handle *entry = fixed_dict_get(&dict, manifold_key);
if (entry) { if (entry) {
manifold = entity_from_handle(store, *entry); struct entity *t = entity_from_handle(store, *entry);
if (entity_is_valid_and_active(t)) {
manifold = t;
}
} }
/* Ensure manifold hasn't already been computed this iteration */ /* Ensure manifold hasn't already been computed this iteration */
if (manifold->valid) { if (manifold) {
if (manifold->last_manifold_iteration == manifold_iteration) { if (manifold->last_manifold_iteration == manifold_iteration) {
/* Already iterated this manifold from The other entity's perspective, skip */ /* Already iterated this manifold from The other entity's perspective, skip */
continue; continue;
@ -369,14 +355,14 @@ INTERNAL void create_contact_manifolds(void)
CT_ASSERT(ARRAY_COUNT(res.points) == 2); CT_ASSERT(ARRAY_COUNT(res.points) == 2);
/* TODO: Remove this (debugging) */ /* TODO: Remove this (debugging) */
if (manifold->valid) { if (manifold) {
manifold->prototype = res.prototype; manifold->prototype = res.prototype;
manifold->simplex = res.simplex; manifold->simplex = res.simplex;
manifold->solved = res.solved; manifold->solved = res.solved;
} }
if (res.num_points > 0) { if (res.num_points > 0) {
if (!manifold->valid) { if (!manifold) {
manifold = entity_alloc(root); manifold = entity_alloc(root);
manifold->manifold_e0 = e0->handle; manifold->manifold_e0 = e0->handle;
manifold->manifold_e1 = e1->handle; manifold->manifold_e1 = e1->handle;
@ -428,32 +414,33 @@ INTERNAL void create_contact_manifolds(void)
f32 sep = res_point->separation; f32 sep = res_point->separation;
u32 id = res_point->id; u32 id = res_point->id;
struct contact *contact = NULL; struct contact *contact = NULL;
{ /* Match */
for (u32 j = 0; j < manifold->num_contacts; ++j) { for (u32 j = 0; j < manifold->num_contacts; ++j) {
struct contact *t = &manifold->contacts[j]; struct contact *t = &manifold->contacts[j];
if (t->id == id) { if (t->id == id) {
/* Update existing */
contact = t; contact = t;
contact->persisted = true;
break; break;
} }
} }
if (!contact) { if (contact) {
/* Update existing */
contact->accumulated_impulse = 0;
contact->persisted = true;
} else {
/* Insert new */ /* Insert new */
contact = &manifold->contacts[manifold->num_contacts++]; contact = &manifold->contacts[manifold->num_contacts++];
MEMZERO_STRUCT(contact); MEMZERO_STRUCT(contact);
contact->id = id; contact->id = id;
} }
}
contact->point_local_e0 = xform_invert_mul_v2(e0_xf, point); contact->point_local_e0 = xform_invert_mul_v2(e0_xf, point);
contact->point_local_e1 = xform_invert_mul_v2(e1_xf, point); contact->point_local_e1 = xform_invert_mul_v2(e1_xf, point);
contact->starting_separation = sep; contact->starting_separation = sep;
} }
} else if (manifold->valid) { } else if (manifold) {
/* No longer colliding, delete manifold */ /* No longer colliding, delete manifold */
#if 0 #if 1
manifold->num_contacts = 0; manifold->num_contacts = 0;
entity_enable_prop(manifold, ENTITY_PROP_RELEASE); entity_enable_prop(manifold, ENTITY_PROP_RELEASE);
#else #else
@ -470,6 +457,45 @@ INTERNAL void create_contact_manifolds(void)
INTERNAL void warm_start_contacts(f32 dt)
{
struct entity_store *store = G.tick.entity_store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *manifold = &store->entities[entity_index];
if (!entity_is_valid_and_active(manifold)) continue;
if (!entity_has_prop(manifold, ENTITY_PROP_MANIFOLD)) continue;
struct entity *e0 = entity_from_handle(store, manifold->manifold_e0);
struct entity *e1 = entity_from_handle(store, manifold->manifold_e1);
if (entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
struct v2 normal = manifold->manifold_normal;
struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1);
/* Warm start */
for (u32 i = 0; i < manifold->num_contacts; ++i) {
struct contact *contact = &manifold->contacts[i];
struct v2 p0 = xform_mul_v2(e0_xf, contact->point_local_e0);
struct v2 p1 = xform_mul_v2(e1_xf, contact->point_local_e1);
f32 separation = v2_dot(v2_sub(p1, p0), normal) + contact->starting_separation;
(UNUSED)p0;
(UNUSED)p1;
(UNUSED)separation;
(UNUSED)dt;
contact->accumulated_impulse = 0;
}
}
}
}
INTERNAL void solve_collisions(f32 dt, b32 apply_bias) INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
@ -478,7 +504,7 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
struct entity_store *store = G.tick.entity_store; struct entity_store *store = G.tick.entity_store;
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *manifold = &store->entities[entity_index]; struct entity *manifold = &store->entities[entity_index];
if (!(manifold->valid && entity_has_prop(manifold, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(manifold)) continue;
if (!entity_has_prop(manifold, ENTITY_PROP_MANIFOLD)) continue; if (!entity_has_prop(manifold, ENTITY_PROP_MANIFOLD)) continue;
struct entity *e0 = entity_from_handle(store, manifold->manifold_e0); struct entity *e0 = entity_from_handle(store, manifold->manifold_e0);
@ -486,8 +512,8 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
u32 num_contacts = manifold->num_contacts; u32 num_contacts = manifold->num_contacts;
f32 inv_num_contacts = 1.f / num_contacts; f32 inv_num_contacts = 1.f / num_contacts;
(UNUSED)inv_num_contacts;
if (num_contacts > 0 && e0->valid && e1->valid) { if (num_contacts > 0 && entity_is_valid_and_active(e0) && entity_is_valid_and_active(e1)) {
struct xform e0_xf = entity_get_xform(e0); struct xform e0_xf = entity_get_xform(e0);
struct xform e1_xf = entity_get_xform(e1); struct xform e1_xf = entity_get_xform(e1);
@ -519,11 +545,11 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
f32 bias = 0; f32 bias = 0;
if (apply_bias) { if (apply_bias) {
//f32 bias_factor = 0.2f; //f32 bias_factor = 0.2f;
f32 bias_factor = 0.2f; f32 bias_factor = 0.1f;
//f32 bias_factor = 0.025f; //f32 bias_factor = 0.025f;
//f32 bias_slop = 0.0005f; //f32 bias_slop = 0.0005f;
f32 bias_slop = 0.001f; f32 bias_slop = 0.005f;
//f32 bias_slop = 0.00f; //f32 bias_slop = 0.00f;
bias = (bias_factor / dt) * max_f32((separation - bias_slop), 0); bias = (bias_factor / dt) * max_f32((separation - bias_slop), 0);
@ -547,7 +573,6 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
/* (to be applied along n) */ /* (to be applied along n) */
f32 j = (vn + bias) / k; f32 j = (vn + bias) / k;
j *= inv_num_contacts; /* TODO: Is this the correct place to do this? */ j *= inv_num_contacts; /* TODO: Is this the correct place to do this? */
(UNUSED)inv_num_contacts;
f32 old_accumulated_impulse = contact->accumulated_impulse; f32 old_accumulated_impulse = contact->accumulated_impulse;
f32 new_accumulated_impulse = max_f32(contact->accumulated_impulse + j, 0); f32 new_accumulated_impulse = max_f32(contact->accumulated_impulse + j, 0);
@ -584,7 +609,7 @@ INTERNAL void integrate_positions(f32 dt)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
struct xform xf = entity_get_xform(ent); struct xform xf = entity_get_xform(ent);
@ -726,7 +751,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_TRIGGER_NEXT_TICK)) { if (entity_has_prop(ent, ENTITY_PROP_TRIGGER_NEXT_TICK)) {
entity_disable_prop(ent, ENTITY_PROP_TRIGGER_NEXT_TICK); entity_disable_prop(ent, ENTITY_PROP_TRIGGER_NEXT_TICK);
@ -742,7 +767,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (sprite_tag_is_nil(ent->sprite)) continue; if (sprite_tag_is_nil(ent->sprite)) continue;
/* Update animation */ /* Update animation */
@ -794,7 +819,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_ATTACHED)) continue; if (!entity_has_prop(ent, ENTITY_PROP_ATTACHED)) continue;
struct entity *parent = entity_from_handle(store, ent->parent); struct entity *parent = entity_from_handle(store, ent->parent);
@ -819,7 +844,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
/* Process cmds */ /* Process cmds */
@ -880,7 +905,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_TEST)) continue; if (!entity_has_prop(ent, ENTITY_PROP_TEST)) continue;
#if 0 #if 0
@ -935,11 +960,11 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) { if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) {
struct entity *eq = entity_from_handle(store, ent->equipped); struct entity *eq = entity_from_handle(store, ent->equipped);
if (eq->valid) { if (entity_is_valid_and_active(eq)) {
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK); entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
} }
} }
@ -951,7 +976,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) continue; if (!entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) continue;
if ((time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue; if ((time - ent->last_triggered < ent->trigger_delay) && ent->last_triggered != 0) continue;
@ -994,7 +1019,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#if 0 #if 0
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
struct v2 move = ent->control.move; struct v2 move = ent->control.move;
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
@ -1007,7 +1032,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#else #else
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct v2 move = ent->control.move; struct v2 move = ent->control.move;
@ -1024,7 +1049,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#if 0 #if 0
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct xform xf = entity_get_xform(ent); struct xform xf = entity_get_xform(ent);
@ -1087,7 +1112,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#else #else
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct xform xf = entity_get_xform(ent); struct xform xf = entity_get_xform(ent);
@ -1178,7 +1203,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
/* TODO: Do this globally rather than creating entities for constant forces */ /* TODO: Do this globally rather than creating entities for constant forces */
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
#if 1 #if 1
if (ent->linear_ground_friction != 0) { if (ent->linear_ground_friction != 0) {
@ -1238,7 +1263,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue; if (!entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) continue;
struct xform xf = entity_get_xform(ent); struct xform xf = entity_get_xform(ent);
@ -1265,11 +1290,12 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
{ {
create_contact_manifolds(); create_contact_manifolds();
pre_step(); //warm_start_contacts(dt);
(UNUSED)create_contact_manifolds; (UNUSED)create_contact_manifolds;
(UNUSED)solve_collisions; (UNUSED)solve_collisions;
(UNUSED)integrate_positions; (UNUSED)integrate_positions;
(UNUSED)warm_start_contacts;
f32 substep_dt = dt / GAME_PHYSICS_SUBSTEPS; f32 substep_dt = dt / GAME_PHYSICS_SUBSTEPS;
for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) { for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) {
@ -1290,7 +1316,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
/* FIXME: Apply src entity velocity to bullet velocity */ /* FIXME: Apply src entity velocity to bullet velocity */
@ -1317,7 +1343,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#if 0 #if 0
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
/* Camera follow */ /* Camera follow */
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) { if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
@ -1354,7 +1380,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#else #else
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
/* Camera follow */ /* Camera follow */
if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) { if (entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
@ -1401,7 +1427,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) { for (u64 entity_index = 0; entity_index < store->reserved; ++entity_index) {
struct entity *ent = &store->entities[entity_index]; struct entity *ent = &store->entities[entity_index];
if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; if (!entity_is_valid_and_active(ent)) continue;
if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) { if (entity_has_prop(ent, ENTITY_PROP_TEST_SOUND_EMITTER)) {
struct mixer_desc desc = ent->sound_desc; struct mixer_desc desc = ent->sound_desc;

View File

@ -356,7 +356,7 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
DBGSTEP; DBGSTEP;
{ {
const f32 wedge_epsilon = 0.001; const f32 wedge_epsilon = 0.001f;
/* shape0 a -> b winding = clockwise */ /* shape0 a -> b winding = clockwise */
u32 id_a0; u32 id_a0;

View File

@ -1135,7 +1135,7 @@ INTERNAL void user_update(void)
/* Draw normal */ /* Draw normal */
{ {
u32 color = COLOR_WHITE; u32 color = COLOR_WHITE;
f32 len = 0.1; f32 len = 0.1f;
f32 arrow_thickness = 2; f32 arrow_thickness = 2;
f32 arrow_height = 5; f32 arrow_height = 5;
struct v2 start = xform_mul_v2(G.world_view, point); struct v2 start = xform_mul_v2(G.world_view, point);
@ -1155,8 +1155,8 @@ INTERNAL void user_update(void)
); );
struct string text = string_format(temp.arena, fmt, struct string text = string_format(temp.arena, fmt,
FMT_HEX(contact.id), FMT_HEX(contact.id),
FMT_FLOAT(contact.accumulated_impulse), FMT_FLOAT_P(contact.accumulated_impulse, 3),
FMT_FLOAT(contact.starting_separation)); FMT_FLOAT_P(contact.starting_separation, 3));
draw_text(G.viewport_canvas, disp_font, v2_add(v2_round(xform_mul_v2(G.world_view, point)), V2(0, offset_px)), text); draw_text(G.viewport_canvas, disp_font, v2_add(v2_round(xform_mul_v2(G.world_view, point)), V2(0, offset_px)), text);
@ -1267,8 +1267,7 @@ INTERNAL void user_update(void)
input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed); input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed);
} }
struct v2 input_aim_pos = G.world_cursor; struct v2 input_aim_pos = G.world_cursor;
//if (!G.debug_camera) { if (!G.debug_camera) {
{
queue_game_cmd(scratch.arena, &cmd_list, (struct game_cmd) { queue_game_cmd(scratch.arena, &cmd_list, (struct game_cmd) {
.kind = GAME_CMD_KIND_PLAYER_MOVE, .kind = GAME_CMD_KIND_PLAYER_MOVE,
.move_dir = input_move_dir, .move_dir = input_move_dir,