mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-08 01:53:52 +00:00
fix(editor): NPC nameplates align with NPC + togglable to selected only
Three issues fixed in one pass: 1. Z-offset was 35 yards — nameplates floated way above the actual NPC position. Dropped to 3.5 yards (just above an average creature's head) so the label reads as attached. 2. Horizontal alignment was a fixed -30 px offset, which only looked centered for ~6-character names. Switched to ImGui::CalcTextSize and centering on the projected position. 3. Nameplates were always-on, which got noisy fast on populated zones. Added "Nameplate on selected only" checkbox in the NPC panel (default ON); when unchecked, all NPCs show their names. Vertical position also slightly tightened (sy - textSz.y - 2 vs sy - 10) so the text baseline aligns rather than floating below.
This commit is contained in:
parent
0e2b55f9fd
commit
3a6f119f7a
2 changed files with 32 additions and 3 deletions
|
|
@ -83,17 +83,34 @@ void EditorUI::render(EditorApp& app) {
|
|||
auto& cam = app.getEditorCamera().getCamera();
|
||||
auto vp2 = ImGui::GetMainViewport();
|
||||
glm::mat4 viewProj = cam.getProjectionMatrix() * cam.getViewMatrix();
|
||||
for (const auto& npc : app.getNpcSpawner().getSpawns()) {
|
||||
bool selectedOnly = app.getViewport().getNpcNameplatesSelectedOnly();
|
||||
int selIdx = app.getNpcSpawner().getSelectedIndex();
|
||||
const auto& spawns = app.getNpcSpawner().getSpawns();
|
||||
for (size_t i = 0; i < spawns.size(); ++i) {
|
||||
const auto& npc = spawns[i];
|
||||
// Toggle: when selectedOnly is on, skip every NPC except the
|
||||
// selected one. Was previously always-on, which got noisy on
|
||||
// populated zones.
|
||||
if (selectedOnly && static_cast<int>(i) != selIdx) continue;
|
||||
// Z offset: was 35 yards (way too high; nameplates floated in
|
||||
// the sky). Drop to ~3.5 yards which sits just above an
|
||||
// average creature's head and reads as attached.
|
||||
glm::vec4 clip = viewProj * glm::vec4(npc.position.x, npc.position.y,
|
||||
npc.position.z + 35.0f, 1.0f);
|
||||
npc.position.z + 3.5f, 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;
|
||||
|
||||
// Center the text on the projected position by measuring the
|
||||
// actual string width — the previous fixed -30 X offset
|
||||
// misaligned every name that wasn't ~6 chars long.
|
||||
ImVec2 textSz = ImGui::CalcTextSize(npc.name.c_str());
|
||||
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),
|
||||
ImGui::GetForegroundDrawList()->AddText(
|
||||
ImVec2(sx - textSz.x * 0.5f, sy - textSz.y - 2),
|
||||
ImGui::ColorConvertFloat4ToU32(col),
|
||||
npc.name.c_str());
|
||||
}
|
||||
}
|
||||
|
|
@ -1818,6 +1835,9 @@ void EditorUI::renderNpcPanel(EditorApp& app) {
|
|||
bool showMarkers = app.getViewport().getShowNpcMarkers();
|
||||
if (ImGui::Checkbox("Show Position Markers", &showMarkers))
|
||||
app.getViewport().setShowNpcMarkers(showMarkers);
|
||||
bool selOnly = app.getViewport().getNpcNameplatesSelectedOnly();
|
||||
if (ImGui::Checkbox("Nameplate on selected only", &selOnly))
|
||||
app.getViewport().setNpcNameplatesSelectedOnly(selOnly);
|
||||
ImGui::Separator();
|
||||
|
||||
// ---- Creature Browser ----
|
||||
|
|
|
|||
|
|
@ -62,6 +62,14 @@ public:
|
|||
void setWireframe(bool enabled);
|
||||
void setShowNpcMarkers(bool show) { showNpcMarkers_ = show; }
|
||||
bool getShowNpcMarkers() const { return showNpcMarkers_; }
|
||||
|
||||
// Nameplates: when true, only show the floating name label on the
|
||||
// currently-selected NPC; otherwise show on all of them. Default true
|
||||
// to keep the viewport quiet — was previously always-on, which got
|
||||
// noisy fast on populated zones.
|
||||
void setNpcNameplatesSelectedOnly(bool sel) { npcNameplatesSelectedOnly_ = sel; }
|
||||
bool getNpcNameplatesSelectedOnly() const { return npcNameplatesSelectedOnly_; }
|
||||
|
||||
bool isWireframe() const { return wireframe_; }
|
||||
|
||||
void setClearColor(float r, float g, float b) { clearR_=r; clearG_=g; clearB_=b; }
|
||||
|
|
@ -143,6 +151,7 @@ private:
|
|||
|
||||
// NPC position markers
|
||||
bool showNpcMarkers_ = true;
|
||||
bool npcNameplatesSelectedOnly_ = true;
|
||||
VkBuffer npcMarkerVB_ = VK_NULL_HANDLE;
|
||||
VmaAllocation npcMarkerVBAlloc_ = VK_NULL_HANDLE;
|
||||
uint32_t npcMarkerVertCount_ = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue