From fa57ec29aa9cd466597716f178e0a5278a3cfbf2 Mon Sep 17 00:00:00 2001 From: iDunnoDev Date: Mon, 30 May 2022 12:32:44 +0100 Subject: [PATCH] Tried out this fractal terrain stuff but it just looks the same i guess? --- Graphics2/FractalTerrainNode.cpp | 98 +++++++++++++++++++++++++++++ Graphics2/FractalTerrainNode.h | 18 ++++++ Graphics2/Graphics2.cpp | 3 +- Graphics2/Graphics2.h | 1 + Graphics2/Graphics2.vcxproj | 2 + Graphics2/Graphics2.vcxproj.filters | 6 ++ Graphics2/PerlinTerrainNode.cpp | 6 +- Graphics2/PerlinTerrainNode.h | 4 +- Graphics2/TerrainNode.cpp | 2 +- 9 files changed, 134 insertions(+), 6 deletions(-) create mode 100644 Graphics2/FractalTerrainNode.cpp create mode 100644 Graphics2/FractalTerrainNode.h diff --git a/Graphics2/FractalTerrainNode.cpp b/Graphics2/FractalTerrainNode.cpp new file mode 100644 index 0000000..c252cb1 --- /dev/null +++ b/Graphics2/FractalTerrainNode.cpp @@ -0,0 +1,98 @@ +#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; +} \ No newline at end of file diff --git a/Graphics2/FractalTerrainNode.h b/Graphics2/FractalTerrainNode.h new file mode 100644 index 0000000..d173168 --- /dev/null +++ b/Graphics2/FractalTerrainNode.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include "PerlinTerrainNode.h" + +class FractalTerrainNode : public PerlinTerrainNode +{ +public: + FractalTerrainNode(wstring name, wstring seed, float chunkSize, int widthX = 1023, int widthZ = 1023, float waterHeight = 300.0f, int cellSizeX = 10, int cellSizeZ = 10); + +private: + void GenerateSquares(const int k, const int p); + void GenerateDiamonds(const int k, const int p); + + void DoSquare(const int row, const int col, const int k, const float offset); + void DoDiamond(const int row, const int col, const int k, const float offset); + +}; + diff --git a/Graphics2/Graphics2.cpp b/Graphics2/Graphics2.cpp index cd00f2f..9594a13 100644 --- a/Graphics2/Graphics2.cpp +++ b/Graphics2/Graphics2.cpp @@ -28,7 +28,8 @@ void Graphics2::CreateSceneGraph() sceneGraph->Add(skyDome); //shared_ptr terrainNode = make_shared(L"MainTerrain", L"Textures\\Example_HeightMap.raw", L"RandomWords"); - shared_ptr terrainNode = make_shared(L"MainTerrain", L"LovelyCat", 10.0f); + //shared_ptr terrainNode = make_shared(L"MainTerrain", L"LovelyCat", 10.0f); + shared_ptr terrainNode = make_shared(L"MainTerrain", L"LovelyCat", 10.0f); terrainNode->SetAmbientLight(DirectXFramework::GetDXFramework()->GetGlobalLighting()->GetAmbientLight()); terrainNode->SetDirectionalLight(DirectXFramework::GetDXFramework()->GetGlobalLighting()->GetDirectionalLightDirection(), DirectXFramework::GetDXFramework()->GetGlobalLighting()->GetDirectionalLightColor()); terrainNode->SetWaterColor(XMFLOAT4(SharedMethods::RGBValueToIntensity(0x84), SharedMethods::RGBValueToIntensity(0xC1), SharedMethods::RGBValueToIntensity(0xF9), 1.0f)); diff --git a/Graphics2/Graphics2.h b/Graphics2/Graphics2.h index 19eb632..7f9e01d 100644 --- a/Graphics2/Graphics2.h +++ b/Graphics2/Graphics2.h @@ -9,6 +9,7 @@ #include "ControlledSplitMeshNode.h" #include "HeightMapTerrainNode.h" #include "PerlinTerrainNode.h" +#include "FractalTerrainNode.h" #include "SkyNode.h" #include #include diff --git a/Graphics2/Graphics2.vcxproj b/Graphics2/Graphics2.vcxproj index a5269dd..b80b0bf 100644 --- a/Graphics2/Graphics2.vcxproj +++ b/Graphics2/Graphics2.vcxproj @@ -152,6 +152,7 @@ + @@ -197,6 +198,7 @@ + diff --git a/Graphics2/Graphics2.vcxproj.filters b/Graphics2/Graphics2.vcxproj.filters index b31986b..bf3f6aa 100644 --- a/Graphics2/Graphics2.vcxproj.filters +++ b/Graphics2/Graphics2.vcxproj.filters @@ -117,6 +117,9 @@ Header Files + + Header Files + @@ -225,6 +228,9 @@ Source Files + + Source Files + diff --git a/Graphics2/PerlinTerrainNode.cpp b/Graphics2/PerlinTerrainNode.cpp index feea799..a3ab374 100644 --- a/Graphics2/PerlinTerrainNode.cpp +++ b/Graphics2/PerlinTerrainNode.cpp @@ -14,8 +14,8 @@ PerlinTerrainNode::PerlinTerrainNode(wstring name, wstring seed, float chunkSize void PerlinTerrainNode::GeneratePerlinValues() { std::seed_seq seedGenerator(_seedString.begin(), _seedString.end()); - std::mt19937 generator; - generator.seed(seedGenerator); + + _generator.seed(seedGenerator); std::uniform_int_distribution<> dist(0, 511); char bufferChar; int newPosition; @@ -25,7 +25,7 @@ void PerlinTerrainNode::GeneratePerlinValues() for (int i = 0; i < 512; i++) { - newPosition = dist(generator); + newPosition = dist(_generator); bufferChar = _p[i]; _p[i] = _p[newPosition]; _p[newPosition] = bufferChar; diff --git a/Graphics2/PerlinTerrainNode.h b/Graphics2/PerlinTerrainNode.h index aae1fc8..b86f8cd 100644 --- a/Graphics2/PerlinTerrainNode.h +++ b/Graphics2/PerlinTerrainNode.h @@ -11,7 +11,7 @@ class PerlinTerrainNode : public TerrainNode public: PerlinTerrainNode(wstring name, wstring seed, float chunkSize, int widthX = 1023, int widthZ = 1023, float waterHeight = 300.0f, int cellSizeX = 10, int cellSizeZ = 10); -private: +protected: // the static perlin permutation array, we could calculate a random one but apparently you can run into sequencing issues and this just seems like the best solution vector _staticP = { 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23, @@ -45,6 +45,8 @@ private: float _chunkSize; + std::mt19937 _generator; + float Fade(float t); float Grad(int hash, float x, float y); diff --git a/Graphics2/TerrainNode.cpp b/Graphics2/TerrainNode.cpp index 02f411e..baaf549 100644 --- a/Graphics2/TerrainNode.cpp +++ b/Graphics2/TerrainNode.cpp @@ -672,7 +672,7 @@ float TerrainNode::GetHeightAtPoint(float x, float z, bool waterCollide) int cellX = (int)((x - _terrainStartX) / _cellSizeX); int cellZ = (int)((_terrainStartZ - z) / _cellSizeZ); - int currentIndex = (cellZ * _gridCols * 4) + (cellX * 4); + int currentIndex = ((cellZ * _gridCols) + cellX) * 4; float dx = x - _terrainVerts[currentIndex].Position.x; float dz = z - _terrainVerts[currentIndex].Position.z;