1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Move more simplex functions to SimplexNoise unit

This commit is contained in:
Aaron van Geffen
2024-12-30 17:32:16 +01:00
parent 6386307b77
commit a809f48106
4 changed files with 91 additions and 85 deletions

View File

@@ -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<int32_t>(normalisedNoiseValue * high);
}
}
}
} // namespace OpenRCT2::World::MapGenerator

View File

@@ -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

View File

@@ -10,7 +10,11 @@
#include "SimplexNoise.h"
#include "../../util/Util.h"
#include "HeightMap.hpp"
#include "MapGen.h"
#include "MapHelpers.h"
#include <algorithm>
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<int32_t>(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

View File

@@ -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