From 9eae67d574d7171818f29fae389292ab17a53474 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 01:35:26 -0700 Subject: [PATCH] feat(editor): NPC scatter snaps each spawn to ground when enabled The scatter tool spawned creatures all at the cursor's z-height which made them hover when scattered over uneven terrain. Added a Snap to Ground checkbox (defaults to on) that raycasts each scattered NPC and places it on the actual surface. --- tools/editor/editor_ui.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index 7e5f679a..00f1f291 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -2015,12 +2015,26 @@ void EditorUI::renderNpcPanel(EditorApp& app) { if (ImGui::CollapsingHeader("Scatter Tool")) { static int scatterCount = 5; static float scatterRadius = 50.0f; + static bool scatterSnap = true; ImGui::SliderInt("Count", &scatterCount, 1, 30); ImGui::SliderFloat("Radius##scatter", &scatterRadius, 10.0f, 200.0f); + ImGui::Checkbox("Snap to Ground##scatter", &scatterSnap); auto& brush = app.getTerrainEditor().brush(); if (ImGui::Button("Scatter at Cursor", ImVec2(-1, 0))) { if (brush.isActive() && !tmpl.modelPath.empty()) { + size_t before = spawner.spawnCount(); spawner.scatter(tmpl, brush.getPosition(), scatterRadius, scatterCount); + if (scatterSnap) { + auto& tEd = app.getTerrainEditor(); + for (size_t i = before; i < spawner.spawnCount(); i++) { + auto& s = spawner.getSpawns()[i]; + rendering::Ray ray; + ray.origin = s.position + glm::vec3(0, 0, 500); + ray.direction = glm::vec3(0, 0, -1); + glm::vec3 hit; + if (tEd.raycastTerrain(ray, hit)) s.position.z = hit.z; + } + } app.markObjectsDirty(); } }