mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-06 00:53:52 +00:00
feat(editor): erosion brush, NPC load, auto-save
- Erode brush mode: simulates water erosion by moving height downhill based on slope, creating natural drainage patterns and gullies - NPC JSON loader: File > Load NPCs parses saved creatures.json back into the spawn list (round-trip save/load now works) - Auto-save: every 5 minutes when unsaved changes exist, exports the full zone (ADT + WDT + creatures) to the output directory - Sculpt mode now has 6 brush types: Raise/Lower/Smooth/Flatten/Level/Erode
This commit is contained in:
parent
42749e9b58
commit
a91233a6ec
7 changed files with 164 additions and 7 deletions
|
|
@ -252,6 +252,7 @@ void TerrainEditor::applyBrush(float deltaTime) {
|
|||
case BrushMode::Smooth: applySmooth(deltaTime); break;
|
||||
case BrushMode::Flatten:
|
||||
case BrushMode::Level: applyFlatten(deltaTime); break;
|
||||
case BrushMode::Erode: applyErode(deltaTime); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -586,6 +587,50 @@ void TerrainEditor::removeWater(const glm::vec3& center, float radius) {
|
|||
}
|
||||
}
|
||||
|
||||
void TerrainEditor::applyErode(float dt) {
|
||||
float factor = std::min(1.0f, brush_.settings().strength * dt * 0.3f);
|
||||
|
||||
auto affected = getAffectedChunks(brush_.getPosition(), brush_.settings().radius);
|
||||
for (int chunkIdx : affected) {
|
||||
bool modified = false;
|
||||
auto& chunk = terrain_->chunks[chunkIdx];
|
||||
for (int v = 0; v < 145; v++) {
|
||||
glm::vec3 pos = chunkVertexWorldPos(chunkIdx, v);
|
||||
float dist = glm::length(glm::vec2(pos.x - brush_.getPosition().x,
|
||||
pos.y - brush_.getPosition().y));
|
||||
float influence = brush_.getInfluence(dist);
|
||||
if (influence <= 0.0f) continue;
|
||||
|
||||
float h = chunk.heightMap.heights[v];
|
||||
int row = v / 17, col = v % 17;
|
||||
|
||||
// Find lowest neighbor (same chunk)
|
||||
float lowestH = h;
|
||||
if (col <= 8) {
|
||||
int neighbors[] = {v - 17, v + 17, v - 1, v + 1};
|
||||
for (int n : neighbors) {
|
||||
if (n >= 0 && n < 145)
|
||||
lowestH = std::min(lowestH, chunk.heightMap.heights[n]);
|
||||
}
|
||||
}
|
||||
|
||||
// Move height toward lowest neighbor (erosion)
|
||||
float slope = h - lowestH;
|
||||
if (slope > 0.1f) {
|
||||
float erosion = slope * factor * influence * 0.3f;
|
||||
chunk.heightMap.heights[v] -= erosion;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (modified) {
|
||||
stitchEdges(chunkIdx);
|
||||
if (std::find(dirtyChunks_.begin(), dirtyChunks_.end(), chunkIdx) == dirtyChunks_.end())
|
||||
dirtyChunks_.push_back(chunkIdx);
|
||||
dirty_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerrainEditor::applyNoise(float frequency, float amplitude, int octaves, uint32_t seed) {
|
||||
if (!terrain_) return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue