Added better perlin terrain generation
Added function to scatter models onto the terrain
This commit is contained in:
@ -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<TexturedCubeNode> cube = make_shared<TexturedCubeNode>(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<HeightMapTerrainNode> terrainNode = make_shared<HeightMapTerrainNode>(L"MainTerrain", L"Textures\\Example_HeightMap.raw", L"RandomWords");
|
||||
shared_ptr<PerlinTerrainNode> terrainNode = make_shared<PerlinTerrainNode>(L"MainTerrain", L"LovelyCat", 10.0f, 20.0f, 1.0f, 1);
|
||||
shared_ptr<PerlinTerrainNode> terrainNode = make_shared<PerlinTerrainNode>(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<SceneGraph> treeGroupA = make_shared<SceneGraph>(L"TreeGroupA");
|
||||
|
||||
shared_ptr<MeshNode> treeNode1 = make_shared<MeshNode>(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<MeshNode> treeNode2 = make_shared<MeshNode>(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<MeshNode> treeNode3 = make_shared<MeshNode>(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<MeshNode> treeNode4 = make_shared<MeshNode>(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<ControlledSplitMeshNode> plane1Node = make_shared<ControlledSplitMeshNode>(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<TerrainNode> mainTerrain = dynamic_pointer_cast<TerrainNode>(sceneGraph->Find(L"MainTerrain"));
|
||||
|
||||
if (!_initDone && mainTerrain != nullptr)
|
||||
{
|
||||
vector<TerrainPopNode> 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<SceneGraph> treeGroupA = make_shared<SceneGraph>(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<TerrainNode> mainTerrain = dynamic_pointer_cast<TerrainNode>(sceneGraph->Find(L"MainTerrain"));
|
||||
XMVECTOR currentCameraPos = GetCamera()->GetCameraPosition();
|
||||
GetCamera()->Update();
|
||||
if (mainTerrain != nullptr)
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ public:
|
||||
void UpdateSceneGraph();
|
||||
|
||||
private:
|
||||
bool _initDone = false;
|
||||
|
||||
bool _boosting = false;
|
||||
float _boostMultiplier = 1;
|
||||
float _boostMin = 1;
|
||||
|
27
Graphics2/Models/Boat/NWW83WKS0AJC0W7C1XP0CFCET.mtl
Normal file
27
Graphics2/Models/Boat/NWW83WKS0AJC0W7C1XP0CFCET.mtl
Normal file
@ -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
|
||||
|
BIN
Graphics2/Models/Boat/boat_fishing02.jpeg
Normal file
BIN
Graphics2/Models/Boat/boat_fishing02.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
BIN
Graphics2/Models/Boat/boat_fishing02.jpg
Normal file
BIN
Graphics2/Models/Boat/boat_fishing02.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
BIN
Graphics2/Models/Tree/Bush1.fbx
Normal file
BIN
Graphics2/Models/Tree/Bush1.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Bush2.fbx
Normal file
BIN
Graphics2/Models/Tree/Bush2.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Bush3.fbx
Normal file
BIN
Graphics2/Models/Tree/Bush3.fbx
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 134 KiB |
BIN
Graphics2/Models/Tree/Grass1.fbx
Normal file
BIN
Graphics2/Models/Tree/Grass1.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Grass2.fbx
Normal file
BIN
Graphics2/Models/Tree/Grass2.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Grass3.fbx
Normal file
BIN
Graphics2/Models/Tree/Grass3.fbx
Normal file
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 111 KiB |
BIN
Graphics2/Models/Tree/Rock1.fbx
Normal file
BIN
Graphics2/Models/Tree/Rock1.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Rock2.fbx
Normal file
BIN
Graphics2/Models/Tree/Rock2.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Rock3.fbx
Normal file
BIN
Graphics2/Models/Tree/Rock3.fbx
Normal file
Binary file not shown.
Binary file not shown.
BIN
Graphics2/Models/Tree/Tree1.fbx
Normal file
BIN
Graphics2/Models/Tree/Tree1.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Tree2.fbx
Normal file
BIN
Graphics2/Models/Tree/Tree2.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Tree3.fbx
Normal file
BIN
Graphics2/Models/Tree/Tree3.fbx
Normal file
Binary file not shown.
BIN
Graphics2/Models/Tree/Tree4.fbx
Normal file
BIN
Graphics2/Models/Tree/Tree4.fbx
Normal file
Binary file not shown.
@ -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<float>(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<float>(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);
|
||||
}
|
@ -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<int> 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<unsigned char> _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<unsigned char> _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();
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "DirectXCore.h"
|
||||
#include <string>
|
||||
|
||||
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);
|
||||
|
@ -498,6 +498,52 @@ void TerrainNode::LoadTerrainTextures()
|
||||
));
|
||||
}
|
||||
|
||||
void TerrainNode::PopulateTerrain(SceneGraphPointer currentSceneGraph, vector<TerrainPopNode>& 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<MeshNode> newNode = make_shared<MeshNode>(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<RGBA> 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<int>(avgHeight - 450.0f, 0, 150);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD mapValue = (a << 24) + (b << 16) + (g << 8) + r;
|
||||
*blendMapPtr++ = mapValue;
|
||||
|
@ -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<TerrainPopNode>& 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);
|
||||
|
Reference in New Issue
Block a user