public DistanceToMaterial ( |
||
cord | ||
vec | ||
matidx | byte | |
invert | bool | |
return | double |
public void makeroots(ref IMapHandler map, List <Vector3i> rootbases) { foreach (Vector3i coord in foliage_cords) { // First, set the threshhold for randomly selecting this // coordinate for root creation. double dist = Math.Sqrt(Math.Pow(coord[0] - Pos[0], 2) + Math.Pow(coord[2] - Pos[2], 2)); double ydist = coord[1] - Pos[1]; double value = (branchdensity * 220 * Height) / Math.Pow((ydist + dist), 3d); // Randomly skip roots, based on the above threshold if (value < rand.NextDouble()) { continue; } // initialize the internal variables from a selection of // starting locations. int ci = rand.Next(0, rootbases.Count - 1); Vector3i rootbase = rootbases[ci]; long rootx = rootbase[0]; long rootz = rootbase[1]; double rootbaseradius = rootbase[2]; // Offset the root origin location by a random amount // (radialy) from the starting location. double rndr = (Math.Sqrt(rand.NextDouble()) * rootbaseradius * .618); double rndang = rand.NextDouble() * 2 * Math.PI; int rndx = (int)(rndr * Math.Sin(rndang) + 0.5); int rndz = (int)(rndr * Math.Cos(rndang) + 0.5); int rndy = (int)(rand.NextDouble() * rootbaseradius * 0.5); Vector3i startcoord = new Vector3i(rootx + rndx, Pos[1] + rndy, rootz + rndz); // offset is the distance from the root base to the root tip. Vector3i offset = startcoord - coord; // If this is a mangrove tree, make the roots longer. if (SHAPE == "mangrove") { offset = (offset * 1.618) - 1.5; } Vector3i endcoord = startcoord + offset; double rootstartsize = (rootbaseradius * 0.618 * Math.Abs(offset[1]) / (Height * 0.618)); if (rootstartsize < 1.0) { rootstartsize = 1.0; } double endsize = 1.0; // If ROOTS is set to "tostone" or "hanging" we need to check // along the distance for collision with existing materials. if (ROOTS == "tostone" || ROOTS == "hanging") { double offlength = Math.Sqrt( Math.Pow(offset[0], 2) + Math.Pow(offset[1], 2) + Math.Pow(offset[2], 2)); if (offlength < 1) { continue; } double rootmid = endsize; // vec is a unit vector along the direction of the root. Vector3i vec = offset / offlength; byte searchindex; if (ROOTS == "tostone") { searchindex = 1; } else // Hanging { searchindex = 0; } // startdist is how many steps to travel before starting to // search for the material. It is used to ensure that large // roots will go some distance before changing directions // or stopping. double startdist = (int)(rand.NextDouble() * 6 * Math.Sqrt(rootstartsize) + 2.8); // searchstart is the coordinate where the search should begin Vector3i searchstart = (startcoord + startdist) * vec; // dist stores how far the search went (including searchstart) // before encountering the expected marterial. dist = startdist + map.DistanceToMaterial(searchstart, vec, searchindex); // If the distance to the materila is less than the length // of the root, change the end point of the root to where // the search found the material. if (dist < offlength) { // rootmid is the size of the crossection at endcoord. rootmid += (rootstartsize - endsize) * (1 - dist / offlength); } // endcoord is the midpoint for hanging roots, // and the endpoint for roots stopped by stone. endcoord = startcoord + (vec * dist); if (ROOTS == "hanging") { // remaining_dist is how far the root had left // to go when it was stopped. double remaining_dist = offlength - dist; // Initialize bottomcord to the stopping point of // the root, and then hang straight down // a distance of remaining_dist. Vector3i bottomcord = endcoord; bottomcord.Y += -(long)remaining_dist; // Make the hanging part of the hanging root. taperedlimb(ref map, endcoord, bottomcord, (int)rootmid, (int)endsize); } // make the beginning part of hanging or "tostone" roots taperedlimb(ref map, startcoord, endcoord, (int)rootstartsize, (int)rootmid); // If you aren't searching for stone or air, just make the root. } else { taperedlimb(ref map, startcoord, endcoord, (int)rootstartsize, (int)endsize); } } }
public void makeroots(ref IMapHandler map, List<Vector3i> rootbases) { foreach(Vector3i coord in foliage_cords) { // First, set the threshhold for randomly selecting this // coordinate for root creation. double dist = Math.Sqrt( Math.Pow(coord[0]-Pos[0],2) + Math.Pow(coord[2]-Pos[2],2)); double ydist = coord[1]-Pos[1]; double value = (branchdensity * 220 * Height)/Math.Pow((ydist + dist), 3d); // Randomly skip roots, based on the above threshold if(value < rand.NextDouble()) continue; // initialize the internal variables from a selection of // starting locations. int ci = rand.Next(0, rootbases.Count-1); Vector3i rootbase = rootbases[ci]; long rootx = rootbase[0]; long rootz = rootbase[1]; double rootbaseradius = rootbase[2]; // Offset the root origin location by a random amount // (radialy) from the starting location. double rndr = (Math.Sqrt(rand.NextDouble())*rootbaseradius*.618); double rndang = rand.NextDouble()*2*Math.PI; int rndx = (int)(rndr*Math.Sin(rndang) + 0.5); int rndz = (int)(rndr*Math.Cos(rndang) + 0.5); int rndy = (int)(rand.NextDouble()*rootbaseradius*0.5); Vector3i startcoord = new Vector3i(rootx+rndx,Pos[1]+rndy,rootz+rndz); // offset is the distance from the root base to the root tip. Vector3i offset = startcoord-coord; // If this is a mangrove tree, make the roots longer. if(SHAPE == "mangrove") { offset = (offset * 1.618) - 1.5; } Vector3i endcoord = startcoord+offset; double rootstartsize = (rootbaseradius*0.618* Math.Abs(offset[1])/(Height*0.618)); if(rootstartsize < 1.0) rootstartsize = 1.0; double endsize = 1.0; // If ROOTS is set to "tostone" or "hanging" we need to check // along the distance for collision with existing materials. if(ROOTS == "tostone" || ROOTS == "hanging") { double offlength = Math.Sqrt( Math.Pow(offset[0],2) + Math.Pow(offset[1],2) + Math.Pow(offset[2],2)); if(offlength < 1) continue; double rootmid = endsize; // vec is a unit vector along the direction of the root. Vector3i vec = offset/offlength; byte searchindex; if(ROOTS == "tostone") searchindex = 1; else // Hanging searchindex = 0; // startdist is how many steps to travel before starting to // search for the material. It is used to ensure that large // roots will go some distance before changing directions // or stopping. double startdist = (int)(rand.NextDouble()*6*Math.Sqrt(rootstartsize) + 2.8); // searchstart is the coordinate where the search should begin Vector3i searchstart = (startcoord + startdist) * vec; // dist stores how far the search went (including searchstart) // before encountering the expected marterial. dist = startdist + map.DistanceToMaterial(searchstart,vec,searchindex); // If the distance to the materila is less than the length // of the root, change the end point of the root to where // the search found the material. if(dist < offlength) // rootmid is the size of the crossection at endcoord. rootmid += (rootstartsize - endsize)*(1-dist/offlength); // endcoord is the midpoint for hanging roots, // and the endpoint for roots stopped by stone. endcoord = startcoord+(vec*dist); if(ROOTS == "hanging") { // remaining_dist is how far the root had left // to go when it was stopped. double remaining_dist = offlength - dist; // Initialize bottomcord to the stopping point of // the root, and then hang straight down // a distance of remaining_dist. Vector3i bottomcord = endcoord; bottomcord.Y += -(long)remaining_dist; // Make the hanging part of the hanging root. taperedlimb(ref map, endcoord, bottomcord, (int)rootmid, (int)endsize); } // make the beginning part of hanging or "tostone" roots taperedlimb(ref map, startcoord, endcoord, (int)rootstartsize, (int)rootmid); // If you aren't searching for stone or air, just make the root. } else { taperedlimb(ref map, startcoord, endcoord, (int)rootstartsize, (int)endsize); } } }