diff --git a/core/src/main/java/com/boydti/fawe/FaweCache.java b/core/src/main/java/com/boydti/fawe/FaweCache.java index e17accde..e1faa714 100644 --- a/core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/core/src/main/java/com/boydti/fawe/FaweCache.java @@ -16,6 +16,7 @@ import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.CuboidClipboard; import com.sk89q.worldedit.blocks.BaseBlock; +import java.awt.Color; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; @@ -68,6 +69,8 @@ public class FaweCache { */ public final static PseudoRandom RANDOM = new PseudoRandom(); + public final static Color[] CACHE_COLOR = new Color[Short.MAX_VALUE]; + /** * Get the cached BaseBlock object for an id/data
* - The block is immutable @@ -106,6 +109,18 @@ public class FaweCache { return getCombined(block.getId(), block.getData()); } + public static Color getColor(int id, int data) { + Color exact = CACHE_COLOR[getCombined(id, data)]; + if (exact != null) { + return exact; + } + Color base = CACHE_COLOR[getCombined(id, 0)]; + if (base != null) { + return base; + } + return CACHE_COLOR[0]; + } + static { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { @@ -159,6 +174,75 @@ public class FaweCache { } }; } + + CACHE_COLOR[getCombined(0, 0)] = new Color(128, 128, 128); //Air + CACHE_COLOR[getCombined(1, 0)] = new Color(180, 180, 180); //stone + CACHE_COLOR[getCombined(2, 0)] = new Color(0, 225, 0); //grass + CACHE_COLOR[getCombined(3, 0)] = new Color(168, 117, 68); //dirt + CACHE_COLOR[getCombined(4, 0)] = new Color(125, 125, 125); //cobblestone + CACHE_COLOR[getCombined(5, 0)] = new Color(185, 133, 83); //wood planks + CACHE_COLOR[getCombined(6, 0)] = new Color(0, 210, 0); //saplings + CACHE_COLOR[getCombined(7, 0)] = new Color(60, 60, 60); //bedrock + CACHE_COLOR[getCombined(8, 0)] = new Color(0, 0, 255); //water new Color(flowing) + CACHE_COLOR[getCombined(9, 0)] = new Color(0, 0, 235); //water new Color(stationary) + CACHE_COLOR[getCombined(10, 0)] = new Color(255, 155, 102); //lava new Color(flowing) + CACHE_COLOR[getCombined(11, 0)] = new Color(255, 129, 61); //lava new Color(stationary) + CACHE_COLOR[getCombined(12, 0)] = new Color(228, 216, 174); //sand + CACHE_COLOR[getCombined(13, 0)] = new Color(190, 190, 210); //gravel + CACHE_COLOR[getCombined(14, 0)] = new Color(245, 232, 73); //gold ore + CACHE_COLOR[getCombined(15, 0)] = new Color(211, 179, 160); //iron ore + CACHE_COLOR[getCombined(16, 0)] = new Color(61, 61, 61); //coal ore + CACHE_COLOR[getCombined(17, 0)] = new Color(165, 103, 53); //wood + CACHE_COLOR[getCombined(18, 0)] = new Color(76, 150, 24); //leaves + CACHE_COLOR[getCombined(20, 0)] = new Color(158, 255, 243); //glass + CACHE_COLOR[getCombined(24, 0)] = new Color(226, 206, 140); //sandstone + CACHE_COLOR[getCombined(31, 0)] = new Color(0, 210, 0); //long grass + CACHE_COLOR[getCombined(32, 0)] = new Color(224, 162, 64); //shrub + CACHE_COLOR[getCombined(37, 0)] = new Color(255, 248, 56); //yellow flower + CACHE_COLOR[getCombined(38, 0)] = new Color(225, 0, 0); //red rose + CACHE_COLOR[getCombined(41, 0)] = new Color(255, 215, 0); //gold block + CACHE_COLOR[getCombined(42, 0)] = new Color(135, 135, 135); //iron block + CACHE_COLOR[getCombined(44, 0)] = new Color(165, 165, 165); //step + CACHE_COLOR[getCombined(50, 0)] = new Color(255, 248, 56); //torch + CACHE_COLOR[getCombined(53, 0)] = new Color(185, 133, 83); //wood stairs + CACHE_COLOR[getCombined(59, 0)] = new Color(205, 222, 61); //wheat crops + CACHE_COLOR[getCombined(65, 0)] = new Color(185, 133, 83); //ladder + CACHE_COLOR[getCombined(67, 0)] = new Color(125, 125, 125); //cobblestone stairs + CACHE_COLOR[getCombined(78, 0)] = new Color(230, 255, 255); //snow layer + CACHE_COLOR[getCombined(79, 0)] = new Color(180, 255, 236); //ice + CACHE_COLOR[getCombined(81, 0)] = new Color(76, 150, 24); //cactus + CACHE_COLOR[getCombined(82, 0)] = new Color(150, 150, 180); //clay + CACHE_COLOR[getCombined(83, 0)] = new Color(89, 255, 89); //reed + CACHE_COLOR[getCombined(85, 0)] = new Color(185, 133, 83); //wood fence + CACHE_COLOR[getCombined(99, 0)] = new Color(168, 125, 99); //large brown mushroom + CACHE_COLOR[getCombined(100, 0)] = new Color(186, 27, 27); //large red mushroom + CACHE_COLOR[getCombined(102, 0)] = new Color(158, 255, 243); //glass pane + CACHE_COLOR[getCombined(106, 0)] = new Color(0, 150, 0); //vines + CACHE_COLOR[getCombined(110, 0)] = new Color(100, 90, 100); //mycelium + CACHE_COLOR[getCombined(111, 0)] = new Color(96, 188, 30); //lily pad + CACHE_COLOR[getCombined(128, 0)] = new Color(226, 206, 140); //sandstone stairs + CACHE_COLOR[getCombined(134, 0)] = new Color(185, 133, 83); //spruce wood stairs + CACHE_COLOR[getCombined(141, 0)] = new Color(205, 222, 61); //carrot crops + CACHE_COLOR[getCombined(142, 0)] = new Color(205, 222, 61); //potato crops + CACHE_COLOR[getCombined(161, 0)] = new Color(67, 132, 21); //dark oak leaves + CACHE_COLOR[getCombined(38, 8)] = new Color(255, 250, 155); //daisy flower + CACHE_COLOR[getCombined(175, 8)] = new Color(0, 200, 0); //double tall grass and flowers top + CACHE_COLOR[getCombined(35, 0)] = new Color(254, 254, 254); // White - Wools colors borrowed from Sk89q's draw script + CACHE_COLOR[getCombined(35, 1)] = new Color(255, 100, 0); // Orange + CACHE_COLOR[getCombined(35, 2)] = new Color(200, 0, 200); // Magenta + CACHE_COLOR[getCombined(35, 3)] = new Color(87, 132, 223); // Light blue + CACHE_COLOR[getCombined(35, 4)] = new Color(255, 255, 0); // Yellow + CACHE_COLOR[getCombined(35, 5)] = new Color(0, 255, 0); // Green + CACHE_COLOR[getCombined(35, 6)] = new Color(255, 180, 200); // Pink + CACHE_COLOR[getCombined(35, 7)] = new Color(72, 72, 72); // Gray + CACHE_COLOR[getCombined(35, 8)] = new Color(173, 173, 173); // Light grey + CACHE_COLOR[getCombined(35, 9)] = new Color(0, 100, 160); // Cyan + CACHE_COLOR[getCombined(35, 10)] = new Color(120, 0, 200); // Purple + CACHE_COLOR[getCombined(35, 11)] = new Color(0, 0, 175); // Blue + CACHE_COLOR[getCombined(35, 12)] = new Color(100, 60, 0); // Brown + CACHE_COLOR[getCombined(35, 13)] = new Color(48, 160, 0); // Cactus green + CACHE_COLOR[getCombined(35, 14)] = new Color(255, 0, 0); // Red + CACHE_COLOR[getCombined(35, 15)] = new Color(0, 0, 0); // Black } /** diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java index 61a1d0b3..83d26c53 100644 --- a/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java @@ -94,15 +94,23 @@ public class MemoryOptimizedClipboard extends FaweClipboard { if (!air) { continue; } - for (int y2 = 0; y2 < 16; y2++) { + for (int y2 = 0; y2 < height; y2++) { pos.x = x; pos.z = z; pos.y = y1 + y2; + int yy = y1 + y2; + if (yy >= height) { + break; + } task.run(pos, EditSession.nullBlock); } continue; } for (int y2 = 0; y2 < idArray.length; y2++) { + int yy = y1 + y2; + if (yy >= height) { + break; + } int id = idArray[y2] & 0xFF; if (id == 0 && !air) { continue; diff --git a/core/src/main/java/com/boydti/fawe/object/schematic/PNGWriter.java b/core/src/main/java/com/boydti/fawe/object/schematic/PNGWriter.java new file mode 100644 index 00000000..065037f6 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/schematic/PNGWriter.java @@ -0,0 +1,177 @@ +package com.boydti.fawe.object.schematic; + +import com.boydti.fawe.FaweCache; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.registry.WorldData; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageOutputStream; + +public class PNGWriter implements ClipboardWriter { + + private final ImageOutputStream out; + + public PNGWriter(OutputStream out) throws IOException { + this.out = ImageIO.createImageOutputStream(out); + } + + + + public static Color getTopColor(int id, int data) { + return FaweCache.getColor(id, data); + } + + public static Color getRightColor(int id, int data) { + return FaweCache.getColor(id, data).darker(); + } + + public static Color getLeftColor(int id, int data) { + return FaweCache.getColor(id, data).brighter(); + } + + @Override + public void write(Clipboard clipboard, WorldData data) throws IOException { + Region region = clipboard.getRegion(); + int width = region.getWidth(); + int height = region.getHeight(); + int length = region.getLength(); + int imageSize = 1080; + BufferedImage img = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = img.createGraphics(); + double d = Math.min((double) imageSize / length, (double) imageSize / width) / 3; + double d_2 = d/2; + double cx = (double) imageSize / 2; + double cy = (double) imageSize / 2; + + int[] poly1X = new int[4]; + int[] poly1Y = new int[4]; + int[] poly2X = new int[4]; + int[] poly2Y = new int[4]; + int[] poly3X = new int[4]; + int[] poly3Y = new int[4]; + + double[] dpxj = new double[length]; + double[] dpxi = new double[Math.max(256, width)]; + double[] dpyj = new double[length]; + double[] dpyi = new double[Math.max(256, width)]; + double[] hd = new double[256]; + for (int i = 0; i < hd.length; i++) { + } + for (int j = 0; j < dpxj.length; j++) { + dpxj[j] = cx + j * d; + dpyj[j] = imageSize + d + j * d_2; + } + for (int i = 0; i < Math.max(256, dpxi.length); i++) { + dpxi[i] = i * d; + dpyi[i] = i * d_2; + } + + g2.setColor(new Color(0, 0, 0)); + g2.drawRect(0, 0, imageSize - 1, imageSize - 1); + + boolean fill = length * 4 < imageSize && width * 4 < imageSize; + + Vector mutable = new Vector(0, 0, 0); + Vector mutableTop = new Vector(0, 0, 0); + Vector mutableRight = new Vector(0, 0, 0); + Vector mutableLeft = new Vector(0, 0, 0); + + Vector min = clipboard.getMinimumPoint(); + int y0 = min.getBlockY(); + int z0 = min.getBlockZ(); + int x0 = min.getBlockX(); + for (int x = x0; x < x0 + width; x++) { + mutable.x = x; + mutableTop.x = x; + mutableRight.x = x; + mutableLeft.x = x + 1; + int xx = x - x0; + double cpx1 = -dpxi[xx]; + double cpy1 = dpyi[xx]; + for (int z = z0; z < z0 + length; z++) { + mutable.z = z; + mutableTop.z = z; + mutableRight.z = z + 1; + mutableLeft.z = z; + int zz = z - z0; + double cpx = cpx1 + dpxj[zz]; + double cpy2 = cpy1 + dpyj[zz]; + for (int y = y0; y < y0 + height; y++) { + mutable.y = y; + BaseBlock block = clipboard.getBlock(mutable); + if (block == EditSession.nullBlock) { + continue; + } + mutableTop.y = y + 1; + mutableRight.y = y; + mutableLeft.y = y; + if (clipboard.getBlock(mutableTop) != EditSession.nullBlock && clipboard.getBlock(mutableRight) != EditSession.nullBlock && clipboard.getBlock(mutableLeft) != EditSession.nullBlock) { + continue; + } + double cpy = cpy2 - dpxi[y - y0]; + poly1X[0] = (int) (cpx); + poly1Y[0] = (int) (cpy); + poly1X[1] = (int) (cpx - d); + poly1Y[1] = (int) (cpy - d_2); + poly1X[2] = (int) (cpx); + poly1Y[2] = (int) (cpy - d); + poly1X[3] = (int) (cpx + d); + poly1Y[3] = (int) (cpy - d_2); + + poly2X[0] = (int) (cpx); + poly2Y[0] = (int) (cpy); + poly2X[1] = (int) (cpx + d); + poly2Y[1] = (int) (cpy - d_2); + poly2X[2] = (int) (cpx + d); + poly2Y[2] = (int) (cpy + d_2 + dpxi[0]); + poly2X[3] = (int) (cpx); + poly2Y[3] = (int) (cpy + dpxi[1]); + + poly3X[0] = (int) (cpx); + poly3Y[0] = (int) (cpy); + poly3X[1] = (int) (cpx - d); + poly3Y[1] = (int) (cpy - d_2); + poly3X[2] = (int) (cpx - d); + poly3Y[2] = (int) (cpy + d_2 + dpxi[0]); + poly3X[3] = (int) (cpx); + poly3Y[3] = (int) (cpy + dpxi[1]); + + Color colorTop = getTopColor(block.getId(), block.getData()); + Color colorRight = getRightColor(block.getId(), block.getData()); + Color colorLeft = getLeftColor(block.getId(), block.getData()); + + if (fill) { + g2.setColor(colorTop); + g2.fillPolygon(poly1X, poly1Y, 4); + g2.setColor(colorRight); + g2.fillPolygon(poly2X, poly2Y, 4); + g2.setColor(colorLeft); + g2.fillPolygon(poly3X, poly3Y, 4); + } else { + g2.setColor(colorTop); + g2.drawPolygon(poly1X, poly1Y, 4); + g2.setColor(colorRight); + g2.drawPolygon(poly2X, poly2Y, 4); + g2.setColor(colorLeft); + g2.drawPolygon(poly3X, poly3Y, 4); + } + } + } + } + ImageIO.write(img, "png", out); + } + + @Override + public void close() throws IOException { + out.close(); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java b/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java index 4c9fa323..30d77cb6 100644 --- a/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java +++ b/core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java @@ -86,8 +86,8 @@ public class FaweSchematicHandler extends SchematicHandler { for (RegionWrapper region : regions) { for (int z = region.minZ; z <= region.maxZ; z++) { mutable.z = z - region.minZ; - for (int y = 0; y < 256; y++) { - mutable.y = y; + for (int y = region.minY; y <= Math.min(255, region.maxY); y++) { + mutable.y = y - region.minY; for (int x = region.minX; x <= region.maxX; x++) { mutable.x = x - region.minX; BaseBlock block = editSession.getLazyBlock(x, y, z); diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 20528b59..caf4b122 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -925,7 +925,6 @@ public class EditSession implements Extent { @Nullable public Entity createEntity(final com.sk89q.worldedit.util.Location location, final BaseEntity entity) { Entity result = this.bypassNone.createEntity(location, entity); - System.out.println("RESULT: " + result); return result; } diff --git a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java index f8f5c053..791e7b62 100644 --- a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java +++ b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.extent.clipboard.io; import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; import com.boydti.fawe.object.schematic.FaweFormat; +import com.boydti.fawe.object.schematic.PNGWriter; import com.boydti.fawe.object.schematic.StructureFormat; import com.boydti.fawe.util.MainUtil; import com.sk89q.jnbt.NBTConstants; @@ -137,6 +138,28 @@ public enum ClipboardFormat { } }, + PNG("png") { + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + return null; + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + return new PNGWriter(outputStream); + } + + @Override + public String getExtension() { + return "png"; + } + + @Override + public boolean isFormat(File file) { + return file.getName().endsWith(".png"); + } + }, + /** * The FAWE file format: * - Streamable for known dimensions with mode 0 diff --git a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicWriter.java b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicWriter.java index 1830e07b..78dd075f 100644 --- a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicWriter.java +++ b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicWriter.java @@ -129,6 +129,9 @@ public class SchematicWriter implements ClipboardWriter { throw new IllegalArgumentException("Length of region too large for a .schematic"); } + System.out.println(clipboard.getMinimumPoint()); + System.out.println(clipboard.getMaximumPoint()); + // ==================================================================== // Metadata // ==================================================================== @@ -152,11 +155,11 @@ public class SchematicWriter implements ClipboardWriter { // Precalculate index vars int area = width * length; final int[] yarea = new int[height]; - final int[] zwidth = new int[width]; + final int[] zwidth = new int[length]; for (int i = 0; i < height; i++) { yarea[i] = i * area; } - for (int i = 0; i < width; i++) { + for (int i = 0; i < length; i++) { zwidth[i] = i * width; } if (clipboard instanceof BlockArrayClipboard) { @@ -165,9 +168,9 @@ public class SchematicWriter implements ClipboardWriter { faweClip.forEach(forEach, false); addBlocks = forEach.addBlocks; } else { - final int mx = (int) min.x; - final int my = (int) min.y; - final int mz = (int) min.z; + final int mx = min.getBlockX(); + final int my = min.getBlockY(); + final int mz = min.getBlockZ(); Vector mutable = new Vector(0, 0, 0); ForEach forEach = new ForEach(yarea, zwidth, blocks, blockData, tileEntities); for (Vector point : region) {