Files
directx-plane-game/Graphics2/FractalTerrainNode.cpp

98 lines
2.6 KiB
C++

#include "FractalTerrainNode.h"
FractalTerrainNode::FractalTerrainNode(wstring name, wstring seed, float chunkSize, int widthX, int widthZ, float waterHeight, int cellSizeX, int cellSizeZ) : PerlinTerrainNode(name, seed, chunkSize, widthX, widthZ, waterHeight, cellSizeX, cellSizeZ)
{
if (!_initError)
{
float p = 1.0f;
for (int k = 1023; k > 2; k = (k + 1) / 2)
{
GenerateDiamonds(k, p);
GenerateSquares(k, p);
p *= 0.5f;
}
}
}
void FractalTerrainNode::GenerateSquares(const int k, const int p)
{
int stride = k - 1;
uniform_real_distribution<float> distro(0.0f, 1.0f);
for (int z = k / 2; z < _gridRows; z += stride)
{
for (int x = 0; x < _gridCols; x += stride)
{
DoSquare(z, x, k, p * distro(_generator));
}
}
for (int z = 0; z < _gridRows; z += stride)
{
for (int x = k / 2; x < _gridCols; x += stride)
{
DoSquare(z, x, k, p * distro(_generator));
}
}
}
void FractalTerrainNode::GenerateDiamonds(const int k, const int p)
{
int stride = k - 1;
uniform_real_distribution<float> distro(0.0f, 1.0f);
for (int z = k * 0.5f; z < _gridRows; z += stride)
{
for (int x = k * 0.5f; x < _gridCols; x += stride)
{
DoDiamond(z, x, k, p * distro(_generator));
}
}
}
void FractalTerrainNode::DoSquare(const int row, const int col, const int k, const float offset)
{
int step = k * 0.5f;
vector<float> featurePoints;
vector<vector<int>> points = { {row, col - step}, {row, col + step}, {row - step, col}, {row + step, col} };
for (vector<int> point : points)
{
if (point[0] >= 0 && point[0] < (int)_gridRows && point[1] >= 0 && point[1] < (int)_gridCols)
{
int pointIndex = ((point[0] * _gridCols) + point[1]);
featurePoints.push_back(_heightValues[pointIndex]);
}
}
float newHeight = (accumulate(featurePoints.begin(), featurePoints.end(), 0.0f) / featurePoints.size()) + offset;
int currentIndex = ((row * _gridCols) + col);
_heightValues[currentIndex] = newHeight;
}
void FractalTerrainNode::DoDiamond(const int row, const int col, const int k, const float offset)
{
int step = k * 0.5f;
float newHeight = 0.0f;
vector<vector<int>> points = { {row - step, col - step}, {row + step, col - step}, {row - step, col + step}, {row + step, col - step} };
for (vector<int> point : points)
{
if (point[0] >= 0 && point[0] < (int)_gridRows && point[1] >= 0 && point[1] < (int)_gridCols)
{
int pointIndex = ((point[0] * _gridCols) + point[1]);
newHeight += _heightValues[pointIndex];
}
}
newHeight *= 0.25f;
newHeight += offset;
int currentIndex = ((row * _gridCols) + col);
_heightValues[currentIndex] = newHeight;
}