RoughRavines: Added per-height radius modifier. Ledges!
This commit is contained in:
parent
472f70a676
commit
960ab982b9
@ -22,6 +22,7 @@ class cRoughRavine :
|
|||||||
public:
|
public:
|
||||||
cRoughRavine(int a_Seed, int a_Size, float a_CenterWidth, float a_Roughness, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
|
cRoughRavine(int a_Seed, int a_Size, float a_CenterWidth, float a_Roughness, int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) :
|
||||||
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
|
super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
|
||||||
|
m_Seed(a_Seed + 100),
|
||||||
m_Noise(a_Seed + 100),
|
m_Noise(a_Seed + 100),
|
||||||
m_Roughness(a_Roughness)
|
m_Roughness(a_Roughness)
|
||||||
{
|
{
|
||||||
@ -41,6 +42,9 @@ public:
|
|||||||
// Calculate the points in between, recursively:
|
// Calculate the points in between, recursively:
|
||||||
SubdivideLine(0, Half);
|
SubdivideLine(0, Half);
|
||||||
SubdivideLine(Half, Max);
|
SubdivideLine(Half, Max);
|
||||||
|
|
||||||
|
// Initialize the per-height radius modifiers:
|
||||||
|
InitPerHeightRadius(a_GridX, a_GridZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -63,6 +67,8 @@ protected:
|
|||||||
};
|
};
|
||||||
typedef std::vector<sRavineDefPoint> sRavineDefPoints;
|
typedef std::vector<sRavineDefPoint> sRavineDefPoints;
|
||||||
|
|
||||||
|
int m_Seed;
|
||||||
|
|
||||||
cNoise m_Noise;
|
cNoise m_Noise;
|
||||||
|
|
||||||
int m_MaxSize;
|
int m_MaxSize;
|
||||||
@ -71,6 +77,9 @@ protected:
|
|||||||
|
|
||||||
float m_Roughness;
|
float m_Roughness;
|
||||||
|
|
||||||
|
/** Number to add to the radius based on the height. This creates the "ledges" in the ravine walls. */
|
||||||
|
float m_PerHeightRadius[cChunkDef::Height];
|
||||||
|
|
||||||
|
|
||||||
/** Recursively subdivides the line between the points of the specified index.
|
/** Recursively subdivides the line between the points of the specified index.
|
||||||
Sets the midpoint to the center of the line plus or minus a random offset, then calls itself for each half
|
Sets the midpoint to the center of the line plus or minus a random offset, then calls itself for each half
|
||||||
@ -114,6 +123,29 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InitPerHeightRadius(int a_GridX, int a_GridZ)
|
||||||
|
{
|
||||||
|
int h = 0;
|
||||||
|
while (h < cChunkDef::Height)
|
||||||
|
{
|
||||||
|
m_Noise.SetSeed(m_Seed + h);
|
||||||
|
int rnd = m_Noise.IntNoise2DInt(a_GridX, a_GridZ) / 13;
|
||||||
|
int NumBlocks = (rnd % 3) + 2;
|
||||||
|
rnd = rnd / 4;
|
||||||
|
float Val = (float)(rnd % 256) / 128 - 1; // Random float in range [-1, +1]
|
||||||
|
if (h + NumBlocks > cChunkDef::Height)
|
||||||
|
{
|
||||||
|
NumBlocks = cChunkDef::Height - h;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < NumBlocks; i++)
|
||||||
|
{
|
||||||
|
m_PerHeightRadius[h + i] = Val;
|
||||||
|
}
|
||||||
|
h += NumBlocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
|
virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
|
||||||
{
|
{
|
||||||
int BlockStartX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
int BlockStartX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
|
||||||
@ -123,18 +155,20 @@ protected:
|
|||||||
for (sRavineDefPoints::const_iterator itr = m_DefPoints.begin(), end = m_DefPoints.end(); itr != end; ++itr)
|
for (sRavineDefPoints::const_iterator itr = m_DefPoints.begin(), end = m_DefPoints.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
(ceilf (itr->m_X + itr->m_Radius) < BlockStartX) ||
|
(ceilf (itr->m_X + itr->m_Radius + 2) < BlockStartX) ||
|
||||||
(floorf(itr->m_X - itr->m_Radius) > BlockEndX) ||
|
(floorf(itr->m_X - itr->m_Radius - 2) > BlockEndX) ||
|
||||||
(ceilf (itr->m_Z + itr->m_Radius) < BlockStartZ) ||
|
(ceilf (itr->m_Z + itr->m_Radius + 2) < BlockStartZ) ||
|
||||||
(floorf(itr->m_Z - itr->m_Radius) > BlockEndZ)
|
(floorf(itr->m_Z - itr->m_Radius - 2) > BlockEndZ)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Cannot intersect, bail out early
|
// Cannot intersect, bail out early
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Carve out a cylinder around the xz point, m_Radius in diameter, from Bottom to Top:
|
// Carve out a cylinder around the xz point, up to (m_Radius + 2) in diameter, from Bottom to Top:
|
||||||
float RadiusSq = itr->m_Radius * itr->m_Radius; // instead of doing sqrt for each distance, we do sqr of the radius
|
// On each height level, use m_PerHeightRadius[] to modify the actual radius used
|
||||||
|
// EnlargedRadiusSq is the square of the radius enlarged by the maximum m_PerHeightRadius offset - anything outside it will never be touched.
|
||||||
|
float RadiusSq = (itr->m_Radius + 2) * (itr->m_Radius + 2);
|
||||||
float DifX = BlockStartX - itr->m_X; // substitution for faster calc
|
float DifX = BlockStartX - itr->m_X; // substitution for faster calc
|
||||||
float DifZ = BlockStartZ - itr->m_Z; // substitution for faster calc
|
float DifZ = BlockStartZ - itr->m_Z; // substitution for faster calc
|
||||||
for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
|
for (int x = 0; x < cChunkDef::Width; x++) for (int z = 0; z < cChunkDef::Width; z++)
|
||||||
@ -147,37 +181,44 @@ protected:
|
|||||||
}
|
}
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
|
// If the column is outside the enlarged radius, bail out completely
|
||||||
float DistSq = (DifX + x) * (DifX + x) + (DifZ + z) * (DifZ + z);
|
float DistSq = (DifX + x) * (DifX + x) + (DifZ + z) * (DifZ + z);
|
||||||
if (DistSq <= RadiusSq)
|
if (DistSq > RadiusSq)
|
||||||
{
|
{
|
||||||
int Top = std::min((int)ceilf(itr->m_Top), +cChunkDef::Height);
|
continue;
|
||||||
for (int y = std::max((int)floorf(itr->m_Bottom), 1); y <= Top; y++)
|
|
||||||
{
|
|
||||||
switch (a_ChunkDesc.GetBlockType(x, y, z))
|
|
||||||
{
|
|
||||||
// Only carve out these specific block types
|
|
||||||
case E_BLOCK_DIRT:
|
|
||||||
case E_BLOCK_GRASS:
|
|
||||||
case E_BLOCK_STONE:
|
|
||||||
case E_BLOCK_COBBLESTONE:
|
|
||||||
case E_BLOCK_GRAVEL:
|
|
||||||
case E_BLOCK_SAND:
|
|
||||||
case E_BLOCK_SANDSTONE:
|
|
||||||
case E_BLOCK_NETHERRACK:
|
|
||||||
case E_BLOCK_COAL_ORE:
|
|
||||||
case E_BLOCK_IRON_ORE:
|
|
||||||
case E_BLOCK_GOLD_ORE:
|
|
||||||
case E_BLOCK_DIAMOND_ORE:
|
|
||||||
case E_BLOCK_REDSTONE_ORE:
|
|
||||||
case E_BLOCK_REDSTONE_ORE_GLOWING:
|
|
||||||
{
|
|
||||||
a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Top = std::min((int)ceilf(itr->m_Top), +cChunkDef::Height);
|
||||||
|
for (int y = std::max((int)floorf(itr->m_Bottom), 1); y <= Top; y++)
|
||||||
|
{
|
||||||
|
if ((itr->m_Radius + m_PerHeightRadius[y]) * (itr->m_Radius + m_PerHeightRadius[y]) < DistSq)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (a_ChunkDesc.GetBlockType(x, y, z))
|
||||||
|
{
|
||||||
|
// Only carve out these specific block types
|
||||||
|
case E_BLOCK_DIRT:
|
||||||
|
case E_BLOCK_GRASS:
|
||||||
|
case E_BLOCK_STONE:
|
||||||
|
case E_BLOCK_COBBLESTONE:
|
||||||
|
case E_BLOCK_GRAVEL:
|
||||||
|
case E_BLOCK_SAND:
|
||||||
|
case E_BLOCK_SANDSTONE:
|
||||||
|
case E_BLOCK_NETHERRACK:
|
||||||
|
case E_BLOCK_COAL_ORE:
|
||||||
|
case E_BLOCK_IRON_ORE:
|
||||||
|
case E_BLOCK_GOLD_ORE:
|
||||||
|
case E_BLOCK_DIAMOND_ORE:
|
||||||
|
case E_BLOCK_REDSTONE_ORE:
|
||||||
|
case E_BLOCK_REDSTONE_ORE_GLOWING:
|
||||||
|
{
|
||||||
|
a_ChunkDesc.SetBlockType(x, y, z, E_BLOCK_AIR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
} // switch (BlockType)
|
||||||
|
} // for y
|
||||||
} // for x, z - a_BlockTypes
|
} // for x, z - a_BlockTypes
|
||||||
} // for itr - m_Points[]
|
} // for itr - m_Points[]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user