diff --git a/src/game.c b/src/game.c index e13697c8..9bfe9d7e 100644 --- a/src/game.c +++ b/src/game.c @@ -19,6 +19,9 @@ GLOBAL struct { b32 paused; struct sprite_scope *sprite_frame_scope; + /* TODO: Remove this (testing) */ + b32 box_spawned; + /* Game thread input */ struct sys_mutex game_cmds_mutex; struct arena game_cmds_arena; @@ -129,10 +132,10 @@ INTERNAL void spawn_test_entities(void) //struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */ //struct v2 size = V2(1, 1); struct v2 size = V2(0.5, 0.5); - f32 r = PI / 4; + //f32 r = PI / 4; //f32 r = PI / 3; //f32 r = PI / 2; - //f32 r = 0; + f32 r = 0; f32 skew = 0; struct entity *e = entity_alloc(root); @@ -149,14 +152,15 @@ INTERNAL void spawn_test_entities(void) entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); //e->control_force = 4500; - e->control_force = 1200; + //e->control_force = 1200; + e->control_force = 250; e->control_torque = 10; e->control.focus = V2(0, -1); entity_enable_prop(e, ENTITY_PROP_PHYSICAL); e->mass_unscaled = 100; - //e->inertia_unscaled = 1; - e->inertia_unscaled = F32_INFINITY; + e->inertia_unscaled = 25; + //e->inertia_unscaled = F32_INFINITY; e->linear_ground_friction = 1000; e->angular_ground_friction = 100; @@ -188,7 +192,9 @@ INTERNAL void spawn_test_entities(void) } /* Box */ - { + if (!G.box_spawned) { + G.box_spawned = true; + //struct v2 pos = V2(0.5, -0.5); struct v2 pos = V2(0.5, -1); struct v2 size = V2(1, 1); @@ -281,6 +287,11 @@ INTERNAL void create_contact_manifolds(void) if (!(e1->valid && entity_has_prop(e1, ENTITY_PROP_ACTIVE))) continue; if (!entity_has_prop(e1, ENTITY_PROP_PHYSICAL)) continue; + /* TODO: Remove this (temporary stop to prevent double-manifold creation) */ + if (e0_index >= e1_index) { + continue; + } + /* TODO: Remove this */ static struct arena dict_arena = ZI; static struct fixed_dict dict = ZI; @@ -295,10 +306,6 @@ INTERNAL void create_contact_manifolds(void) { struct entity_handle h0 = e0->handle; struct entity_handle h1 = e1->handle; - if (h0.idx > h1.idx) { - h0 = e1->handle; - h1 = e0->handle; - } manifold_hash = hash_fnv64(HASH_FNV64_BASIS, BUFFER_FROM_STRUCT(&h0)); manifold_hash = hash_fnv64(manifold_hash, BUFFER_FROM_STRUCT(&h1)); manifold_key = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&manifold_hash)); @@ -335,11 +342,14 @@ INTERNAL void create_contact_manifolds(void) } #if 1 - const f32 remove_contact_threshold_global_dist_sq = 0.005f * 0.005f; - const f32 insert_contact_threshold_global_dist_sq = 0.005f * 0.005f; -#else + const f32 remove_contact_threshold_global_dist_sq = 0.025f * 0.025f; + const f32 insert_contact_threshold_global_dist_sq = 0.025f * 0.025f; +#elif 0 const f32 remove_contact_threshold_global_dist_sq = 0; const f32 insert_contact_threshold_global_dist_sq = 0; +#else + const f32 remove_contact_threshold_global_dist_sq = F32_INFINITY; + const f32 insert_contact_threshold_global_dist_sq = F32_INFINITY; #endif struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly); @@ -502,8 +512,12 @@ INTERNAL void create_contact_manifolds(void) /* Copy */ /* TODO: Optimize */ CT_ASSERT(ARRAY_COUNT(manifold->contacts) == 2); /* Logic assumes 2 contact points */ - manifold->contacts[0] = *deepest; - manifold->contacts[1] = *furthest; + { + struct contact deepest_cpy = *deepest; + struct contact furthest_cpy = *furthest; + manifold->contacts[0] = deepest_cpy; + manifold->contacts[1] = furthest_cpy; + } } @@ -527,17 +541,11 @@ INTERNAL void create_contact_manifolds(void) #endif - - - - - } else if (manifold->valid) { /* No longer colliding, delete manifold */ -#if 0 +#if 1 manifold->num_contacts = 0; - //fixed_dict_set(&dict_arena, &dict, manifold_key, NULL); - //entity_enable_prop(manifold, ENTITY_PROP_RELEASE); + entity_enable_prop(manifold, ENTITY_PROP_RELEASE); #else if (res.solved) { manifold->prototype.len = 0; @@ -599,10 +607,10 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias) f32 bias = 0; if (apply_bias) { //f32 bias_factor = 0.2f; - f32 bias_factor = 0.1f; + f32 bias_factor = 0.025f; //f32 bias_slop = 0.0005f; - f32 bias_slop = 0.001f; + f32 bias_slop = 0.005f; //f32 bias_slop = 0.00f; bias = (bias_factor / dt) * max_f32((contact->depth - bias_slop), 0); @@ -745,8 +753,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) * Spawn test entities * ========================== */ - /* TODO: remove this (testing) */ - /* Initialize entities */ + /* TODO: remove this (testing) */ + /* Initialize entities */ { static b32 run = 0; if (!run) { @@ -764,13 +772,16 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) switch (cmd.kind) { /* Clear level */ - case GAME_CMD_KIND_CLEAR_ALL: { + case GAME_CMD_KIND_CLEAR_ALL: + { logf_info("Clearing level"); entity_store_reset(store); + G.box_spawned = false; } break; /* Spawn test */ - case GAME_CMD_KIND_SPAWN_TEST: { + case GAME_CMD_KIND_SPAWN_TEST: + { logf_info("Spawning (test)"); spawn_test_entities(); } break; @@ -1250,7 +1261,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) * ========================== */ #if 0 - /* 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) { struct entity *ent = &store->entities[entity_index]; if (!(ent->valid && entity_has_prop(ent, ENTITY_PROP_ACTIVE))) continue; @@ -1295,14 +1306,14 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) f32 impulse = -angular_velocity * inertia; entity_apply_angular_impulse(ent, impulse); } + } } } - } #else - /* TODO: Remove this (gravity test) */ - struct xform xf = entity_get_xform(ent); - f32 mass = ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); - entity_apply_force_to_center(ent, V2(0, 9.81 * mass)); + /* TODO: Remove this (gravity test) */ + struct xform xf = entity_get_xform(ent); + f32 mass = ent->mass_unscaled * math_fabs(xform_get_determinant(xf)); + entity_apply_force_to_center(ent, V2(0, 9.81 * mass)); #endif } #endif @@ -1339,9 +1350,8 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) * ========================== */ { - u32 substeps = 4; - f32 substep_dt = dt / substeps; - for (u32 i = 0; i < substeps; ++i) { + f32 substep_dt = dt / GAME_PHYSICS_SUBSTEPS; + for (u32 i = 0; i < GAME_PHYSICS_SUBSTEPS; ++i) { #if 0 create_contact_manifolds(); diff --git a/src/user.c b/src/user.c index 4aa7bce4..40fbdb9b 100644 --- a/src/user.c +++ b/src/user.c @@ -987,7 +987,6 @@ INTERNAL void user_update(void) } } -#if 1 /* Draw collision */ if (entity_has_prop(ent, ENTITY_PROP_MANIFOLD)) { struct entity *e0 = entity_from_handle(store, ent->manifold_e0); @@ -1025,7 +1024,12 @@ INTERNAL void user_update(void) }; } } + (UNUSED)e0_quad; + (UNUSED)e0_poly; + (UNUSED)e1_quad; + (UNUSED)e1_poly; +#if 0 #if 0 /* Draw collision shapes */ { @@ -1119,7 +1123,9 @@ INTERNAL void user_update(void) draw_solid_poly_line(G.viewport_canvas, simplex_array, simplex.len > 2, thickness, line_color); } } +#endif +#if 1 /* Draw contacts */ { f32 radius = 5; @@ -1141,8 +1147,8 @@ INTERNAL void user_update(void) } } } - } #endif + } /* Draw hierarchy */ if (entity_has_prop(parent, ENTITY_PROP_ACTIVE) && !parent->is_root) {