Re-merge the nether render support, and update race condition fixes

This commit is contained in:
Mike Primm 2011-05-14 23:25:59 -05:00
parent 600dd00bcd
commit 0ffc825b05
9 changed files with 197 additions and 154 deletions

View file

@ -12,7 +12,9 @@ import java.util.Map;
import javax.imageio.ImageIO;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.dynmap.Client;
import org.dynmap.ColorScheme;
import org.dynmap.MapManager;
@ -28,25 +30,6 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
protected Color highlightColor = new Color(255, 0, 0);
private static final Color[] woolshades = {
Color.WHITE,
Color.ORANGE,
Color.MAGENTA,
new Color(51,204,255),
Color.YELLOW,
new Color(102,255,102),
Color.PINK,
Color.GRAY,
Color.LIGHT_GRAY,
Color.CYAN,
new Color(255,0,255),
Color.BLUE,
new Color(102,51,51),
Color.GREEN,
Color.RED,
Color.BLACK
};
@Override
public String getName() {
return name;
@ -65,6 +48,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
public boolean render(KzedMapTile tile, File outputFile) {
World world = tile.getWorld();
boolean isnether = (world.getEnvironment() == Environment.NETHER);
BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
WritableRaster r = im.getRaster();
@ -74,6 +58,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
int iy = maximumHeight;
int iz = KzedMap.anchorz + tile.px / 2 - tile.py / 2 + ((127-maximumHeight)/2);
/* Don't mess with existing height-clipped renders */
if(maximumHeight < 127)
isnether = false;
int jx, jz;
int x, y;
@ -84,8 +72,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
jz = iz;
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
Color c1 = scan(world, jx, iy, jz, 0);
Color c2 = scan(world, jx, iy, jz, 2);
Color c1 = scan(world, jx, iy, jz, 0, isnether);
Color c2 = scan(world, jx, iy, jz, 2, isnether);
isempty = isempty && c1 == translucent && c2 == translucent;
r.setPixel(x, y, new int[] {
c1.getRed(),
@ -107,10 +95,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
jz = iz - 1;
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
Color c1 = scan(world, jx, iy, jz, 2);
Color c1 = scan(world, jx, iy, jz, 2, isnether);
jx++;
jz++;
Color c2 = scan(world, jx, iy, jz, 0);
Color c2 = scan(world, jx, iy, jz, 0, isnether);
isempty = isempty && c1 == translucent && c2 == translucent;
r.setPixel(x, y, new int[] {
c1.getRed(),
@ -132,100 +120,112 @@ public class DefaultTileRenderer implements MapTileRenderer {
final File fname = outputFile;
final KzedMapTile mtile = tile;
final BufferedImage img = im;
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
(KzedMap) mtile.getMap(), mtile);
final File zoomFile = MapManager.mapman.getTileFile(zmtile);
MapManager.mapman.enqueueImageWrite(new Runnable() {
public void run() {
doFileWrites(fname, mtile, img, zmtile, zoomFile);
}
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
(KzedMap) mtile.getMap(), mtile);
final File zoomFile = MapManager.mapman.getTileFile(zmtile);
MapManager.mapman.enqueueImageWrite(new Runnable() {
public void run() {
doFileWrites(fname, mtile, img, zmtile, zoomFile);
}
});
return !isempty;
}
private void doFileWrites(final File fname, final KzedMapTile mtile,
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) {
Debug.debug("saving image " + fname.getPath());
try {
ImageIO.write(img, "png", fname);
} catch (IOException e) {
Debug.error("Failed to save image: " + fname.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
}
mtile.file = fname;
// Since we've already got the new tile, and we're on an async thread, just
// make the zoomed tile here
int px = mtile.px;
int py = mtile.py;
int zpx = zmtile.getTileX();
int zpy = zmtile.getTileY();
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) {
Debug.debug("saving image " + fname.getPath());
try {
ImageIO.write(img, "png", fname);
} catch (IOException e) {
Debug.error("Failed to save image: " + fname.getPath(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
}
mtile.file = fname;
// Since we've already got the new tile, and we're on an async thread, just
// make the zoomed tile here
int px = mtile.px;
int py = mtile.py;
int zpx = zmtile.getTileX();
int zpy = zmtile.getTileY();
/* scaled size */
int scw = KzedMap.tileWidth / 2;
int sch = KzedMap.tileHeight / 2;
/* scaled size */
int scw = KzedMap.tileWidth / 2;
int sch = KzedMap.tileHeight / 2;
/* origin in zoomed-out tile */
int ox = 0;
int oy = 0;
/* origin in zoomed-out tile */
int ox = 0;
int oy = 0;
if (zpx != px)
ox = scw;
if (zpy != py)
oy = sch;
if (zpx != px)
ox = scw;
if (zpy != py)
oy = sch;
BufferedImage zIm = null;
try {
zIm = ImageIO.read(zoomFile);
} catch (IOException e) {
} catch (IndexOutOfBoundsException e) {
}
BufferedImage zIm = null;
try {
zIm = ImageIO.read(zoomFile);
} catch (IOException e) {
} catch (IndexOutOfBoundsException e) {
}
if (zIm == null) {
/* create new one */
zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
Debug.debug("New zoom-out tile created " + zmtile.getFilename());
} else {
Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename());
}
/* blit scaled rendered tile onto zoom-out tile */
Graphics2D g2 = zIm.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, ox, oy, scw, sch, null);
if (zIm == null) {
/* create new one */
zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
Debug.debug("New zoom-out tile created " + zmtile.getFilename());
} else {
Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename());
}
/* blit scaled rendered tile onto zoom-out tile */
Graphics2D g2 = zIm.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, ox, oy, scw, sch, null);
img.flush();
img.flush();
/* save zoom-out tile */
try {
ImageIO.write(zIm, "png", zoomFile);
Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
} catch (IOException e) {
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e);
}
zIm.flush();
/* Push updates for both files.*/
MapManager.mapman.pushUpdate(mtile.getWorld(),
new Client.Tile(mtile.getFilename()));
MapManager.mapman.pushUpdate(zmtile.getWorld(),
new Client.Tile(zmtile.getFilename()));
/* save zoom-out tile */
try {
ImageIO.write(zIm, "png", zoomFile);
Debug.debug("Saved zoom-out tile at " + zoomFile.getName());
} catch (IOException e) {
Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e);
} catch (java.lang.NullPointerException e) {
Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e);
}
zIm.flush();
/* Push updates for both files.*/
MapManager.mapman.pushUpdate(mtile.getWorld(),
new Client.Tile(mtile.getFilename()));
MapManager.mapman.pushUpdate(zmtile.getWorld(),
new Client.Tile(zmtile.getFilename()));
}
protected Color scan(World world, int x, int y, int z, int seq) {
protected Color scan(World world, int x, int y, int z, int seq, boolean isnether) {
Color result = translucent;
for (;;) {
if (y < 0)
return translucent;
if (y < 0) {
return result;
}
int id = world.getBlockTypeIdAt(x, y, z);
byte data = 0;
if(colorScheme.datacolors[id] != null) { /* If data colored */
data = world.getBlockAt(x, y, z).getData();
if(isnether) { /* Make bedrock ceiling into air in nether */
if(id != 0) {
/* Remember first color we see, in case we wind up solid */
if(result == translucent)
if(colorScheme.colors[id] != null)
result = colorScheme.colors[id][seq];
id = 0;
}
else
isnether = false;
}
if(colorScheme.datacolors[id] != null) { /* If data colored */
data = world.getBlockAt(x, y, z).getData();
}
switch (seq) {
case 0:
@ -250,9 +250,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
}
Color[] colors;
if(data != 0)
colors = colorScheme.datacolors[id][data];
colors = colorScheme.datacolors[id][data];
else
colors = colorScheme.colors[id];
colors = colorScheme.colors[id];
if (colors != null) {
Color c = colors[seq];
if (c.getAlpha() > 0) {
@ -263,7 +263,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
}
/* this block is transparent, so recurse */
Color bg = scan(world, x, y, z, seq);
Color bg = scan(world, x, y, z, seq, isnether);
int cr = c.getRed();
int cg = c.getGreen();