From a809f481066c71b6a8e95454497dd038e273bad7 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Mon, 30 Dec 2024 17:32:16 +0100 Subject: [PATCH] Move more simplex functions to SimplexNoise unit --- src/openrct2/world/map_generator/MapGen.cpp | 88 +------------------ src/openrct2/world/map_generator/MapGen.h | 6 ++ .../world/map_generator/SimplexNoise.cpp | 78 ++++++++++++++++ .../world/map_generator/SimplexNoise.h | 4 + 4 files changed, 91 insertions(+), 85 deletions(-) diff --git a/src/openrct2/world/map_generator/MapGen.cpp b/src/openrct2/world/map_generator/MapGen.cpp index cf93eff806..0ca7bcf66d 100644 --- a/src/openrct2/world/map_generator/MapGen.cpp +++ b/src/openrct2/world/map_generator/MapGen.cpp @@ -16,7 +16,6 @@ #include "../tile_element/Slope.h" #include "../tile_element/SurfaceElement.h" #include "HeightMap.hpp" -#include "MapHelpers.h" #include "PngTerrainGenerator.h" #include "SimplexNoise.h" #include "SurfaceSelection.h" @@ -27,7 +26,6 @@ namespace OpenRCT2::World::MapGenerator { static void generateBlankMap(Settings* settings); - static void generateSimplexMap(Settings* settings); static void addBeaches(Settings* settings); @@ -58,11 +56,7 @@ namespace OpenRCT2::World::MapGenerator placeTrees(settings); } - static void setWaterLevel(int32_t waterLevel); - static void smoothHeightMap(int32_t iterations, HeightMap& heightMap); - static void setMapHeight(Settings* settings, const HeightMap& heightMap); - - static void resetSurfaces(Settings* settings) + void resetSurfaces(Settings* settings) { MapClearAllElements(); MapInit(settings->mapSize); @@ -92,34 +86,6 @@ namespace OpenRCT2::World::MapGenerator setWaterLevel(settings->waterLevel); } - static void generateSimplexNoise(Settings* settings, HeightMap& heightMap); - - static void generateSimplexMap(Settings* settings) - { - resetSurfaces(settings); - - // Create the temporary height map and initialise - auto& mapSize = settings->mapSize; - auto heightMap = HeightMap(mapSize.x * 2, mapSize.y * 2); - - generateSimplexNoise(settings, heightMap); - smoothHeightMap(2 + (UtilRand() % 6), heightMap); - - // Set the game map to the height map - setMapHeight(settings, heightMap); - - if (settings->smoothTileEdges) - { - // Set the tile slopes so that there are no cliffs - while (MapSmooth(1, 1, mapSize.x - 1, mapSize.y - 1)) - { - } - } - - // Add the water - setWaterLevel(settings->waterLevel); - } - static void addBeaches(Settings* settings) { auto beachTextureId = generateBeachTextureId(); @@ -143,7 +109,7 @@ namespace OpenRCT2::World::MapGenerator /** * Sets each tile's water level to the specified water level if underneath that water level. */ - static void setWaterLevel(int32_t waterLevel) + void setWaterLevel(int32_t waterLevel) { auto& gameState = GetGameState(); for (int32_t y = 1; y < gameState.MapSize.y - 1; y++) @@ -157,37 +123,10 @@ namespace OpenRCT2::World::MapGenerator } } - /** - * Smooths the height map. - */ - static void smoothHeightMap(int32_t iterations, HeightMap& heightMap) - { - for (auto i = 0; i < iterations; i++) - { - auto copyHeight = heightMap; - for (auto y = 1; y < heightMap.height - 1; y++) - { - for (auto x = 1; x < heightMap.width - 1; x++) - { - auto avg = 0; - for (auto yy = -1; yy <= 1; yy++) - { - for (auto xx = -1; xx <= 1; xx++) - { - avg += copyHeight[{ y + yy, x + xx }]; - } - } - avg /= 9; - heightMap[{ x, y }] = avg; - } - } - } - } - /** * Sets the height of the actual game map tiles to the height map. */ - static void setMapHeight(Settings* settings, const HeightMap& heightMap) + void setMapHeight(Settings* settings, const HeightMap& heightMap) { for (auto y = 1; y < heightMap.height / 2 - 1; y++) { @@ -229,25 +168,4 @@ namespace OpenRCT2::World::MapGenerator } } } - - static void generateSimplexNoise(Settings* settings, HeightMap& heightMap) - { - float freq = settings->simplex_base_freq / 100.0f * (1.0f / heightMap.width); - int32_t octaves = settings->simplex_octaves; - - int32_t low = settings->heightmapLow / 2; - int32_t high = settings->heightmapHigh / 2 - low; - - NoiseRand(); - for (int32_t y = 0; y < heightMap.height; y++) - { - for (int32_t x = 0; x < heightMap.width; x++) - { - float noiseValue = std::clamp(FractalNoise(x, y, freq, octaves, 2.0f, 0.65f), -1.0f, 1.0f); - float normalisedNoiseValue = (noiseValue + 1.0f) / 2.0f; - - heightMap[{ x, y }] = low + static_cast(normalisedNoiseValue * high); - } - } - } } // namespace OpenRCT2::World::MapGenerator diff --git a/src/openrct2/world/map_generator/MapGen.h b/src/openrct2/world/map_generator/MapGen.h index cf1c2476e4..431a231217 100644 --- a/src/openrct2/world/map_generator/MapGen.h +++ b/src/openrct2/world/map_generator/MapGen.h @@ -49,5 +49,11 @@ namespace OpenRCT2::World::MapGenerator bool normalize_height = true; }; + class HeightMap; + void generate(Settings* settings); + void resetSurfaces(Settings* settings); + void setWaterLevel(int32_t waterLevel); + void setMapHeight(Settings* settings, const HeightMap& heightMap); + } // namespace OpenRCT2::World::MapGenerator diff --git a/src/openrct2/world/map_generator/SimplexNoise.cpp b/src/openrct2/world/map_generator/SimplexNoise.cpp index 6ea77f2e46..e65273feb9 100644 --- a/src/openrct2/world/map_generator/SimplexNoise.cpp +++ b/src/openrct2/world/map_generator/SimplexNoise.cpp @@ -10,7 +10,11 @@ #include "SimplexNoise.h" #include "../../util/Util.h" +#include "HeightMap.hpp" #include "MapGen.h" +#include "MapHelpers.h" + +#include namespace OpenRCT2::World::MapGenerator { @@ -146,4 +150,78 @@ namespace OpenRCT2::World::MapGenerator float v = h < 4 ? y : x; // and compute the dot product with (x,y). return ((h & 1) != 0 ? -u : u) + ((h & 2) != 0 ? -2.0f * v : 2.0f * v); } + + /** + * Smooths the height map. + */ + static void smoothHeightMap(int32_t iterations, HeightMap& heightMap) + { + for (auto i = 0; i < iterations; i++) + { + auto copyHeight = heightMap; + for (auto y = 1; y < heightMap.height - 1; y++) + { + for (auto x = 1; x < heightMap.width - 1; x++) + { + auto avg = 0; + for (auto yy = -1; yy <= 1; yy++) + { + for (auto xx = -1; xx <= 1; xx++) + { + avg += copyHeight[{ y + yy, x + xx }]; + } + } + avg /= 9; + heightMap[{ x, y }] = avg; + } + } + } + } + + static void generateSimplexNoise(Settings* settings, HeightMap& heightMap) + { + float freq = settings->simplex_base_freq / 100.0f * (1.0f / heightMap.width); + int32_t octaves = settings->simplex_octaves; + + int32_t low = settings->heightmapLow / 2; + int32_t high = settings->heightmapHigh / 2 - low; + + NoiseRand(); + for (int32_t y = 0; y < heightMap.height; y++) + { + for (int32_t x = 0; x < heightMap.width; x++) + { + float noiseValue = std::clamp(FractalNoise(x, y, freq, octaves, 2.0f, 0.65f), -1.0f, 1.0f); + float normalisedNoiseValue = (noiseValue + 1.0f) / 2.0f; + + heightMap[{ x, y }] = low + static_cast(normalisedNoiseValue * high); + } + } + } + + void generateSimplexMap(Settings* settings) + { + resetSurfaces(settings); + + // Create the temporary height map and initialise + auto& mapSize = settings->mapSize; + auto heightMap = HeightMap(mapSize.x * 2, mapSize.y * 2); + + generateSimplexNoise(settings, heightMap); + smoothHeightMap(2 + (UtilRand() % 6), heightMap); + + // Set the game map to the height map + setMapHeight(settings, heightMap); + + if (settings->smoothTileEdges) + { + // Set the tile slopes so that there are no cliffs + while (MapSmooth(1, 1, mapSize.x - 1, mapSize.y - 1)) + { + } + } + + // Add the water + setWaterLevel(settings->waterLevel); + } } // namespace OpenRCT2::World::MapGenerator diff --git a/src/openrct2/world/map_generator/SimplexNoise.h b/src/openrct2/world/map_generator/SimplexNoise.h index c46df9bd60..f8e5a3f515 100644 --- a/src/openrct2/world/map_generator/SimplexNoise.h +++ b/src/openrct2/world/map_generator/SimplexNoise.h @@ -13,6 +13,10 @@ namespace OpenRCT2::World::MapGenerator { + struct Settings; + void NoiseRand(); float FractalNoise(int32_t x, int32_t y, float frequency, int32_t octaves, float lacunarity, float persistence); + + void generateSimplexMap(Settings* settings); } // namespace OpenRCT2::World::MapGenerator