diff --git a/src/collider.c b/src/collider.c index 884295d9..69df138d 100644 --- a/src/collider.c +++ b/src/collider.c @@ -24,6 +24,7 @@ INTERNAL void _dbgbreakable(void) struct v2 collider_support_point(struct collider_shape *a, struct xform xf, struct v2 dir) { +#if 0 struct v2 *points = a->points; u32 count = a->count; f32 radius = a->radius; @@ -46,6 +47,62 @@ struct v2 collider_support_point(struct collider_shape *a, struct xform xf, stru } return furthest; +#elif 0 + struct v2 *points = a->points; + u32 count = a->count; + f32 radius = a->radius; + + /* TODO: Could probably binary search for largest dot since shape is convex */ + struct xform inv = xform_invert(xf); + dir = xform_basis_mul_v2(inv, dir); + + struct v2 furthest = ZI; + f32 furthest_dot = -F32_INFINITY; + for (u32 i = 0; i < count; ++i) { + struct v2 p = points[i]; + f32 dot = v2_dot(dir, p); + if (dot > furthest_dot) { + furthest = p; + furthest_dot = dot; + } + } + + if (radius > 0.0) { + dir = v2_with_len(dir, radius); + furthest = v2_add(furthest, dir); + } + + furthest = xform_mul_v2(xf, furthest); + + return furthest; +#else + struct v2 *points = a->points; + u32 count = a->count; + f32 radius = a->radius; + + dir = v2_rotated(dir, -xform_get_rotation(xf)); + dir = v2_mul_v2(dir, xform_get_scale(xf)); + + struct v2 furthest = ZI; + f32 furthest_dot = -F32_INFINITY; + for (u32 i = 0; i < count; ++i) { + struct v2 p = points[i]; + f32 dot = v2_dot(dir, p); + if (dot > furthest_dot) { + furthest = p; + furthest_dot = dot; + } + } + + if (radius > 0.0) { + dir = v2_with_len(dir, radius); + furthest = v2_add(furthest, dir); + } + + furthest = xform_mul_v2(xf, furthest); + + return furthest; +#endif } INTERNAL u32 collider_support_point_index(struct collider_shape *a, struct xform xf, struct v2 dir) @@ -487,7 +544,7 @@ struct collider_collision_points_result collider_collision_points(struct collide } } -#if 1 +#if 0 if (radius0 > 0.0) { struct v2 scale = xform_get_scale(xf0); struct v2 normal_radius = v2_mul_v2(v2_mul(normal, radius0), scale); @@ -501,6 +558,24 @@ struct collider_collision_points_result collider_collision_points(struct collide a1 = v2_sub(a1, normal_radius); b1 = v2_sub(b1, normal_radius); } +#else + if (radius0 > 0.0) { + struct v2 radius_dir = v2_rotated(normal, -xform_get_rotation(xf0)); + radius_dir = v2_mul_v2(radius_dir, xform_get_scale(xf0)); + radius_dir = v2_with_len(radius_dir, radius0); + radius_dir = xform_basis_mul_v2(xf0, radius_dir); + a0 = v2_add(a0, radius_dir); + b0 = v2_add(b0, radius_dir); + } + + if (radius1 > 0.0) { + struct v2 radius_dir = v2_rotated(normal, -xform_get_rotation(xf1)); + radius_dir = v2_mul_v2(radius_dir, xform_get_scale(xf1)); + radius_dir = v2_with_len(radius_dir, radius1); + radius_dir = xform_basis_mul_v2(xf1, radius_dir); + a1 = v2_sub(a1, radius_dir); + b1 = v2_sub(b1, radius_dir); + } #endif f32 a0t = 0; @@ -571,10 +646,17 @@ struct collider_collision_points_result collider_collision_points(struct collide point->point = contact_b; } +#if 0 res.a0 = a0_clipped; res.a1 = a1_clipped; res.b0 = b0_clipped; res.b1 = b1_clipped; +#else + res.a0 = a0; + res.a1 = a1; + res.b0 = b0; + res.b1 = b1; +#endif } } diff --git a/src/config.h b/src/config.h index e80424eb..9cad9d77 100644 --- a/src/config.h +++ b/src/config.h @@ -38,7 +38,7 @@ #define GAME_PHYSICS_ENABLE_RELAXATION 1 #define GAME_PHYSICS_ENABLE_GROUND_FRICTION 0 -#define GAME_SPAWN_LOTS 0 +#define GAME_SPAWN_LOTS 1 #define GAME_MAX_LINEAR_VELOCITY 100 #define GAME_MAX_ANGULAR_VELOCITY ((2 * PI) * 20) diff --git a/src/draw.c b/src/draw.c index 7d221c52..055f8574 100644 --- a/src/draw.c +++ b/src/draw.c @@ -283,8 +283,16 @@ void draw_solid_collider_line(struct renderer_canvas *canvas, struct xform draw_ points[i] = p; } +#if 1 struct v2_array poly = { .points = points, .count = detail }; draw_solid_poly_line(canvas, poly, true, thickness, color); +#else + for (u64 i = 0; i < detail; ++i) { + struct v2 point = points[i]; + (UNUSED)thickness; + draw_solid_circle(canvas, point, 3, color, 10); + } +#endif scratch_end(scratch); } diff --git a/src/game.c b/src/game.c index 28dc9353..75a147b4 100644 --- a/src/game.c +++ b/src/game.c @@ -134,7 +134,7 @@ INTERNAL void spawn_test_entities(f32 offset) //struct v2 pos = V2(0.25, -10); //struct v2 pos = V2(0.25, -7); //struct v2 pos = V2(0.25, -5.27); - struct v2 pos = V2(0.25, -1); + struct v2 pos = V2(0.5, -1); //struct v2 pos = V2(1.1230469346046448864129274625156, -1); /* Touching right side of box */ //struct v2 pos = V2(1.1230469346046448864129274625156 - 0.0001, -1); /* Touching right side of box */ //struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */ @@ -143,14 +143,16 @@ INTERNAL void spawn_test_entities(f32 offset) pos = v2_add(pos, V2(0, offset_all)); //struct v2 size = V2(1, 1); - struct v2 size = V2(0.5, 0.5); + //struct v2 size = V2(0.5, 0.5); + struct v2 size = V2(1.0, 0.5); //f32 r = PI; - //f32 r = PI / 4; + f32 r = PI / 4; //f32 r = PI / 3; //f32 r = 0.05; //f32 r = PI / 2; - f32 r = 0; + //f32 r = 0; //f32 skew = PI / 4; + //f32 skew = 0.9f; f32 skew = 0; struct entity *e = entity_alloc(root); @@ -166,9 +168,12 @@ INTERNAL void spawn_test_entities(f32 offset) e->sprite_span_name = STR("idle.two_handed"); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); +#if GAME_PHYSICS_ENABLE_GROUND_FRICTION //e->control_force = 4500; - //e->control_force = 1200; + e->control_force = 1200; +#else e->control_force = 250; +#endif e->control_torque = 10; e->control.focus = V2(0, -1); @@ -189,8 +194,7 @@ INTERNAL void spawn_test_entities(f32 offset) //struct v2 pos = V2(0.25, -10); //struct v2 pos = V2(0.25, -7); //struct v2 pos = V2(0.25, -5.27); - //struct v2 pos = V2(0.85, -2); - struct v2 pos = V2(0.25, -1); + struct v2 pos = V2(0.5, -1); //struct v2 pos = V2(1.1230469346046448864129274625156, -1); /* Touching right side of box */ //struct v2 pos = V2(1.1230469346046448864129274625156 - 0.0001, -1); /* Touching right side of box */ //struct v2 pos = V2(0.374142020941, -0.246118023992); /* Touching glitch spot */ @@ -199,13 +203,14 @@ INTERNAL void spawn_test_entities(f32 offset) pos = v2_add(pos, V2(0, offset_all)); //struct v2 size = V2(1, 1); - struct v2 size = V2(0.5, 0.5); + //struct v2 size = V2(0.5, 0.5); + struct v2 size = V2(1.0, 0.5); //f32 r = PI; - //f32 r = PI / 4; + f32 r = PI / 4; //f32 r = PI / 3; //f32 r = 0.05; //f32 r = PI / 2; - f32 r = 0; + //f32 r = 0; //f32 skew = PI / 4; f32 skew = 0; @@ -268,8 +273,11 @@ 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); +#if !GAME_SPAWN_LOTS + struct v2 size = V2(1, 1); +#else struct v2 size = V2(500, 1); +#endif //f32 rot = PI / 4; f32 rot = 0; struct entity *e = entity_alloc(root); @@ -832,12 +840,21 @@ INTERNAL void integrate_positions_from_velocities(f32 dt) ent->linear_velocity = v2_clamp_len(ent->linear_velocity, GAME_MAX_LINEAR_VELOCITY); ent->angular_velocity = clamp_f32(ent->angular_velocity, -GAME_MAX_ANGULAR_VELOCITY, GAME_MAX_ANGULAR_VELOCITY); +#if 0 struct xform xf = entity_get_xform(ent); struct v2 tick_linear_velocity = v2_mul(ent->linear_velocity, dt); f32 tick_angular_velocity = ent->angular_velocity * dt; xf.og = v2_add(xf.og, tick_linear_velocity); xf = xform_rotated(xf, tick_angular_velocity); entity_set_xform(ent, xf); +#else + struct xform xf = entity_get_xform(ent); + struct v2 tick_linear_velocity = v2_mul(ent->linear_velocity, dt); + f32 tick_angular_velocity = ent->angular_velocity * dt; + xf.og = v2_add(xf.og, tick_linear_velocity); + xf = xform_rotated_to(xf, xform_get_rotation(xf) + tick_angular_velocity); + entity_set_xform(ent, xf); +#endif } } @@ -1056,7 +1073,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) ent->local_collider.points[1] = V2(0, -0.5); ent->local_collider.count = 2; ent->local_collider.radius = 0.25; -#elif 1 +#elif 0 #if 1 /* "Bad" winding order */ ent->local_collider.points[0] = V2(-0.5, 0.5); @@ -1071,7 +1088,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds) ent->local_collider.radius = 0.25; //ent->local_collider.radius = math_fabs(math_sin(G.tick.time) / 3); #else - ent->local_collider.radius = 0.25; + ent->local_collider.radius = 0.5; #endif } #endif diff --git a/src/user.c b/src/user.c index 33ab0b04..50c397dd 100644 --- a/src/user.c +++ b/src/user.c @@ -998,17 +998,34 @@ INTERNAL void user_update(void) struct collider_shape collider = ent->local_collider; u32 color = ent->colliding > 0 ? RGBA_32_F(1, 1, 1, 0.5) : RGBA_32_F(1, 1, 0, 0.25); f32 thickness = 2; - //u32 detail = 32; - u32 detail = 512; - draw_solid_collider_line(G.viewport_canvas, G.world_view, collider, xf, thickness, color, detail); + { + /* Draw collider using support points */ + u32 detail = 512; + draw_solid_collider_line(G.viewport_canvas, G.world_view, collider, xf, thickness, color, detail); + } + { + /* Draw collider shape points */ + for (u32 i = 0; i < collider.count; ++i) { + struct v2 p = xform_mul_v2(xform_mul(G.world_view, xf), collider.points[i]); + draw_solid_circle(G.viewport_canvas, p, 3, COLOR_BLUE, 10); + } + } if (collider.count == 1 && collider.radius > 0) { /* Draw upwards line for circle */ struct v2 start = xf.og; - struct v2 end = collider_support_point(&collider, xf, v2_neg(xf.by)); + struct v2 end = collider_support_point(&collider, xf, xf.by); start = xform_mul_v2(G.world_view, start); end = xform_mul_v2(G.world_view, end); draw_solid_line(G.viewport_canvas, start, end, thickness, color); } +#if 0 + /* Draw support point at focus dir */ + { + struct v2 p = collider_support_point(&collider, xf, ent->control.focus); + p = xform_mul_v2(G.world_view, p); + draw_solid_circle(G.viewport_canvas, p, 3, COLOR_RED, 10); + } +#endif } /* Draw collision */ @@ -1144,7 +1161,7 @@ INTERNAL void user_update(void) struct v2 end = xform_mul_v2(G.world_view, v2_add(point, v2_mul(v2_norm(ent->manifold_normal), len))); draw_solid_arrow_line(G.viewport_canvas, start, end, arrow_thickness, arrow_height, color); } -#if 1 +#if 0 /* Draw contact info */ { struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);