void FindTrees( List<Tree> treelist ) { int treeheight = args.Height; for( int x = 0; x < args.InMap.WidthX; x++ ) { for( int z = 0; z < args.InMap.WidthY; z++ ) { int y = args.InMap.Height - 1; while( true ) { int foliagetop = args.InMap.SearchColumn( x, z, args.FoliageBlock, y ); if( foliagetop < 0 ) break; y = foliagetop; Vector3i trunktop = new Vector3i( x, z, y - 1 ); int height = DistanceToBlock( args.InMap, new Vector3f( trunktop ), new Vector3f( 0, 0, -1 ), args.TrunkBlock, true ); if( height == 0 ) { y--; continue; } y -= height; if( args.Height > 0 ) { height = args.Rand.Next( treeheight - args.HeightVariation, treeheight + args.HeightVariation + 1 ); } treelist.Add( new Tree { Args = args, Pos = new Vector3i( x, z, y ), Height = height } ); y--; } } } }
public void Copy( Tree other ) { Args = other.Args; Pos = other.Pos; Height = other.Height; }
void MakeRoots(RootBase[] rootbases) { 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.Length)]; 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 = offset * 1.618f - 1.5f; } Vector3i endcoord = startcoord + new Vector3i(offset); float rootstartsize = (float)(rootbaseradius * .618 * Math.Abs(offset[1]) / (height * .618)); if (rootstartsize < 1) rootstartsize = 1; float endsize = 1; if (args.ROOTS == RootMode.ToStone || args.ROOTS == RootMode.Hanging) { float offlength = offset.GetLength(); if (offlength < 1) continue; float rootmid = endsize; Vector3f vec = offset / offlength; int searchIndex = TILETYPE_AIR; if (args.ROOTS == RootMode.ToStone) { searchIndex = TILETYPE_STONE; } else if (args.ROOTS == RootMode.Hanging) { searchIndex = TILETYPE_AIR; } int startdist = (int)(args.rand.NextDouble() * 6 * Math.Sqrt(rootstartsize) + 2.8); Vector3i searchstart = new Vector3i(startcoord + vec * startdist); dist = startdist + DistanceToBlock(args.inMap, 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 remaining_dist = offlength - dist; Vector3i bottomcord = endcoord; bottomcord[1] -= (int)remaining_dist; TaperedLimb(endcoord, bottomcord, rootmid, endsize); } } TaperedLimb(startcoord, endcoord, rootstartsize, rootmid); } else { TaperedLimb(startcoord, endcoord, rootstartsize, endsize); } } }
void MakeBranches() { int topy = pos[1] + (int)(trunkHeight + .5); float endrad = trunkRadius * (1 - trunkHeight / (float)height); if (endrad < 1) endrad = 1; foreach (Vector3i coord in foliageCoords) { float dist = (float)Math.Sqrt(Sqr(coord.x - pos.x) + Sqr(coord.z - pos.z)); float ydist = coord[1] - pos[1]; float value = (branchDensity * 220 * height) / Cub(ydist + dist); if (value < args.rand.NextDouble()) continue; int posy = coord[1]; float slope = (float)(branchSlope + (.5 - args.rand.NextDouble()) * .16); float branchy, basesize; if (coord[1] - dist * slope > topy) { float threshold = 1 / (float)height; if (args.rand.NextDouble() < threshold) continue; branchy = topy; basesize = endrad; } else { branchy = posy - dist * slope; basesize = endrad + (trunkRadius - endrad) * (topy - branchy) / trunkHeight; } float startsize = (float)(basesize * (1 + args.rand.NextDouble()) * .618 * Math.Pow(dist / (float)height, .618)); float rndr = (float)(Math.Sqrt(args.rand.NextDouble()) * basesize * .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); Vector3i startcoord = new Vector3i { x = pos[0] + rndx, z = pos[2] + rndz, y = (int)branchy }; if (startsize < 1) startsize = 1; float endsize = 1; TaperedLimb(startcoord, coord, startsize, endsize); } }
public int CompareTo(Vector3i other) { return(Math.Sign(LengthSquared - LengthSquared)); }
public Vector3i(Vector3i other) { x = other.x; z = other.z; y = other.y; }
void MakeRoots( RootBase[] rootbases ) { if( rootbases.Length == 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.Length )]; 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 = offset * 1.618f - 1.5f; } Vector3i endcoord = startcoord + new Vector3i( offset ); 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.InMap, 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 ); } } }
void TaperedLimb( Vector3i start, Vector3i end, float startSize, float endSize ) { Vector3i delta = end - start; int primidx = delta.GetLargestComponent(); int maxdist = delta[primidx]; if( maxdist == 0 ) return; int primsign = (maxdist > 0 ? 1 : -1); int secidx1 = (primidx - 1) % 3; int secidx2 = (primidx + 1) % 3; int secdelta1 = delta[secidx1]; float secfac1 = secdelta1 / (float)delta[primidx]; int secdelta2 = delta[secidx2]; float secfac2 = secdelta2 / (float)delta[primidx]; Vector3i coord = new Vector3i(); int endoffset = delta[primidx] + primsign; for( int primoffset = 0; primoffset < endoffset; primoffset += primsign ) { int primloc = start[primidx] + primoffset; int secloc1 = (int)(start[secidx1] + primoffset * secfac1); int secloc2 = (int)(start[secidx2] + primoffset * secfac2); coord[primidx] = primloc; coord[secidx1] = secloc1; coord[secidx2] = secloc2; float primdist = Math.Abs( delta[primidx] ); float radius = endSize + (startSize - endSize) * Math.Abs( delta[primidx] - primoffset ) / primdist; CrossSection( coord, radius, primidx, Args.TrunkBlock ); } return; }
void PlantRainForestTrees(List <Tree> treelist, int gx, int gy, int gz, int chunksize) { int treeheight = args.HEIGHT; int existingtreenum = treelist.Count; int remainingtrees = args.TREECOUNT - existingtreenum; int short_tree_fraction = 6; int tries = 0; for (int i = 0; i < remainingtrees;) { if (tries++ > 10) { return; } float randomfac = (float)((Math.Sqrt(args.rand.NextDouble()) * 1.618 - .618) * args.HEIGHTVARIATION + .5); int height; if (i % short_tree_fraction == 0) { height = (int)(treeheight + randomfac); } else { height = (int)(treeheight - randomfac); } Vector3i xyz = RandomTreeLoc(gx, gy, gz, chunksize, height); if (xyz.y < 0) { continue; } xyz.y++; bool displaced = false; foreach (Tree othertree in treelist) { Vector3i other_loc = othertree.pos; float otherheight = othertree.height; int tallx = other_loc[0]; int tallz = other_loc[2]; float dist = (float)Math.Sqrt(Sqr(tallx - xyz.x + .5) + Sqr(tallz - xyz.z + .5)); float threshold = (otherheight + height) * .193f; if (dist < threshold) { displaced = true; break; } } if (displaced) { continue; } treelist.Add(new RainforestTree { args = args, pos = xyz, height = height }); i++; } }
void MakeRoots(RootBase[] rootbases) { 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.Length)]; 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 = offset * 1.618f - 1.5f; } Vector3i endcoord = startcoord + new Vector3i(offset); float rootstartsize = (float)(rootbaseradius * .618 * Math.Abs(offset[1]) / (height * .618)); if (rootstartsize < 1) { rootstartsize = 1; } float endsize = 1; if (args.ROOTS == RootMode.ToStone || args.ROOTS == RootMode.Hanging) { float offlength = offset.GetLength(); if (offlength < 1) { continue; } float rootmid = endsize; Vector3f vec = offset / offlength; int searchIndex = TILETYPE_AIR; if (args.ROOTS == RootMode.ToStone) { searchIndex = TILETYPE_STONE; } else if (args.ROOTS == RootMode.Hanging) { searchIndex = TILETYPE_AIR; } int startdist = (int)(args.rand.NextDouble() * 6 * Math.Sqrt(rootstartsize) + 2.8); Vector3i searchstart = new Vector3i(startcoord + vec * startdist); dist = startdist + DistanceToBlock(args.inMap, 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 remaining_dist = offlength - dist; Vector3i bottomcord = endcoord; bottomcord[1] -= (int)remaining_dist; TaperedLimb(endcoord, bottomcord, rootmid, endsize); } } TaperedLimb(startcoord, endcoord, rootstartsize, rootmid); } else { TaperedLimb(startcoord, endcoord, rootstartsize, endsize); } } }
void MakeBranches() { int topy = pos[1] + (int)(trunkHeight + .5); float endrad = trunkRadius * (1 - trunkHeight / (float)height); if (endrad < 1) { endrad = 1; } foreach (Vector3i coord in foliageCoords) { float dist = (float)Math.Sqrt(Sqr(coord.x - pos.x) + Sqr(coord.z - pos.z)); float ydist = coord[1] - pos[1]; float value = (branchDensity * 220 * height) / Cub(ydist + dist); if (value < args.rand.NextDouble()) { continue; } int posy = coord[1]; float slope = (float)(branchSlope + (.5 - args.rand.NextDouble()) * .16); float branchy, basesize; if (coord[1] - dist * slope > topy) { float threshold = 1 / (float)height; if (args.rand.NextDouble() < threshold) { continue; } branchy = topy; basesize = endrad; } else { branchy = posy - dist * slope; basesize = endrad + (trunkRadius - endrad) * (topy - branchy) / trunkHeight; } float startsize = (float)(basesize * (1 + args.rand.NextDouble()) * .618 * Math.Pow(dist / (float)height, .618)); float rndr = (float)(Math.Sqrt(args.rand.NextDouble()) * basesize * .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); Vector3i startcoord = new Vector3i { x = pos[0] + rndx, z = pos[2] + rndz, y = (int)branchy }; if (startsize < 1) { startsize = 1; } float endsize = 1; TaperedLimb(startcoord, coord, startsize, endsize); } }
void MakeRoots(RootBase[] rootbases) { if (rootbases.Length == 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.Length)]; 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 = offset * 1.618f - 1.5f; } Vector3i endcoord = startcoord + new Vector3i(offset); 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.InMap, 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); } } }
void MakeBranches() { int topy = Pos[1] + (int)(TrunkHeight + .5); float endrad = TrunkRadius * (1 - TrunkHeight / Height); if (endrad < 1) { endrad = 1; } foreach (Vector3i coord in FoliageCoords) { float dist = (float)Math.Sqrt(Sqr(coord.X - Pos.X) + Sqr(coord.Z - Pos.Z)); float ydist = coord[1] - Pos[1]; float value = (BranchDensity * 220 * Height) / Cub(ydist + dist); if (value < Args.Rand.NextDouble()) { continue; } int posy = coord[1]; float slope = (float)(BranchSlope + (.5 - Args.Rand.NextDouble()) * .16); float branchy, basesize; if (coord[1] - dist * slope > topy) { float threshold = 1 / (float)Height; if (Args.Rand.NextDouble() < threshold) { continue; } branchy = topy; basesize = endrad; } else { branchy = posy - dist * slope; basesize = endrad + (TrunkRadius - endrad) * (topy - branchy) / TrunkHeight; } float startsize = (float)(basesize * (1 + Args.Rand.NextDouble()) * .618 * Math.Pow(dist / Height, .618)); float rndr = (float)(Math.Sqrt(Args.Rand.NextDouble()) * basesize * .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); Vector3i startcoord = new Vector3i { X = Pos[0] + rndx, Z = Pos[2] + rndz, Y = (int)branchy }; if (startsize < 1) { startsize = 1; } const float endsize = 1; TaperedLimb(startcoord, coord, startsize, endsize); } }
public void Copy(Tree other) { Args = other.Args; Pos = other.Pos; Height = other.Height; }
void CrossSection( Vector3i center, float radius, int diraxis, Block matidx ) { int rad = (int)(radius + .618); int secidx1 = (diraxis - 1) % 3; int secidx2 = (diraxis + 1) % 3; Vector3i coord = new Vector3i(); for( int off1 = -rad; off1 <= rad; off1++ ) { for( int off2 = -rad; off2 <= rad; off2++ ) { float thisdist = (float)Math.Sqrt( Sqr( Math.Abs( off1 ) + .5 ) + Sqr( Math.Abs( off2 ) + .5 ) ); if( thisdist > radius ) continue; int pri = center[diraxis]; int sec1 = center[secidx1] + off1; int sec2 = center[secidx2] + off2; coord[diraxis] = pri; coord[secidx1] = sec1; coord[secidx2] = sec2; Args.OutMap.SetBlock( coord, matidx ); } } }
void FoliageCluster( Vector3i center ) { int y = center[1]; foreach( float i in FoliageShape ) { CrossSection( new Vector3i( center[0], center[2], y ), i, 1, Args.FoliageBlock ); y++; } }
public void Copy(Tree other) { args = other.args; pos = other.pos; height = other.height; }
void MakeBranches() { int topy = Pos[1] + (int)(TrunkHeight + .5); float endrad = TrunkRadius * (1 - TrunkHeight / Height); if( endrad < 1 ) endrad = 1; foreach( Vector3i coord in FoliageCoords ) { float dist = (float)Math.Sqrt( Sqr( coord.X - Pos.X ) + Sqr( coord.Z - Pos.Z ) ); float ydist = coord[1] - Pos[1]; float value = (BranchDensity * 220 * Height) / Cub( ydist + dist ); if( value < Args.Rand.NextDouble() ) continue; int posy = coord[1]; float slope = (float)(BranchSlope + (.5 - Args.Rand.NextDouble()) * .16); float branchy, basesize; if( coord[1] - dist * slope > topy ) { float threshold = 1 / (float)Height; if( Args.Rand.NextDouble() < threshold ) continue; branchy = topy; basesize = endrad; } else { branchy = posy - dist * slope; basesize = endrad + (TrunkRadius - endrad) * (topy - branchy) / TrunkHeight; } float startsize = (float)(basesize * (1 + Args.Rand.NextDouble()) * .618 * Math.Pow( dist / Height, .618 )); float rndr = (float)(Math.Sqrt( Args.Rand.NextDouble() ) * basesize * .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); Vector3i startcoord = new Vector3i { X = Pos[0] + rndx, Z = Pos[2] + rndz, Y = (int)branchy }; if( startsize < 1 ) startsize = 1; const float endsize = 1; TaperedLimb( startcoord, coord, startsize, endsize ); } }
void FindTrees(List<Tree> treelist, int gx, int gy, int gz, int chunksize) { return;//TODO Z int treeheight = args.HEIGHT; //for (int x = 0; x < args.inMap.MapSizeX; x++) for (int x = gx; x < gx + chunksize; x++) { // for (int z = 0; z < args.inMap.MapSizeY; z++) for (int z = gy; z < gy + chunksize; gy++) { int y = args.inMap.MapSizeZ - 1; while (true) { int foliagetop = MapUtil.SearchColumn(args.inMap, x, z, TILETYPE_LEAVES, y); if (foliagetop < 0) break; y = foliagetop; Vector3i trunktop = new Vector3i(x, z, y - 1); int height = DistanceToBlock(args.inMap, new Vector3f(trunktop), new Vector3f(0, 0, -1), TILETYPE_LOG, true); if (height == 0) { y--; continue; } y -= height; if (args.HEIGHT > 0) { height = args.rand.Next(treeheight - args.HEIGHTVARIATION, treeheight + args.HEIGHTVARIATION + 1); } treelist.Add(new Tree { args = args, pos = new Vector3i(x, z, y), height = height }); y--; } } } }
void FoliageCluster(Vector3i center) { int y = center[1]; foreach (float i in foliageShape) { CrossSection(new Vector3i(center[0], center[2], y), i, 1, TILETYPE_LEAVES); y++; } }
public Vector3f(Vector3i other) { x = other.x; y = other.z; h = other.y; }
public Vector3f(Vector3i other) { X = other.X; Y = other.Z; Z = other.Y; }