private int[] CalculateBiomes(ChunkCoordinates coordinates, ChunkLandscape landscape) { // var biomes = BiomeProvider.GetBiomes().ToArray(); int worldX = coordinates.X << 4; int worldZ = coordinates.Z << 4; float[] weightedBiomes = new float[256]; var biomeData = new int[SampleArraySize * SampleArraySize]; for (int x = -SampleSize; x < SampleSize + 5; x++) { for (int z = -SampleSize; z < SampleSize + 5; z++) { var xx = worldX + ((x * 8f)); var zz = worldZ + ((z * 8f)); var temp = TemperatureNoise.GetValue(xx, zz); //Note for self: The temperature noise returns a value between -1 & 1 however we need the value to be between 0 & 2. //We do this by getting the absolute value (0 to 1) and multiplying it by 2. temp = MathF.Abs(temp) * 2f; var rain = MathF.Abs(RainfallNoise.GetValue(xx, zz)); if (temp < _lowestTemp) { _lowestTemp = temp; } if (temp > _highestTemp) { _highestTemp = temp; } if (rain < _lowestHumidity) { _lowestHumidity = rain; } if (rain > _highestHumidity) { _highestHumidity = rain; } _totalTemp += temp; _totalHumidity += rain; _totalLookups++; if (_totalLookups % 1024 == 0) { /* Console.Clear(); * * Console.WriteLine( * $"Average temperature: {_totalTemp / _totalLookups} Highest: {_highestTemp} Lowest: {_lowestTemp}"); * * Console.WriteLine( * $"Average humidity: {_totalHumidity / _totalLookups} Highest: {_highestHumidity} Lowest: {_lowestHumidity}"); * * Console.WriteLine($"Unique biomes: {_uniqueBiomes.Count}");*/ } biomeData[(x + SampleSize) * SampleArraySize + (z + SampleSize)] = (BiomeProvider.GetBiome( (float)temp, (float)rain).Id); } } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { int index = NoiseMap.GetIndex(x, z); float totalWeight = 0; for (int mapX = 0; mapX < SampleArraySize; mapX++) { for (int mapZ = 0; mapZ < SampleArraySize; mapZ++) { float weight = _weightings[mapX * SampleArraySize + mapZ][(x << 4) + z]; if (weight > 0) { totalWeight += weight; weightedBiomes[biomeData[mapX * SampleArraySize + mapZ]] += weight; } } } // normalize biome weights for (int biomeIndex = 0; biomeIndex < weightedBiomes.Length; biomeIndex++) { weightedBiomes[biomeIndex] /= totalWeight; } // combine mesa biomes // mesaCombiner.adjust(weightedBiomes); landscape.Noise[index] = 0f; float river = TerrainBase.GetRiverStrength(new BlockCoordinates(worldX + x, 0, worldZ + z), this); landscape.River[index] = -river; float maxWeight = 0f; for (int i = 0; i < weightedBiomes.Length; i++) { var value = weightedBiomes[i]; if (value > 0f) { var biome = BiomeProvider.GetBiome(i); landscape.Noise[index] += biome.RNoise( this, worldX + x, worldZ + z, value, river + 1f) * value; weightedBiomes[i] = 0f; if (value > maxWeight) { maxWeight = value; landscape.Biome[index] = biome; if (!_uniqueBiomes.Contains(biome.Id)) { _uniqueBiomes.TryAdd(biome.Id); // Console.WriteLine($"Unique biomes: {uniqueBiomes.Count}"); } } } } //landscape.Biome[index] = weightedBiomes.; // landscape.Biome[index] = BiomeProvider.GetBiome(i); //landscape.Biome[index] = BiomeProvider.GetBiome(); } } return(biomeData); }
private void FixBiomes(ChunkColumn column, ChunkLandscape landscape, int[] neighboring) { var orginalBiomes = landscape.Biome.ToArray(); ISimplexData2D jitterData = SimplexData2D.NewDisk(); BiomeBase[] jitteredBiomes = new BiomeBase[256]; BiomeBase jitterbiome, actualbiome; for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { int x = (column.X * 16) + i; int z = (column.Z * 16) + j; this.SimplexInstance(0).GetValue(x, z, jitterData); int pX = (int)Math.Round(x + jitterData.GetDeltaX() * BlendRadius); int pZ = (int)Math.Round(z + jitterData.GetDeltaY() * BlendRadius); actualbiome = landscape.Biome[(x & 15) * 16 + (z & 15)]; jitterbiome = landscape.Biome[(pX & 15) * 16 + (pZ & 15)]; jitteredBiomes[i * 16 + j] = (actualbiome.Config.SurfaceBlendIn && jitterbiome.Config.SurfaceBlendOut) ? jitterbiome : actualbiome; } } BiomeBase realisticBiome; int realisticBiomeId; var noise = landscape.Noise; var riverStrength = landscape.River; // currently just stuffs the genLayer into the jitter; for (int i = 0; i < MAX_BIOMES; i++) { realisticBiome = orginalBiomes[i]; bool canBeRiver = riverStrength[i] > 0.7; if (noise[i] > 61.5) { // replace jitteredBiomes[i] = realisticBiome; } else { // check for river if (canBeRiver && (realisticBiome.Type & BiomeType.Ocean) == 0 && (realisticBiome.Type & BiomeType.Swamp) == 0) { // make river jitteredBiomes[i] = BiomeProvider.GetBiome(realisticBiome.GetRiverBiome()); } else { // replace jitteredBiomes[i] = realisticBiome; } } } // SmoothingSearchStatus beachSearch = new SmoothingSearchStatus(BeachBiome); SmoothingSearchStatus landSearch = new SmoothingSearchStatus(LandBiome); /* beachSearch.SetNotHunted(); * beachSearch.SetAbsent(); * * landSearch.SetNotHunted(); * landSearch.SetAbsent();*/ // beachSearch.Hunt(neighboring); landSearch.Hunt(neighboring); float beachTop = 64.5f; for (int i = 0; i < MAX_BIOMES; i++) { float beachBottom = 61.5f; if (noise[i] < beachBottom || noise[i] > RiverAdjusted(beachTop, riverStrength[i])) { continue;// this block isn't beach level } if ((jitteredBiomes[i].Type & BiomeType.Swamp) != 0) { continue; } /* if (beachSearch.IsNotHunted()) * { * beachSearch.Hunt(neighboring); * landSearch.Hunt(neighboring); * }*/ // int foundBiome = beachSearch.Biomes[i]; // if (foundBiome != -1) { int nearestLandBiome = landSearch.Biomes[i]; if (nearestLandBiome > -1) { var foundBiome = BiomeProvider.GetBiome(nearestLandBiome).GetBeachBiome(); var biome = BiomeProvider.GetBiome(foundBiome); if (biome != null && biome.Terrain != null && biome.Surface != null) { jitteredBiomes[i] = biome; } } // // } } landscape.Biome = jitteredBiomes; }
private int[] CalculateBiomes(ChunkCoordinates coordinates, ChunkLandscape landscape) { int worldX = coordinates.X * 16; int worldZ = coordinates.Z * 16; float[] weightedBiomes = new float[256]; var biomeData = new int[SampleArraySize * SampleArraySize]; for (int x = -SampleSize; x < SampleSize + 5; x++) { for (int z = -SampleSize; z < SampleSize + 5; z++) { var temp = TemperatureNoise.GetValue(worldX + ((x * 8)), worldZ + ((z * 8))); var rain = RainfallNoise.GetValue(worldX + ((x * 8)), worldZ + ((z * 8))); biomeData[(x + SampleSize) * SampleArraySize + (z + SampleSize)] = (BiomeProvider.GetBiome((float)temp, (float)rain).Id); } } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { int index = NoiseMap.GetIndex(x, z); float totalWeight = 0; for (int mapX = 0; mapX < SampleArraySize; mapX++) { for (int mapZ = 0; mapZ < SampleArraySize; mapZ++) { float weight = _weightings[mapX * SampleArraySize + mapZ][x * 16 + z]; if (weight > 0) { totalWeight += weight; weightedBiomes[biomeData[mapX * SampleArraySize + mapZ]] += weight; } } } // normalize biome weights for (int biomeIndex = 0; biomeIndex < weightedBiomes.Length; biomeIndex++) { weightedBiomes[biomeIndex] /= totalWeight; } // combine mesa biomes // mesaCombiner.adjust(weightedBiomes); landscape.Noise[index] = 0f; float river = TerrainBase.GetRiverStrength(new BlockCoordinates(worldX + x, 0, worldZ + z), this); landscape.River[index] = -river; for (int i = 0; i < 256; i++) { var value = weightedBiomes[i]; if (value > 0f) { var biome = BiomeProvider.GetBiome(i); landscape.Noise[index] += biome.RNoise(this, worldX + x, worldZ + z, value, river + 1f) * value; landscape.Biome[index] = biome; // 0 for the next column weightedBiomes[i] = 0f; } } // landscape.Biome[index] = BiomeProvider.GetBiome(i); //landscape.Biome[index] = BiomeProvider.GetBiome(); } } for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { BlockCoordinates pos = new BlockCoordinates(worldX + (x - 7) * 8 + 4, 0, worldZ + (z - 7) * 8 + 4); // landscape.Biome[x * 16 + z] = BiomeProvider.GetBiome(pos.X, pos.Z); } } return(biomeData); }
private void InitBiomeProviders(int seed) { var biomeScale = 128f;// Preset.CoordinateScale; // var biomeScale = 8f * Preset.BiomeSize; INoiseModule distortionX = new SimplexPerlin(seed, NoiseQuality.Fast); distortionX = new PipeNoiseModule() { Primitive = distortionX, Frequency = 1f / 48.24345f }; INoiseModule distortionY = new SimplexPerlin(seed, NoiseQuality.Fast); distortionY = new PipeNoiseModule() { Primitive = distortionY, Frequency = 1f / 32.24145f }; // INoiseModule temperatureNoise = new SimplexPerlin(seed^3, NoiseQuality.Fast); /*temperatureNoise = new BillowNoiseModule() * { * Primitive = temperatureNoise, * Lacunarity = 2f, * Frequency = 0.25f, * OctaveCount = 1 * // Scale = 0.1f, * // Bias = 1f * // SpectralExponent = 0.8f, * // Offset = 1f, * // Gain = 2f * };*/ INoiseModule temperatureNoise = new SimplexPerlin(seed ^ 3, NoiseQuality.Fast); /* temperatureNoise = new OctaveNoise(temperatureNoise, 4) * { * Amplitude = 16f, * Frequency = 1.8f * }; */ temperatureNoise = new VoronoiNoseModule() { Primitive = temperatureNoise, Distance = false, Frequency = 0.343f,//0.125644f, Displacement = 1f, Size = 2, }; temperatureNoise = new ScaledNoiseModule(temperatureNoise) { ScaleX = 1f / biomeScale, ScaleY = 1f / biomeScale, ScaleZ = 1f / biomeScale }; temperatureNoise = new TurbulenceNoiseModule(temperatureNoise, distortionX, distortionY, distortionY, 16f); // temperatureNoise = new AverageSelectorModule(temperatureNoise, temperatureNoise); INoiseModule rainNoise = new SimplexPerlin(seed * seed ^ 2, NoiseQuality.Fast); rainNoise = new VoronoiNoseModule() { Primitive = rainNoise, Distance = false, Frequency = 0.22776f, Displacement = 1f, Size = 2 }; rainNoise = new ScaledNoiseModule(rainNoise) { ScaleX = 1f / biomeScale, ScaleY = 1f / biomeScale, ScaleZ = 1f / biomeScale }; rainNoise = new TurbulenceNoiseModule(rainNoise, distortionY, distortionX, distortionX, 16f); BiomeProvider = new BiomeProvider(); RainfallNoise = rainNoise; TemperatureNoise = temperatureNoise; }
private void InitBiomeProviders(int seed) { // var biomeScale = 32f * Preset.BiomeSize; var biomeScale = 8f * Preset.BiomeSize; SimplexPerlin temperaturePerlin = new SimplexPerlin(seed + seed * seed, NoiseQuality.Fast); INoiseModule temperatureNoise = new OctaveNoise(temperaturePerlin, 4) { Amplitude = 3f, Frequency = 0.535f }; temperatureNoise = new ScaledNoiseModule(temperatureNoise) { ScaleX = 1f / biomeScale, ScaleZ = 1f / biomeScale, ScaleY = 1f / biomeScale }; temperatureNoise = new VoronoiNoseModule() { Primitive = temperatureNoise, Distance = false, Frequency = 0.2325f, // SpectralExponent = 0.25f }; INoiseModule rainNoise = new SimplexPerlin(seed - seed * seed, NoiseQuality.Fast); rainNoise = new OctaveNoise(rainNoise, 4) { Amplitude = 3f, Frequency = 0.345f }; rainNoise = new ScaledNoiseModule(rainNoise) { ScaleX = 1f / biomeScale, ScaleZ = 1f / biomeScale, ScaleY = 1f / biomeScale }; rainNoise = new VoronoiNoseModule() { Primitive = rainNoise, Distance = false, Frequency = 0.25f, // SpectralExponent = 0.25f }; BiomeProvider = new BiomeProvider() { //RainfallProvider = rainNoise, //TemperatureProvider = temperatureNoise }; RainfallNoise = rainNoise; TemperatureNoise = temperatureNoise; /* TemperatureNoise = new SpacedCellularNoise(seed * seed) * { * Settings = new VoronoiSettings(3200.0) * }; * RainfallNoise = new SpacedCellularNoise(-seed) * { * Settings = new VoronoiSettings(3200.0) * };*/ }