create separate entities for visualizing collision debug info
This commit is contained in:
parent
9981b600a8
commit
33df739cc6
@ -36,7 +36,7 @@
|
||||
#define GAME_PHYSICS_ENABLE_WARM_STARTING 1
|
||||
#define GAME_PHYSICS_ENABLE_RELAXATION 1
|
||||
|
||||
#define USER_DRAW_MENKOWSKI 0
|
||||
#define USER_DRAW_MENKOWSKI 1
|
||||
#define GAME_PHYSICS_ENABLE_COLLISION 1
|
||||
#define GAME_SPAWN_TESTENT 0
|
||||
#define GAME_PLAYER_AIM 1
|
||||
|
||||
15
src/entity.h
15
src/entity.h
@ -14,6 +14,7 @@ enum entity_prop {
|
||||
ENTITY_PROP_PHYSICAL_DYNAMIC,
|
||||
ENTITY_PROP_PHYSICAL_KINEMATIC,
|
||||
|
||||
ENTITY_PROP_COLLISION_DEBUG,
|
||||
ENTITY_PROP_CONTACT_CONSTRAINT,
|
||||
ENTITY_PROP_MOTOR_JOINT,
|
||||
ENTITY_PROP_MOUSE_JOINT,
|
||||
@ -102,11 +103,18 @@ struct contact_constraint {
|
||||
|
||||
struct math_spring_result softness;
|
||||
f32 pushout_velocity;
|
||||
};
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
struct collision_debug {
|
||||
struct entity_handle e0;
|
||||
struct entity_handle e1;
|
||||
struct collider_collision_points_result res;
|
||||
struct xform dbg_xf0;
|
||||
struct xform dbg_xf1;
|
||||
|
||||
struct contact_point points[2];
|
||||
u32 num_points;
|
||||
|
||||
struct xform xf0;
|
||||
struct xform xf1;
|
||||
};
|
||||
|
||||
|
||||
@ -226,6 +234,7 @@ struct entity {
|
||||
|
||||
/* TODO: Remove this (testing) */
|
||||
i32 colliding;
|
||||
struct collision_debug collision_debug_data;
|
||||
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
90
src/game.c
90
src/game.c
@ -30,6 +30,14 @@ struct contact_lookup {
|
||||
struct contact_lookup_entry *first_free_entry;
|
||||
};
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
/* TODO: Remove this (debugging) */
|
||||
struct collision_debug_lookup {
|
||||
struct arena arena;
|
||||
struct fixed_dict dict;
|
||||
};
|
||||
#endif
|
||||
|
||||
GLOBAL struct {
|
||||
struct atomic_i32 game_thread_shutdown;
|
||||
struct sys_thread game_thread;
|
||||
@ -57,6 +65,9 @@ GLOBAL struct {
|
||||
|
||||
/* Bookkeeping structures */
|
||||
struct contact_lookup contact_lookup;
|
||||
#if COLLIDER_DEBUG
|
||||
struct collision_debug_lookup collision_debug_lookup;
|
||||
#endif
|
||||
|
||||
/* Ticks */
|
||||
struct sys_mutex prev_tick_mutex;
|
||||
@ -280,10 +291,17 @@ INTERNAL void reset_world(void)
|
||||
/* Release world */
|
||||
world_release(&G.tick);
|
||||
/* Release bookkeeping */
|
||||
arena_release(&G.collision_debug_lookup.arena);
|
||||
contact_lookup_release(&G.contact_lookup);
|
||||
}
|
||||
|
||||
/* Create bookkeeping */
|
||||
contact_lookup_alloc(&G.contact_lookup);
|
||||
#if COLLIDER_DEBUG
|
||||
G.collision_debug_lookup.arena = arena_alloc(GIGABYTE(64));
|
||||
G.collision_debug_lookup.dict = fixed_dict_init(&G.collision_debug_lookup.arena, 4096);
|
||||
#endif
|
||||
|
||||
/* Re-create world */
|
||||
world_alloc(&G.tick);
|
||||
G.tick.continuity_gen = atomic_u64_eval(&G.prev_tick_continuity_gen) + 1;
|
||||
@ -491,6 +509,7 @@ INTERNAL void create_contacts(void)
|
||||
CT_ASSERT(ARRAY_COUNT(constraint_ent->contact_constraint_data.points) == 2);
|
||||
CT_ASSERT(ARRAY_COUNT(collider_res.points) == 2);
|
||||
|
||||
struct contact_constraint *constraint = NULL;
|
||||
if (collider_res.num_points > 0) {
|
||||
if (!entity_is_valid_and_active(constraint_ent)) {
|
||||
/* Create hit event */
|
||||
@ -543,29 +562,8 @@ INTERNAL void create_contacts(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
struct contact_constraint *constraint = &constraint_ent->contact_constraint_data;
|
||||
constraint = &constraint_ent->contact_constraint_data;
|
||||
constraint->normal = collider_res.normal;
|
||||
|
||||
#if 0
|
||||
/* TODO: Remove this (debugging) */
|
||||
{
|
||||
constraint->res = collider_res;
|
||||
constraint->dbg_xf0 = e0_xf;
|
||||
constraint->dbg_xf1 = e1_xf;
|
||||
if (constraint->num_points == 0) {
|
||||
if (collider_res.num_points > 0) {
|
||||
++e0->colliding;
|
||||
++e1->colliding;
|
||||
}
|
||||
} else {
|
||||
if (collider_res.num_points == 0) {
|
||||
--e0->colliding;
|
||||
--e1->colliding;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
constraint->friction = math_sqrt(e0->friction * e1->friction);
|
||||
|
||||
/* Delete old contacts that are no longer present */
|
||||
@ -622,6 +620,54 @@ INTERNAL void create_contacts(void)
|
||||
} else if (constraint_ent->valid) {
|
||||
constraint_ent->contact_constraint_data.num_points = 0;
|
||||
}
|
||||
|
||||
/* TODO: Remove this (debugging) */
|
||||
#if COLLIDER_DEBUG
|
||||
{
|
||||
struct string fdkey = STRING_FROM_BUFFER(BUFFER_FROM_STRUCT(&lookup_hash));
|
||||
struct entity_handle *dbg_ent_handle = fixed_dict_get(&G.collision_debug_lookup.dict, fdkey);
|
||||
if (!dbg_ent_handle) {
|
||||
dbg_ent_handle = arena_push_zero(&G.collision_debug_lookup.arena, struct entity_handle);
|
||||
}
|
||||
|
||||
struct entity *dbg_ent = entity_from_handle(store, *dbg_ent_handle);
|
||||
|
||||
if (!dbg_ent->valid) {
|
||||
/* FIXME: Entity never released */
|
||||
dbg_ent = entity_alloc(root);
|
||||
entity_enable_prop(dbg_ent, ENTITY_PROP_COLLISION_DEBUG);
|
||||
*dbg_ent_handle = dbg_ent->handle;
|
||||
fixed_dict_set(&G.collision_debug_lookup.arena, &G.collision_debug_lookup.dict, fdkey, dbg_ent_handle);
|
||||
}
|
||||
|
||||
struct collision_debug *dbg = &dbg_ent->collision_debug_data;
|
||||
|
||||
if (dbg->res.num_points == 0) {
|
||||
if (collider_res.num_points > 0) {
|
||||
++e0->colliding;
|
||||
++e1->colliding;
|
||||
}
|
||||
} else {
|
||||
if (collider_res.num_points == 0) {
|
||||
--e0->colliding;
|
||||
--e1->colliding;
|
||||
}
|
||||
}
|
||||
dbg->e0 = e0->handle;
|
||||
dbg->e1 = e1->handle;
|
||||
dbg->res = collider_res;
|
||||
|
||||
if (constraint) {
|
||||
MEMCPY(dbg->points, constraint->points, sizeof(dbg->points));
|
||||
dbg->num_points = constraint->num_points;
|
||||
} else {
|
||||
dbg->num_points = 0;
|
||||
}
|
||||
|
||||
dbg->xf0 = e0_xf;
|
||||
dbg->xf1 = e1_xf;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
50
src/user.c
50
src/user.c
@ -1069,10 +1069,14 @@ INTERNAL void user_update(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Draw collision */
|
||||
/* Draw constraint */
|
||||
#if 1
|
||||
if (entity_has_prop(ent, ENTITY_PROP_CONTACT_CONSTRAINT)) {
|
||||
struct contact_constraint *data = &ent->contact_constraint_data;
|
||||
if (entity_has_prop(ent, ENTITY_PROP_COLLISION_DEBUG)) {
|
||||
struct collision_debug *data = &ent->collision_debug_data;
|
||||
struct collider_collision_points_result collider_res = data->res;
|
||||
|
||||
//struct contact_constraint *data = &entity_from_handle(store, data->contact_constraint_ent)->contact_constraint_data;
|
||||
//struct contact_constraint *data = &data->contact_constraint_data;
|
||||
struct entity *e0 = entity_from_handle(store, data->e0);
|
||||
struct entity *e1 = entity_from_handle(store, data->e1);
|
||||
struct collider_shape e0_collider = e0->local_collider;
|
||||
@ -1080,18 +1084,15 @@ INTERNAL void user_update(void)
|
||||
(UNUSED)e0_collider;
|
||||
(UNUSED)e1_collider;
|
||||
|
||||
//struct xform e0_xf = entity_get_xform(e0);
|
||||
//struct xform e1_xf = entity_get_xform(e1);
|
||||
struct xform e0_xf = data->dbg_xf0;
|
||||
struct xform e1_xf = data->dbg_xf1;
|
||||
(UNUSED)e0_xf;
|
||||
(UNUSED)e1_xf;
|
||||
|
||||
#if USER_DRAW_MENKOWSKI
|
||||
struct xform e0_xf = data->xf0;
|
||||
struct xform e1_xf = data->xf1;
|
||||
|
||||
#if 0
|
||||
/* Only draw points with large separation */
|
||||
b32 should_draw = false;
|
||||
for (u32 i = 0; i < ent->num_contacts; ++i) {
|
||||
if (ent->contacts[i].starting_separation < -0.1) {
|
||||
for (u32 i = 0; i < data->num_points; ++i) {
|
||||
if (data->points[i].starting_separation < -0.1) {
|
||||
should_draw = true;
|
||||
break;
|
||||
}
|
||||
@ -1128,13 +1129,12 @@ INTERNAL void user_update(void)
|
||||
/* Draw menkowski */
|
||||
{
|
||||
|
||||
u32 color = data->res.solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1);
|
||||
u32 color = collider_res.solved ? RGBA_32_F(0, 0, 0.25, 1) : RGBA_32_F(0, 0.25, 0.25, 1);
|
||||
f32 thickness = 2;
|
||||
u32 detail = 512;
|
||||
(UNUSED)thickness;
|
||||
|
||||
struct v2_array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
|
||||
//struct v2_array m = menkowski(temp.arena, e0_collider, e1_collider, v2_sub(ent->xf1.og, ent->xf0.og));
|
||||
|
||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_view, m.points[i]);
|
||||
draw_solid_poly_line(G.viewport_canvas, m, true, thickness, color);
|
||||
@ -1161,7 +1161,7 @@ INTERNAL void user_update(void)
|
||||
f32 arrow_thickness = 2;
|
||||
f32 arrow_height = 5;
|
||||
struct v2 start = xform_mul_v2(G.world_view, V2(0, 0));
|
||||
struct v2 end = xform_mul_v2(G.world_view, v2_mul(v2_norm(data->normal), len));
|
||||
struct v2 end = xform_mul_v2(G.world_view, v2_mul(v2_norm(collider_res.normal), len));
|
||||
draw_solid_arrow_line(G.viewport_canvas, start, end, arrow_thickness, arrow_height, color);
|
||||
}
|
||||
|
||||
@ -1171,8 +1171,8 @@ INTERNAL void user_update(void)
|
||||
u32 color = RGBA_32_F(1, 1, 1, 0.25);
|
||||
|
||||
struct v2_array m = {
|
||||
.points = data->res.prototype.points,
|
||||
.count = data->res.prototype.len
|
||||
.points = collider_res.prototype.points,
|
||||
.count = collider_res.prototype.len
|
||||
};
|
||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_view, m.points[i]);
|
||||
draw_solid_poly_line(G.viewport_canvas, m, true, thickness, color);
|
||||
@ -1187,7 +1187,7 @@ INTERNAL void user_update(void)
|
||||
u32 color_second = RGBA_32_F(0, 1, 0, 0.75);
|
||||
u32 color_third = RGBA_32_F(0, 0, 1, 0.75);
|
||||
|
||||
struct collider_simplex simplex = data->res.simplex;
|
||||
struct collider_simplex simplex = collider_res.simplex;
|
||||
struct v2 simplex_points[] = { simplex.a, simplex.b, simplex.c };
|
||||
for (u64 i = 0; i < ARRAY_COUNT(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_view, simplex_points[i]);
|
||||
struct v2_array simplex_array = { .count = simplex.len, .points = simplex_points };
|
||||
@ -1212,11 +1212,11 @@ INTERNAL void user_update(void)
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/* Draw contacts */
|
||||
/* Draw contact points */
|
||||
{
|
||||
f32 radius = 5;
|
||||
for (u32 i = 0; i < ent->contact_constraint_data.num_points; ++i) {
|
||||
struct contact_point point = ent->contact_constraint_data.points[i];
|
||||
for (u32 i = 0; i < data->num_points; ++i) {
|
||||
struct contact_point point = data->points[i];
|
||||
#if 0
|
||||
struct v2 p0 = xform_mul_v2(e0_xf, contact.point_local_e0);
|
||||
struct v2 p1 = xform_mul_v2(e1_xf, contact.point_local_e1);
|
||||
@ -1239,7 +1239,7 @@ INTERNAL void user_update(void)
|
||||
f32 arrow_thickness = 2;
|
||||
f32 arrow_height = 5;
|
||||
struct v2 start = xform_mul_v2(G.world_view, dbg_pt);
|
||||
struct v2 end = xform_mul_v2(G.world_view, v2_add(dbg_pt, v2_mul(v2_norm(ent->contact_constraint_data.normal), len)));
|
||||
struct v2 end = xform_mul_v2(G.world_view, v2_add(dbg_pt, v2_mul(v2_norm(collider_res.normal), len)));
|
||||
draw_solid_arrow_line(G.viewport_canvas, start, end, arrow_thickness, arrow_height, color);
|
||||
}
|
||||
#if 0
|
||||
@ -1262,7 +1262,7 @@ INTERNAL void user_update(void)
|
||||
"num contacts: %F"
|
||||
);
|
||||
struct string text = string_format(temp.arena, fmt,
|
||||
FMT_SINT(data->res.path),
|
||||
FMT_SINT(collider_res.path),
|
||||
FMT_UINT(e0->handle.idx),
|
||||
FMT_UINT(e1->handle.idx),
|
||||
FMT_HEX(point.id),
|
||||
@ -1292,7 +1292,6 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* Draw clipping */
|
||||
{
|
||||
f32 thickness = 2;
|
||||
@ -1300,7 +1299,7 @@ INTERNAL void user_update(void)
|
||||
u32 color_line = RGBA_32_F(1, 0, 1, 0.5);
|
||||
u32 color_a = RGBA_32_F(1, 0, 0, 0.5);
|
||||
u32 color_b = RGBA_32_F(0, 1, 0, 0.5);
|
||||
struct collider_collision_points_result res = ent->contact_constraint_data.res;
|
||||
struct collider_collision_points_result res = collider_res;
|
||||
{
|
||||
struct v2 a = xform_mul_v2(G.world_view, res.a0);
|
||||
struct v2 b = xform_mul_v2(G.world_view, res.b0);
|
||||
@ -1316,7 +1315,6 @@ INTERNAL void user_update(void)
|
||||
draw_solid_circle(G.viewport_canvas, b, radius, color_b, 10);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user