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); } } }
public Vector3I(Vector3F other) { X = (int)other.X; Y = (int)other.Y; Z = (int)other.Z; }
static int DistanceToBlock(Map map, Vector3F coord, Vector3F vec, Block blockType) { return(DistanceToBlock(map, coord, vec, blockType, false)); }
public Vector3F Cross(Vector3F b) { return(new Vector3F((Y * b.Z) - (Z * b.Y), (Z * b.X) - (X * b.Z), (X * b.Y) - (Y * b.X))); }
public float Dot(Vector3F b) { return((X * b.X) + (Y * b.Y) + (Z * b.Z)); }
public int CompareTo(Vector3F other) { return(Math.Sign(LengthSquared - other.LengthSquared)); }
public void ModifyDirection(ref Vector3F direction, Block currentBlock) { }
public Sphere(float x, float y, float z, float radius) { Origin = new Vector3F(x, y, z); Radius = radius; }