feat(editor): biome vegetation auto-population system

One-click procedural object placement based on biome rules:

- 10 biome vegetation rulesets with density, scale range, and slope
  constraints per asset type (trees, bushes, rocks, ferns, etc.)
- Grassland: pine trees + bushes + rocks
- Forest: ashenvale trees + ferns + forest rocks (dense canopy)
- Jungle: palm trees + ferns + vines (high density)
- Desert: cacti + desert rocks + bones (sparse)
- Barrens: scattered trees + dry bushes + rocks
- Snow: snow pines + snowdrifts + rocks
- Swamp: dark trees + mushrooms + logs
- Rocky: rock formations + rock piles
- Beach: palm trees + beach rocks
- Volcanic: lava rocks + charred trees

Objects panel > Auto-Populate Biome: select biome, set seed, click
"Populate Zone" to fill the entire tile with biome-appropriate
vegetation at rule-defined densities.
This commit is contained in:
Kelsi 2026-05-05 16:42:41 -07:00
parent 0d401c3eb8
commit 110f250150
4 changed files with 143 additions and 0 deletions

View file

@ -1668,6 +1668,34 @@ void EditorUI::renderObjectPanel(EditorApp& app) {
}
}
if (ImGui::CollapsingHeader("Auto-Populate Biome")) {
static int popBiome = 0;
static uint32_t popSeed = 42;
const char* biomeNames[] = {"Grassland", "Forest", "Jungle", "Desert",
"Barrens", "Snow", "Swamp", "Rocky", "Beach", "Volcanic"};
ImGui::Combo("Biome##pop", &popBiome, biomeNames, 10);
int seed = static_cast<int>(popSeed);
if (ImGui::InputInt("Seed##pop", &seed)) popSeed = static_cast<uint32_t>(seed);
auto veg = getBiomeVegetation(static_cast<Biome>(popBiome));
ImGui::TextColored(ImVec4(0.6f,0.6f,0.6f,1), "%zu asset types, density-based",
veg.assets.size());
if (ImGui::Button("Populate Zone", ImVec2(-1, 0)) && app.hasTerrainLoaded()) {
auto* t = app.getTerrainEditor().getTerrain();
float tileSize = 533.33333f;
glm::vec3 origin(
(32.0f - t->coord.y) * tileSize,
(32.0f - t->coord.x) * tileSize, 0);
int n = placer.populateBiome(veg, tileSize, origin, popSeed);
app.markObjectsDirty();
app.showToast("Populated " + std::string(biomeNames[popBiome]) +
": " + std::to_string(n) + " objects");
}
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Auto-place trees, rocks, bushes based on biome rules");
}
ImGui::Separator();
// Bulk operations
if (ImGui::CollapsingHeader("Bulk Operations")) {