From 2ed521a8f7e918f609363ec374ddc2b36621c5d1 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 5 May 2026 07:15:12 -0700 Subject: [PATCH] feat(editor): NPC name labels floating above markers in viewport - Creature names rendered as screen-space text above each NPC marker - Red text for hostile, green for friendly - Labels project from 3D world position to screen coordinates - Only visible when NPC is in front of camera (clip.w > 0) - Much easier to identify placed creatures at a glance --- tools/editor/editor_ui.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index 97695184..de0722b4 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -51,6 +51,26 @@ void EditorUI::render(EditorApp& app) { renderPropertiesPanel(app); renderStatusBar(app); + // NPC name labels in viewport (screen-space text above markers) + if (app.hasTerrainLoaded() && app.getNpcSpawner().spawnCount() > 0) { + auto& cam = app.getEditorCamera().getCamera(); + auto vp2 = ImGui::GetMainViewport(); + glm::mat4 viewProj = cam.getProjectionMatrix() * cam.getViewMatrix(); + for (const auto& npc : app.getNpcSpawner().getSpawns()) { + glm::vec4 clip = viewProj * glm::vec4(npc.position.x, npc.position.y, + npc.position.z + 35.0f, 1.0f); + if (clip.w <= 0.01f) continue; + glm::vec3 ndc = glm::vec3(clip) / clip.w; + float sx = (ndc.x * 0.5f + 0.5f) * vp2->Size.x; + float sy = (ndc.y * 0.5f + 0.5f) * vp2->Size.y; + if (sx < 0 || sx > vp2->Size.x || sy < 0 || sy > vp2->Size.y) continue; + + ImVec4 col = npc.hostile ? ImVec4(1, 0.3f, 0.3f, 0.9f) : ImVec4(0.3f, 1, 0.3f, 0.9f); + ImGui::GetForegroundDrawList()->AddText(ImVec2(sx - 30, sy - 10), ImGui::ColorConvertFloat4ToU32(col), + npc.name.c_str()); + } + } + // Toast notifications ImGuiViewport* tvp = ImGui::GetMainViewport(); float toastY = tvp->Size.y - 60;