more gjk collision work for rounded shapes

This commit is contained in:
jacob 2024-10-09 13:05:01 -05:00
parent 33b32e849c
commit f22aec28bb
4 changed files with 269 additions and 1329 deletions

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ struct collider_collision_point {
u32 id; /* Based on polygon edge-to-edge */ u32 id; /* Based on polygon edge-to-edge */
}; };
struct collider_prototype { struct v2 points[256]; u32 len; }; struct collider_prototype { struct v2 points[64]; u32 len; };
struct collider_collision_points_result { struct collider_collision_points_result {
struct v2 normal; struct v2 normal;

View File

@ -166,6 +166,61 @@ INTERNAL void spawn_test_entities(f32 offset)
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED); entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
//e->control_force = 4500; //e->control_force = 4500;
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->linear_ground_friction = 1000;
e->angular_ground_friction = 100;
//entity_enable_prop(e, ENTITY_PROP_TEST);
player_ent = e;
}
{
//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, -2);
//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 */
pos = v2_add(pos, V2(0, offset));
pos = v2_add(pos, V2(0, offset_all));
//struct v2 size = V2(1, 1);
struct v2 size = V2(0.5, 0.5);
//f32 r = PI;
//f32 r = PI / 4;
//f32 r = PI / 3;
//f32 r = 0.05;
//f32 r = PI / 2;
f32 r = 0;
//f32 skew = PI / 4;
f32 skew = 0;
struct entity *e = entity_alloc(root);
struct xform xf = XFORM_TRS(.t = pos, .r = r, .s = size);
xf = xform_skewed_to(xf, skew);
entity_set_xform(e, xf);
//e->sprite = sprite_tag_from_path(STR("res/graphics/tim.ase"));
e->sprite = sprite_tag_from_path(STR("res/graphics/box.ase"));
//e->sprite_span_name = STR("idle.unarmed");
//e->sprite_span_name = STR("idle.one_handed");
e->sprite_span_name = STR("idle.two_handed");
//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_force = 250;
e->control_torque = 10; e->control_torque = 10;
@ -173,14 +228,12 @@ INTERNAL void spawn_test_entities(f32 offset)
entity_enable_prop(e, ENTITY_PROP_PHYSICAL); entity_enable_prop(e, ENTITY_PROP_PHYSICAL);
e->mass_unscaled = 100; e->mass_unscaled = 100;
e->inertia_unscaled = F32_INFINITY; //e->inertia_unscaled = F32_INFINITY;
//e->inertia_unscaled = 25; e->inertia_unscaled = 25;
e->linear_ground_friction = 1000; e->linear_ground_friction = 1000;
e->angular_ground_friction = 100; e->angular_ground_friction = 100;
//entity_enable_prop(e, ENTITY_PROP_TEST); //entity_enable_prop(e, ENTITY_PROP_TEST);
player_ent = e;
} }
/* Weapon */ /* Weapon */
@ -206,7 +259,7 @@ INTERNAL void spawn_test_entities(f32 offset)
} }
/* Box */ /* Box */
#if 1 #if 0
if (!G.first_spawn) { if (!G.first_spawn) {
struct v2 pos = V2(0.5, -1); struct v2 pos = V2(0.5, -1);
//struct v2 pos = V2(0.5, 29); //struct v2 pos = V2(0.5, 29);
@ -575,7 +628,7 @@ INTERNAL struct soft_result make_soft(f32 hertz, f32 zeta, f32 h)
INTERNAL void solve_collisions(f32 dt, b32 apply_bias) INTERNAL void solve_collisions(f32 dt, b32 apply_bias)
{ {
#if 1 #if 0
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];
@ -957,16 +1010,25 @@ 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); 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 = collider_from_quad(xform_mul_quad(ent->sprite_local_xform, quad_from_rect(slice.rect)));
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { //if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
if ((true)) {
#if 0 #if 0
ent->local_collider.points[0] = V2(0, 0); ent->local_collider.points[0] = V2(0, 0);
ent->local_collider.count = 1; ent->local_collider.count = 1;
ent->local_collider.radius = 0.5; ent->local_collider.radius = 0.5;
#else #elif 0
ent->local_collider.points[0] = V2(0, 0.5); ent->local_collider.points[0] = V2(0, 0.5);
ent->local_collider.points[1] = V2(0, -0.5); ent->local_collider.points[1] = V2(0, -0.5);
ent->local_collider.count = 2; ent->local_collider.count = 2;
ent->local_collider.radius = 0.25; ent->local_collider.radius = 0.25;
#elif 1
ent->local_collider.points[0] = V2(-0.5, 0.5);
ent->local_collider.points[1] = V2(0.5, 0.5);
ent->local_collider.points[2] = V2(0, -0.5);
ent->local_collider.count = 3;
ent->local_collider.radius = 0.25;
#else
ent->local_collider.radius = 0.25;
#endif #endif
} }
} }
@ -1358,7 +1420,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
* Create ground friction force (gravity) * Create ground friction force (gravity)
* ========================== */ * ========================== */
#if 0 #if 1
/* 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];
@ -1434,7 +1496,7 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
#endif #endif
solve_collisions(substep_dt, true); solve_collisions(substep_dt, true);
integrate_positions_from_velocities(substep_dt); integrate_positions_from_velocities(substep_dt);
solve_collisions(substep_dt, false); /* Relaxation */ //solve_collisions(substep_dt, false); /* Relaxation */
} }
} }
#else #else

