// Use this for initialization void Start() { ProbMeter p = new ProbMeter(new double[] { 0, 2, 4, 8 }, new double[] { 2, 1, 1 }); Debug.Log(p.getValue(.25)); Debug.Log(p.getValue(.5)); Debug.Log(p.getValue(1)); int[] count = { 0, 0, 0, 0 }; for (int i = 0; i < 100000000; i++) { float num = PlanetBuilder.eDist(.5, 10000, Random.value); if (num < 10) { count[0]++; } else if (num < 100) { count[1]++; } else if (num < 1000) { count[2]++; } else if (num < 10000) { count[3]++; } } print(count[0] + " " + count[1] + " " + count[2] + " " + count[3]); }
//builds a simple texture for a base feature //also return its abundance and if it's temperature dependent private static ModuleBase buildTexture(Dictionary <Sub, double> subList, out float abundance, int lev, System.Random rand) { //build a compound texture if (rand.NextDouble() < .3 && lev < 3) { float ab1, ab2; ModuleBase text1 = buildTexture(subList, out ab1, lev + 1, rand); ModuleBase text2 = buildTexture(subList, out ab2, lev + 1, rand); double controlScale = eDist(1, 1000, rand.NextDouble()); //the base control for the selector that adds two new features ModuleBase baseControl = getGradientNoise(hnProb, rand.NextDouble(), controlScale, rand); //baseControl = new Cylinders(1/controlScale); double amount = getAmount(ab1, ab2, rand.NextDouble()); //the abundance of this texture is that of the most abundand substance within it abundance = Mathf.Max(ab1, ab2); return(addModule(text1, text2, baseControl, amount, 0)); } else //get a solid texture { Sub newSub; if (rand.NextDouble() < .5 && subList.Count > 0) //get an already used substance { //newSub = subList[Random.Range(0, subList.Count)]; //newSub = subList.Keys List <Sub> keyList = new List <Sub>(subList.Keys); newSub = keyList[rand.Next(0, keyList.Count)]; } else //get a new substance { //random substance based on universal abundance newSub = (Sub)Substance.surfProb.getValue(rand.NextDouble()); //add the new substance to the list if (!subList.ContainsKey(newSub)) { //its universal abundance double uniAb = Substance.subs[newSub].surfAb; planAbundProb.Values = new double[] { 0, uniAb *.5, Mathf.Min((float)uniAb * 2f, 100f), 100 }; //its planetary abundance double planab = planAbundProb.getValue(rand.NextDouble()); subList.Add(newSub, planab); } } abundance = (float)subList[newSub]; return(new Const(newSub)); } }
//returns the amount of rocks in a surface unit given the subs it contains and its position public override int getAmount(List <Sub> subs, WorldPos pos, double random) { //if the rock is substance dependent and the substance is not present, don't build any if (subDependent && !subs.Contains(substance)) { return(0); } //TODO: possibly dependent on a noise function return((int)amountProb.getValue(random)); }
/// <summary> /// returns the amount to add one module to another based on their abundance in the universe /// </summary> /// <returns>The amount.</returns> /// <param name="ab1">the abundance of 1 substance/feature</param> /// <param name="ab2">Ab2.</param> private static double getAmount(float ab1, float ab2, double per) { //percent abundance of feature 1 float ab1percent = ab1 / (ab1 + ab2); //reset abundProb values to account for these two features //TODO: add another node featAbundProb.Values = new double[] { 0, ab1percent *.6, Mathf.Min(ab1percent * 1.3f, .90f), 1 }; //possible TODO: later amount will be somewhat dependant on the feature number(feature #6 will have an average lower amount than feature #2) return(featAbundProb.getValue(per)); }
public override Mesh buildObject(int seed) { System.Random rand = new System.Random(seed); MeshBuilder mb = new MeshBuilder(); float size = (float)sizeprob.getValue(rand.NextDouble()); ProcMesh.addCube(mb, Vector3.zero, size, size, size, substance); ModMesh.displace(mb, size * (float)dispProb.getValue(rand.NextDouble())); return(mb.getMesh()); }
//a feature is either some noise with a texture or a composition of two features //the final terrain of a planet is a very complex feature made up of many features //this is funny: a feature is a composition of features; recursive logic and the function is recursive! //What the heck? that's not funny //noiseScale is the max scale of noise from the inner iterations to prevent large mountains from being selected on small scales public static void buildFeature(System.Random rand, out ModuleBase terrain, out ModuleBase texture, out float noiseScale, int lev, Dictionary <Sub, double> subList, out float abundance, bool needsTexture) { //Debug.Log("level " + lev); if (rand.NextDouble() < 1.3 / lev && lev < 4) { ModuleBase terrain1, terrain2, texture1, texture2; float nScale1, nScale2; float ab1, ab2; //the relative abundance of the substances of each feature /*bool textureThis = false; * //possibly create a mulitfeature texture * if(needsTexture && Random.value<.2) * { * textureThis = true; * needsTexture = false; * }*/ buildFeature(rand, out terrain1, out texture1, out nScale1, lev + 1, subList, out ab1, needsTexture); buildFeature(rand, out terrain2, out texture2, out nScale2, lev + 1, subList, out ab2, needsTexture); noiseScale = Mathf.Max(nScale1, nScale2); //TODO: some probability that edist lower bound is lower than noisescale double controlScale = eDist(Mathf.Max(noiseScale, 100), 1000000, rand.NextDouble()); //the base control for the selector that adds two new features ModuleBase baseControl = getGradientNoise(hnProb, rand.NextDouble(), controlScale, rand); //baseControl = new Scale(50, 1, 1, baseControl); //create a cache module because this value will be calculated twice (once for terrain and once for texture)(possibly) baseControl = new Cache(baseControl); //make possible edge controller //loop and make inner controllers //the amount to add of this feature to the biome(0 is add none, 1 is completely cover) //NOTE: later amount will be somewhat dependant on the feature number(feature #6 will have an average lower amount than feature #2) double amount = getAmount(ab1, ab2, rand.NextDouble()); double falloff = rand.NextDouble(); terrain = addModule(terrain1, terrain2, baseControl, amount, falloff); //if(textureThis) // texture = buildTexture(subList, texture = addModule(texture1, texture2, baseControl, amount, 0); //the abundance of this final feature is that of the most abundand substance within it abundance = Mathf.Max(ab1, ab2); } else { //scale is the inverse of the frequency and is used to influence amplitude //float scale = eDist(80, 20000, rand.NextDouble()); float scale = (float)baseNoiseScale.getValue(rand.NextDouble()); //scale = 100; //the starting noise for the final feature that will be modified terrain = getGradientNoise(hnProb, rand.NextDouble(), scale, rand); //apply some random modification to the primordial noise //possibly in the future multiple mods can be applied int numPreMods = (int)preModAmount.getValue(rand.NextDouble()); for (int i = 0; i < numPreMods; i++) { terrain = modMod(terrain, (int)preModType.getValue(rand.NextDouble()), rand); } //the amplidude or max height of the terrain //NOTE: later will be related to the frequency double amplitude = eDist(1, scale * amplitudeProb.getValue(rand.NextDouble()), rand.NextDouble()); //randDoub(2, 100); //bias is the number added to the noise before multiplying //-1 makes canyons/indentions, 1 makes all feautures above sea level //NOTE: later make a greater chance to be 1 or -1 double bias = biasProb.getValue(rand.NextDouble()); //.1;//randDoub(-1, 1); //now apply the bias and amplitude terrain = new ScaleBias(amplitude, bias * amplitude, terrain); //apply some random post modifications int numMods = (int)postModAmount.getValue(rand.NextDouble()); for (int i = 0; i < numMods; i++) { terrain = modMod(terrain, (int)postModType.getValue(rand.NextDouble()), rand); } //texture = Random.value<.7 ? buildTexture(subList, out abundance, 1) : null; //build a texture if it still needs one //texture = needsTexture ? buildTexture(subList, out abundance, 1, rand) : null; texture = buildTexture(subList, out abundance, 1, rand); noiseScale = scale; } }