From 835762fb5c574ca9462af2f58eaa90345ed63988 Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 22 Feb 2025 10:34:06 -0600 Subject: [PATCH] entity debug info. keep old local handles when translating. --- src/user.c | 164 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 135 insertions(+), 29 deletions(-) diff --git a/src/user.c b/src/user.c index 190b258f..6f1f137b 100644 --- a/src/user.c +++ b/src/user.c @@ -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; }