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;
struct entity_handle colliding_with;
struct gjk_extended_simplex simplex;
struct v2 pen;
struct v2 spot;
struct v2 point;

View File

@ -775,10 +775,10 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
}
b32 colliding = false;
struct gjk_extended_simplex simplex = { 0 };
struct v2 pen = V2(0, 0);
struct v2 spot = V2(0, 0);
struct entity_handle colliding_with = { 0 };
struct v2 point0 = V2(0, 0);
struct v2 point1 = V2(0, 0);
struct entity *colliding_with = entity_nil();
struct gjk_extended_simplex final_simplex = { 0 };
for (u64 e1_index = 0; e1_index < store->reserved; ++e1_index) {
struct entity *e1 = &store->entities[e1_index];
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);
colliding = res.colliding;
colliding_with = e1->handle;
simplex = res.final_simplex;
pen = res.colliding_pen;
point0 = res.p0;
point1 = res.p1;
colliding_with = e1;
final_simplex = res.final_simplex;
if (colliding) {
//pen = epa_colliding_pen(e0_poly, e1_poly, simplex);
#if 0
/* 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);
}
#endif
} else {
spot = e0->spot;
}
}
e0->colliding = colliding;
e0->colliding_with = colliding_with;
e0->simplex = simplex;
e0->pen = pen;
e0->spot = spot;
e0->colliding_with = colliding_with->handle;
e0->point = point0;
e0->simplex = final_simplex;
if (colliding_with->valid) {
colliding_with->colliding = colliding;
colliding_with->colliding_with = e0->handle;
colliding_with->point = point1;
}
}
#endif

View File

@ -988,13 +988,14 @@ INTERNAL void user_update(void)
}
}
/* Draw player collision */
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
/* Draw collision */
if (ent->is_top) {
b32 colliding = ent->colliding;
struct entity *e1 = entity_from_handle(store, ent->colliding_with);
(UNUSED)colliding;
/* Draw menkowski */
{
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
struct quad ent_quad;
struct v2_array ent_poly;
struct quad e1_quad;
@ -1032,6 +1033,14 @@ INTERNAL void user_update(void)
//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 */
{
f32 thickness = 2;
@ -1062,6 +1071,7 @@ INTERNAL void user_update(void)
}
}
#if 0
/* Draw pen */
if (colliding) {
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);
}
#endif
}
/* 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();
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;
/* Simplex */
@ -461,7 +462,7 @@ struct gjk_extended_result gjk_extended(struct v2_array poly0, struct v2_array p
}
u32 proto_count = 3;
pen = V2(0, 0);
struct v2 pen = V2(0, 0);
f32 pen_len = F32_INFINITY;
while (true) {
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;
}
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:
struct gjk_extended_result res = { 0 };
res.colliding = colliding;
res.colliding_pen = pen;
res.p0 = shape0_p;
res.p1 = shape1_p;
res.final_simplex = s;
scratch_end(scratch);
return res;

View File

@ -199,7 +199,10 @@ struct gjk_extended_simplex {
struct gjk_extended_result {
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;
};