mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-05 16:43:52 +00:00
feat(editor): rotate terrain 90 degrees clockwise
- Rotate 90 CW button in Mirror/Rotate section - Snapshots outer vertex heights into 129x129 grid, rotates in-place, writes back with inner vertices averaged from surrounding outers - Useful for reorienting terrain features or creating rotational symmetry (rotate + mirror for 4-way symmetric arenas)
This commit is contained in:
parent
66b6404d25
commit
14d305a477
3 changed files with 53 additions and 1 deletions
|
|
@ -627,7 +627,11 @@ void EditorUI::renderBrushPanel(EditorApp& app) {
|
|||
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1), "Set start then end to apply");
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Mirror Terrain")) {
|
||||
if (ImGui::CollapsingHeader("Mirror / Rotate")) {
|
||||
if (ImGui::Button("Rotate 90 CW", ImVec2(-1, 0))) {
|
||||
app.getTerrainEditor().rotateTerrain90();
|
||||
app.showToast("Terrain rotated 90 degrees");
|
||||
}
|
||||
if (ImGui::Button("Mirror X (Left<>Right)", ImVec2(-1, 0))) {
|
||||
app.getTerrainEditor().mirrorX();
|
||||
app.showToast("Terrain mirrored X");
|
||||
|
|
|
|||
|
|
@ -900,6 +900,51 @@ void TerrainEditor::applyVoronoiNoise(int cellCount, float amplitude, uint32_t s
|
|||
dirty_ = true;
|
||||
}
|
||||
|
||||
void TerrainEditor::rotateTerrain90() {
|
||||
if (!terrain_) return;
|
||||
// Snapshot all outer vertex heights into a 129x129 grid
|
||||
std::array<std::array<float, 129>, 129> grid{};
|
||||
for (int cy = 0; cy < 16; cy++) {
|
||||
for (int cx = 0; cx < 16; cx++) {
|
||||
auto& chunk = terrain_->chunks[cy * 16 + cx];
|
||||
if (!chunk.hasHeightMap()) continue;
|
||||
for (int v = 0; v < 145; v++) {
|
||||
int row = v / 17, col = v % 17;
|
||||
if (col > 8) continue;
|
||||
grid[cy * 8 + row][cx * 8 + col] = chunk.heightMap.heights[v];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Rotate 90 degrees CW: new[x][128-y] = old[y][x]
|
||||
std::array<std::array<float, 129>, 129> rotated{};
|
||||
for (int y = 0; y < 129; y++)
|
||||
for (int x = 0; x < 129; x++)
|
||||
rotated[x][128 - y] = grid[y][x];
|
||||
// Write back
|
||||
for (int cy = 0; cy < 16; cy++) {
|
||||
for (int cx = 0; cx < 16; cx++) {
|
||||
auto& chunk = terrain_->chunks[cy * 16 + cx];
|
||||
if (!chunk.hasHeightMap()) continue;
|
||||
for (int v = 0; v < 145; v++) {
|
||||
int row = v / 17, col = v % 17;
|
||||
if (col > 8) {
|
||||
// Inner vertex: average of surrounding outer
|
||||
int innerCol = col - 9;
|
||||
int gy = cy * 8 + row, gx = cx * 8 + innerCol;
|
||||
if (gy < 128 && gx < 128)
|
||||
chunk.heightMap.heights[v] = (rotated[gy][gx] + rotated[gy][gx+1] +
|
||||
rotated[gy+1][gx] + rotated[gy+1][gx+1]) * 0.25f;
|
||||
} else {
|
||||
chunk.heightMap.heights[v] = rotated[cy * 8 + row][cx * 8 + col];
|
||||
}
|
||||
}
|
||||
dirtyChunks_.push_back(cy * 16 + cx);
|
||||
}
|
||||
}
|
||||
for (int ci = 0; ci < 256; ci++) stitchEdges(ci);
|
||||
dirty_ = true;
|
||||
}
|
||||
|
||||
void TerrainEditor::offsetHeights(float amount) {
|
||||
if (!terrain_) return;
|
||||
for (int ci = 0; ci < 256; ci++) {
|
||||
|
|
|
|||
|
|
@ -126,6 +126,9 @@ public:
|
|||
// Add random detail noise to existing terrain (preserves shape, adds roughness)
|
||||
void addDetailNoise(float amplitude, float frequency, uint32_t seed);
|
||||
|
||||
// Rotate terrain 90 degrees clockwise
|
||||
void rotateTerrain90();
|
||||
|
||||
// Import/export heightmap (raw 16-bit grayscale, 129x129)
|
||||
bool importHeightmap(const std::string& path, float heightScale);
|
||||
bool exportHeightmap(const std::string& path, float heightScale);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue