public override void Perform(Vec3S32[] marks, Brush brush, Action <DrawOpBlock> output) { Vec3U16 p0 = Clamp(marks[0]); selector = null; CalcThreshold(); CalcDirectionVectors(Direction); PaletteEntry[] palette = ImagePalette.GetPalette(Mode); if (Mode == 6) { selector = new GrayscalePalette(); } else { selector = new RgbPalette(); } selector.SetAvailableBlocks(palette); using (PixelGetter getter = new PixelGetter(Source)) { getter.Init(); getter.Iterate(output, OutputPixel); } Source.Dispose(); Source = null; if (Filename == "tempImage_" + Player.name) { File.Delete("extra/images/tempImage_" + Player.name + ".bmp"); } Player.Message(Player, "Finished printing image using " + ImagePalette.Names[Mode]); }
public override void Perform(Vec3S32[] marks, Brush brush, DrawOpOutput output) { selector = new RgbPaletteMatcher(); CalcLayerColors(); using (PixelGetter getter = new PixelGetter(Source)) { getter.Init(); OutputPixels(getter, output); } selector = null; // Put all the blocks in shadow if (DualLayer) { ushort y = (ushort)(Origin.Y + Source.Height); for (int i = 0; i < Source.Width; i++) { ushort x = (ushort)(Origin.X + dx.X * i); ushort z = (ushort)(Origin.Z + dx.Z * i); output(Place(x, y, z, Block.Stone)); x = (ushort)(x + adj.X); z = (ushort)(z + adj.Z); output(Place(x, y, z, Block.Stone)); } } Source.Dispose(); Source = null; Player.Message("Finished printing image using {0} palette.", Palette.Name); }
static bool IsShorterBy(int height, PixelGetter pixels, int x, int z) { if (x >= pixels.Width || x < 0 || z >= pixels.Height || z < 0) { return(false); } int neighbourHeight = pixels.Get(x, z).R; return(height >= neighbourHeight + 2); }
void OutputPixels(PixelGetter pixels, DrawOpOutput output) { int width = pixels.Width, height = pixels.Height; int srcY = height - 1; // need to flip coords in bitmap vertically for (int yy = 0; yy < height; yy++, srcY--) { for (int xx = 0; xx < width; xx++) { Pixel P = pixels.Get(xx, srcY); ushort x = (ushort)(Origin.X + dx.X * xx + dy.X * yy); ushort y = (ushort)(Origin.Y + dx.Y * xx + dy.Y * yy); ushort z = (ushort)(Origin.Z + dx.Z * xx + dy.Z * yy); if (P.A < 20) { output(Place(x, y, z, Block.Air)); continue; } BlockID block; if (!DualLayer) { block = selector.BestMatch(P.R, P.G, P.B); } else { bool backLayer; block = selector.BestMatch(P.R, P.G, P.B, out backLayer); if (backLayer) { x = (ushort)(x + adj.X); z = (ushort)(z + adj.Z); } } output(Place(x, y, z, block)); } } }
void OutputPixels(PixelGetter pixels, DrawOpOutput output) { int width = pixels.Width, height = pixels.Height; for (int yy = 0; yy < height; yy++) { for (int xx = 0; xx < width; xx++) { Pixel P = pixels.Get(xx, yy); ushort x = (ushort)(Origin.X + dx.X * xx + dy.X * yy); ushort y = (ushort)(Origin.Y + dx.Y * xx + dy.Y * yy); ushort z = (ushort)(Origin.Z + dx.Z * xx + dy.Z * yy); if (P.A < 20) { output(Place(x, y, z, ExtBlock.Air)); continue; } byte raw = 0; if (!DualLayer) { raw = selector.BestMatch(P.R, P.G, P.B); } else { bool backLayer; raw = selector.BestMatch(P.R, P.G, P.B, out backLayer); if (backLayer) { x = (ushort)(x + adj.X); z = (ushort)(z + adj.Z); } } output(Place(x, y, z, ExtBlock.FromRaw(raw))); } } }
public static bool Generate(Player p, Level lvl, string url) { if (url.Length == 0) { p.Message("You need to provide a url for the image."); return(false); } byte[] data = HttpUtil.DownloadImage(url, p); if (data == null) { return(false); } Bitmap bmp = DecodeImage(data, p); if (bmp == null) { return(false); } int index = 0, oneY = lvl.Width * lvl.Length; try { if (lvl.Width != bmp.Width || lvl.Length != bmp.Height) { p.Message("&cHeightmap size ({0}x{1}) does not match Width x Length ({2}x{3}) of the level", bmp.Width, bmp.Height, lvl.Width, lvl.Length); p.Message("&cAs such, the map may not look accurate."); bmp = Resize(bmp, lvl.Width, lvl.Length); } using (PixelGetter pixels = new PixelGetter(bmp)) { pixels.Init(); for (int z = 0; z < pixels.Height; z++) { for (int x = 0; x < pixels.Width; x++) { int height = pixels.Get(x, z).R; byte layer = Block.Dirt, top = Block.Grass; if ( IsShorterBy(height, pixels, x - 1, z) || IsShorterBy(height, pixels, x + 1, z) || IsShorterBy(height, pixels, x, z - 1) || IsShorterBy(height, pixels, x, z + 1)) { layer = Block.Stone; top = Block.Stone; } // remap from 0..255 to 0..lvl.Height height = height * lvl.Height / 255; for (int y = 0; y < height - 1; y++) { lvl.blocks[index + oneY * y] = layer; } if (height > 0) { lvl.blocks[index + oneY * (height - 1)] = top; } index++; } } } // Cannot use using { } here because bmp may be reassigned } finally { bmp.Dispose(); } return(true); }
public static bool Generate(Player p, Level lvl, string args) { if (args.Length == 0) { p.Message("You need to provide a url for the image."); return(false); } if (!DownloadImage(args, "extra/heightmap/", p)) { return(false); } Bitmap bmp = ReadBitmap("tempImage_" + p.name, "extra/heightmap/", p); if (bmp == null) { return(false); } int index = 0, oneY = lvl.Width * lvl.Length; using (bmp) { if (lvl.Width != bmp.Width || lvl.Length != bmp.Height) { p.Message("The size of the heightmap is {0} by {1}.", bmp.Width, bmp.Height); p.Message("The width and length of the new level must match that size."); return(false); } using (PixelGetter pixels = new PixelGetter(bmp)) { pixels.Init(); for (int z = 0; z < pixels.Height; z++) { for (int x = 0; x < pixels.Width; x++) { int height = pixels.Get(x, z).R; byte layer = Block.Dirt, top = Block.Grass; if ( IsShorterBy(height, pixels, x - 1, z) || IsShorterBy(height, pixels, x + 1, z) || IsShorterBy(height, pixels, x, z - 1) || IsShorterBy(height, pixels, x, z + 1)) { layer = Block.Stone; top = Block.Stone; } height = height * lvl.Height / 255; for (int y = 0; y < height - 1; y++) { lvl.blocks[index + oneY * y] = layer; } if (height > 0) { lvl.blocks[index + oneY * (height - 1)] = top; } index++; } } } } return(true); }