entity debug info. keep old local handles when translating.

This commit is contained in:
jacob 2025-02-22 10:34:06 -06:00
parent d05ecbabb9
commit 835762fb5c

View File

@ -332,6 +332,57 @@ INTERNAL void debug_draw_movement(struct sim_ent *ent)
}
}
INTERNAL struct string get_ent_debug_text(struct arena *arena, struct sim_ent *ent)
{
struct temp_arena scratch = scratch_begin(arena);
struct sim_snapshot *ss = ent->ss;
struct string res = ZI;
res.text = arena_dry_push(arena, u8);
{
const u8 hex[] = "0123456789abcdef";
res.len += string_copy(arena, LIT("props: 0x")).len;
for (u64 chunk_index = ARRAY_COUNT(ent->props); chunk_index-- > 0;) {
u64 chunk = ent->props[chunk_index];
for (u64 part_index = 8; part_index-- > 0;) {
if ((chunk_index != (ARRAY_COUNT(ent->props) - 1)) || ((chunk_index * 64) + (part_index * 8)) <= SIM_ENT_PROP_COUNT) {
u8 part = (chunk >> (part_index * 8)) & 0xFF;
string_from_char(arena, hex[(part >> 4) & 0x0F]);
string_from_char(arena, hex[(part >> 0) & 0x0F]);
res.len += 2;
}
}
}
res.len += string_copy(arena, LIT("\n")).len;
}
if (!sim_ent_handle_eq(ent->parent, SIM_ENT_ROOT_HANDLE)) {
res.len += string_format(arena, LIT("parent: <%F:%F>\n"), FMT_UINT(ent->parent.idx), FMT_UINT(ent->parent.gen)).len;
}
if (!sim_ent_handle_eq(ent->next, SIM_ENT_NIL_HANDLE) || !sim_ent_handle_eq(ent->prev, SIM_ENT_NIL_HANDLE)) {
res.len += string_format(arena, LIT("prev: <%F:%F>\n"), FMT_UINT(ent->prev.idx), FMT_UINT(ent->prev.gen)).len;
res.len += string_format(arena, LIT("next: <%F:%F>\n"), FMT_UINT(ent->next.idx), FMT_UINT(ent->next.gen)).len;
}
if (!sim_ent_handle_eq(ent->first, SIM_ENT_NIL_HANDLE) || !sim_ent_handle_eq(ent->last, SIM_ENT_NIL_HANDLE)) {
res.len += string_format(arena, LIT("first child: <%F:%F>\n"), FMT_UINT(ent->first.idx), FMT_UINT(ent->first.gen)).len;
res.len += string_format(arena, LIT("last child: <%F:%F>\n"), FMT_UINT(ent->last.idx), FMT_UINT(ent->last.gen)).len;
struct sim_ent *child = sim_ent_from_handle(ss, ent->first);
while (child->valid) {
res.len += string_format(arena, LIT("\nCHILD <%F:%F>\n"), FMT_UINT(child->handle.idx), FMT_UINT(child->handle.gen)).len;
struct string child_text = get_ent_debug_text(scratch.arena, child);
res.len += string_indent(arena, child_text, 4).len;
child = sim_ent_from_handle(ss, child->next);
}
}
scratch_end(scratch);
return res;
}
/* ========================== *
* Sort entities
* ========================== */
@ -633,6 +684,35 @@ INTERNAL void user_update(void)
struct sim_ent *local_player = sim_ent_from_handle(G.ss_blended, local_client_ent->client_control_ent);
struct sim_ent *local_camera = sim_ent_from_handle(G.ss_blended, local_client_ent->client_camera_ent);
/* ========================== *
* Find hovered entity
* ========================== */
struct sim_ent *hovered_ent = sim_ent_nil();
{
struct xform mouse_xf = xform_from_pos(G.world_cursor);
struct collider_shape mouse_shape = ZI;
mouse_shape.points[0] = V2(0, 0);
mouse_shape.count = 1;
mouse_shape.radius = 0.01;
for (u64 ent_index = 0; ent_index < G.ss_blended->num_ents_reserved; ++ent_index) {
struct sim_ent *ent = &G.ss_blended->ents[ent_index];
if (!sim_ent_is_valid_and_active(ent)) continue;
if (!ent->is_top) continue;
struct collider_shape ent_collider = ent->local_collider;
if (ent_collider.count > 0) {
/* TODO: Can just use boolean GJK */
struct xform ent_xf = sim_ent_get_xform(ent);
struct collider_collision_points_result res = collider_collision_points(&ent_collider, &mouse_shape, ent_xf, mouse_xf);
if (res.num_points > 0) {
hovered_ent = ent;
break;
}
}
}
}
/* ========================== *
* Apply shake
* ========================== */
@ -1462,12 +1542,36 @@ INTERNAL void user_update(void)
}
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ========================== *
* Draw ent debug info
* ========================== */
if (G.debug_draw && hovered_ent->valid) {
struct sim_ent *ent = hovered_ent;
struct v2 pos = v2_add(G.ui_cursor, V2(15, 15));
struct font *font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f);
if (font) {
struct temp_arena temp = arena_temp_begin(scratch.arena);
struct string dbg_text = ZI;
dbg_text.text = arena_dry_push(temp.arena, u8);
dbg_text.len += string_format(temp.arena, LIT("ENT <%F:%F>\n"), FMT_UINT(ent->handle.idx), FMT_UINT(ent->handle.gen)).len;
dbg_text.len += get_ent_debug_text(temp.arena, ent).len;
draw_text(G.ui_cmd_buffer, font, pos, dbg_text);
arena_temp_end(temp);
}
}
/* ========================== *
* Draw global debug info
* ========================== */
/* Debug draw info */
if (G.debug_draw) {
f32 spacing = 20;
struct v2 pos = V2(10, 8);
struct font *font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f);
@ -1719,16 +1823,20 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_thread_entry_point, arg)
/* TODO: Move this */
#define translate(fieldname) local->fieldname = _translate(remote_lookup, old.fieldname, remote_client_handle, remote->fieldname)
INTERNAL struct sim_ent_handle _translate(struct sim_lookup *remote_lookup, struct sim_ent_handle old_local_handle, struct sim_client_handle remote_client_handle, struct sim_ent_handle remote_ent_handle)
#define translate(fieldname) local->fieldname = _translate(remote_lookup, remote_client_handle, old.fieldname, remote->fieldname)
INTERNAL struct sim_ent_handle _translate(struct sim_lookup *remote_lookup, struct sim_client_handle remote_client_handle, struct sim_ent_handle old_local_handle, struct sim_ent_handle remote_ent_handle)
{
struct sim_lookup_key key = sim_lookup_key_from_client_and_ent_handles(remote_client_handle, remote_ent_handle);
struct sim_lookup_entry *entry = sim_lookup_get(remote_lookup, key);
return entry ? entry->ent : old_local_handle;
if (!sim_ent_handle_eq(remote_ent_handle, SIM_ENT_ROOT_HANDLE)) {
struct sim_lookup_key key = sim_lookup_key_from_client_and_ent_handles(remote_client_handle, remote_ent_handle);
struct sim_lookup_entry *entry = sim_lookup_get(remote_lookup, key);
return entry ? entry->ent : old_local_handle;
} else {
return SIM_ENT_ROOT_HANDLE;
}
}
INTERNAL void sim_ent_sync_with_remote(struct sim_accel *accel, struct sim_ent *local, struct sim_ent *remote, struct sim_ent *client_ent)
INTERNAL void sim_ent_sync_remote(struct sim_accel *accel, struct sim_ent *local, struct sim_ent *remote, struct sim_ent *client_ent)
{
struct sim_client_handle remote_client_handle = remote->ss->client->handle;
struct sim_lookup *remote_lookup = &accel->remote_lookup;
@ -1736,24 +1844,22 @@ INTERNAL void sim_ent_sync_with_remote(struct sim_accel *accel, struct sim_ent *
struct sim_ent old = *local;
MEMCPY_STRUCT(local, remote);
sim_ent_enable_prop(local, SIM_ENT_PROP_REMOTE);
/* Keep non-remote handles */
local->ss = old.ss;
local->handle = old.handle;
local->remote_client = remote_client_handle;
local->remote_ent = remote->handle;
sim_ent_enable_prop(local, SIM_ENT_PROP_REMOTE);
//sim_ent_set_xform(local, sim_ent_get_xform(remote));
local->parent = old.parent;
local->prev = old.prev;
local->next = old.next;
local->first = old.first;
local->last = old.last;
local->top = old.top;
local->next_free = old.next_free;
/* Translate remote handles */
translate(parent);
if (!sim_ent_from_handle(local->ss, local->parent)->valid) {
local->parent = SIM_ENT_ROOT_HANDLE;
}
translate(top);
translate(next);
translate(prev);
translate(first);
translate(last);
translate(next_free);
translate(client_control_ent);
translate(client_camera_ent);
translate(client_dbg_drag_joint_ent);
@ -1772,7 +1878,7 @@ INTERNAL void sim_ent_sync_with_remote(struct sim_accel *accel, struct sim_ent *
}
INTERNAL void sim_ent_alloc_from_remote(struct sim_accel *accel, struct sim_ent *local_parent, struct sim_ent *remote)
INTERNAL void sim_ent_alloc_remote(struct sim_accel *accel, struct sim_ent *local_parent, struct sim_ent *remote)
{
struct sim_snapshot *local_ss = local_parent->ss;
struct sim_snapshot *remote_ss = remote->ss;
@ -1796,13 +1902,13 @@ INTERNAL void sim_ent_alloc_from_remote(struct sim_accel *accel, struct sim_ent
sim_lookup_set(remote_lookup, key, local_ent->handle);
}
for (struct sim_ent *remote_child = sim_ent_from_handle(remote_ss, remote->first); remote_child->valid; remote_child = sim_ent_from_handle(remote_ss, remote_child->next)) {
sim_ent_alloc_from_remote(accel, local_ent, remote_child);
sim_ent_alloc_remote(accel, local_ent, remote_child);
}
}
}
INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss)
INTERNAL void sim_snapshot_sync_remote_ents(struct sim_accel *accel, struct sim_snapshot *local_ss, struct sim_snapshot *remote_ss)
{
__prof;
@ -1832,7 +1938,7 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_
/* Create new ents from remote */
for (struct sim_ent *remote_top = sim_ent_from_handle(remote_ss, remote_root->first); remote_top->valid; remote_top = sim_ent_from_handle(remote_ss, remote_top->next)) {
sim_ent_alloc_from_remote(accel, local_root, remote_top);
sim_ent_alloc_remote(accel, local_root, remote_top);
}
/* Sync ents with remote */
@ -1842,7 +1948,7 @@ INTERNAL void sim_snapshot_sync_with_remote(struct sim_accel *accel, struct sim_
struct sim_ent *remote_ent = sim_ent_from_handle(remote_ss, local_ent->remote_ent);
if (remote_ent->valid) {
/* Copy all ent data from remote */
sim_ent_sync_with_remote(accel, local_ent, remote_ent, client_ent);
sim_ent_sync_remote(accel, local_ent, remote_ent, client_ent);
} else {
/* Remote ent is no longer valid / networked, release it */
sim_ent_enable_prop(local_ent, SIM_ENT_PROP_RELEASE);
@ -2019,7 +2125,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
/* Rebuild acceleration tables */
sim_accel_rebuild(local_ss, &accel);
/* Sync ents with local client */
/* Sync remote ents with client */
{
struct sim_ent *local_root = sim_ent_from_handle(local_ss, SIM_ENT_ROOT_HANDLE);
for (u64 client_index = 0; client_index < store->num_clients_reserved; ++client_index) {
@ -2048,7 +2154,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(user_local_sim_thread_entry_point, arg)
if (client != publish_client && client != local_client) {
struct sim_snapshot *client_ss = sim_snapshot_from_tick(client, step_tick);
if (client_ss->valid) {
sim_snapshot_sync_with_remote(&accel, local_ss, client_ss);
sim_snapshot_sync_remote_ents(&accel, local_ss, client_ss);
if (!is_master && client == master_client) {
local_ss->local_client = client_ss->local_client;
}