Added better perlin terrain generation

Added function to scatter models onto the terrain
This commit is contained in:
iDunnoDev
2022-05-11 21:03:19 +01:00
committed by iDunnoDev
parent f6bba67897
commit b856b43209
26 changed files with 248 additions and 126 deletions

View File

@ -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;