import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Point; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.PriorityQueue; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; public class TestStaticFormat { private final static int E = 1; private final static int W = 2; private final static int S = 4; private final static int N = 8; private ByteBuffer[][][] _buffer = null; private int _rx, _ry, _layer; private int _mode = 0; private JLabel _mapLabel; private BufferedImage _mapImage; private JLabel _coordLabel; private BufferedImage _zoomImage; private JLabel _zoomLabel; private int[] _colorRange; private short _minZ; private short _maxZ; private JSplitPane _splitPane; private JScrollPane _scrollPane; private JComboBox _chooseMode; private int _maxLayer; public static void main(String[] args) throws IOException { // TestStaticFormat t = new TestStaticFormat(23, 18,1); TestStaticFormat t = new TestStaticFormat(19, 21, 0); System.out.println(""); t.plotMap(); // t.loadGeodataFile(19, 21); } public TestStaticFormat(int rx, int ry, int layer) throws IOException { _rx = rx; _ry = ry; _layer = layer; } public boolean checkVisibility(int x1, int y1, int x2, int y2, int h1, int h2, int maxrange) throws IOException { int dx = Math.abs(x1 - x2); int dy = Math.abs(y1 - y2); if (dx + dy == 0) return true; if (dx * dx + dy * dy > maxrange * maxrange) return false; int[] moveForward; int[] moveSideward; if (dx > dy) { moveForward = new int[] { x1 > x2 ? -1 : 1, 0 }; moveSideward = new int[] { 0, y1 > y2 ? -1 : 1 }; } else { moveSideward = new int[] { x1 > x2 ? -1 : 1, 0 }; moveForward = new int[] { 0, y1 > y2 ? -1 : 1 }; int t = dx; dx = dy; dy = t; } int error = dx >> 1; int height = (getCellHeight(x1, y1, _layer) + h1) * 65536; int heightTarget = (getCellHeight(x2, y2, _layer) + h2) * 65536; int heightDelta = (heightTarget - height) / Math.max(dx, dy); // Linienalgorithmus nach Bresenham (siehe // http://de.wikipedia.org/wiki/Bresenham-Algorithmus) while (x1 != x2 || y2 != y2) { x1 += moveForward[0]; y1 += moveForward[1]; error -= dy; height += heightDelta; // Neue Zelle blockiert ? if (getCellHeight(x1, y1, _layer) * 65536 > height) return false; // Prüfe Bewegung zur Seite überhaupt nötig ist ! if (error > 0) { continue; } x1 += moveSideward[0]; y1 += moveSideward[1]; error += dx; // Neue Zelle blockiert ? if (getCellHeight(x1, y1, _layer) * 65536 > height) return false; } return true; } public int[] checkDirectPath(int x1, int y1, int x2, int y2) throws IOException { int dx = Math.abs(x1 - x2); int dy = Math.abs(y1 - y2); int[] moveForward; int[] moveSideward; int forward; int sideward; if (dx > dy) { moveForward = new int[] { x1 > x2 ? -1 : 1, 0 }; moveSideward = new int[] { 0, y1 > y2 ? -1 : 1 }; forward = x1 > x2 ? W : E; sideward = y1 > y2 ? N : S; } else { moveSideward = new int[] { x1 > x2 ? -1 : 1, 0 }; moveForward = new int[] { 0, y1 > y2 ? -1 : 1 }; sideward = x1 > x2 ? W : E; forward = y1 > y2 ? N : S; int t = dx; dx = dy; dy = t; } int[] index = new int[] { x1 & 0xfffc, y1 & 0xfffc }; byte indexValue = getIndex(index[0], index[1], _layer); boolean freeBlockForward = (indexValue & forward) != 0; boolean freeBlockSideward = (indexValue & sideward) != 0; int stepsForwardInsideBlock = 0; int stepsSidewardInsideBlock = 0; for (int tx = x1, ty = y1; (tx & 0xfffc) == index[0] && (ty & 0xfffc) == index[1]; tx += moveForward[0], ty += moveForward[1]) stepsForwardInsideBlock++; for (int tx = x1, ty = y1; (tx & 0xfffc) == index[0] && (ty & 0xfffc) == index[1]; tx += moveSideward[0], ty += moveSideward[1]) stepsSidewardInsideBlock++; int error = dx >> 1; // Linienalgorithmus nach Bresenham (siehe // http://de.wikipedia.org/wiki/Bresenham-Algorithmus) while (x1 != x2 || y2 != y2) { // Prüfe Bewegung nach vorne if (!freeBlockForward) { int block = getCellBlock(x1, y1, _layer); // Bewegung nach vorne blockiert ? if ((block & forward) == 0) { System.out.println("Blocked forward by Block " + (x1 / 8) + "/" + (y1 / 8) + " Cell " + (x1 & 7) + "/" + (y1 & 7)); break; } } // erfolgreich bewegt x1 += moveForward[0]; y1 += moveForward[1]; error -= dy; // neuen Block erreicht ? stepsForwardInsideBlock--; if (stepsForwardInsideBlock == 0) { stepsForwardInsideBlock = 4; index[0] += (moveForward[0] * 4); index[1] += (moveForward[1] * 4); indexValue = getIndex(index[0], index[1], _layer); freeBlockForward = (indexValue & forward) != 0; freeBlockSideward = (indexValue & sideward) != 0; // System.out.println("New Index // "+freeBlockForward+"/"+freeBlockSideward+ // " Block: "+(x1/8)+"/"+(y1/8)+" Cell "+(x1&7)+"/"+(y1&7)); } // Prüfe Bewegung zur Seite überhaupt nötig ist ! if (error > 0) { continue; } if (!freeBlockSideward) { int block = getCellBlock(x1, y1, _layer); // Bewegung nach vorne blockiert ? if ((block & sideward) == 0) { System.out.println("Blocked sideward by Block " + (x1 / 8) + "/" + (y1 / 8) + " Cell " + (x1 & 7) + "/" + (y1 & 7)); break; } } // erfolgreich bewegt x1 += moveSideward[0]; y1 += moveSideward[1]; error += dx; // neuen Block erreicht ? stepsSidewardInsideBlock--; if (stepsSidewardInsideBlock == 0) { stepsSidewardInsideBlock = 4; index[0] += (moveSideward[0] * 4); index[1] += (moveSideward[1] * 4); indexValue = getIndex(index[0], index[1], _layer); freeBlockForward = (indexValue & forward) != 0; freeBlockSideward = (indexValue & sideward) != 0; // System.out.println("New Index // "+freeBlockForward+"/"+freeBlockSideward+ // " Block: "+(x1/8)+"/"+(y1/8)+" Cell "+(x1&7)+"/"+(y1&7)); } } return new int[] { x1, y1 }; } private class CellComparater implements Comparator { private Map _costs; public CellComparater(Map costs) { _costs = costs; } public int compare(Integer o1, Integer o2) { return _costs.get(o1).compareTo(_costs.get(o2)); } } public int[] findPath(int x1, int y1, int x2, int y2) throws IOException { long lengthSquared = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); if (lengthSquared > 1024 * 1024) return new int[0]; HashMap g = new HashMap(); HashMap queueSort = new HashMap(); HashMap last = new HashMap(); PriorityQueue open = new PriorityQueue(100, new CellComparater(queueSort)); HashSet closed = new HashSet(); int start = x1 + (y1 << 16); int target = x2 + (y2 << 16); int[] neighFree = new int[] { N, E, S, W }; int[] neighOffset = new int[] { -65536, 1, 65536, -1 }; g.put(start, 0); queueSort.put(start, 0); open.add(start); Integer next; int maxSize = 1; while ((next = open.poll()) != null) { if (next == target) break; maxSize = Math.max(open.size(), maxSize); closed.add(next); int free = getCellBlock(next & 0xffff, next >> 16, _layer); int newCost = g.get(next) + 1000; long nCS = newCost * newCost; if (nCS > lengthSquared * 1440000) continue; for (int i = 0; i < 4; i++) { int neighPos = next + neighOffset[i]; if ((free & neighFree[i]) == 0) continue; if (open.contains(neighPos) && newCost < g.get(neighPos)) open.remove(neighPos); if (closed.contains(neighPos) && newCost < g.get(neighPos)) closed.remove(neighPos); if (!(open.contains(neighPos) || closed.contains(neighPos))) { g.put(neighPos, newCost); queueSort.put(neighPos, newCost + h(neighPos, i, x1, y1, x2, y2)); open.add(neighPos); last.put(neighPos, next); } } } if (next == null) return new int[0]; // Draw Path int[] result = new int[g.get(target)]; int count = result.length - 1; while (target != start) { result[count] = target; count--; target = last.get(target); } return result; } public Integer[] findQuickPath(int x1, int y1, int x2, int y2) throws IOException { x1 = x1 & 0xfffc; x2 = x2 & 0xfffc; y1 = y1 & 0xfffc; y2 = y2 & 0xfffc; long lengthSquared = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); if (lengthSquared > 1024 * 1024) return new Integer[0]; HashMap g = new HashMap(); HashMap queueSort = new HashMap(); HashMap last = new HashMap(); PriorityQueue open = new PriorityQueue(100, new CellComparater(queueSort)); HashSet closed = new HashSet(); int start = x1 + (y1 << 16); int target = x2 + (y2 << 16); int[] neighFree = new int[] { N, E, S, W }; int[] neighOffset = new int[] { -65536 * 4, 4, 65536 * 4, -4 }; g.put(start, 0); queueSort.put(start, 0); open.add(start); Integer next; while ((next = open.poll()) != null) { if (next == target) break; closed.add(next); int free = getIndex(next & 0xffff, next >> 16, _layer); int newCost = g.get(next) + 1000; long nCS = newCost * newCost; if (nCS > lengthSquared * 1440000) continue; for (int i = 0; i < 4; i++) { int neighPos = next + neighOffset[i]; if ((free & neighFree[i]) == 0) continue; if (open.contains(neighPos) && newCost < g.get(neighPos)) open.remove(neighPos); if (closed.contains(neighPos) && newCost < g.get(neighPos)) closed.remove(neighPos); if (!(open.contains(neighPos) || closed.contains(neighPos))) { g.put(neighPos, newCost); queueSort.put(neighPos, newCost + h(neighPos, i, x1, y1, x2, y2)); open.add(neighPos); last.put(neighPos, next); } } } if (next == null) return new Integer[0]; // Draw Path ArrayList out = new ArrayList(); while (target != start) { out.add(target); target = last.get(target); } out.add(start); return (Integer[]) out.toArray(new Integer[out.size()]); } private int h(int pos, int dir, int x1, int y1, int x2, int y2) { int x = pos & 65535; int y = pos >> 16; // int penalty = 0; int diffX = Math.abs(x2 - x); int diffY = Math.abs(y2 - y); return Math.max(diffX, diffY) * 1001; // if (dir == 0 || dir == 2) // N & S // penalty = diffX > diffY ? 1 : 0; // else // E & W // penalty = diffX > diffY ? 0 : 1; // return (diffX + diffY) * 1002 + penalty; } public long getUsedMemoryMB() { return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); } public void plotMap() throws IOException { JFrame frame = new JFrame("Output"); JPanel panel = new JPanel(new BorderLayout()); frame.setContentPane(panel); _splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); panel.add(_splitPane, BorderLayout.CENTER); _scrollPane = new JScrollPane(); _splitPane.setLeftComponent(_scrollPane); _mapImage = new BufferedImage(2048, 2048, BufferedImage.TYPE_INT_RGB); Icon icon = new ImageIcon(_mapImage, ""); _mapLabel = new JLabel(icon); _scrollPane.setViewportView(_mapLabel); BufferedImage colorScaleImage = new BufferedImage(256 * 5, 8, BufferedImage.TYPE_INT_RGB); Icon colorIcon = new ImageIcon(colorScaleImage, ""); JLabel colorScale = new JLabel(colorIcon); panel.add(colorScale, BorderLayout.NORTH); JPanel sidebarWrapper = new JPanel(new BorderLayout()); _splitPane.setRightComponent(sidebarWrapper); _splitPane.setDividerLocation(1000-270); JPanel sidebarPanel = new JPanel(new GridLayout(0, 1)); sidebarWrapper.add(sidebarPanel, BorderLayout.NORTH); _coordLabel = new JLabel("-----/----- (-----)"); _coordLabel.setBorder(BorderFactory.createTitledBorder("Mouse Position:")); sidebarPanel.add(_coordLabel); _chooseMode = new JComboBox(new String[] { "find quick path", "find path", "check LoS", "check direct path", "Zoom", "Zoom3D" }); _chooseMode.setBorder(BorderFactory.createTitledBorder("Choose Mode:")); _chooseMode.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _mode = _chooseMode.getSelectedIndex(); } }); sidebarPanel.add(_chooseMode); _zoomImage = new BufferedImage(256+32/4,256+32/4, BufferedImage.TYPE_INT_RGB); Icon zoomIcon = new ImageIcon(_zoomImage, ""); _zoomLabel = new JLabel(zoomIcon); _zoomLabel.setDoubleBuffered(true); sidebarWrapper.add(_zoomLabel, BorderLayout.CENTER); frame.setSize(1000, 750); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); MouseListener mouseListener = new MouseListener(); _mapLabel.addMouseListener(mouseListener); _mapLabel.addMouseMotionListener(mouseListener); MouseWheelListener wheelListener = new MouseWheelListener() { public void mouseWheelMoved(MouseWheelEvent e) { int rotate = e.getWheelRotation(); rotate += _chooseMode.getSelectedIndex(); if (rotate >= 0 && rotate < _chooseMode.getItemCount()) { _chooseMode.setSelectedIndex(rotate); } } }; _mapLabel.addMouseWheelListener(wheelListener); _minZ = Short.MAX_VALUE; _maxZ = Short.MIN_VALUE; _colorRange = new int[256 * 5]; int index = 0; File dir = new File("./data/geodata/" + _rx + "_" + _ry); for (int c = 0; c < 256; index++, c++) { _colorRange[index] = 255 + (255 - c) * 65536; for (int y = 0; y < 8; y++) { colorScaleImage.setRGB(c, y, _colorRange[index]); } } for (int c = 0; c < 256; index++, c++) { _colorRange[index] = 255 + c * 256; for (int y = 0; y < 8; y++) { colorScaleImage.setRGB(c + 256, y, _colorRange[index]); } } for (int c = 0; c < 256; index++, c++) { _colorRange[index] = 255 * 256 + (255 - c); for (int y = 0; y < 8; y++) { colorScaleImage.setRGB(c + 512, y, _colorRange[index]); } } for (int c = 0; c < 256; index++, c++) { _colorRange[index] = 255 * 256 + c * 65536; for (int y = 0; y < 8; y++) { colorScaleImage.setRGB(c + 768, y, _colorRange[index]); } } for (int c = 0; c < 256; index++, c++) { _colorRange[index] = 255 * 65536 + (255 - c) * 256; for (int y = 0; y < 8; y++) { colorScaleImage.setRGB(c + 1024, y, _colorRange[index]); } } initializeMinMax(dir); int count[] = new int[16]; Arrays.fill(count, 0); for (int y = 0; y < 2048; y++) { for (int x = 0; x < 2048; x++) { short value = _buffer[x / 128][y / 128][_layer].getShort((x & 127) * 2 + (y & 127) * 256); index = _buffer[x / 128][y / 128][_layer].get(32768 + (x & 127) / 4 + (y & 127) / 4 * 32); drawCell(y, x, value, index, false); count[value & 0xf]++; } _mapLabel.repaint(); } // for (int i = 0; i < 16; i++) { // String b = "000" + Integer.toBinaryString(i); // System.out.println(b.substring(b.length() - 4) + ": " + count[i] + " times"); // } } /** * @param dir * @throws FileNotFoundException * @throws IOException */ private void initializeMinMax(File dir) throws FileNotFoundException, IOException { for (int y = 0; y < 2048; y++) { for (int x = 0; x < 2048; x++) { short value = getCellHeight(x, y, _layer); if (value > _maxZ) _maxZ = value; if (value < _minZ) _minZ = value; } } } /** * @param y * @param x * @param value * @param index * @param zoomed TODO */ private int drawCell(int y, int x, short value, int index, boolean zoomed) { short color = (short) (value & 0xfff0); int c; if (value == 0) c = 0; else { color = (short) ((color - _minZ) * (_colorRange.length - 1) / (_maxZ - _minZ)); if ((index & 0xf) == 15) c = _colorRange[color]; else { c = (_colorRange[color] & 0xfe) / 2 + (_colorRange[color] & 0xfe00) / 2 + (_colorRange[color] & 0xfe0000) / 2; } } if (!zoomed) { _mapImage.setRGB(x, y, c); } return c; } private synchronized ByteBuffer getBuffer(int x, int y, int layer) throws IOException { // int regionX = x >> 11; // int regionY = y >> 11; int fileX = (x >> 7) & 0xf; int fileY = (y >> 7) & 0xf; if (_buffer == null) { loadBuffer(_rx, _ry); } return _buffer[fileX][fileY][layer]; } private int getCellBlock(int x, int y, int layer) throws IOException { ByteBuffer buffer = getBuffer(x, y, layer); int sx = x & 0x7f; int sy = y & 0x7f; return buffer.getShort((sx << 1) + (sy << 8)) & 0xf; } private short getCellHeight(int x, int y, int layer) throws IOException { ByteBuffer buffer = getBuffer(x, y, layer); int sx = x & 0x7f; int sy = y & 0x7f; return (short) (buffer.getShort((sx << 1) + (sy << 8)) & 0xfff0); } private byte getIndex(int x, int y, int layer) throws IOException { ByteBuffer buffer = getBuffer(x, y, layer); int ix = (x >> 2) & 0x1f; int iy = (y >> 2) & 0x1f; return buffer.get(32768 + ix + (iy << 5)); } private void loadBuffer(int fileX, int fileY) throws IOException { File dir = new File("./data/geodata/" + fileX + "_" + fileY + "/"); _maxLayer = countLayers(dir); _buffer = new ByteBuffer[16][16][_maxLayer+1]; ByteBuffer b = ByteBuffer.allocate(32768+1024); int count = 0; for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { for (int l=0; l <= _maxLayer; l++) { _buffer[x][y][l] = b; File f = new File(dir, "block" + x + "_" + y + "_l" + l); if (!f.exists()) { count++; continue; } FileChannel roChannel = new RandomAccessFile(f, "r").getChannel(); long size = (int) roChannel.size(); _buffer[x][y][l] = roChannel.map(FileChannel.MapMode.READ_ONLY, 0, size).load(); } } } } private int countLayers(File dir) { String[] files = dir.list(); int count = 0; for (int i = 0; i < files.length; i++) { if (files[i].startsWith("block")) { int layer = Integer.parseInt(files[i].substring(files[i].lastIndexOf('l')+1)); if (layer > count) { count = layer; } } } return 1; } private void open3DZoom(int x, int y) throws IOException { short[][][] height = new short[32][32][_maxLayer+1]; Date now = new Date(); short minHeight = Short.MAX_VALUE; short maxHeight = Short.MIN_VALUE; for (int xx=0; xx<32; xx++) { for (int yy=0; yy<32; yy++) { for (int l=0; l<=_maxLayer; l++) { short h = getCellHeight(x+xx, y+yy, l); height[xx][yy][l] = h; if (h == 0) continue; if (h > maxHeight) maxHeight = h; if (h < minHeight) minHeight = h; } Arrays.sort(height[0][0]); } } BufferedImage image = new BufferedImage(512 + 256, 512 + 256, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) image.getGraphics(); JFrame frame = new JFrame("3D"); JScrollPane scroll = new JScrollPane(); frame.setContentPane(scroll); ImageIcon icon = new ImageIcon(image, ""); JLabel label = new JLabel(icon); scroll.setViewportView(label); frame.pack(); frame.setVisible(true); frame.toFront(); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { System.gc(); } }); g.clearRect(0,0, image.getWidth(), image.getHeight()); int bottom = 511; int scale = maxHeight - minHeight; if (scale < 512) scale = 512; for (int xx=31; xx>=0 && frame.isShowing(); xx--) { for (int yy=0; yy<32 && frame.isShowing(); yy++) { for (int l=0; l<=0 && frame.isShowing(); l++) { int h = height[xx][yy][l]; if (h == 0) continue; h -= minHeight; h = h * 256 / scale; Polygon p = new Polygon(); p.addPoint(16 * xx + 8 * yy, bottom - 128 + yy * 8 - h); p.addPoint(16 * xx + 8 * yy + 16, bottom - 128 + yy * 8 - h); p.addPoint(16 * xx + 8 * yy + 24, bottom - 128 + yy * 8 - h + 8); p.addPoint(16 * xx + 8 * yy + 8, bottom - 128 + yy * 8 - h + 8); g.setColor(Color.blue); g.fillPolygon(p); g.setColor(Color.white); g.drawPolygon(p); if (xx > 0 && height[xx-1][yy][l] != 0) { int h2 = (height[xx-1][yy][l] - minHeight)*256/scale; p = new Polygon(); p.addPoint(16 * xx + 8 * yy, bottom - 128 + yy * 8 - h); p.addPoint(16 * xx + 8 * yy + 8, bottom - 128 + yy * 8 - h + 8); p.addPoint(16 * xx + 8 * yy + 8, bottom - 128 + yy * 8 - h2 + 8); p.addPoint(16 * xx + 8 * yy, bottom - 128 + yy * 8 - h2); g.setColor(Color.gray); g.fillPolygon(p); g.setColor(Color.white); g.drawPolygon(p); } if (yy < 31 && height[xx][yy+1][l] != 0) { int h2 = (height[xx][yy+1][l] - minHeight)*256/scale; p = new Polygon(); p.addPoint(16 * xx + 8 * yy + 24, bottom - 128 + yy * 8 - h + 8); p.addPoint(16 * xx + 8 * yy + 8, bottom - 128 + yy * 8 - h + 8); p.addPoint(16 * xx + 8 * yy + 8, bottom - 128 + yy * 8 - h2 + 8); p.addPoint(16 * xx + 8 * yy + 24, bottom - 128 + yy * 8 - h2 + 8); g.setColor(Color.red); g.fillPolygon(p); g.setColor(Color.white); g.drawPolygon(p); } } } } label.repaint(); g.dispose(); System.out.println(new Date().getTime() - now.getTime()); } private class MouseListener extends MouseAdapter implements Runnable, MouseMotionListener { private int _x1, _y1, _x2, _y2; private int _moveX, _moveY; private Rectangle _visible; public MouseListener() { } public void mouseMoved(MouseEvent e) { StringBuffer out = new StringBuffer(""); out.append(e.getX()); out.append('/'); out.append(e.getY()); out.append(" (height: "); try { out.append(getCellHeight(e.getX(), e.getY(), _layer)); } catch (IOException e1) { } out.append(')'); _coordLabel.setText(out.toString()); } public void mouseDragged(MouseEvent e) { if (_visible != null && e.getModifiersEx() == MouseEvent.BUTTON3_DOWN_MASK) { Component c = (Component)e.getSource(); Point p = c.getParent().getMousePosition(true); if (p==null) return; Rectangle r = new Rectangle((p.x - _moveX)*2 + _visible.x, (p.y - _moveY)*2 + _visible.y, _visible.width, _visible.height); _mapLabel.scrollRectToVisible(r); } } @Override public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { _x1 = e.getX(); _y1 = e.getY(); } else if(e.getButton() == MouseEvent.BUTTON3) { JLabel c = (JLabel)e.getSource(); Point p = c.getParent().getMousePosition(true); _moveX = p.x; _moveY = p.y; _visible = c.getVisibleRect(); } } @Override public void mouseReleased(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { _x2 = e.getX(); _y2 = e.getY(); new Thread(this).start(); } else if (e.getButton() == MouseEvent.BUTTON2) { // do nothing } } public void run() { try { if (_mode == 3) { int[] target = checkDirectPath(_x1, _y1, _x2, _y2); _mapImage.getGraphics().drawLine(_x1, _y1, target[0], target[1]); } else if (_mode == 2) { System.out.println(checkVisibility(_x1, _y1, _x2, _y2, 64, 64, 200)); } else if (_mode == 1) { Date now = new Date(); int[] path = findPath(_x1, _y1, _x2, _y2); System.out.println(new Date().getTime() - now.getTime()); for (int i = 0; i < path.length; i++) { int x = path[i] & 0xffff; int y = path[i] >> 16; _mapImage.setRGB(x, y, 0xffffff); } } else if (_mode == 0) { Date now = new Date(); Integer[] path1 = findQuickPath(_x1, _y1, _x2, _y2); System.out.println(new Date().getTime() - now.getTime()); if (path1.length < 3) return; Graphics g = _mapImage.getGraphics(); int[] path2 = new int[path1.length - 1]; int[] path3 = new int[path1.length - 2]; for (int i = 1, last = path1[0]; i < path1.length; i++) { int next = path1[i]; path2[i - 1] = ((next + last) & 0xfffeffff) >> 1; last = next; } for (int i = 1, last = path2[0]; i < path2.length; i++) { int next = path2[i]; path3[i - 1] = ((next + last) & 0xfffeffff) >> 1; last = next; } g.drawLine(path1[0] & 0xffff, path1[0] >> 16, path2[0] & 0xffff, path2[0] >> 16); int xx = path2[0] & 0xffff; int yy = path2[0] >> 16; for (int i = 0; i < path3.length; i++) { int x = path3[i] & 0xffff; int y = path3[i] >> 16; g.drawLine(xx, yy, x, y); xx = x; yy = y; } int p2 = path2[path2.length - 1]; int p1 = path1[path1.length - 1]; g.drawLine(xx, yy, p2 & 0xffff, p2 >> 16); g.drawLine(p2 & 0xffff, p2 >> 16, p1 & 0xffff, p1 >> 16); } else if (_mode == 4) { int left = Math.max(_x2 - 16, 0); int top = Math.max(_y2 - 16, 0); _zoomImage.getGraphics().clearRect(0,0,_zoomImage.getWidth(), _zoomImage.getHeight()); for (int x=0; x<32; x++) { for (int y=0; y<32; y++) { ByteBuffer b = _buffer[(x+left)>>7][(y+top)>>7][_layer]; short value = b.getShort(((x+left) & 127) * 2 + ((y+top) & 127) * 256); int index = value & 0xf; int c = drawCell(left+x, top+y,value, index, true); int addX = (x+left)/4 - left/4; int addY = (y+top)/4 - top/4; for (int xx=0; xx<8; xx++) { for (int yy=0; yy<8; yy++) { if (xx==0 || yy==0) { _zoomImage.setRGB((x<<3)+xx+addX, (y<<3)+yy+addY, 0); } else { _zoomImage.setRGB((x<<3)+xx+addX, (y<<3)+yy+addY, c); } } } } } _zoomLabel.repaint(); } else if (_mode == 5) { int left = Math.max(_x2 - 16, 0); int top = Math.max(_y2 - 16, 0); open3DZoom(left, top); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } _mapLabel.repaint(); } } }