feat(editor): one-click Generate Complete Zone pipeline

- File > Generate Complete Zone: runs the full procedural pipeline
  in one click: noise → smooth (3 passes) → recalc normals →
  height-based auto-paint (sand/grass/rock/snow) → slope-based
  cliff paint (rock on steep faces)
- Creates a fully textured, natural-looking zone from flat terrain
- Removed stale quickGenerate checkbox from New Terrain dialog
This commit is contained in:
Kelsi 2026-05-05 07:21:59 -07:00
parent 59c6dab2b3
commit e516c3c71f
3 changed files with 39 additions and 5 deletions

View file

@ -816,6 +816,41 @@ void EditorApp::flyToSelected() {
}
}
void EditorApp::generateCompleteZone() {
if (!terrain_.isLoaded()) return;
showToast("Generating zone...");
// Step 1: Apply noise
terrainEditor_.applyNoise(0.005f, 30.0f, 4, 42);
// Step 2: Smooth
terrainEditor_.smoothEntireTile(3);
// Step 3: Recalc normals for slope paint
std::vector<int> allChunks;
for (int i = 0; i < 256; i++) allChunks.push_back(i);
terrainEditor_.recalcNormals(allChunks);
// Step 4: Auto-paint by height
std::vector<TexturePainter::HeightBand> bands = {
{90.0f, "Tileset\\Tanaris\\TanarisSandBase01.blp"},
{110.0f, "Tileset\\Elwynn\\ElwynnGrassBase.blp"},
{140.0f, "Tileset\\Barrens\\BarrensRock01.blp"},
{99999.0f, "Tileset\\Expansion02\\Dragonblight\\DragonblightFreshSmoothSnowA.blp"}
};
texturePainter_.autoPaintByHeight(bands);
// Step 5: Slope paint (rock on cliffs)
texturePainter_.autoPaintBySlope(0.4f, "Tileset\\Desolace\\DesolaceRock01.blp");
// Refresh
auto mesh = terrainEditor_.regenerateMesh();
viewport_.clearTerrain();
viewport_.loadTerrain(mesh, terrain_.textures, loadedTileX_, loadedTileY_);
showToast("Zone generated!");
}
void EditorApp::clearAllObjects() {
vkDeviceWaitIdle(window_->getVkContext()->getDevice());
objectPlacer_.clearAll();

View file

@ -77,6 +77,7 @@ public:
void snapSelectedToGround();
void flyToSelected();
void clearAllObjects();
void generateCompleteZone();
void centerOnTerrain();
// Multi-tile support

View file

@ -141,9 +141,10 @@ void EditorUI::renderMenuBar(EditorApp& app) {
}
ImGui::EndMenu();
}
if (ImGui::MenuItem("Clear All Objects/NPCs", nullptr, false, app.hasTerrainLoaded())) {
if (ImGui::MenuItem("Generate Complete Zone", nullptr, false, app.hasTerrainLoaded()))
app.generateCompleteZone();
if (ImGui::MenuItem("Clear All Objects/NPCs", nullptr, false, app.hasTerrainLoaded()))
app.clearAllObjects();
}
ImGui::Separator();
if (ImGui::MenuItem("Quick Save", "Ctrl+S", false, app.hasTerrainLoaded()))
app.quickSave();
@ -345,9 +346,6 @@ void EditorUI::renderNewTerrainDialog(EditorApp& /*app*/) {
ImGui::TextColored(ImVec4(0.5f, 0.6f, 0.5f, 1.0f), " + %s", bt.detail);
ImGui::Spacing();
static bool quickGenerate = false;
ImGui::Checkbox("Quick Generate (noise + smooth + auto-paint)", &quickGenerate);
if (ImGui::Button("Create", ImVec2(120, 0))) { newRequested_ = true; showNewDialog_ = false; }
ImGui::SameLine();
if (ImGui::Button("Cancel", ImVec2(120, 0))) showNewDialog_ = false;