public static byte[] Export(TerrainTile[,] tiles) { List<TerrainTile> dict = new List<TerrainTile>(); int w = tiles.GetLength(0); int h = tiles.GetLength(1); byte[] dat = new byte[w * h * 3]; int idx = 0; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { TerrainTile tile = tiles[x, y]; short i = (short)dict.IndexOf(tile); if (i == -1) { i = (short)dict.Count; dict.Add(tile); } dat[idx] = (byte)(i & 0xff); dat[idx + 1] = (byte)(i >> 8); dat[idx + 2] = (byte)tile.Elevation; idx += 3; } MemoryStream ms = new MemoryStream(); using (BinaryWriter wtr = new BinaryWriter(ms)) { wtr.Write((short)dict.Count); foreach (var i in dict) { wtr.Write(i.TileId); wtr.Write(i.TileObj ?? ""); wtr.Write(i.Name ?? ""); wtr.Write((byte)i.Terrain); wtr.Write((byte)i.Region); //wtr.Write((byte)i.Elevation); } wtr.Write(w); wtr.Write(h); wtr.Write(dat); } byte[] buff = ZlibStream.CompressBuffer(ms.ToArray()); byte[] ret = new byte[buff.Length + 1]; Buffer.BlockCopy(buff, 0, ret, 1, buff.Length); ret[0] = 2; return ret; }
//https://code.google.com/p/imagelibrary/source/browse/trunk/Filters/GaussianBlurFilter.cs //Blur the elevation static void BlurElevation(TerrainTile[,] tiles, double radius) { int w = tiles.GetLength(0); int h = tiles.GetLength(1); int shift, source; int blurDiam = (int)Math.Pow(radius, 2); int gaussWidth = (blurDiam * 2) + 1; double[] kernel = CreateKernel(gaussWidth, blurDiam); // Calculate the sum of the Gaussian kernel double gaussSum = 0; for (int n = 0; n < gaussWidth; n++) { gaussSum += kernel[n]; } // Scale the Gaussian kernel for (int n = 0; n < gaussWidth; n++) { kernel[n] = kernel[n] / gaussSum; } //premul = kernel[k] / gaussSum; // Create an X & Y pass buffer float[,] gaussPassX = new float[w, h]; // Do Horizontal Pass for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { // Iterate through kernel for (int k = 0; k < gaussWidth; k++) { // Get pixel-shift (pixel dist between dest and source) shift = k - blurDiam; // Basic edge clamp source = x + shift; if (source <= 0 || source >= w) { source = x; } // Combine source and destination pixels with Gaussian Weight gaussPassX[x, y] = (float)(gaussPassX[x, y] + tiles[source, y].Elevation * kernel[k]); } } } // Do Vertical Pass for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { tiles[x, y].Elevation = 0; // Iterate through kernel for (int k = 0; k < gaussWidth; k++) { // Get pixel-shift (pixel dist between dest and source) shift = k - blurDiam; // Basic edge clamp source = y + shift; if (source <= 0 || source >= h) { source = y; } // Combine source and destination pixels with Gaussian Weight tiles[x, y].Elevation = (float)(tiles[x, y].Elevation + (gaussPassX[x, source]) * kernel[k]); } } } }
void Randomize(TerrainTile[,] buff) { int w = buff.GetLength(0); int h = buff.GetLength(1); TerrainTile[,] tmp = (TerrainTile[,])buff.Clone(); for (int y = 10; y < h - 10; y++) for (int x = 10; x < w - 10; x++) { var tile = buff[x, y]; if (tile.TileId == TileTypes.Water && tile.Elevation >= elevationThreshold[3]) tile.TileId = TileTypes.SnowRock; else if (tile.TileId != TileTypes.Water && tile.TileId != TileTypes.Road && tile.TileId != TileTypes.Beach && tile.TileId != TileTypes.MovingWater && tile.TileId != TileTypes.DeepWater) { var id = tmp[x + rand.Next(-3, 4), y + rand.Next(-3, 4)].TileId; while (id == TileTypes.Water || id == TileTypes.Road || id == TileTypes.Beach || id == TileTypes.MovingWater || id == TileTypes.DeepWater) id = tmp[x + rand.Next(-3, 4), y + rand.Next(-3, 4)].TileId; tile.TileId = id; } //if (tile.TileId == TileTypes.Beach) // tile.Region = TileRegion.Spawn; string biome = tile.Biome; if (tile.TileId == TileTypes.Beach) biome = "beach"; else if (tile.TileId == TileTypes.MovingWater) biome = "coast"; var biomeObj = Decoration.GetDecor(biome, rand); if (biomeObj != null) { tile.TileObj = biomeObj; var size = Decoration.GetSize(biomeObj, rand); if (size != null) tile.Name = "size:" + size; } float elevation = 0; int c = 0; for (int dy = -1; dy <= 1; dy++) for (int dx = -1; dx <= 1; dx++) { if (x + dx < 0 || x + dx >= w || y + dy < 0 || y + dy >= h) continue; elevation += tmp[x + dx, y + dy].Elevation; c++; } tile.Elevation = elevation / c; buff[x, y] = tile; } }
void ComputeSpawnTerrains(TerrainTile[,] buff) { int w = buff.GetLength(0); int h = buff.GetLength(1); for (int y = 0; y < w; y++) for (int x = 0; x < h; x++) { var tile = buff[x, y]; tile.Terrain = GetBiomeTerrain(tile); buff[x, y] = tile; } }
void AddNoiseAndBiome(TerrainTile[,] buff, Dictionary<MapPolygon, double> moist) { int w = buff.GetLength(0); int h = buff.GetLength(1); var elevationNoise = new Noise(rand.Next()); var moistureNoise = new Noise(rand.Next()); //var elevationNoise = PerlinNoise.GetPerlinNoise(rand.Next(), 256, 256, 2); //var moistureNoise = PerlinNoise.GetPerlinNoise(rand.Next(), 256, 256, 2); for (int y = 0; y < w; y++) for (int x = 0; x < h; x++) { var tile = buff[x, y]; if (tile.PolygonId != -1) { var poly = map.Polygons[tile.PolygonId]; tile.Elevation = Math.Min(1, (float)(poly.DistanceToCoast + poly.DistanceToCoast * elevationNoise.GetNoise(x * 128.0 / w, y * 128.0 / h, 0.3) * 0.01f) * 2); if (tile.Elevation > 1) tile.Elevation = 1; else if (tile.Elevation < 0) tile.Elevation = 0; tile.Elevation = (float)Math.Pow(tile.Elevation, 1.5); tile.Moisture = (float)(moist[poly] + moist[poly] * moistureNoise.GetNoise(x * 128.0 / w, y * 128.0 / h, 0.3) * 0.01f); if (tile.Moisture > 1) tile.Moisture = 1; else if (tile.Moisture < 0) tile.Moisture = 0; } tile.Biome = GetBiome(tile); var biomeGround = GetBiomeGround(tile.Biome); if (biomeGround != 0) tile.TileId = biomeGround; buff[x, y] = tile; } }
static Bitmap RenderTerrainBmp(TerrainTile[,] tiles) { int w = tiles.GetLength(0); int h = tiles.GetLength(1); Bitmap bmp = new Bitmap(w, h); BitmapBuffer buff = new BitmapBuffer(bmp); buff.Lock(); for (int y = 0; y < w; y++) for (int x = 0; x < h; x++) { buff[x, y] = TileTypes.terrainColor[tiles[x, y].Terrain]; } buff.Unlock(); return bmp; }
static Bitmap RenderMoistBmp(TerrainTile[,] tiles) { int w = tiles.GetLength(0); int h = tiles.GetLength(1); Bitmap bmp = new Bitmap(w, h); BitmapBuffer buff = new BitmapBuffer(bmp); buff.Lock(); for (int y = 0; y < w; y++) for (int x = 0; x < h; x++) { uint color = 0x00ffffff; color |= (uint)(tiles[x, y].Moisture * 255) << 24; buff[x, y] = color; } buff.Unlock(); return bmp; }