private void MakeRoots( IList<RootBase> rootbases )
{
if ( rootbases.Count == 0 )
return;
foreach ( Vector3I coord in FoliageCoords ) {
float dist = ( float )Math.Sqrt( Sqr( coord[0] - Pos[0] ) + Sqr( coord[2] - Pos[2] ) );
float ydist = coord[1] - Pos[1];
float value = ( BranchDensity * 220 * Height ) / Cub( ydist + dist );
if ( value < Args.Rand.NextDouble() )
continue;
RootBase rootbase = rootbases[Args.Rand.Next( 0, rootbases.Count )];
int rootx = rootbase.X;
int rootz = rootbase.Z;
float rootbaseradius = rootbase.Radius;
float rndr = ( float )( Math.Sqrt( Args.Rand.NextDouble() ) * rootbaseradius * .618 );
float rndang = ( float )( Args.Rand.NextDouble() * 2 * Math.PI );
int rndx = ( int )( rndr * Math.Sin( rndang ) + .5 );
int rndz = ( int )( rndr * Math.Cos( rndang ) + .5 );
int rndy = ( int )( Args.Rand.NextDouble() * rootbaseradius * .5 );
Vector3I startcoord = new Vector3I {
X = rootx + rndx,
Z = rootz + rndz,
Y = Pos[1] + rndy
};
Vector3F offset = new Vector3F( startcoord - coord );
if ( Args.Shape == TreeShape.Mangrove ) {
// offset = [int(val * 1.618 - 1.5) for val in offset]
offset = offset * 1.618f - HalfBlock * 3;
}
Vector3I endcoord = startcoord + offset.RoundDown();
float rootstartsize = ( float )( rootbaseradius * .618 * Math.Abs( offset[1] ) / ( Height * .618 ) );
if ( rootstartsize < 1 )
rootstartsize = 1;
const float endsize = 1;
if ( Args.Roots == RootMode.ToStone ||
Args.Roots == RootMode.Hanging ) {
float offlength = offset.Length;
if ( offlength < 1 )
continue;
float rootmid = endsize;
Vector3F vec = offset / offlength;
Block searchIndex = Block.Air;
if ( Args.Roots == RootMode.ToStone ) {
searchIndex = Block.Stone;
} else if ( Args.Roots == RootMode.Hanging ) {
searchIndex = Block.Air;
}
int startdist = ( int )( Args.Rand.NextDouble() * 6 * Math.Sqrt( rootstartsize ) + 2.8 );
Vector3I searchstart = new Vector3I( startcoord + vec * startdist );
dist = startdist + DistanceToBlock( Args.Map, new Vector3F( searchstart ), vec, searchIndex );
if ( dist < offlength ) {
rootmid += ( rootstartsize - endsize ) * ( 1 - dist / offlength );
endcoord = new Vector3I( startcoord + vec * dist );
if ( Args.Roots == RootMode.Hanging ) {
float remainingDist = offlength - dist;
Vector3I bottomcord = endcoord;
bottomcord[1] -= ( int )remainingDist;
TaperedLimb( endcoord, bottomcord, rootmid, endsize );
}
}
TaperedLimb( startcoord, endcoord, rootstartsize, rootmid );
} else {
TaperedLimb( startcoord, endcoord, rootstartsize, endsize );
}
}
}