diff --git a/Graphics2/Graphics2.cpp b/Graphics2/Graphics2.cpp index 881b0f7..106f93f 100644 --- a/Graphics2/Graphics2.cpp +++ b/Graphics2/Graphics2.cpp @@ -15,7 +15,7 @@ void Graphics2::CreateSceneGraph() GetCamera()->SetCameraPosition(0.0f, 550.0f, -80.0f); SceneGraphPointer sceneGraph = GetSceneGraph(); - + // This is where you add nodes to the scene graph //shared_ptr cube = make_shared(L"Body", L"Textures\\woodbox.bmp"); //cube->SetWorldTransform(XMMatrixScaling(5.0f, 8.0f, 2.5f) * XMMatrixTranslation(0, 23.0f, 0)); @@ -28,7 +28,7 @@ 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, 20.0f, 1.0f, 1); + 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)); @@ -36,26 +36,6 @@ void Graphics2::CreateSceneGraph() //terrainNode->SetWaterColor(XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f)); sceneGraph->Add(terrainNode); - shared_ptr treeGroupA = make_shared(L"TreeGroupA"); - - shared_ptr treeNode1 = make_shared(L"Tree1", L"Models\\Tree\\Tree1.3ds"); - treeNode1->SetWorldTransform(XMMatrixScaling(0.005f, 0.01f, 0.005f) * XMMatrixRotationAxis(XMVectorSet(1.0f, 0.0f, 1.0f, 0.0f), 0.1f * XM_PI) * XMMatrixTranslation(0.0f, 320.0f, 250.0f)); - treeGroupA->Add(treeNode1); - - shared_ptr treeNode2 = make_shared(L"Tree2", L"Models\\Tree\\Tree1.3ds"); - treeNode2->SetWorldTransform(XMMatrixScaling(0.002f, 0.002f, 0.002f) * XMMatrixTranslation(-150.0f, 380.0f, 150.0f)); - treeGroupA->Add(treeNode2); - - shared_ptr treeNode3 = make_shared(L"Tree3", L"Models\\Tree\\Tree1.3ds"); - treeNode3->SetWorldTransform(XMMatrixScaling(0.005f, 0.005f, 0.005f) * XMMatrixRotationAxis(XMVectorSet(1.0f, 0.0f, 1.0f, 0.0f), -0.1f * XM_PI) * XMMatrixTranslation(100.0f, 290.0f, 350.0f)); - treeGroupA->Add(treeNode3); - - shared_ptr treeNode4 = make_shared(L"Tree4", L"Models\\Tree\\Tree1.3ds"); - treeNode4->SetWorldTransform(XMMatrixScaling(0.005f, 0.01f, 0.005f) * XMMatrixRotationAxis(XMVectorSet(1.0f, 0.0f, 1.0f, 0.0f), 0.1f * XM_PI) * XMMatrixTranslation(0.0f, 320.0f, 250.0f)); - treeGroupA->Add(treeNode4); - - sceneGraph->Add(treeGroupA); - shared_ptr plane1Node = make_shared(L"Plane1", L"Models\\Plane\\Bonanza.3DS"); plane1Node->SetStartOrientation(XMMatrixRotationAxis(XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f), XM_PI) * XMMatrixRotationAxis(XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f), 0.5f * XM_PI)); plane1Node->SetNodePosition(0.0f, 550.0f, -50.0f); @@ -74,9 +54,30 @@ void Graphics2::CreateSceneGraph() void Graphics2::UpdateSceneGraph() { - GetCurrentControlInputs(); - SceneGraphPointer sceneGraph = GetSceneGraph(); + shared_ptr mainTerrain = dynamic_pointer_cast(sceneGraph->Find(L"MainTerrain")); + + if (!_initDone && mainTerrain != nullptr) + { + vector rngSpawnList; + + TerrainPopNode treeModelA = TerrainPopNode(); + treeModelA.modelName = L"Models\\Tree\\Tree2.fbx"; + treeModelA.nodeBaseName = L"treeA"; + treeModelA.scaleFactor = 1.0f; + + rngSpawnList.push_back(treeModelA); + + shared_ptr treeGroupA = make_shared(L"TreeGroupA"); + + mainTerrain->PopulateTerrain(treeGroupA, rngSpawnList, 10, 10, 400.0f, 550.0f, 0.9f, 1.0f); + treeGroupA->Initialise(); + sceneGraph->Add(treeGroupA); + + _initDone = true; + } + + GetCurrentControlInputs(); XMVECTOR startCameraPos = GetCamera()->GetCameraPosition(); if (_currentPlayerObject != nullptr) @@ -189,8 +190,7 @@ void Graphics2::UpdateSceneGraph() } // Check the camera and our terrain boundaries - XMVECTOR currentCameraPos = GetCamera()->GetCameraPosition(); - shared_ptr mainTerrain = dynamic_pointer_cast(sceneGraph->Find(L"MainTerrain")); + XMVECTOR currentCameraPos = GetCamera()->GetCameraPosition(); GetCamera()->Update(); if (mainTerrain != nullptr) { diff --git a/Graphics2/Graphics2.h b/Graphics2/Graphics2.h index 59b89b1..7e80e0a 100644 --- a/Graphics2/Graphics2.h +++ b/Graphics2/Graphics2.h @@ -19,6 +19,8 @@ public: void UpdateSceneGraph(); private: + bool _initDone = false; + bool _boosting = false; float _boostMultiplier = 1; float _boostMin = 1; diff --git a/Graphics2/Models/Boat/NWW83WKS0AJC0W7C1XP0CFCET.mtl b/Graphics2/Models/Boat/NWW83WKS0AJC0W7C1XP0CFCET.mtl new file mode 100644 index 0000000..2f7f867 --- /dev/null +++ b/Graphics2/Models/Boat/NWW83WKS0AJC0W7C1XP0CFCET.mtl @@ -0,0 +1,27 @@ +newmtl mat_0-default-grey.jpg +Ka 0.000000 0.000000 0.000000 +Kd 0.698039 0.698039 0.698039 +Ks 0.000000 0.000000 0.000000 +d 1.000000 +illum 2 +Ns 9.84916 +map_Kd default-grey.jpg + +newmtl mat_1-boat_fishing02.jpg +Ka 0.000000 0.000000 0.000000 +Kd 0.698039 0.698039 0.698039 +Ks 0.000000 0.000000 0.000000 +d 1.000000 +illum 2 +Ns 9.84916 +map_Kd boat_fishing02.jpg + +newmtl mat_2-default-grey.jpg +Ka 0.000000 0.000000 0.000000 +Kd 0.698039 0.698039 0.698039 +Ks 0.000000 0.000000 0.000000 +d 1.000000 +illum 2 +Ns 9.84916 +map_Kd default-grey.jpg + diff --git a/Graphics2/Models/Boat/boat_fishing02.jpeg b/Graphics2/Models/Boat/boat_fishing02.jpeg new file mode 100644 index 0000000..2907ac1 Binary files /dev/null and b/Graphics2/Models/Boat/boat_fishing02.jpeg differ diff --git a/Graphics2/Models/Boat/boat_fishing02.jpg b/Graphics2/Models/Boat/boat_fishing02.jpg new file mode 100644 index 0000000..2907ac1 Binary files /dev/null and b/Graphics2/Models/Boat/boat_fishing02.jpg differ diff --git a/Graphics2/Models/Tree/Bush1.fbx b/Graphics2/Models/Tree/Bush1.fbx new file mode 100644 index 0000000..7fc1249 Binary files /dev/null and b/Graphics2/Models/Tree/Bush1.fbx differ diff --git a/Graphics2/Models/Tree/Bush2.fbx b/Graphics2/Models/Tree/Bush2.fbx new file mode 100644 index 0000000..f5dc980 Binary files /dev/null and b/Graphics2/Models/Tree/Bush2.fbx differ diff --git a/Graphics2/Models/Tree/Bush3.fbx b/Graphics2/Models/Tree/Bush3.fbx new file mode 100644 index 0000000..ec0b1ff Binary files /dev/null and b/Graphics2/Models/Tree/Bush3.fbx differ diff --git a/Graphics2/Models/Tree/COLOR.JPG b/Graphics2/Models/Tree/COLOR.JPG deleted file mode 100644 index cea16ae..0000000 Binary files a/Graphics2/Models/Tree/COLOR.JPG and /dev/null differ diff --git a/Graphics2/Models/Tree/Grass1.fbx b/Graphics2/Models/Tree/Grass1.fbx new file mode 100644 index 0000000..a8a1824 Binary files /dev/null and b/Graphics2/Models/Tree/Grass1.fbx differ diff --git a/Graphics2/Models/Tree/Grass2.fbx b/Graphics2/Models/Tree/Grass2.fbx new file mode 100644 index 0000000..fab2fdc Binary files /dev/null and b/Graphics2/Models/Tree/Grass2.fbx differ diff --git a/Graphics2/Models/Tree/Grass3.fbx b/Graphics2/Models/Tree/Grass3.fbx new file mode 100644 index 0000000..6623820 Binary files /dev/null and b/Graphics2/Models/Tree/Grass3.fbx differ diff --git a/Graphics2/Models/Tree/Kashtan.jpg b/Graphics2/Models/Tree/Kashtan.jpg deleted file mode 100644 index dbd81b7..0000000 Binary files a/Graphics2/Models/Tree/Kashtan.jpg and /dev/null differ diff --git a/Graphics2/Models/Tree/Rock1.fbx b/Graphics2/Models/Tree/Rock1.fbx new file mode 100644 index 0000000..1a2b6d5 Binary files /dev/null and b/Graphics2/Models/Tree/Rock1.fbx differ diff --git a/Graphics2/Models/Tree/Rock2.fbx b/Graphics2/Models/Tree/Rock2.fbx new file mode 100644 index 0000000..6f251c7 Binary files /dev/null and b/Graphics2/Models/Tree/Rock2.fbx differ diff --git a/Graphics2/Models/Tree/Rock3.fbx b/Graphics2/Models/Tree/Rock3.fbx new file mode 100644 index 0000000..f74240a Binary files /dev/null and b/Graphics2/Models/Tree/Rock3.fbx differ diff --git a/Graphics2/Models/Tree/Tree1.3ds b/Graphics2/Models/Tree/Tree1.3ds deleted file mode 100644 index 813923a..0000000 Binary files a/Graphics2/Models/Tree/Tree1.3ds and /dev/null differ diff --git a/Graphics2/Models/Tree/Tree1.fbx b/Graphics2/Models/Tree/Tree1.fbx new file mode 100644 index 0000000..9555ae9 Binary files /dev/null and b/Graphics2/Models/Tree/Tree1.fbx differ diff --git a/Graphics2/Models/Tree/Tree2.fbx b/Graphics2/Models/Tree/Tree2.fbx new file mode 100644 index 0000000..2a5c4dd Binary files /dev/null and b/Graphics2/Models/Tree/Tree2.fbx differ diff --git a/Graphics2/Models/Tree/Tree3.fbx b/Graphics2/Models/Tree/Tree3.fbx new file mode 100644 index 0000000..3fb451b Binary files /dev/null and b/Graphics2/Models/Tree/Tree3.fbx differ diff --git a/Graphics2/Models/Tree/Tree4.fbx b/Graphics2/Models/Tree/Tree4.fbx new file mode 100644 index 0000000..f6461f2 Binary files /dev/null and b/Graphics2/Models/Tree/Tree4.fbx differ diff --git a/Graphics2/PerlinTerrainNode.cpp b/Graphics2/PerlinTerrainNode.cpp index bd21d83..feea799 100644 --- a/Graphics2/PerlinTerrainNode.cpp +++ b/Graphics2/PerlinTerrainNode.cpp @@ -1,11 +1,8 @@ #include "PerlinTerrainNode.h" -PerlinTerrainNode::PerlinTerrainNode(wstring name, wstring seed, float offsetX, float offsetY, float chunkSize, int layers, int widthX, int widthZ, float waterHeight, int cellSizeX, int cellSizeZ) : TerrainNode(name, seed, waterHeight, widthX, widthZ, cellSizeX, cellSizeZ) +PerlinTerrainNode::PerlinTerrainNode(wstring name, wstring seed, float chunkSize, int widthX, int widthZ, float waterHeight, int cellSizeX, int cellSizeZ) : TerrainNode(name, seed, waterHeight, widthX, widthZ, cellSizeX, cellSizeZ) { - _offsetX = offsetX; - _offsetY = offsetY; _chunkSize = chunkSize; - _layers = layers; GeneratePerlinValues(); if (!GeneratePerlinHeights()) @@ -14,44 +11,64 @@ PerlinTerrainNode::PerlinTerrainNode(wstring name, wstring seed, float offsetX, } } +void PerlinTerrainNode::GeneratePerlinValues() +{ + std::seed_seq seedGenerator(_seedString.begin(), _seedString.end()); + std::mt19937 generator; + generator.seed(seedGenerator); + std::uniform_int_distribution<> dist(0, 511); + char bufferChar; + int newPosition; + + _p.clear(); + copy(_staticP.begin(), _staticP.end(), back_inserter(_p)); + + for (int i = 0; i < 512; i++) + { + newPosition = dist(generator); + bufferChar = _p[i]; + _p[i] = _p[newPosition]; + _p[newPosition] = bufferChar; + } +} + // Method for filling the height values array for the terrain generation bool PerlinTerrainNode::GeneratePerlinHeights() { for (int z = 0; z < _gridRows; z++) { - float mapZ = ((float)z / (float)_gridRows) + 0.5f; + float mapZ = ((float)z / (float)_gridRows); for (int x = 0; x < _gridCols; x++) { - float mapX = ((float)x / (float)_gridCols) + 0.5f; + float mapX = ((float)x / (float)_gridCols); - float currentHeightValue = GetPerlinValueAt(_offsetX + mapX, _offsetY + mapZ, 8, 0.85f) - 0.25f; + //float currentHeightValue = GetPerlinValueAt(mapX, mapZ, 8, 0.85f) - 0.25f; + float currentHeightValue = 0.0f; + + int octaves = 12; + float currentOctaveValue = 1.0f; + float stepOff = 1.0f; + float stepTotal = 0.0f; + // n covers the persistance, frequency and + for (int n = 1; n <= octaves; n++) + { + currentHeightValue += stepOff * GetNoiseValueAt(((float)x * currentOctaveValue) / ((float)_gridCols / _chunkSize), ((float)z * currentOctaveValue) / ((float)_gridRows / _chunkSize)); + currentOctaveValue *= 2; + stepTotal += stepOff; + stepOff *= 0.5f; + + } + + //currentHeightValue = currentHeightValue / stepTotal; // *(currentHeightValue * 2.0f); //currentHeightValue = currentHeightValue - floor(currentHeightValue); - _heightValues.push_back(currentHeightValue); + _heightValues.push_back((currentHeightValue + 1.0f) * 0.5f); } } return true; } -// Method for generating the permutation array needed for perlin noise -void PerlinTerrainNode::GeneratePerlinValues() -{ - // Set the permutation array length - p.resize(256); - - // Fill the permutation array with 0 to 255 - iota(p.begin(), p.end(), 0); - - default_random_engine engine(_seedHash); - - // Shuffle the array values using the seed value given - shuffle(p.begin(), p.end(), engine); - - // Duplicate the permutation results so our array is 512 - p.insert(p.end(), p.begin(), p.end()); -} - float PerlinTerrainNode::Fade(float t) { return t * t * t * (t * (t * 6 - 15) + 10); @@ -59,77 +76,56 @@ float PerlinTerrainNode::Fade(float t) float PerlinTerrainNode::Grad(int hash, float x, float y) { - // Fast Grad switch check converted from a java implimentation of perlin noise - switch (hash & 0xF) + int h = hash & 7; + float u = y; + float v = x; + if (h < 4) { - case 0x0: return x; - case 0x1: return x + y; - case 0x2: return y; - case 0x3: return -x + y; - case 0x4: return -x; - case 0x5: return -x - y; - case 0x6: return -y; - case 0x7: return x - y; - case 0x8: return x; - case 0x9: return x + y; - case 0xA: return y; - case 0xB: return -x + y; - case 0xC: return -x; - case 0xD: return -x - y; - case 0xE: return -y; - case 0xF: return x - y; - - default: return 0; // Never occurs + u = x; + v = y; } -} - -// Method to calculate the perlin value at x/y with the given octaves and persistance values, also normalised -float PerlinTerrainNode::GetPerlinValueAt(float x, float y, int octaves, float persistance) -{ - float total = 0.0f; - float frequency = 1.0f; - float amplitude = 1.0f; - float maxValue = 0.0f; - - for (int i = 0; i < octaves; i++) + + float outA = u; + if ((h & 1)) { - total += (GetNoiseValueAt(x * frequency, y * frequency) * amplitude); - maxValue += amplitude; - - amplitude *= persistance; - frequency *= 2; + outA = -u; } - return total / maxValue; + float outB = 2.0f * v; + if ((h & 2)) + { + outB = -2.0f * v; + } + + return outA + outB; } // Method to get the perlin noise value at x/y float PerlinTerrainNode::GetNoiseValueAt(float x, float y) { - int x0 = (int)x & 255; - int y0 = (int)y & 255; + int ix0 = (int)floor(x); + int iy0 = (int)floor(y); - int x1 = x0 + 1; - int y1 = y0 + 1; + float fx0 = x - (float)ix0; + float fy0 = y - (float)iy0; + float fx1 = fx0 - 1.0f; + float fy1 = fy0 - 1.0f; + + int ix1 = (ix0 + 1) & 0xff; + int iy1 = (iy0 + 1) & 0xff; + ix0 = ix0 & 0xff; + iy0 = iy0 & 0xff; - float dx = x - (float)x0; - float dy = y - (float)y0; + float t = Fade(fy0); + float s = Fade(fx0); - float u = Fade(dx); - float v = Fade(dy); + float nx0 = Grad(_p[ix0 + _p[iy0]], fx0, fy0); + float nx1 = Grad(_p[ix0 + _p[iy1]], fx0, fy1); + float n0 = SharedMethods::Lerp(nx0, nx1, t); - int aa = p[p[x0] + y0]; - int ab = p[p[x0] + y1]; - int ba = p[p[x1] + y0]; - int bb = p[p[x1] + y1]; + nx0 = Grad(_p[ix1 + _p[iy0]], fx1, fy0); + nx1 = Grad(_p[ix1 + _p[iy1]], fx1, fy1); + float n1 = SharedMethods::Lerp(nx0, nx1, t); - float na0 = Grad(aa, dx, dy); - float na1 = Grad(ba, dx - 1.0f, dy); - float nal = SharedMethods::Lerp(na0, na1, u); - - float nb0 = Grad(ab, dx, dy - 1.0f); - float nb1 = Grad(bb, dx - 1.0f, dy - 1.0f); - float nbl = SharedMethods::Lerp(nb0, nb1, u); - - return (SharedMethods::Lerp(nal, nbl, v) + 1.0f) / 2.0f; + return 0.507f * SharedMethods::Lerp(n0, n1, s); } \ No newline at end of file diff --git a/Graphics2/PerlinTerrainNode.h b/Graphics2/PerlinTerrainNode.h index 6eade91..aae1fc8 100644 --- a/Graphics2/PerlinTerrainNode.h +++ b/Graphics2/PerlinTerrainNode.h @@ -9,21 +9,48 @@ class PerlinTerrainNode : public TerrainNode { public: - PerlinTerrainNode(wstring name, wstring seed, float offsetX, float offsetY, float chunkSize, int layers, int widthX = 1023, int widthZ = 1023, float waterHeight = 150.0f, int cellSizeX = 10, int cellSizeZ = 10); + PerlinTerrainNode(wstring name, wstring seed, float chunkSize, int widthX = 1023, int widthZ = 1023, float waterHeight = 300.0f, int cellSizeX = 10, int cellSizeZ = 10); private: - vector p; - float _offsetX; - float _offsetY; + // 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, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180, + 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, + 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33, + 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166, + 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244, + 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196, + 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123, + 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42, + 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9, + 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228, + 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107, + 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 + }; + + vector _p; + float _chunkSize; - int _layers; float Fade(float t); float Grad(int hash, float x, float y); + void GeneratePerlinValues(); bool GeneratePerlinHeights(); float GetPerlinValueAt(float x, float y, int octaves, float persistance); float GetNoiseValueAt(float x, float y); - void GeneratePerlinValues(); }; diff --git a/Graphics2/SharedMethods.h b/Graphics2/SharedMethods.h index fb098eb..cc83f6d 100644 --- a/Graphics2/SharedMethods.h +++ b/Graphics2/SharedMethods.h @@ -1,5 +1,6 @@ #pragma once #include "DirectXCore.h" +#include struct CBUFFER { @@ -16,6 +17,13 @@ struct CBUFFER float padding[2]; }; +struct TerrainPopNode +{ + std::wstring nodeBaseName; + std::wstring modelName; + float scaleFactor; +}; + namespace SharedMethods { XMMATRIX RotateFromPoint(const float x, const float y, const float z, const XMMATRIX rotationMatrix); diff --git a/Graphics2/TerrainNode.cpp b/Graphics2/TerrainNode.cpp index ad82dfe..fb6bb2f 100644 --- a/Graphics2/TerrainNode.cpp +++ b/Graphics2/TerrainNode.cpp @@ -498,6 +498,52 @@ void TerrainNode::LoadTerrainTextures() )); } +void TerrainNode::PopulateTerrain(SceneGraphPointer currentSceneGraph, vector& nodesForPop, int xStep, int zStep, float heightLower, float heightUpper, float slopeLower, float slopeUpper) +{ + for (int z = 0; z < _gridRows; z += zStep) + { + for (int x = 0; x < _gridCols; x += xStep) + { + int currentIndex = ((z * _gridCols) + x) * 4; + + float totalHeights = 0.0f; + float totalSlope = 0.0f; + for (int si = 0; si < 4; si++) + { + totalHeights += _terrainVerts[currentIndex + si].Position.y; + totalSlope += _terrainVerts[currentIndex + si].Normal.y; + } + + float heightValue = totalHeights / 4.0f; + + if (heightValue >= heightLower && heightValue <= heightUpper) + { + float avgSlope = totalSlope / 4.0f; + + if (avgSlope >= slopeLower && avgSlope <= slopeUpper) + { + int nodeIndex = 0; + if (nodesForPop.size() > 1) + { + nodeIndex = rand() % nodesForPop.size(); + } + + float scale = (rand() % 100 * 0.01f) * nodesForPop[nodeIndex].scaleFactor; + + float xPos = x * _cellSizeX + _terrainStartX; + float yPos = heightValue - 1.0f; + float zPos = (-z + 1) * _cellSizeZ + _terrainStartZ; + + wstring nodeName = L"_" + to_wstring(z) + L"_" + to_wstring(x); + shared_ptr newNode = make_shared(nodesForPop[nodeIndex].nodeBaseName + nodeName, nodesForPop[nodeIndex].modelName); + newNode->SetWorldTransform(XMMatrixScaling(scale, scale, scale) * XMMatrixTranslation(xPos, yPos, zPos)); + currentSceneGraph->Add(newNode); + } + } + } + } +} + void TerrainNode::GenerateBlendMap() { RGBA snowTops = RGBA{ 0u, 0u, 0u, 255u }; @@ -507,7 +553,13 @@ void TerrainNode::GenerateBlendMap() vector colorSteps = {darkDirt, lightDirt, grassLand, grassLand, grassLand, snowTops}; - ColorGradient terrainBlendGradient = ColorGradient(80.0f, 620.0f, colorSteps); + float waterOffset = _waterHeight - 50.0f; + if (waterOffset < 0.0f) + { + waterOffset = 0.0f; + } + + ColorGradient terrainBlendGradient = ColorGradient(waterOffset, 820.0f, colorSteps); // Note that _numberOfRows and _numberOfColumns need to be setup // to the number of rows and columns in your grid in order for this @@ -538,24 +590,30 @@ void TerrainNode::GenerateBlendMap() int currentIndex = ((i * _gridCols) + j) * 4; float totalHeights = 0.0f; - float biggestSlope = 0.0f; + float totalSlope = 0.0f; for (int si = 0; si < 4; si++) { - totalHeights += _terrainVerts[currentIndex + si].Position.y; - if (_terrainVerts[currentIndex + si].Normal.y > biggestSlope) - { - biggestSlope = _terrainVerts[currentIndex + si].Normal.y; - } + totalHeights += _terrainVerts[currentIndex + si].Position.y; + totalSlope += _terrainVerts[currentIndex + si].Normal.y; } - + float avgHeight = totalHeights / 4.0f; + float avgSlope = totalSlope / 4.0f; RGBA currentBlend = terrainBlendGradient.GetRGBAValue(avgHeight); r = (BYTE)currentBlend.red; g = (BYTE)currentBlend.green; b = (BYTE)currentBlend.blue; - a = (BYTE)currentBlend.alpha; + a = (BYTE)currentBlend.alpha; + // Override the G channel if we are cliff height and slope angle + if (avgHeight > 500.0f) + { + if (avgSlope < 0.6f) + { + g = (BYTE)SharedMethods::Clamp(avgHeight - 450.0f, 0, 150); + } + } DWORD mapValue = (a << 24) + (b << 16) + (g << 8) + r; *blendMapPtr++ = mapValue; diff --git a/Graphics2/TerrainNode.h b/Graphics2/TerrainNode.h index 16ffaa2..91f36cd 100644 --- a/Graphics2/TerrainNode.h +++ b/Graphics2/TerrainNode.h @@ -8,7 +8,9 @@ #include "WICTextureLoader.h" #include "SharedMethods.h" #include "SceneNode.h" - +#include "SceneGraph.h" +#include "MeshNode.h" +#include "SplitMeshNode.h" typedef struct TerrainVertex { @@ -49,6 +51,8 @@ public: void Render(void); void virtual Shutdown(void); + void PopulateTerrain(SceneGraphPointer currentSceneGraph, vector& nodesForPop, int xStep, int zStep, float heightLower, float heightUpper, float slopeLower, float slopeUpper); + float GetHeightAtPoint(float x, float z, bool waterCollide = false); bool CheckXBoundary(float x); bool CheckZBoundary(float z);