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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user