diff --git a/tools/editor/editor_ui.cpp b/tools/editor/editor_ui.cpp index 7b1428f9..f7a48a1d 100644 --- a/tools/editor/editor_ui.cpp +++ b/tools/editor/editor_ui.cpp @@ -1513,6 +1513,10 @@ void EditorUI::renderWaterPanel(EditorApp& app) { app.getTerrainEditor().removeWater(brush.getPosition(), s.radius); } } + if (ImGui::Button("Smooth Beaches", ImVec2(-1, 0))) { + app.getTerrainEditor().smoothBeaches(app.getWaterHeight(), 15.0f); + app.showToast("Beaches smoothed"); + } if (ImGui::Button("Remove ALL Water", ImVec2(-1, 0))) { for (int ci = 0; ci < 256; ci++) app.getTerrainEditor().getTerrain()->waterData[ci].layers.clear(); diff --git a/tools/editor/terrain_editor.cpp b/tools/editor/terrain_editor.cpp index 316c7f5d..f581bb25 100644 --- a/tools/editor/terrain_editor.cpp +++ b/tools/editor/terrain_editor.cpp @@ -962,6 +962,29 @@ void TerrainEditor::fillWater(float height, uint16_t liquidType) { dirty_ = true; } +void TerrainEditor::smoothBeaches(float waterHeight, float beachWidth) { + if (!terrain_) return; + for (int ci = 0; ci < 256; ci++) { + auto& chunk = terrain_->chunks[ci]; + if (!chunk.hasHeightMap()) continue; + bool modified = false; + for (int v = 0; v < 145; v++) { + float absH = chunk.position[2] + chunk.heightMap.heights[v]; + float distToWater = std::abs(absH - waterHeight); + if (distToWater < beachWidth) { + // Smooth toward water level with gentle slope + float t = distToWater / beachWidth; + float target = waterHeight + (absH > waterHeight ? 1.0f : -1.0f) * beachWidth * t * t; + float relTarget = target - chunk.position[2]; + chunk.heightMap.heights[v] = chunk.heightMap.heights[v] * 0.3f + relTarget * 0.7f; + modified = true; + } + } + if (modified) { stitchEdges(ci); dirtyChunks_.push_back(ci); } + } + dirty_ = true; +} + void TerrainEditor::thermalErosion(int iterations, float talusAngle) { if (!terrain_) return; float unitSize = CHUNK_SIZE / 8.0f; diff --git a/tools/editor/terrain_editor.hpp b/tools/editor/terrain_editor.hpp index 50e5cfcf..1b81ad73 100644 --- a/tools/editor/terrain_editor.hpp +++ b/tools/editor/terrain_editor.hpp @@ -117,6 +117,9 @@ public: // Fill entire tile with water at a height void fillWater(float height, uint16_t liquidType); + // Smooth terrain near water level to create natural beaches + void smoothBeaches(float waterHeight, float beachWidth); + // Import/export heightmap (raw 16-bit grayscale, 129x129) bool importHeightmap(const std::string& path, float heightScale); bool exportHeightmap(const std::string& path, float heightScale);