/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.pepsoft.worldpainter.layers.bo2; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Stroke; import java.awt.image.BufferedImage; import java.awt.image.RescaleOp; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JComponent; import javax.vecmath.Point3i; import org.pepsoft.minecraft.Constants; import org.pepsoft.minecraft.Material; import org.pepsoft.util.ColourUtils; import org.pepsoft.worldpainter.ColourScheme; import org.pepsoft.worldpainter.objects.WPObject; /** * * @author pepijn */ public class OffsetViewer extends JComponent { public OffsetViewer() { setMinimumSize(new Dimension(200, 200)); setPreferredSize(new Dimension(300, 300)); } public void rotateLeft() { direction = Direction.values()[(direction.ordinal() + 1) % 4]; repaint(); } public void rotateRight() { direction = Direction.values()[(direction.ordinal() + 3) % 4]; repaint(); } public WPObject getObject() { return object; } public void setObject(WPObject object) { this.object = object; repaint(); } public Point3i getOffset() { return offset; } public void setOffset(Point3i offset) { this.offset = offset; repaint(); } public ColourScheme getColourScheme() { return colourScheme; } public void setColourScheme(ColourScheme colourScheme) { this.colourScheme = colourScheme; } public BufferedImage getTexturePack() { return texturePack; } public void setTexturePack(BufferedImage texturePack) { this.texturePack = texturePack; } @Override protected void paintComponent(Graphics g) { if ((object == null) || (offset == null)) { return; } Graphics2D g2 = (Graphics2D) g; int baseLine = getHeight() * 3 / 4; int middle = getWidth() / 2; Point3i dim = object.getDimensions(); switch (direction) { case X_ASC: for (int y = 0; y <= Math.min(-offset.y, dim.y - 1); y++) { for (int x = 0; x < dim.x; x++) { for (int z = 0; z < dim.z; z++) { if (object.getMask(x, y, z)) { paintBlock(g2, baseLine, middle, x + offset.x, z + offset.z, -offset.y - y, object.getMaterial(x, y, z)); } } } } g2.drawImage(IMAGE_X_ASC, middle + 10, getHeight() - IMAGE_X_ASC.getHeight() - 2, null); break; case Y_ASC: for (int x = 0; x <= Math.min(-offset.x, dim.x - 1); x++) { for (int y = 0; y < dim.y; y++) { for (int z = 0; z < dim.z; z++) { if (object.getMask(x, y, z)) { paintBlock(g2, baseLine, middle, y + offset.y, z + offset.z, -offset.x - x, object.getMaterial(x, y, z)); } } } } g2.drawImage(IMAGE_Y_ASC, middle + 10, getHeight() - IMAGE_Y_ASC.getHeight() - 2, null); break; case X_DESC: for (int y = dim.y - 1; y >= Math.max(-offset.y, 0); y--) { for (int x = 0; x < dim.x; x++) { for (int z = 0; z < dim.z; z++) { if (object.getMask(x, y, z)) { paintBlock(g2, baseLine, middle, -x - offset.x, z + offset.z, y - -offset.y, object.getMaterial(x, y, z)); } } } } g2.drawImage(IMAGE_X_DESC, middle - IMAGE_X_DESC.getWidth() - 10, getHeight() - IMAGE_X_DESC.getHeight() - 2, null); break; case Y_DESC: for (int x = dim.x - 1; x >= Math.max(-offset.x, 0); x--) { for (int y = 0; y < dim.y; y++) { for (int z = 0; z < dim.z; z++) { if (object.getMask(x, y, z)) { paintBlock(g2, baseLine, middle, -y - offset.y, z + offset.z, x - -offset.x, object.getMaterial(x, y, z)); } } } } g2.drawImage(IMAGE_Y_DESC, middle - IMAGE_Y_DESC.getWidth() - 10, getHeight() - IMAGE_Y_DESC.getHeight() - 2, null); break; } g2.setColor(Color.BLACK); g2.setStroke(STROKE); g2.drawRect(middle - 8, baseLine - 8, 16, 16); g2.drawLine(middle - 8, baseLine + 8, 0, baseLine + 8); g2.drawLine(middle + 7, baseLine + 8, getWidth() - 1, baseLine + 8); } private void paintBlock(Graphics2D g2, int baseLine, int middle, int x, int y, int depth, Material material) { if (material.blockType == Constants.BLK_AIR) { return; } if (texturePack != null) { if (depth > 0) { RescaleOp rescaleOp = new RescaleOp(new float[] {1.0f, 1.0f, 1.0f, (float) Math.pow(2.0, -depth)}, new float[] {0.0f, 0.0f, 0.0f, 0.0f}, null); g2.drawImage(material.getImage(texturePack), rescaleOp, middle + x * 16 - 8, baseLine - y * 16 - 8); } else { g2.drawImage(material.getImage(texturePack), middle + x * 16 - 8, baseLine - y * 16 - 8, null); } } else { int colour = colourScheme.getColour(material); if (depth > 0) { colour = ColourUtils.mix(colour, WHITE, (int) (Math.pow(0.5, depth) * 256 + 0.5)); } g2.setColor(new Color(colour)); g2.fillRect(middle + x * 16 - 8, baseLine - y * 16 - 8, 16, 16); } } private BufferedImage texturePack; private WPObject object; private Point3i offset; private ColourScheme colourScheme; private Direction direction = Direction.X_ASC; private static final BufferedImage IMAGE_X_ASC = loadImage("x_asc.png"); private static final BufferedImage IMAGE_Y_ASC = loadImage("z_asc.png"); private static final BufferedImage IMAGE_X_DESC = loadImage("x_desc.png"); private static final BufferedImage IMAGE_Y_DESC = loadImage("z_desc.png"); private static final int WHITE = 0xffffff; private static final Stroke STROKE = new BasicStroke(2.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[] {3.0f, 4.0f}, 0.0f); private static final long serialVersionUID = 1L; private static BufferedImage loadImage(String name) { try { return ImageIO.read(OffsetViewer.class.getResourceAsStream("/org/pepsoft/worldpainter/resources/" + name)); } catch (IOException e) { throw new RuntimeException("I/O error loading image " + name, e); } } enum Direction {X_ASC, Y_ASC, X_DESC, Y_DESC} }