fix(editor): random-populate ground-snaps spawns to actual terrain

Previously every random-populated creature and object dropped at
baseZ (the manifest's flat height), which sat below the carved
terrain on hills and floated above it in valleys. After
generateCompleteZone the terrain is far from flat, so the spawns
showed up clipping or floating.

Added an inline groundZ(x, y) helper that casts a downward ray
from baseZ+500y at the spawn's (x, y) and uses the hit position's
Z. Falls back to baseZ if the ray misses terrain (shouldn't happen
inside the loaded tile bbox but is safer than NaN).

Both creature and object loops now consult groundZ. Snap-to-ground
is the runtime placer's default behavior anyway, so this lines up
with the rest of the editor's expectations.
This commit is contained in:
Kelsi 2026-05-07 12:15:45 -07:00
parent 89dacba666
commit 8c20f732ce

View file

@ -1738,6 +1738,18 @@ void EditorApp::randomPopulateZone(int creatureCount, int objectCount,
"World/Generic/Stump.wmo",
"World/Generic/Mushroom.wmo",
};
// Ground-snap helper: cast a downward ray from far above the (x,y)
// position to find the actual terrain height. Without this, spawns
// sit at baseZ which can be metres below or above the carved
// terrain after generation.
auto groundZ = [&](float x, float y) -> float {
rendering::Ray ray;
ray.origin = glm::vec3(x, y, baseZ + 500.0f);
ray.direction = glm::vec3(0, 0, -1);
glm::vec3 hit;
if (terrainEditor_.raycastTerrain(ray, hit)) return hit.z;
return baseZ; // fall back to base if the ray misses
};
int placedCreatures = 0, placedObjects = 0;
for (int n = 0; n < creatureCount; ++n) {
const auto& [name, baseLvl] = kRandomCreatures[
@ -1746,7 +1758,7 @@ void EditorApp::randomPopulateZone(int creatureCount, int objectCount,
s.name = name;
s.position.x = rangeF(wMinX, wMaxX);
s.position.y = rangeF(wMinY, wMaxY);
s.position.z = baseZ;
s.position.z = groundZ(s.position.x, s.position.y);
int lvl = std::max(1, static_cast<int>(baseLvl) + rangeI(-1, 2));
s.level = static_cast<uint32_t>(lvl);
s.health = 50 + s.level * 10;
@ -1764,7 +1776,7 @@ void EditorApp::randomPopulateZone(int creatureCount, int objectCount,
o.type = PlaceableType::WMO;
o.position.x = rangeF(wMinX, wMaxX);
o.position.y = rangeF(wMinY, wMaxY);
o.position.z = baseZ;
o.position.z = groundZ(o.position.x, o.position.y);
o.rotation = glm::vec3(0.0f, rangeF(0.0f, 6.28f), 0.0f);
o.scale = rangeF(0.8f, 1.4f);
o.uniqueId = ++maxUid;