mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-26 10:37:44 +01:00
Tune shadow render, add to accept wait queue on web server
This commit is contained in:
parent
b56332eae8
commit
024e7dc96c
@ -63,8 +63,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
World world = tile.getWorld();
|
World world = tile.getWorld();
|
||||||
boolean isnether = (world.getEnvironment() == Environment.NETHER);
|
boolean isnether = (world.getEnvironment() == Environment.NETHER);
|
||||||
BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
|
BufferedImage im = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB);
|
||||||
|
BufferedImage zim = new BufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2, BufferedImage.TYPE_INT_RGB);
|
||||||
WritableRaster r = im.getRaster();
|
WritableRaster r = im.getRaster();
|
||||||
|
WritableRaster zr = zim.getRaster();
|
||||||
boolean isempty = true;
|
boolean isempty = true;
|
||||||
|
|
||||||
int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2 - ((127-maximumHeight)/2);
|
int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2 - ((127-maximumHeight)/2);
|
||||||
@ -81,7 +82,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
|
|
||||||
Color c1 = new Color();
|
Color c1 = new Color();
|
||||||
Color c2 = new Color();
|
Color c2 = new Color();
|
||||||
int[] rgb = new int[3];
|
int[] rgb = new int[3*KzedMap.tileWidth];
|
||||||
|
int[] zrgb = new int[3*KzedMap.tileWidth/2];
|
||||||
/* draw the map */
|
/* draw the map */
|
||||||
for (y = 0; y < KzedMap.tileHeight;) {
|
for (y = 0; y < KzedMap.tileHeight;) {
|
||||||
jx = ix;
|
jx = ix;
|
||||||
@ -90,21 +92,27 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
|
for (x = KzedMap.tileWidth - 1; x >= 0; x -= 2) {
|
||||||
scan(world, jx, iy, jz, 0, isnether, c1, cache);
|
scan(world, jx, iy, jz, 0, isnether, c1, cache);
|
||||||
scan(world, jx, iy, jz, 2, isnether, c2, cache);
|
scan(world, jx, iy, jz, 2, isnether, c2, cache);
|
||||||
if(c1.isTransparent() == false) {
|
|
||||||
rgb[0] = c1.getRed(); rgb[1] = c1.getGreen(); rgb[2] = c1.getBlue();
|
|
||||||
r.setPixel(x, y, rgb);
|
|
||||||
isempty = false;
|
|
||||||
}
|
|
||||||
if(c2.isTransparent() == false) {
|
|
||||||
rgb[0] = c2.getRed(); rgb[1] = c2.getGreen(); rgb[2] = c2.getBlue();
|
|
||||||
r.setPixel(x - 1, y, rgb);
|
|
||||||
isempty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
rgb[3*x] = c1.getRed();
|
||||||
|
rgb[3*x+1] = c1.getGreen();
|
||||||
|
rgb[3*x+2] = c1.getBlue();
|
||||||
|
rgb[3*x-3] = c2.getRed();
|
||||||
|
rgb[3*x-2] = c2.getGreen();
|
||||||
|
rgb[3*x-1] = c2.getBlue();
|
||||||
|
|
||||||
|
isempty = isempty && c1.isTransparent() && c2.isTransparent();
|
||||||
|
|
||||||
jx++;
|
jx++;
|
||||||
jz++;
|
jz++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
r.setPixels(0, y, KzedMap.tileWidth, 1, rgb);
|
||||||
|
/* Sum up zoomed pixels - bilinar filter */
|
||||||
|
for(x = 0; x < KzedMap.tileWidth / 2; x++) {
|
||||||
|
zrgb[3*x] = rgb[6*x] + rgb[6*x+3];
|
||||||
|
zrgb[3*x+1] = rgb[6*x+1] + rgb[6*x+4];
|
||||||
|
zrgb[3*x+2] = rgb[6*x+2] + rgb[6*x+5];
|
||||||
|
}
|
||||||
|
|
||||||
y++;
|
y++;
|
||||||
|
|
||||||
@ -116,19 +124,25 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
jx++;
|
jx++;
|
||||||
jz++;
|
jz++;
|
||||||
scan(world, jx, iy, jz, 0, isnether, c2, cache);
|
scan(world, jx, iy, jz, 0, isnether, c2, cache);
|
||||||
if(c1.isTransparent() == false) {
|
|
||||||
rgb[0] = c1.getRed(); rgb[1] = c1.getGreen(); rgb[2] = c1.getBlue();
|
|
||||||
r.setPixel(x, y, rgb);
|
|
||||||
isempty = false;
|
|
||||||
}
|
|
||||||
if(c2.isTransparent() == false) {
|
|
||||||
rgb[0] = c2.getRed(); rgb[1] = c2.getGreen(); rgb[2] = c2.getBlue();
|
|
||||||
|
|
||||||
r.setPixel(x - 1, y, rgb);
|
rgb[3*x] = c1.getRed();
|
||||||
isempty = false;
|
rgb[3*x+1] = c1.getGreen();
|
||||||
}
|
rgb[3*x+2] = c1.getBlue();
|
||||||
|
rgb[3*x-3] = c2.getRed();
|
||||||
|
rgb[3*x-2] = c2.getGreen();
|
||||||
|
rgb[3*x-1] = c2.getBlue();
|
||||||
|
|
||||||
|
isempty = isempty && c1.isTransparent() && c2.isTransparent();
|
||||||
}
|
}
|
||||||
|
r.setPixels(0, y, KzedMap.tileWidth, 1, rgb);
|
||||||
|
/* Finish summing values for zoomed pixels */
|
||||||
|
for(x = 0; x < KzedMap.tileWidth / 2; x++) {
|
||||||
|
zrgb[3*x] = (zrgb[3*x] + rgb[6*x] + rgb[6*x+3]) >> 2;
|
||||||
|
zrgb[3*x+1] = (zrgb[3*x+1] + rgb[6*x+1] + rgb[6*x+4]) >> 2;
|
||||||
|
zrgb[3*x+2] = (zrgb[3*x+2] + rgb[6*x+2] + rgb[6*x+5]) >> 2;
|
||||||
|
}
|
||||||
|
zr.setPixels(0, y/2, KzedMap.tileWidth/2, 1, zrgb);
|
||||||
|
|
||||||
y++;
|
y++;
|
||||||
|
|
||||||
ix++;
|
ix++;
|
||||||
@ -139,13 +153,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
final File fname = outputFile;
|
final File fname = outputFile;
|
||||||
final KzedMapTile mtile = tile;
|
final KzedMapTile mtile = tile;
|
||||||
final BufferedImage img = im;
|
final BufferedImage img = im;
|
||||||
|
final BufferedImage zimg = zim;
|
||||||
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
|
final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(),
|
||||||
(KzedMap) mtile.getMap(), mtile);
|
(KzedMap) mtile.getMap(), mtile);
|
||||||
final File zoomFile = MapManager.mapman.getTileFile(zmtile);
|
final File zoomFile = MapManager.mapman.getTileFile(zmtile);
|
||||||
|
|
||||||
MapManager.mapman.enqueueImageWrite(new Runnable() {
|
MapManager.mapman.enqueueImageWrite(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
doFileWrites(fname, mtile, img, zmtile, zoomFile);
|
doFileWrites(fname, mtile, img, zmtile, zoomFile, zimg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,7 +168,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doFileWrites(final File fname, final KzedMapTile mtile,
|
private void doFileWrites(final File fname, final KzedMapTile mtile,
|
||||||
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) {
|
final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile,
|
||||||
|
final BufferedImage zimg) {
|
||||||
Debug.debug("saving image " + fname.getPath());
|
Debug.debug("saving image " + fname.getPath());
|
||||||
try {
|
try {
|
||||||
ImageIO.write(img, "png", fname);
|
ImageIO.write(img, "png", fname);
|
||||||
@ -162,6 +178,8 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
} catch (java.lang.NullPointerException e) {
|
} catch (java.lang.NullPointerException e) {
|
||||||
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
|
Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e);
|
||||||
}
|
}
|
||||||
|
img.flush();
|
||||||
|
|
||||||
mtile.file = fname;
|
mtile.file = fname;
|
||||||
// Since we've already got the new tile, and we're on an async thread, just
|
// Since we've already got the new tile, and we're on an async thread, just
|
||||||
// make the zoomed tile here
|
// make the zoomed tile here
|
||||||
@ -199,12 +217,9 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* blit scaled rendered tile onto zoom-out tile */
|
/* blit scaled rendered tile onto zoom-out tile */
|
||||||
Graphics2D g2 = zIm.createGraphics();
|
WritableRaster zim = zIm.getRaster();
|
||||||
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
zim.setRect(ox, oy, zimg.getRaster());
|
||||||
g2.drawImage(img, ox, oy, scw, sch, null);
|
zimg.flush();
|
||||||
g2.dispose(); /* Supposed to speed up non-heap memory recovery */
|
|
||||||
|
|
||||||
img.flush();
|
|
||||||
|
|
||||||
/* save zoom-out tile */
|
/* save zoom-out tile */
|
||||||
|
|
||||||
@ -226,12 +241,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
|
|
||||||
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
|
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
|
||||||
MapChunkCache cache) {
|
MapChunkCache cache) {
|
||||||
scan(world, x, y, z, seq, isnether, result, cache, 15);
|
int lightlevel = 15;
|
||||||
}
|
|
||||||
|
|
||||||
private void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
|
|
||||||
MapChunkCache cache, int lightlevel) {
|
|
||||||
int newlightlevel = 15;
|
|
||||||
result.setTransparent();
|
result.setTransparent();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
@ -250,13 +260,29 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
else
|
else
|
||||||
isnether = false;
|
isnether = false;
|
||||||
}
|
}
|
||||||
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
if(id != 0) { /* No update needed for air */
|
||||||
data = cache.getBlockData(x, y, z);
|
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
||||||
|
data = cache.getBlockData(x, y, z);
|
||||||
|
}
|
||||||
|
if((shadowscale != null) && (y < 127)) {
|
||||||
|
/* Find light level of previous chunk */
|
||||||
|
switch(seq) {
|
||||||
|
case 0:
|
||||||
|
lightlevel = cache.getBlockSkyLight(x, y+1, z);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
lightlevel = cache.getBlockSkyLight(x+1, y, z);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
lightlevel = cache.getBlockSkyLight(x, y+1, z);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
lightlevel = cache.getBlockSkyLight(x, y, z-1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(shadowscale != null) {
|
|
||||||
newlightlevel = cache.getBlockSkyLight(x, y, z); /* Remember this - light path for next block */
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (seq) {
|
switch (seq) {
|
||||||
case 0:
|
case 0:
|
||||||
x--;
|
x--;
|
||||||
@ -298,7 +324,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* this block is transparent, so recurse */
|
/* this block is transparent, so recurse */
|
||||||
scan(world, x, y, z, seq, isnether, result, cache, newlightlevel);
|
scan(world, x, y, z, seq, isnether, result, cache);
|
||||||
|
|
||||||
int cr = c.getRed();
|
int cr = c.getRed();
|
||||||
int cg = c.getGreen();
|
int cg = c.getGreen();
|
||||||
@ -319,14 +345,11 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lightlevel = newlightlevel; /* Advance - next block uses last block's light */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private final void shadowColor(Color c, int lightlevel) {
|
private final void shadowColor(Color c, int lightlevel) {
|
||||||
int scale = shadowscale[lightlevel];
|
int scale = shadowscale[lightlevel];
|
||||||
if(scale == 0)
|
if(scale < 256)
|
||||||
c.setRGBA(0, 0, 0, c.getAlpha());
|
|
||||||
else if(scale < 256)
|
|
||||||
c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
|
c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
|
||||||
(c.getBlue() * scale) >> 8, c.getAlpha());
|
(c.getBlue() * scale) >> 8, c.getAlpha());
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class HttpServer extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void startServer() throws IOException {
|
public void startServer() throws IOException {
|
||||||
sock = new ServerSocket(port, 5, bindAddress);
|
sock = new ServerSocket(port, 50, bindAddress); /* 5 too low - more than a couple users during render will get connect errors on some tile loads */
|
||||||
listeningThread = this;
|
listeningThread = this;
|
||||||
start();
|
start();
|
||||||
Log.info("Dynmap WebServer started on " + bindAddress + ":" + port);
|
Log.info("Dynmap WebServer started on " + bindAddress + ":" + port);
|
||||||
|
Loading…
Reference in New Issue
Block a user