rendered paste bodyimport 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<Integer> {
private Map<Integer, Integer> _costs;
public CellComparater(Map<Integer, Integer> 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<Integer, Integer> g = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> queueSort = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> last = new HashMap<Integer, Integer>();
PriorityQueue<Integer> open = new PriorityQueue<Integer>(100, new CellComparater(queueSort));
HashSet<Integer> closed = new HashSet<Integer>();
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<Integer, Integer> g = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> queueSort = new HashMap<Integer, Integer>();
HashMap<Integer, Integer> last = new HashMap<Integer, Integer>();
PriorityQueue<Integer> open = new PriorityQueue<Integer>(100, new CellComparater(queueSort));
HashSet<Integer> closed = new HashSet<Integer>();
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<Integer> out = new ArrayList<Integer>();
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("<html>");
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();
}
}
}