public void Render() { Point topLeft = new Point(int.MaxValue, int.MaxValue); Point bottomRight = new Point(int.MinValue, int.MinValue); if (LowerLimit > UpperLimit) { int temp = LowerLimit; LowerLimit = UpperLimit; UpperLimit = temp; } if (Only != null && Exclude != null) { foreach (byte b in Exclude) { if (Only.Contains(b)) Only.Remove(b); } Exclude = null; } String[] paths = Directory.GetFiles(regionDir, "*.mca", SearchOption.TopDirectoryOnly); foreach (String path in paths) { Match m = Regex.Match(path, @"r\.(-?\d+)\.(-?\d+)\.mca"); Coord c = new Coord(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value)); c.RegiontoAbsolute(); if (c.X < topLeft.X) topLeft.X = c.X; if (c.Z < topLeft.Y) topLeft.Y = c.Z; c.Add(REGIONWIDTH, REGIONHEIGHT); if (c.X > bottomRight.X) bottomRight.X = c.X; if (c.Z > bottomRight.Y) bottomRight.Y = c.Z; } String format = String.Format("Reading region {{0}} of {0}", paths.Length); int count = 0; if (LessMemory) { int regionsWide = (bottomRight.X - topLeft.X) / REGIONWIDTH; int regionsTall = (bottomRight.Y - topLeft.Y) / REGIONHEIGHT; Point regionTopLeft = new Point(topLeft.X / REGIONWIDTH, topLeft.Y / REGIONHEIGHT); String[,] regions = new String[regionsWide, regionsTall]; foreach (String path in paths) { Match m = Regex.Match(path, @"r\.(-?\d+)\.(-?\d+)\.mc[ar]"); Coord c = new Coord(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value)); c.Add(-regionTopLeft.X, -regionTopLeft.Y); regions[c.X, c.Z] = path; } Bitmap strip = new Bitmap(bottomRight.X - topLeft.X, REGIONHEIGHT, PixelFormat.Format32bppArgb); PngWriter writer = new PngWriter(outPath, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); for (int y = 0; y < regionsTall; y++) { using (Graphics g = Graphics.FromImage(strip)) { g.Clear(Color.Transparent); } for (int x = 0; x < regionsWide; x++) { if (regions[x, y] != null) { count++; if (updateStatus != null) updateStatus(String.Format(format, count)); if (log != null) { log.Write(String.Format(format, count)); log.WriteLine(String.Format(" :: {0}", Path.GetFileName(regions[x, y]))); } RegionFile region = new RegionFile(regions[x, y]); Coord offset = new Coord(region.Coords); offset.RegiontoAbsolute(); offset.X -= topLeft.X; if (BiomeOverlay) RenderRegionBiomes(region, strip, offset.X, 0); else RenderRegion(region, strip, offset.X, 0); } } writer.WriteBitmap(strip); } writer.Close(); strip.Dispose(); } else { Bitmap map = new Bitmap(bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y); foreach (String path in paths) { count++; if (updateStatus != null) updateStatus(String.Format(format, count)); if (log != null) { log.Write(String.Format(format, count)); log.WriteLine(String.Format(" :: {0}", Path.GetFileName(path))); } RegionFile region = new RegionFile(path); Coord offset = new Coord(region.Coords); offset.RegiontoAbsolute(); offset.Add(-topLeft.X, -topLeft.Y); if (BiomeOverlay) RenderRegionBiomes(region, map, offset.X, offset.Z); else RenderRegion(region, map, offset.X, offset.Z); } if (CropMap) map = Crop(map); Rotate = (Rotate % 360) / 90; if (Rotate == 1) map.RotateFlip(RotateFlipType.Rotate90FlipNone); else if (Rotate == 2) map.RotateFlip(RotateFlipType.Rotate180FlipNone); else if (Rotate == 3) map.RotateFlip(RotateFlipType.Rotate270FlipNone); map.Save(outPath, ImageFormat.Png); map.Dispose(); } if (updateStatus != null) updateStatus("Done"); if (log != null) log.WriteLine("Done"); if (callback != null) callback(); }
private static void RenderRegionChunkstobePopulated(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap populate) { using (Graphics g = Graphics.FromImage(populate)) { Brush brush = new SolidBrush(Color.Yellow); for (int x = chunkStartX; x <= chunkEndX; x++) { for (int z = chunkStartZ; z <= chunkEndZ; z++) { Chunk c = region.Chunks[x, z]; if (c == null || c.Root == null) continue; Coord chunkOffset = new Coord(c.Coords); chunkOffset.ChunktoRegionRelative(); chunkOffset = new Coord(chunkOffset.X - chunkStartX, chunkOffset.Z - chunkStartZ); chunkOffset.ChunktoAbsolute(); chunkOffset.Add(offsetX, offsetY); RenderChunktobePopulated(c, g, brush, chunkOffset.X, chunkOffset.Z); } } brush.Dispose(); } }
private static void RenderRegionTerrain(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap map) { if (signal != null || mutex != null || taskCount > 0) throw new Exception("RenderRegionTerrain re-entered, shouldn't be possible."); signal = new ManualResetEvent(false); taskCount = (chunkEndX - chunkStartX + 1) * (chunkEndZ - chunkStartZ + 1); mutex = new Mutex(); for (int x = chunkStartX; x <= chunkEndX; x++) { for (int z = chunkStartZ; z <= chunkEndZ; z++) { Chunk c = region.Chunks[x, z]; if (c == null || c.Root == null) { if (Interlocked.Decrement(ref taskCount) == 0) signal.Set(); continue; } Coord chunkOffset = new Coord(c.Coords); chunkOffset.ChunktoRegionRelative(); chunkOffset = new Coord(chunkOffset.X - chunkStartX, chunkOffset.Z - chunkStartZ); chunkOffset.ChunktoAbsolute(); chunkOffset.Add(offsetX, offsetY); ThreadPool.QueueUserWorkItem(RenderChunkTerrain, new Object[]{c, map, chunkOffset.X, chunkOffset.Z}); } } signal.WaitOne(); signal.Dispose(); signal = null; mutex.WaitOne(); mutex.ReleaseMutex(); mutex.Dispose(); mutex = null; }
private static void RenderRegionBiomes(RegionFile region, int chunkStartX, int chunkEndX, int chunkStartZ, int chunkEndZ, int offsetX, int offsetY, Bitmap biomes, String[,] toolTips) { for (int x = chunkStartX; x <= chunkEndX; x++) { for (int z = chunkStartZ; z <= chunkEndZ; z++) { Chunk c = region.Chunks[x, z]; if (c == null || c.Root == null) continue; Coord chunkOffset = new Coord(c.Coords); chunkOffset.ChunktoRegionRelative(); chunkOffset = new Coord(chunkOffset.X - chunkStartX, chunkOffset.Z - chunkStartZ); chunkOffset.ChunktoAbsolute(); chunkOffset.Add(offsetX, offsetY); RenderChunkBiomes(c, biomes, toolTips, chunkOffset.X, chunkOffset.Z); } } }