fCraft.Forester.ProceduralTree.MakeRoots C# (CSharp) Method

MakeRoots() private method

private MakeRoots ( IList rootbases ) : void
rootbases IList
return void
            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 );
                    }
                }
            }