diff --git a/src/collider.c b/src/collider.c index c80070c1..dc3cb8eb 100644 --- a/src/collider.c +++ b/src/collider.c @@ -85,7 +85,7 @@ struct collider_collision_points_result collider_collision_points(struct collide (UNUSED)radius1; /* TODO: Parameterize */ - const f32 tolerance = 0.005f; + const f32 tolerance = 0.001f; const f32 min_unique_pt_dist_sq = 0.001f * 0.001f; b32 colliding = false; @@ -130,6 +130,7 @@ struct collider_collision_points_result collider_collision_points(struct collide m = menkowski_point(shape0, shape1, xf0, xf1, dir); /* Check that new point is far enough away from existing point */ if (v2_len_sq(v2_sub(m, s.a)) < min_unique_pt_dist_sq) { + simplex_is_closest_edge = true; done = true; break; } @@ -172,7 +173,7 @@ struct collider_collision_points_result collider_collision_points(struct collide struct v2 rab_dir = v2_perp_towards_dir(vab, v2_neg(vac)); struct v2 rac_dir = v2_perp_towards_dir(vac, v2_neg(vab)); struct v2 rbc_dir = v2_perp_towards_dir(vbc, vab); -#if 0 +#if 1 voronoi_mask |= (v2_dot(rab_dir, v2_neg(s.a)) > 0) << 0; /* Regions ab, a, and b*/ voronoi_mask |= (v2_dot(rac_dir, v2_neg(s.a)) > 0) << 1; /* Regions ac, a, and c */ voronoi_mask |= (v2_dot(rbc_dir, v2_neg(s.b)) > 0) << 2; /* Regions bc, b, and c */ @@ -344,18 +345,27 @@ struct collider_collision_points_result collider_collision_points(struct collide } proto[pen_pe_index] = m; } - } else if (simplex_is_closest_edge && s.len > 1) { - /* Shapes are not overlapping (origin is outside of simplex). Project - * origin to determine if distance is within tolerance. */ - ASSERT(s.len == 2); - struct v2 vab = v2_sub(s.b, s.a); - struct v2 vao = v2_neg(s.a); - f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1); - struct v2 p = v2_add(s.a, v2_mul(vab, ratio)); - if (v2_len_sq(p) <= (tolerance * tolerance)) { - res.path = 2; - normal = v2_norm(dir); - colliding = true; + } else if (simplex_is_closest_edge) { + if (s.len == 1) { + struct v2 p = v2_neg(s.a); + if (v2_len_sq(p) <= (tolerance * tolerance)) { + res.path = 2; + normal = v2_norm(dir); + colliding = true; + } + } else { + /* Shapes are not overlapping (origin is outside of simplex). Project + * origin to determine if distance is within tolerance. */ + ASSERT(s.len == 2); + struct v2 vab = v2_sub(s.b, s.a); + struct v2 vao = v2_neg(s.a); + f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1); + struct v2 p = v2_add(s.a, v2_mul(vab, ratio)); + if (v2_len_sq(p) <= (tolerance * tolerance)) { + res.path = 2; + normal = v2_norm(dir); + colliding = true; + } } } diff --git a/src/game.c b/src/game.c index 26188dc1..168d9182 100644 --- a/src/game.c +++ b/src/game.c @@ -166,15 +166,15 @@ INTERNAL void spawn_test_entities(f32 offset) entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); //e->control_force = 4500; - e->control_force = 1200; - //e->control_force = 250; + //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 = F32_INFINITY; - e->inertia_unscaled = 25; + e->inertia_unscaled = F32_INFINITY; + //e->inertia_unscaled = 25; e->linear_ground_friction = 1000; e->angular_ground_friction = 100; @@ -212,8 +212,8 @@ INTERNAL void spawn_test_entities(f32 offset) //struct v2 pos = V2(0.5, 29); //struct v2 pos = V2(0.5, 24); //struct v2 pos = V2(1, -1); - struct v2 size = V2(1, 1); - //struct v2 size = V2(500, 50); + //struct v2 size = V2(1, 1); + struct v2 size = V2(500, 1); //f32 rot = PI / 4; f32 rot = 0; struct entity *e = entity_alloc(root); @@ -523,7 +523,7 @@ INTERNAL void warm_start_contacts(void) struct v2 vcp1 = v2_sub(p1, e1_xf.og); struct v2 impulse = v2_add(v2_mul(normal, contact->normal_impulse), v2_mul(tangent, contact->tangent_impulse)); - impulse = v2_mul(impulse, 0.5f); + //impulse = v2_mul(impulse, 0.5f); v0 = v2_sub(v0, v2_mul(impulse, contact->inv_m0)); v1 = v2_add(v1, v2_mul(impulse, contact->inv_m1)); @@ -611,21 +611,23 @@ INTERNAL void solve_collisions(f32 dt, b32 apply_bias) f32 mass_scale = 1.0f; f32 impulse_scale = 0.0f; - if (separation > 0.0f) { - velocity_bias = separation / dt; - } else if (apply_bias) { - /* Soft constraint */ + if (apply_bias) { + if (separation > 0.0f) { + velocity_bias = separation / dt; + } else { + /* Soft constraint */ - f32 contact_damping_ratio = 10.0f; - f32 contact_hertz = (GAME_FPS * GAME_PHYSICS_SUBSTEPS) / 8.f; + f32 contact_damping_ratio = 10.0f; + f32 contact_hertz = (GAME_FPS * GAME_PHYSICS_SUBSTEPS) / 8.f; - struct soft_result softness = make_soft(contact_hertz, contact_damping_ratio, dt); + struct soft_result softness = make_soft(contact_hertz, contact_damping_ratio, dt); - f32 contact_pushout_velocity = 3.0f; - velocity_bias = max_f32(softness.bias_rate * separation, -contact_pushout_velocity); + f32 contact_pushout_velocity = 3.0f; + velocity_bias = max_f32(softness.bias_rate * separation, -contact_pushout_velocity); - mass_scale = softness.mass_scale; - impulse_scale = softness.impulse_scale; + mass_scale = softness.mass_scale; + impulse_scale = softness.impulse_scale; + } } struct v2 vel0 = v2_add(v0, v2_perp_mul(vcp0, w0)); @@ -954,7 +956,6 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) { struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("shape"), ent->animation_frame); ent->local_collider = collider_from_quad(xform_mul_quad(ent->sprite_local_xform, quad_from_rect(slice.rect))); - ent->local_collider.radius = 0.1; if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { #if 0 @@ -1357,7 +1358,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) * Create ground friction force (gravity) * ========================== */ -#if 1 +#if 0 /* 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]; diff --git a/src/user.c b/src/user.c index 7536f513..275195a3 100644 --- a/src/user.c +++ b/src/user.c @@ -146,6 +146,8 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, G.window = window; sys_window_register_event_callback(G.window, &window_event_callback); + G.debug_draw = true; + G.user_thread = sys_thread_alloc(&user_thread_entry_point, NULL, STR("[P1] User thread")); app_register_exit_callback(&user_shutdown); @@ -994,9 +996,9 @@ INTERNAL void user_update(void) if (entity_has_prop(ent, ENTITY_PROP_PHYSICAL)) { struct collider_shape collider = ent->local_collider; u32 color = ent->colliding ? RGBA_32_F(1, 1, 1, 0.5) : RGBA_32_F(1, 1, 0, 0.25); - f32 thickness = 1; + f32 thickness = 2; //u32 detail = 32; - u32 detail = 256; + u32 detail = 512; //draw_solid_collider_line(G.viewport_canvas, collider, xform_mul(G.world_view, xf), thickness, color, detail); draw_solid_collider_line(G.viewport_canvas, G.world_view, collider, xf, thickness, color, detail); }