private BiomeCenter GenerateBiomeCenter(SectionCoord coord) { BiomeCenter center = new BiomeCenter(); center.coord = coord; NotRandom.RNG rng = new NotRandom.RNG(NotRandom.Hash2Int(seedHash, center.coord.GetHashCode())); float nx = center.coord.x * biomeCenterSpacing + ((rng.Value() * maxBiomeCenterOffset * 2) - maxBiomeCenterOffset); float nz = center.coord.z * biomeCenterSpacing + ((rng.Value() * maxBiomeCenterOffset * 2) - maxBiomeCenterOffset); center.center = new Vector3(nx, 1f, nz); int index = (int)(rng.ValueUInt() % totalBiomeFrequency); for (int i = 0; i < biomes.Count; i++) { if (index >= 0 && index < biomes[i].relativeFrequency) { center.biome = biomes[i]; break; } index -= biomes[i].relativeFrequency; } return(center); }
public void StartGeneration() { #if UNITY_SERVER return; #endif if (genStarted) { return; } genStarted = true; if (seed == null) { seed = ""; } seedHash = NotRandom.HashString(seed); if (biomes == null || biomes.Count == 0) { biomes = Resources.LoadAll <Biome>("Biomes").ToList(); } int maxHeightmapOctaves = 0; if (biomes != null && biomes.Count > 0) { for (int i = 0; i < biomes.Count; i++) { totalBiomeFrequency += biomes[i].relativeFrequency; if (biomes[i].heightmapOctaves > maxHeightmapOctaves) { maxHeightmapOctaves = biomes[i].heightmapOctaves; } } } offsets = new float[maxHeightmapOctaves, 2]; NotRandom.RNG rng = new NotRandom.RNG(seedHash); for (int i = 0; i < maxHeightmapOctaves; i++) { for (int j = 0; j < 2; j++) { offsets[i, j] = (rng.Value() * maxOffset * 2) - maxOffset; } } detailOffsets = new float[numDetailOctaves, 2]; for (int i = 0; i < numDetailOctaves; i++) { for (int j = 0; j < 2; j++) { detailOffsets[i, j] = (rng.Value() * maxOffset * 2) - maxOffset; } } SetAutomaticUpdates(automaticUpdatesStart); }
private List <TreeInstance> GenerateTreeInstances(SectionCoord coord, out List <TreePrototypeData> treePrototypes) { treePrototypes = new List <TreePrototypeData>(); List <TreeInstance> treeInstances = new List <TreeInstance>(); float cellSize = minTreeDistance / Mathf.Sqrt(2); int numCells = Mathf.CeilToInt(genSettings.length / cellSize); int unprocessed = -1; int noTree = -2; int[,] trees = new int[numCells, numCells]; Vector3[,] points = new Vector3[numCells, numCells]; NotRandom.RNG rng = new NotRandom.RNG(NotRandom.Hash2Int(seedHash, coord.GetHashCode())); List <Vector3> toProcess = new List <Vector3>(); List <Vector3> processed = new List <Vector3>(); List <Vector3> selected = new List <Vector3>(); List <TreePrototypeData> selectedTree = new List <TreePrototypeData>(); Vector3 test, next; List <BiomeStrength> biomes; Biome b = null; int p, ax, az, anx, anz, annx, annz, range, tree, totalTreeFreq; int maxX, maxZ, maxRange; float bx, bz, a, r, str; bool canTree; next = new Vector3(rng.Value() * (genSettings.length - minBorderTreeDistance * 2) + minBorderTreeDistance, 0f, rng.Value() * (genSettings.length - minBorderTreeDistance * 2) + minBorderTreeDistance); anx = Mathf.FloorToInt(next.x / cellSize); anz = Mathf.FloorToInt(next.z / cellSize); maxRange = Mathf.CeilToInt(maxMinTreeDistance / cellSize); range = Mathf.CeilToInt(minTreeDistance / cellSize); trees[anx, anz] = unprocessed; points[anx, anz] = next; toProcess.Add(next); while (toProcess.Count > 0) { p = (int)(rng.ValueUInt() % toProcess.Count); test = toProcess[p]; toProcess.RemoveAt(p); ax = Mathf.FloorToInt(test.x / cellSize); az = Mathf.FloorToInt(test.z / cellSize); canTree = true; maxX = Mathf.Min(maxRange, numCells - 1 - ax); maxZ = Mathf.Min(maxRange, numCells - 1 - az); for (int x = Mathf.Max(-maxRange, -ax); canTree && x <= maxX; x++) { for (int z = Mathf.Max(-maxRange, -az); canTree && z <= maxZ; z++) { anx = ax + x; anz = az + z; tree = trees[anx, anz]; if (tree > 0 && Vector3.Distance(test, points[anx, anz]) < selectedTree[tree - 1].minDistance) { canTree = false; } } } if (canTree) { bx = (coord.x - 0.5f) * genSettings.length + test.x; bz = (coord.z - 0.5f) * genSettings.length + test.z; biomes = GetBiomes(new Vector3(bx, 0f, bz)); if (biomes.Count == 1) { b = biomes[0].biome; str = biomes[0].strength; } else { b = null; str = 0f; for (int i = 0; i < biomes.Count; i++) { if (b == null) { b = biomes[i].biome; str = biomes[i].strength; } else { if (biomes[i].strength > str) { b = biomes[i].biome; str = biomes[i].strength; } } } } if (str < minBiomeTreeStrength || b == null || b.treePrototypes == null || b.treePrototypes.Count == 0) { canTree = false; } } if (canTree && b != null) { totalTreeFreq = 0; for (int i = 0; i < b.treePrototypes.Count; i++) { totalTreeFreq += b.treePrototypes[i].relativeFrequency; } int index = (int)(rng.ValueUInt() % totalTreeFreq); for (int i = 0; i < b.treePrototypes.Count; i++) { if (index >= 0 && index < b.treePrototypes[i].relativeFrequency) { selectedTree.Add(b.treePrototypes[i]); selected.Add(test); trees[ax, az] = selectedTree.Count; break; } index -= b.treePrototypes[i].relativeFrequency; } } for (int i = 0; i < treeTestPoints; i++) { a = rng.Value(); r = rng.Value(); r = r * minTreeDistance + minTreeDistance; next = new Vector3(test.x + r * Mathf.Cos(a * 2 * Mathf.PI), 0f, test.z + r * Mathf.Sin(a * 2 * Mathf.PI)); if (next.x < minBorderTreeDistance || next.z < minBorderTreeDistance || next.x > genSettings.length - minBorderTreeDistance || next.z > genSettings.length - minBorderTreeDistance) { continue; } anx = Mathf.FloorToInt(next.x / cellSize); anz = Mathf.FloorToInt(next.z / cellSize); if (trees[anx, anz] != 0) { continue; } canTree = true; maxX = Mathf.Min(range, numCells - 1 - anx); maxZ = Mathf.Min(range, numCells - 1 - anz); for (int x = Mathf.Max(-range, -anx); canTree && x <= maxX; x++) { for (int z = Mathf.Max(-range, -anz); canTree && z <= maxZ; z++) { annx = anx + x; annz = anz + z; if (trees[annx, annx] != 0 && Vector3.Distance(next, points[annx, annz]) < minTreeDistance) { canTree = false; } } } if (canTree) { toProcess.Add(next); trees[anx, anz] = unprocessed; points[anx, anz] = next; } } processed.Add(test); if (trees[ax, az] < 1) { trees[ax, az] = noTree; } } TreeInstance ti; TreePrototypeData tpd; for (int i = 0; i < selected.Count; i++) { tpd = selectedTree[i]; if (!treePrototypes.Contains(tpd)) { treePrototypes.Add(tpd); } ti = new TreeInstance(); ti.color = tpd.color; ti.lightmapColor = tpd.lightmapColor; ti.prototypeIndex = treePrototypes.IndexOf(tpd); ti.position = selected[i] / genSettings.length; ti.heightScale = rng.Value() * (tpd.maxHeightScale - tpd.minHeightScale) + tpd.minHeightScale; ti.widthScale = rng.Value() * (tpd.maxWidthScale - tpd.minWidthScale) + tpd.minWidthScale; ti.rotation = rng.Value() * 2 * Mathf.PI; treeInstances.Add(ti); } return(treeInstances); }