mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-05 16:43:52 +00:00
feat(editor): auto-paint terrain by height bands
- Auto-Paint by Height: automatically sets base texture per chunk based on average height — configurable thresholds for sand/grass/rock/snow - Uses Tanaris sand, Elwynn grass, Barrens rock, Dragonblight snow - One-click to texture an entire procedurally generated terrain - Adjustable height thresholds via drag floats - Workflow: noise → smooth → clamp → auto-paint for instant biome
This commit is contained in:
parent
1ba1a50112
commit
aa9a6a87a8
3 changed files with 59 additions and 0 deletions
|
|
@ -551,6 +551,32 @@ void EditorUI::renderTexturePaintPanel(EditorApp& app) {
|
|||
ImGui::TextColored(ImVec4(0.5f, 0.9f, 0.5f, 1.0f), "Active: %s",
|
||||
selectedTexture_.c_str());
|
||||
|
||||
// Auto-paint by height
|
||||
if (ImGui::CollapsingHeader("Auto-Paint by Height")) {
|
||||
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1),
|
||||
"Sets base texture per chunk based on average height");
|
||||
static float h1 = 90, h2 = 110, h3 = 140;
|
||||
ImGui::DragFloat("Sand/Dirt max##ap", &h1, 1.0f);
|
||||
ImGui::DragFloat("Grass max##ap", &h2, 1.0f);
|
||||
ImGui::DragFloat("Rock max##ap", &h3, 1.0f);
|
||||
ImGui::Text("Above %.0f: Snow", h3);
|
||||
if (ImGui::Button("Apply Auto-Paint", ImVec2(-1, 0))) {
|
||||
std::vector<TexturePainter::HeightBand> bands = {
|
||||
{h1, "Tileset\\Tanaris\\TanarisSandBase01.blp"},
|
||||
{h2, "Tileset\\Elwynn\\ElwynnGrassBase.blp"},
|
||||
{h3, "Tileset\\Barrens\\BarrensRock01.blp"},
|
||||
{99999.0f, "Tileset\\Expansion02\\Dragonblight\\DragonblightFreshSmoothSnowA.blp"}
|
||||
};
|
||||
app.getTexturePainter().autoPaintByHeight(bands);
|
||||
// Force terrain refresh
|
||||
auto mesh = app.getTerrainEditor().regenerateMesh();
|
||||
// Mark all chunks dirty through a dummy edit
|
||||
app.showToast("Auto-painted by height");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Show textures on chunk under cursor
|
||||
auto& brush = app.getTerrainEditor().brush();
|
||||
if (brush.isActive()) {
|
||||
|
|
|
|||
|
|
@ -165,6 +165,35 @@ std::vector<int> TexturePainter::paint(const glm::vec3& center, float radius,
|
|||
return modified;
|
||||
}
|
||||
|
||||
void TexturePainter::autoPaintByHeight(const std::vector<HeightBand>& bands) {
|
||||
if (!terrain_ || bands.empty()) return;
|
||||
|
||||
// Ensure all band textures are in the texture list
|
||||
for (const auto& band : bands)
|
||||
ensureTextureInList(band.texturePath);
|
||||
|
||||
for (int ci = 0; ci < 256; ci++) {
|
||||
auto& chunk = terrain_->chunks[ci];
|
||||
if (!chunk.hasHeightMap()) continue;
|
||||
|
||||
// Find average height of this chunk
|
||||
float avgH = chunk.position[2];
|
||||
float sum = 0;
|
||||
for (int v = 0; v < 145; v++) sum += chunk.heightMap.heights[v];
|
||||
avgH += sum / 145.0f;
|
||||
|
||||
// Find which band this chunk falls into
|
||||
for (const auto& band : bands) {
|
||||
if (avgH <= band.maxHeight) {
|
||||
uint32_t texId = ensureTextureInList(band.texturePath);
|
||||
if (!chunk.layers.empty())
|
||||
chunk.layers[0].textureId = texId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> TexturePainter::erase(const glm::vec3& center, float radius,
|
||||
float strength, float falloff) {
|
||||
if (!terrain_ || activeTexture_.empty()) return {};
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ public:
|
|||
const std::string& getActiveTexture() const { return activeTexture_; }
|
||||
const std::vector<std::string>& getRecentTextures() const { return recentTextures_; }
|
||||
|
||||
// Auto-paint textures based on terrain height bands
|
||||
struct HeightBand { float maxHeight; std::string texturePath; };
|
||||
void autoPaintByHeight(const std::vector<HeightBand>& bands);
|
||||
|
||||
// Paint the active texture at the given world position
|
||||
// Returns list of modified chunk indices
|
||||
std::vector<int> paint(const glm::vec3& center, float radius, float strength, float falloff);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue