diff --git a/src/collider.c b/src/collider.c index 286efdba..83dc682c 100644 --- a/src/collider.c +++ b/src/collider.c @@ -425,7 +425,14 @@ struct collider_collision_points_result collider_collision_points(struct collide f32 vap_wedge = v2_wedge(vap, normal); f32 vpb_wedge = v2_wedge(vpb, normal); - if (vap_wedge * v2_winding(vap, vpb) < (vpb_wedge + wedge_epsilon)) { + if (count0 > 2 && v2_winding(vap, vpb) > 0) { + /* Winding is reversed, swap */ + f32 t = vap_wedge; + vap_wedge = vpb_wedge; + vpb_wedge = t; + } + + if (vap_wedge > (vpb_wedge + wedge_epsilon)) { id_a0 = a_i; id_b0 = p_i; a0 = a; @@ -453,7 +460,14 @@ struct collider_collision_points_result collider_collision_points(struct collide f32 vap_wedge = v2_wedge(vap, normal); f32 vpb_wedge = v2_wedge(vpb, normal); - if (vap_wedge * -v2_winding(vap, vpb) < (vpb_wedge + wedge_epsilon)) { + if (count1 > 2 && v2_winding(vap, vpb) < 0) { + /* Winding is reversed, swap */ + f32 t = vap_wedge; + vap_wedge = vpb_wedge; + vpb_wedge = t; + } + + if (vap_wedge > (vpb_wedge + wedge_epsilon)) { id_a1 = a_i; id_b1 = p_i; a1 = a; diff --git a/src/config.h b/src/config.h index ad473c5a..f1034393 100644 --- a/src/config.h +++ b/src/config.h @@ -41,11 +41,13 @@ #define GAME_PHYSICS_ENABLE_COLLISION 1 #define GAME_SPAWN_LOTS 0 #define GAME_SPAWN_TESTENT 0 -#define GAME_SPAWN_BOX 1 +#define GAME_SPAWN_BOX 0 #define GAME_PLAYER_AIM 1 -#define GAME_MAX_LINEAR_VELOCITY 100 -#define GAME_MAX_ANGULAR_VELOCITY (TAU * 20) +//#define GAME_MAX_LINEAR_VELOCITY 500 +//#define GAME_MAX_ANGULAR_VELOCITY (TAU * 20) +#define GAME_MAX_LINEAR_VELOCITY F32_INFINITY +#define GAME_MAX_ANGULAR_VELOCITY F32_INFINITY /* How many ticks back in time should the user blend between? * = * diff --git a/src/game.c b/src/game.c index aa9b0faf..338c4861 100644 --- a/src/game.c +++ b/src/game.c @@ -177,10 +177,21 @@ INTERNAL void spawn_test_entities(f32 offset) f32 r = 0; if (!G.extra_spawn) { + entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); + entity_enable_prop(e, ENTITY_PROP_TEST); e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase")); + e->mass_unscaled = 10; + e->inertia_unscaled = 5; } else { + entity_enable_prop(e, ENTITY_PROP_TEST); + e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase")); + e->mass_unscaled = 10; + e->inertia_unscaled = 5; +#if 0 e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase")); - //size = V2(0.5, 0.5); + e->mass_unscaled = 100; + e->inertia_unscaled = 100; +#endif } //e->sprite = sprite_tag_from_path(STR("res/graphics/box_rounded.ase")); @@ -194,32 +205,21 @@ INTERNAL void spawn_test_entities(f32 offset) entity_set_xform(e, xf); - if (!G.extra_spawn) { - entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); - } - - e->linear_ground_friction = 150; - e->angular_ground_friction = 100; + e->linear_ground_friction = 250; + e->angular_ground_friction = 200; //e->control_force = 500; e->control_force = 500; //e->control_force_max_speed = 4; - e->control_torque = 500; - + e->control_torque = 1000; e->control_force_max_speed = 4; entity_enable_prop(e, ENTITY_PROP_PHYSICAL); - e->mass_unscaled = 10; - e->inertia_unscaled = 10; - - entity_enable_prop(e, ENTITY_PROP_TEST); - player_ent = e; - -#if 0 +#if 1 { struct entity *joint_ent = entity_alloc(root); entity_enable_prop(joint_ent, ENTITY_PROP_PHYSICAL); @@ -1203,12 +1203,31 @@ INTERNAL void solve_mouse_joints(f32 dt) f32 mass_scale = softness.mass_scale; f32 impulse_scale = softness.impulse_scale; +#if 0 struct v2 vel = v2_add(v, v2_perp_mul(vcp, w)); - struct v2 b = v2_mul(xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias)), mass_scale); + struct v2 b = v2_mul(xform_basis_mul_v2(xform_invert(joint->linear_mass_xf), v2_add(vel, bias)), mass_scale); + struct v2 old_impulse = joint->linear_impulse; struct v2 impulse = v2_sub(v2_mul(old_impulse, -impulse_scale), b); joint->linear_impulse = v2_clamp_len(v2_add(joint->linear_impulse, impulse), max_impulse); impulse = v2_sub(joint->linear_impulse, old_impulse); +#else + struct v2 vel = v2_add(v, v2_perp_mul(vcp, w)); + struct v2 b = xform_basis_mul_v2(joint->linear_mass_xf, v2_add(vel, bias)); + + struct v2 impulse; + impulse.x = -mass_scale * b.x - impulse_scale * joint->linear_impulse.x; + impulse.y = -mass_scale * b.y - impulse_scale * joint->linear_impulse.y; + + struct v2 old_impulse = joint->linear_impulse; + joint->linear_impulse.x += impulse.x; + joint->linear_impulse.y += impulse.y; + + joint->linear_impulse = v2_clamp_len(joint->linear_impulse, max_impulse); + + impulse.x = joint->linear_impulse.x - old_impulse.x; + impulse.y = joint->linear_impulse.y - old_impulse.y; +#endif v = v2_add(v, v2_mul(impulse, inv_m)); w += v2_wedge(vcp, impulse) * inv_i; @@ -1513,20 +1532,20 @@ 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(cxf, quad_from_rect(slice.rect))); -#if 0 +#if 1 if (entity_has_prop(ent, ENTITY_PROP_TEST)) { //if ((true)) { -#if 1 +#if 0 ent->local_collider.points[0] = V2(0, 0); ent->local_collider.count = 1; ent->local_collider.radius = 0.5; -#elif 0 - ent->local_collider.points[0] = V2(0, 0.5); - ent->local_collider.points[1] = V2(0, -0.5); +#elif 1 + ent->local_collider.points[0] = v2_with_len(V2(0.08, 0.17), 0.15); + ent->local_collider.points[1] = v2_with_len(V2(-0.07, -0.2), 0.15); ent->local_collider.count = 2; - ent->local_collider.radius = 0.25; -#elif 0 -#if 1 + ent->local_collider.radius = 0.075; +#elif 1 +#if 0 /* "Bad" winding order */ ent->local_collider.points[0] = V2(-0.5, 0.5); ent->local_collider.points[1] = V2(0.5, 0.5); diff --git a/src/user.c b/src/user.c index b012b6f3..7a09a4b4 100644 --- a/src/user.c +++ b/src/user.c @@ -87,7 +87,7 @@ GLOBAL READONLY enum user_bind_kind g_binds[SYS_BTN_COUNT] = { /* Testing */ - [SYS_BTN_M1] = USER_BIND_KIND_DEBUG_DRAG, + [SYS_BTN_M2] = USER_BIND_KIND_DEBUG_DRAG, [SYS_BTN_C] = USER_BIND_KIND_DEBUG_CLEAR, [SYS_BTN_V] = USER_BIND_KIND_DEBUG_SPAWN, [SYS_BTN_N] = USER_BIND_KIND_DEBUG_STEP, @@ -1098,7 +1098,7 @@ INTERNAL void user_update(void) /* Draw menkowski */ { - u32 color = ent->res.solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1); + u32 color = data->res.solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1); f32 thickness = 2; u32 detail = 512; (UNUSED)thickness; @@ -1131,7 +1131,7 @@ INTERNAL void user_update(void) f32 arrow_thickness = 2; f32 arrow_height = 5; struct v2 start = xform_mul_v2(G.world_view, V2(0, 0)); - struct v2 end = xform_mul_v2(G.world_view, v2_mul(v2_norm(ent->manifold_normal), len)); + struct v2 end = xform_mul_v2(G.world_view, v2_mul(v2_norm(data->normal), len)); draw_solid_arrow_line(G.viewport_canvas, start, end, arrow_thickness, arrow_height, color); } @@ -1141,8 +1141,8 @@ INTERNAL void user_update(void) u32 color = RGBA_32_F(1, 1, 1, 0.25); struct v2_array m = { - .points = ent->res.prototype.points, - .count = ent->res.prototype.len + .points = data->res.prototype.points, + .count = data->res.prototype.len }; for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_view, m.points[i]); draw_solid_poly_line(G.viewport_canvas, m, true, thickness, color); @@ -1157,7 +1157,7 @@ INTERNAL void user_update(void) u32 color_second = RGBA_32_F(0, 1, 0, 0.75); u32 color_third = RGBA_32_F(0, 0, 1, 0.75); - struct collider_simplex simplex = ent->res.simplex; + struct collider_simplex simplex = data->res.simplex; struct v2 simplex_points[] = { simplex.a, simplex.b, simplex.c }; for (u64 i = 0; i < ARRAY_COUNT(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_view, simplex_points[i]); struct v2_array simplex_array = { .count = simplex.len, .points = simplex_points }; @@ -1417,7 +1417,7 @@ INTERNAL void user_update(void) /* Queue physics drag cmd */ i32 drag_presses = G.bind_states[USER_BIND_KIND_DEBUG_DRAG].num_presses - G.bind_states[USER_BIND_KIND_DEBUG_DRAG].num_releases; - if (G.debug_camera && drag_presses) { + if (drag_presses) { queue_game_cmd(scratch.arena, &cmd_list, (struct game_cmd) { .kind = GAME_CMD_KIND_DRAG_OBJECT, .state = drag_presses > 0 ? GAME_CMD_STATE_START : GAME_CMD_STATE_STOP