View File

@ -1137,7 +1137,7 @@ INTERNAL void user_update(void)
{ {
struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f); struct font *disp_font = font_load_async(STR("res/fonts/fixedsys.ttf"), 12.0f);
if (disp_font) { if (disp_font) {
f32 offset_px = -20; f32 offset_px = 10;
struct string fmt = STR( struct string fmt = STR(
"path: %F\n" "path: %F\n"
@ -1146,7 +1146,9 @@ INTERNAL void user_update(void)
"id: 0x%F\n" "id: 0x%F\n"
"impulse (n): %F\n" "impulse (n): %F\n"
"impulse (t): %F\n" "impulse (t): %F\n"
"separation: %F" "separation: %F\n"
"normal: (%F, %F)\n"
"num contacts: %F"
); );
struct string text = string_format(temp.arena, fmt, struct string text = string_format(temp.arena, fmt,
FMT_SINT(ent->res.path), FMT_SINT(ent->res.path),
@ -1155,7 +1157,9 @@ INTERNAL void user_update(void)
FMT_HEX(contact.id), FMT_HEX(contact.id),
FMT_FLOAT_P(contact.normal_impulse, 3), FMT_FLOAT_P(contact.normal_impulse, 3),
FMT_FLOAT_P(contact.tangent_impulse, 3), FMT_FLOAT_P(contact.tangent_impulse, 3),
FMT_FLOAT_P(contact.starting_separation, 6)); FMT_FLOAT_P(contact.starting_separation, 6),
FMT_FLOAT_P(ent->manifold_normal.x, 6), FMT_FLOAT_P(ent->manifold_normal.y, 6),
FMT_UINT(ent->num_contacts));
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);
@ -1168,8 +1172,8 @@ INTERNAL void user_update(void)
#if 1 #if 1
/* Draw clipping */ /* Draw clipping */
{ {
f32 thickness = 2; f32 thickness = 4;
u32 color = RGBA_32_F(1, 0, 1, 0.75); u32 color = RGBA_32_F(1, 0, 1, 0.5);
{ {
struct v2 start = xform_mul_v2(G.world_view, ent->res.a0); struct v2 start = xform_mul_v2(G.world_view, ent->res.a0);
struct v2 end = xform_mul_v2(G.world_view, ent->res.b0); struct v2 end = xform_mul_v2(G.world_view, ent->res.b0);