2014-07-26 18:03:26 -04:00
// RoughRavines.cpp
// Implements the cRoughRavines class representing the rough ravine generator
# include "Globals.h"
# include "RoughRavines.h"
////////////////////////////////////////////////////////////////////////////////
// cRoughRavine:
class cRoughRavine :
public cGridStructGen : : cStructure
{
typedef cGridStructGen : : cStructure super ;
public :
2014-07-27 07:54:27 -04:00
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 ) :
2014-07-26 18:03:26 -04:00
super ( a_GridX , a_GridZ , a_OriginX , a_OriginZ ) ,
m_Noise ( a_Seed + 100 ) ,
2014-07-27 07:54:27 -04:00
m_Roughness ( a_Roughness )
2014-07-26 18:03:26 -04:00
{
// Create the basic structure - 2 lines meeting at the centerpoint:
2014-07-27 07:54:27 -04:00
int Max = 2 * a_Size ;
int Half = a_Size ; // m_DefPoints[Half] will be the centerpoint
m_DefPoints . resize ( Max + 1 ) ;
2014-07-26 18:03:26 -04:00
int rnd = m_Noise . IntNoise2DInt ( a_OriginX , a_OriginZ ) / 7 ;
2014-07-27 07:54:27 -04:00
float Len = ( float ) a_Size ;
2014-07-26 18:03:26 -04:00
float Angle = ( float ) rnd ; // Angle is in radians, will be wrapped in the "sin" and "cos" operations
float OfsX = sin ( Angle ) * Len ;
float OfsZ = cos ( Angle ) * Len ;
2014-07-27 07:54:27 -04:00
m_DefPoints [ 0 ] . Set ( a_OriginX - OfsX , a_OriginZ - OfsZ , 1 , 42 , 34 ) ;
m_DefPoints [ Half ] . Set ( ( float ) a_OriginX , ( float ) a_OriginZ , a_CenterWidth , 62 , 16 ) ;
m_DefPoints [ Max ] . Set ( a_OriginX + OfsX , a_OriginZ + OfsZ , 1 , 44 , 32 ) ;
2014-07-26 18:03:26 -04:00
// Calculate the points in between, recursively:
SubdivideLine ( 0 , Half ) ;
2014-07-27 07:54:27 -04:00
SubdivideLine ( Half , Max ) ;
2014-07-26 18:03:26 -04:00
}
protected :
struct sRavineDefPoint
{
float m_X ;
float m_Z ;
float m_Radius ;
float m_Top ;
float m_Bottom ;
void Set ( float a_X , float a_Z , float a_Radius , float a_Top , float a_Bottom )
{
m_X = a_X ;
m_Z = a_Z ;
m_Radius = a_Radius ;
m_Top = a_Top ;
m_Bottom = a_Bottom ;
}
} ;
typedef std : : vector < sRavineDefPoint > sRavineDefPoints ;
cNoise m_Noise ;
int m_MaxSize ;
sRavineDefPoints m_DefPoints ;
2014-07-27 07:54:27 -04:00
float m_Roughness ;
2014-07-26 18:03:26 -04:00
/** 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
of the new line . */
void SubdivideLine ( int a_Idx1 , int a_Idx2 )
{
// Calculate the midpoint:
const sRavineDefPoint & p1 = m_DefPoints [ a_Idx1 ] ;
const sRavineDefPoint & p2 = m_DefPoints [ a_Idx2 ] ;
float MidX = ( p1 . m_X + p2 . m_X ) / 2 ;
float MidZ = ( p1 . m_Z + p2 . m_Z ) / 2 ;
float MidR = ( p1 . m_Radius + p2 . m_Radius ) / 2 + 0.1f ;
float MidT = ( p1 . m_Top + p2 . m_Top ) / 2 ;
float MidB = ( p1 . m_Bottom + p2 . m_Bottom ) / 2 ;
// Adjust the midpoint by a small amount of perpendicular vector in a random one of its two directions:
float dx = p2 . m_X - p1 . m_X ;
float dz = p2 . m_Z - p1 . m_Z ;
if ( ( m_Noise . IntNoise2DInt ( ( int ) MidX , ( int ) MidZ ) / 11 ) % 2 = = 0 )
{
2014-07-27 07:54:27 -04:00
MidX + = dz * m_Roughness ;
MidZ - = dx * m_Roughness ;
2014-07-26 18:03:26 -04:00
}
else
{
2014-07-27 07:54:27 -04:00
MidX - = dz * m_Roughness ;
MidZ + = dx * m_Roughness ;
2014-07-26 18:03:26 -04:00
}
int MidIdx = ( a_Idx1 + a_Idx2 ) / 2 ;
m_DefPoints [ MidIdx ] . Set ( MidX , MidZ , MidR , MidT , MidB ) ;
// Recurse the two halves, if they are worth recursing:
if ( MidIdx - a_Idx1 > 1 )
{
SubdivideLine ( a_Idx1 , MidIdx ) ;
}
if ( a_Idx2 - MidIdx > 1 )
{
SubdivideLine ( MidIdx , a_Idx2 ) ;
}
}
virtual void DrawIntoChunk ( cChunkDesc & a_ChunkDesc ) override
{
int BlockStartX = a_ChunkDesc . GetChunkX ( ) * cChunkDef : : Width ;
int BlockStartZ = a_ChunkDesc . GetChunkZ ( ) * cChunkDef : : Width ;
int BlockEndX = BlockStartX + cChunkDef : : Width ;
int BlockEndZ = BlockStartZ + cChunkDef : : Width ;
for ( sRavineDefPoints : : const_iterator itr = m_DefPoints . begin ( ) , end = m_DefPoints . end ( ) ; itr ! = end ; + + itr )
{
if (
( ceilf ( itr - > m_X + itr - > m_Radius ) < BlockStartX ) | |
( floorf ( itr - > m_X - itr - > m_Radius ) > BlockEndX ) | |
( ceilf ( itr - > m_Z + itr - > m_Radius ) < BlockStartZ ) | |
( floorf ( itr - > m_Z - itr - > m_Radius ) > BlockEndZ )
)
{
// Cannot intersect, bail out early
continue ;
}
// Carve out a cylinder around the xz point, m_Radius 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
float DifX = BlockStartX - itr - > m_X ; // 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 + + )
{
# ifdef _DEBUG
// DEBUG: Make the roughravine shapepoints visible on a single layer (so that we can see with Minutor what's going on)
if ( ( DifX + x = = 0 ) & & ( DifZ + z = = 0 ) )
{
a_ChunkDesc . SetBlockType ( x , 4 , z , E_BLOCK_LAPIS_ORE ) ;
}
# endif // _DEBUG
float DistSq = ( DifX + x ) * ( DifX + x ) + ( DifZ + z ) * ( DifZ + z ) ;
if ( DistSq < = RadiusSq )
{
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 + + )
{
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 ;
}
}
}
} // for x, z - a_BlockTypes
} // for itr - m_Points[]
}
} ;
////////////////////////////////////////////////////////////////////////////////
// cRoughRavines:
2014-07-27 07:54:27 -04:00
cRoughRavines : : cRoughRavines (
int a_Seed ,
int a_MaxSize , int a_MinSize ,
float a_MaxCenterWidth , float a_MinCenterWidth ,
float a_MaxRoughness , float a_MinRoughness ,
int a_GridSize , int a_MaxOffset
) :
2014-07-26 18:03:26 -04:00
super ( a_Seed , a_GridSize , a_GridSize , a_MaxOffset , a_MaxOffset , a_MaxSize , a_MaxSize , 64 ) ,
m_Seed ( a_Seed ) ,
2014-07-27 07:54:27 -04:00
m_MaxSize ( a_MaxSize ) ,
m_MinSize ( a_MinSize ) ,
m_MaxCenterWidth ( a_MaxCenterWidth ) ,
m_MinCenterWidth ( a_MinCenterWidth ) ,
m_MaxRoughness ( a_MaxRoughness ) ,
m_MinRoughness ( a_MinRoughness )
2014-07-26 18:03:26 -04:00
{
2014-07-27 07:54:27 -04:00
if ( m_MinSize > m_MaxSize )
{
std : : swap ( m_MinSize , m_MaxSize ) ;
std : : swap ( a_MinSize , a_MaxSize ) ;
}
if ( m_MaxSize < 16 )
2014-07-26 18:03:26 -04:00
{
m_MaxSize = 16 ;
LOGWARNING ( " RoughRavines: MaxSize too small, adjusting request from %d to %d " , a_MaxSize , m_MaxSize ) ;
}
2014-07-27 07:54:27 -04:00
if ( m_MinSize < 16 )
{
m_MinSize = 16 ;
LOGWARNING ( " RoughRavines: MinSize too small, adjusting request from %d to %d " , a_MinSize , m_MinSize ) ;
}
if ( m_MinSize = = m_MaxSize )
{
m_MaxSize = m_MinSize + 1 ;
}
2014-07-26 18:03:26 -04:00
}
cGridStructGen : : cStructurePtr cRoughRavines : : CreateStructure ( int a_GridX , int a_GridZ , int a_OriginX , int a_OriginZ )
{
2014-07-27 07:54:27 -04:00
int Size = m_MinSize + ( m_Noise . IntNoise2DInt ( a_GridX , a_GridZ ) / 7 ) % ( m_MaxSize - m_MinSize ) ; // Random int from m_MinSize to m_MaxSize
float CenterWidth = m_MinCenterWidth + abs ( m_Noise . IntNoise2D ( a_GridX , a_GridZ + 10 ) ) * ( m_MaxCenterWidth - m_MinCenterWidth ) ; // Random float from m_MinCenterWidth to m_MaxCenterWidth
float Roughness = m_MinRoughness + abs ( m_Noise . IntNoise2D ( a_GridX + 10 , a_GridZ ) ) * ( m_MaxRoughness - m_MinRoughness ) ; // Random float from m_MinRoughness to m_MaxRoughness
return cStructurePtr ( new cRoughRavine ( m_Seed , Size , CenterWidth , Roughness , a_GridX , a_GridZ , a_OriginX , a_OriginZ ) ) ;
2014-07-26 18:03:26 -04:00
}