#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 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 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 featurePoints; vector> points = { {row, col - step}, {row, col + step}, {row - step, col}, {row + step, col} }; for (vector 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> points = { {row - step, col - step}, {row + step, col - step}, {row - step, col + step}, {row + step, col - step} }; for (vector 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; }