revert to returning contact pairs from gjk
This commit is contained in:
parent
1d7f9be8b4
commit
e8bc83df3a
BIN
res/graphics/tim.ase
(Stored with Git LFS)
BIN
res/graphics/tim.ase
(Stored with Git LFS)
Binary file not shown.
@ -94,14 +94,15 @@ struct entity {
|
|||||||
|
|
||||||
|
|
||||||
/* TODO: Remove this (testing) */
|
/* TODO: Remove this (testing) */
|
||||||
b32 colliding;
|
|
||||||
struct entity_handle colliding_with;
|
struct entity_handle colliding_with;
|
||||||
struct gjk_simplex simplex;
|
struct gjk_simplex simplex;
|
||||||
struct gjk_prototype prototype;
|
struct gjk_prototype prototype;
|
||||||
struct v2 pendir;
|
struct v2 pendir;
|
||||||
b32 solved;
|
b32 solved;
|
||||||
|
|
||||||
struct v2 point;
|
struct v2 point0;
|
||||||
|
struct v2 point1;
|
||||||
|
u32 num_points;
|
||||||
|
|
||||||
b32 test_torque_applied;
|
b32 test_torque_applied;
|
||||||
b32 test_collided;
|
b32 test_collided;
|
||||||
|
|||||||
25
src/game.c
25
src/game.c
@ -910,8 +910,9 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
b32 colliding = false;
|
b32 colliding = false;
|
||||||
struct v2 p0 = V2(0, 0);
|
struct gjk_contact_pair pair0 = { 0 };
|
||||||
struct v2 p1 = V2(0, 0);
|
struct gjk_contact_pair pair1 = { 0 };
|
||||||
|
u32 num_pairs = 0;
|
||||||
struct entity *colliding_with = entity_nil();
|
struct entity *colliding_with = entity_nil();
|
||||||
struct gjk_simplex simplex = { 0 };
|
struct gjk_simplex simplex = { 0 };
|
||||||
struct gjk_prototype prototype = { 0 };
|
struct gjk_prototype prototype = { 0 };
|
||||||
@ -940,31 +941,35 @@ INTERNAL void game_update(struct game_cmd_array game_cmds)
|
|||||||
|
|
||||||
struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly);
|
struct gjk_contact_points_result res = gjk_contact_points(e0_poly, e1_poly);
|
||||||
|
|
||||||
colliding = res.colliding;
|
num_pairs = res.num_pairs;
|
||||||
p0 = res.p0;
|
colliding = num_pairs > 0;
|
||||||
p1 = res.p1;
|
pair0 = res.pairs[0];
|
||||||
|
pair1 = res.pairs[1];
|
||||||
colliding_with = e1;
|
colliding_with = e1;
|
||||||
simplex = res.simplex;
|
simplex = res.simplex;
|
||||||
prototype = res.prototype;
|
prototype = res.prototype;
|
||||||
solved = res.solved;
|
solved = res.solved;
|
||||||
}
|
}
|
||||||
|
|
||||||
e0->colliding = colliding;
|
|
||||||
e0->colliding_with = colliding_with->handle;
|
e0->colliding_with = colliding_with->handle;
|
||||||
e0->point = p0;
|
e0->point0 = pair0.p0;
|
||||||
|
e0->point1 = pair1.p0;
|
||||||
|
e0->num_points = num_pairs;
|
||||||
e0->simplex = simplex;
|
e0->simplex = simplex;
|
||||||
e0->prototype = prototype;
|
e0->prototype = prototype;
|
||||||
e0->pendir = velocity;
|
e0->pendir = velocity;
|
||||||
e0->solved = solved;
|
e0->solved = solved;
|
||||||
|
|
||||||
if (colliding_with->valid) {
|
if (colliding_with->valid) {
|
||||||
colliding_with->colliding = colliding;
|
|
||||||
colliding_with->colliding_with = e0->handle;
|
colliding_with->colliding_with = e0->handle;
|
||||||
colliding_with->point = p1;
|
colliding_with->point0 = pair0.p1;
|
||||||
|
colliding_with->point1 = pair1.p1;
|
||||||
|
colliding_with->num_points = num_pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(UNUSED)colliding;
|
||||||
{
|
{
|
||||||
#if 1
|
#if 0
|
||||||
if (colliding) {
|
if (colliding) {
|
||||||
struct entity *e1 = colliding_with;
|
struct entity *e1 = colliding_with;
|
||||||
struct xform e1_xf = entity_get_xform(e1);
|
struct xform e1_xf = entity_get_xform(e1);
|
||||||
|
|||||||
38
src/gjk.c
38
src/gjk.c
@ -161,8 +161,9 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
|||||||
struct gjk_menkowski_point *proto = NULL;
|
struct gjk_menkowski_point *proto = NULL;
|
||||||
u32 proto_count = 0;
|
u32 proto_count = 0;
|
||||||
|
|
||||||
struct v2 p0 = { 0 };
|
struct gjk_contact_pair pair0 = { 0 };
|
||||||
struct v2 p1 = { 0 };
|
struct gjk_contact_pair pair1 = { 0 };
|
||||||
|
u32 num_pairs = 0;
|
||||||
|
|
||||||
#if GJK_DEBUG
|
#if GJK_DEBUG
|
||||||
u32 dbg_step = 0;
|
u32 dbg_step = 0;
|
||||||
@ -370,14 +371,16 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
|||||||
|
|
||||||
/* Resolve points */
|
/* Resolve points */
|
||||||
if (s.len == 1) {
|
if (s.len == 1) {
|
||||||
p0 = s.a.p0;
|
pair0.p0 = s.a.p0;
|
||||||
p1 = s.a.p1;
|
pair0.p1 = s.a.p1;
|
||||||
|
num_pairs = 1;
|
||||||
} else {
|
} else {
|
||||||
ASSERT(s.len == 2);
|
ASSERT(s.len == 2);
|
||||||
b32 p0_is_on_edge = !v2_eq(s.a.p0, s.b.p0);
|
b32 p0_is_on_edge = !v2_eq(s.a.p0, s.b.p0);
|
||||||
b32 p1_is_on_edge = !v2_eq(s.a.p1, s.b.p1);
|
b32 p1_is_on_edge = !v2_eq(s.a.p1, s.b.p1);
|
||||||
if (p0_is_on_edge && p1_is_on_edge) {
|
if (p0_is_on_edge && p1_is_on_edge) {
|
||||||
/* Closest features are both faces, use midpoint of clipped faces to represent contact points */
|
/* Closest features are both faces, use midpoint of clipped faces to represent contact points */
|
||||||
|
num_pairs = 2;
|
||||||
struct v2 a = s.a.p0;
|
struct v2 a = s.a.p0;
|
||||||
struct v2 b = s.b.p0;
|
struct v2 b = s.b.p0;
|
||||||
struct v2 c = s.a.p1;
|
struct v2 c = s.a.p1;
|
||||||
@ -394,28 +397,31 @@ struct gjk_contact_points_result gjk_contact_points(struct v2_array shape0, stru
|
|||||||
f32 inv_vab_len_sq = 1.f / v2_len_sq(vab);
|
f32 inv_vab_len_sq = 1.f / v2_len_sq(vab);
|
||||||
f32 inv_vcd_len_sq = 1.f / v2_len_sq(vcd);
|
f32 inv_vcd_len_sq = 1.f / v2_len_sq(vcd);
|
||||||
|
|
||||||
f32 ab_clip_c = clamp_f32(v2_dot(vab, vac) * inv_vab_len_sq, 0, 1);
|
pair0.p0 = v2_add(a, v2_mul(vab, clamp_f32(v2_dot(vab, vac) * inv_vab_len_sq, 0, 1)));
|
||||||
f32 ab_clip_d = clamp_f32(v2_dot(vab, vad) * inv_vab_len_sq, 0, 1);
|
pair0.p1 = v2_add(c, v2_mul(vcd, clamp_f32(v2_dot(vcd, vcb) * inv_vcd_len_sq, 0, 1)));
|
||||||
f32 cd_clip_a = clamp_f32(v2_dot(vcd, vca) * inv_vcd_len_sq, 0, 1);
|
pair1.p0 = v2_add(a, v2_mul(vab, clamp_f32(v2_dot(vab, vad) * inv_vab_len_sq, 0, 1)));
|
||||||
f32 cd_clip_b = clamp_f32(v2_dot(vcd, vcb) * inv_vcd_len_sq, 0, 1);
|
pair1.p1 = v2_add(c, v2_mul(vcd, clamp_f32(v2_dot(vcd, vca) * inv_vcd_len_sq, 0, 1)));
|
||||||
|
|
||||||
p0 = v2_add(a, v2_mul(vab, (ab_clip_c + ab_clip_d) * 0.5f));
|
|
||||||
p1 = v2_add(c, v2_mul(vcd, (cd_clip_a + cd_clip_b) * 0.5f));
|
|
||||||
} else {
|
} else {
|
||||||
/* Determine ratio between edge a & b that projected origin lies */
|
/* Determine ratio between edge a & b that projected origin lies */
|
||||||
|
num_pairs = 1;
|
||||||
f32 ratio;
|
f32 ratio;
|
||||||
{
|
{
|
||||||
struct v2 vab = v2_sub(s.b.p, s.a.p);
|
struct v2 vab = v2_sub(s.b.p, s.a.p);
|
||||||
struct v2 vao = v2_neg(s.a.p);
|
struct v2 vao = v2_neg(s.a.p);
|
||||||
ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
ratio = clamp_f32(v2_dot(vab, vao) / v2_dot(vab, vab), 0, 1);
|
||||||
}
|
}
|
||||||
p0 = v2_add(s.a.p0, v2_mul(v2_sub(s.b.p0, s.a.p0), ratio));
|
pair0.p0 = v2_add(s.a.p0, v2_mul(v2_sub(s.b.p0, s.a.p0), ratio));
|
||||||
p1 = v2_add(s.a.p1, v2_mul(v2_sub(s.b.p1, s.a.p1), ratio));
|
pair0.p1 = v2_add(s.a.p1, v2_mul(v2_sub(s.b.p1, s.a.p1), ratio));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.solved = true;
|
res.solved = true;
|
||||||
abort:
|
abort:
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Remove this */
|
||||||
|
if (!colliding) num_pairs = 0;
|
||||||
|
|
||||||
if (proto_count > 0) {
|
if (proto_count > 0) {
|
||||||
for (u32 i = 0; i < min_u32(proto_count, ARRAY_COUNT(res.prototype.points)); ++i) {
|
for (u32 i = 0; i < min_u32(proto_count, ARRAY_COUNT(res.prototype.points)); ++i) {
|
||||||
res.prototype.points[i] = proto[i].p;
|
res.prototype.points[i] = proto[i].p;
|
||||||
@ -433,9 +439,9 @@ abort:
|
|||||||
}
|
}
|
||||||
res.prototype.len = s.len;
|
res.prototype.len = s.len;
|
||||||
}
|
}
|
||||||
res.colliding = colliding;
|
res.pairs[0] = pair0;
|
||||||
res.p0 = p0;
|
res.pairs[1] = pair1;
|
||||||
res.p1 = p1;
|
res.num_pairs = num_pairs;
|
||||||
res.simplex = s;
|
res.simplex = s;
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
10
src/gjk.h
10
src/gjk.h
@ -21,11 +21,15 @@ struct gjk_simplex {
|
|||||||
/* Returns simple true or false indicating shape collision */
|
/* Returns simple true or false indicating shape collision */
|
||||||
b32 gjk_boolean(struct v2_array shape0, struct v2_array shape1);
|
b32 gjk_boolean(struct v2_array shape0, struct v2_array shape1);
|
||||||
|
|
||||||
|
struct gjk_contact_pair {
|
||||||
|
struct v2 p0, p1;
|
||||||
|
};
|
||||||
|
|
||||||
struct gjk_prototype { struct v2 points[64]; u32 len; };
|
struct gjk_prototype { struct v2 points[64]; u32 len; };
|
||||||
struct gjk_contact_points_result {
|
struct gjk_contact_points_result {
|
||||||
b32 colliding;
|
|
||||||
struct v2 p0;
|
struct gjk_contact_pair pairs[2];
|
||||||
struct v2 p1;
|
u32 num_pairs;
|
||||||
|
|
||||||
/* For debugging */
|
/* For debugging */
|
||||||
b32 solved;
|
b32 solved;
|
||||||
|
|||||||
@ -667,6 +667,7 @@ INLINE struct v2 v2_norm(struct v2 a)
|
|||||||
{
|
{
|
||||||
f32 l = a.x * a.x + a.y * a.y;
|
f32 l = a.x * a.x + a.y * a.y;
|
||||||
if (l != 0) {
|
if (l != 0) {
|
||||||
|
/* TODO: Benchmark with math_rqsrt(l) */
|
||||||
f32 denom = 1.f / math_sqrt(l);
|
f32 denom = 1.f / math_sqrt(l);
|
||||||
a.x *= denom;
|
a.x *= denom;
|
||||||
a.y *= denom;
|
a.y *= denom;
|
||||||
|
|||||||
14
src/user.c
14
src/user.c
@ -888,6 +888,7 @@ INTERNAL void user_update(void)
|
|||||||
/* Debug draw info */
|
/* Debug draw info */
|
||||||
if (G.debug_draw && !skip_debug_draw) {
|
if (G.debug_draw && !skip_debug_draw) {
|
||||||
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
struct temp_arena temp = arena_temp_begin(scratch.arena);
|
||||||
|
b32 colliding = ent->num_points > 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
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);
|
||||||
@ -953,7 +954,7 @@ INTERNAL void user_update(void)
|
|||||||
u32 point_color = RGBA_32_F(1, 0, 0, 1);
|
u32 point_color = RGBA_32_F(1, 0, 0, 1);
|
||||||
u32 ray_color = RGBA_32_F(1, 0, 0.5, 1);
|
u32 ray_color = RGBA_32_F(1, 0, 0.5, 1);
|
||||||
|
|
||||||
if (ent->colliding) {
|
if (colliding) {
|
||||||
quad_color = RGBA_32_F(1, 1, 1, 1);
|
quad_color = RGBA_32_F(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,7 +989,6 @@ INTERNAL void user_update(void)
|
|||||||
|
|
||||||
/* Draw collision */
|
/* Draw collision */
|
||||||
if (ent->is_top) {
|
if (ent->is_top) {
|
||||||
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)e1;
|
(UNUSED)e1;
|
||||||
(UNUSED)colliding;
|
(UNUSED)colliding;
|
||||||
@ -1116,18 +1116,16 @@ INTERNAL void user_update(void)
|
|||||||
/* Draw points */
|
/* Draw points */
|
||||||
{
|
{
|
||||||
f32 radius = 5;
|
f32 radius = 5;
|
||||||
|
u32 color = entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.75) : RGBA_32_F(0, 1, 1, 0.75);
|
||||||
{
|
{
|
||||||
u32 color = entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 0, 0, 0.75) : RGBA_32_F(0, 1, 1, 0.75);
|
struct v2 point = xform_mul_v2(G.world_view, ent->point0);
|
||||||
struct v2 point = xform_mul_v2(G.world_view, ent->point);
|
|
||||||
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
||||||
}
|
}
|
||||||
#if 0
|
if (!v2_is_zero(ent->point1)) {
|
||||||
if (ent->has_2nd_point) {
|
//u32 color = entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 1, 0, 0.75) : RGBA_32_F(1, 0, 1, 0.75);
|
||||||
u32 color = entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED) ? RGBA_32_F(1, 1, 0, 0.75) : RGBA_32_F(1, 0, 1, 0.75);
|
|
||||||
struct v2 point = xform_mul_v2(G.world_view, ent->point1);
|
struct v2 point = xform_mul_v2(G.world_view, ent->point1);
|
||||||
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
draw_solid_circle(G.viewport_canvas, point, radius, color, 10);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user