gjk closest point working for non-colliding entities
This commit is contained in:
parent
2fe3502cfc
commit
ed1a788821
@ -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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
32
src/game.c
32
src/game.c
@ -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
|
||||||
|
|
||||||
|
|||||||
17
src/user.c
17
src/user.c
@ -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 */
|
||||||
|
|||||||
30
src/util.c
30
src/util.c
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user