gjk closest point working for non-colliding entities

This commit is contained in:
jacob 2024-08-30 17:15:26 -05:00
parent 2fe3502cfc
commit ed1a788821
5 changed files with 65 additions and 22 deletions

View File

@ -95,8 +95,7 @@ struct entity {
b32 colliding; b32 colliding;
struct entity_handle colliding_with; struct entity_handle colliding_with;
struct gjk_extended_simplex simplex; struct gjk_extended_simplex simplex;
struct v2 pen; struct v2 point;
struct v2 spot;

View File

@ -775,10 +775,10 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
} }
b32 colliding = false; b32 colliding = false;
struct gjk_extended_simplex simplex = { 0 }; struct v2 point0 = V2(0, 0);
struct v2 pen = V2(0, 0); struct v2 point1 = V2(0, 0);
struct v2 spot = V2(0, 0); struct entity *colliding_with = entity_nil();
struct entity_handle colliding_with = { 0 }; struct gjk_extended_simplex final_simplex = { 0 };
for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) { for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) {
struct entity *e1 = &store->entities[e1_index]; struct entity *e1 = &store->entities[e1_index];
if (e1 == e0) continue; if (e1 == e0) continue;
@ -801,11 +801,13 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
struct gjk_extended_result res = gjk_extended(e0_poly, e1_poly, G.gjk_steps); struct gjk_extended_result res = gjk_extended(e0_poly, e1_poly, G.gjk_steps);
colliding = res.colliding; colliding = res.colliding;
colliding_with = e1->handle; point0 = res.p0;
simplex = res.final_simplex; point1 = res.p1;
pen = res.colliding_pen; colliding_with = e1;
final_simplex = res.final_simplex;
if (colliding) { if (colliding) {
//pen = epa_colliding_pen(e0_poly, e1_poly, simplex); //pen = epa_colliding_pen(e0_poly, e1_poly, simplex);
#if 0 #if 0
/* Pen movement test */ /* Pen movement test */
@ -816,16 +818,20 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
//e1->verlet_xform.og = v2_add(e1->verlet_xform.og, pen); //e1->verlet_xform.og = v2_add(e1->verlet_xform.og, pen);
} }
#endif #endif
} else {
spot = e0->spot;
} }
} }
e0->colliding = colliding; e0->colliding = colliding;
e0->colliding_with = colliding_with; e0->colliding_with = colliding_with->handle;
e0->simplex = simplex; e0->point = point0;
e0->pen = pen; e0->simplex = final_simplex;
e0->spot = spot;
if (colliding_with->valid) {
colliding_with->colliding = colliding;
colliding_with->colliding_with = e0->handle;
colliding_with->point = point1;
}
} }
#endif #endif

View File

@ -988,13 +988,14 @@ INTERNAL void user_update(void)
} }
} }
/* Draw player collision */ /* Draw collision */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) { if (ent->is_top) {
b32 colliding = ent->colliding; b32 colliding = ent->colliding;
struct entity *e1 = entity_from_handle(store, ent->colliding_with); struct entity *e1 = entity_from_handle(store, ent->colliding_with);
(UNUSED)colliding;
/* Draw menkowski */ /* Draw menkowski */
{ if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct quad ent_quad; struct quad ent_quad;
struct v2_array ent_poly; struct v2_array ent_poly;
struct quad e1_quad; struct quad e1_quad;
@ -1032,6 +1033,14 @@ INTERNAL void user_update(void)
//draw_solid_poly(G.viewport_canvas, m, color); //draw_solid_poly(G.viewport_canvas, m, color);
} }
/* Draw point */
{
u32 color = COLOR_RED;
f32 thickness = 4;
struct v2 point = xform_mul_v2(G.world_view, ent->point);
draw_solid_circle(G.viewport_canvas, point, thickness, color, 10);
}
/* Draw simplex */ /* Draw simplex */
{ {
f32 thickness = 2; f32 thickness = 2;
@ -1062,6 +1071,7 @@ INTERNAL void user_update(void)
} }
} }
#if 0
/* Draw pen */ /* Draw pen */
if (colliding) { if (colliding) {
f32 thickness = 2; f32 thickness = 2;
@ -1072,6 +1082,7 @@ INTERNAL void user_update(void)
draw_solid_arrow_ray(G.viewport_canvas, start, ray, thickness, thickness * 4, color); draw_solid_arrow_ray(G.viewport_canvas, start, ray, thickness, thickness * 4, color);
} }
#endif
} }
/* Draw hierarchy */ /* Draw hierarchy */

View File

@ -358,7 +358,8 @@ struct gjk_extended_result gjk_extended(struct v2_array poly0, struct v2_array p
{ {
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
b32 colliding = false; b32 colliding = false;
struct v2 pen = V2(0, 0); struct v2 shape0_p = V2(0, 0);
struct v2 shape1_p = V2(0, 0);
u32 step = 0; u32 step = 0;
/* Simplex */ /* Simplex */
@ -461,7 +462,7 @@ struct gjk_extended_result gjk_extended(struct v2_array poly0, struct v2_array p
} }
u32 proto_count = 3; u32 proto_count = 3;
pen = V2(0, 0); struct v2 pen = V2(0, 0);
f32 pen_len = F32_INFINITY; f32 pen_len = F32_INFINITY;
while (true) { while (true) {
pen = V2(0, 0); pen = V2(0, 0);
@ -521,12 +522,35 @@ struct gjk_extended_result gjk_extended(struct v2_array poly0, struct v2_array p
proto[pen_pe_index] = m.p; proto[pen_pe_index] = m.p;
} }
pen = v2_mul(v2_norm(pen), pen_len); pen = v2_mul(v2_norm(pen), pen_len);
} else {
if (s.len == 1) {
shape0_p = s.a.p0;
shape1_p = s.a.p1;
} else if (s.len == 2) {
/* Determine ratio between edge a & b that projected origin lies */
struct v2 vab = v2_sub(s.b.p, s.a.p);
struct v2 vao = v2_neg(s.a.p);
f32 ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
/* Determine point on shape 0 */
{
shape0_p = v2_sub(s.b.p0, s.a.p0);
shape0_p = v2_mul(shape0_p, ratio);
shape0_p = v2_add(shape0_p, s.a.p0);
}
/* Determine point on shape 1 */
{
shape1_p = v2_sub(s.b.p1, s.a.p1);
shape1_p = v2_mul(shape1_p, ratio);
shape1_p = v2_add(shape1_p, s.a.p1);
}
}
} }
abort: abort:
struct gjk_extended_result res = { 0 }; struct gjk_extended_result res = { 0 };
res.colliding = colliding; res.colliding = colliding;
res.colliding_pen = pen; res.p0 = shape0_p;
res.p1 = shape1_p;
res.final_simplex = s; res.final_simplex = s;
scratch_end(scratch); scratch_end(scratch);
return res; return res;

View File

@ -199,7 +199,10 @@ struct gjk_extended_simplex {
struct gjk_extended_result { struct gjk_extended_result {
b32 colliding; b32 colliding;
struct v2 colliding_pen; struct v2 p0; /* Closest / deepest point on first shape's edge */
struct v2 p1; /* Closest / deepest point on second shape's edge */
/* For debugging */
struct gjk_extended_simplex final_simplex; struct gjk_extended_simplex final_simplex;
}; };