mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-01 06:33:38 +01:00
Merge pull request #185 from mikeprimm/master
Add transparency control option to Flat and Surface renderers, file lock fixes
This commit is contained in:
commit
0f0af92c4b
@ -130,6 +130,8 @@ templates:
|
|||||||
# To render a world as a "night view", set shadowstrength and ambientlight
|
# To render a world as a "night view", set shadowstrength and ambientlight
|
||||||
# shadowstrength: 1.0
|
# shadowstrength: 1.0
|
||||||
# ambientlight: 4
|
# ambientlight: 4
|
||||||
|
# Option to turn on transparency support (off by default) - slows render
|
||||||
|
# transparency: true
|
||||||
- class: org.dynmap.kzedmap.KzedMap
|
- class: org.dynmap.kzedmap.KzedMap
|
||||||
renderers:
|
renderers:
|
||||||
- class: org.dynmap.kzedmap.DefaultTileRenderer
|
- class: org.dynmap.kzedmap.DefaultTileRenderer
|
||||||
@ -144,6 +146,8 @@ templates:
|
|||||||
# ambientlight: 4
|
# ambientlight: 4
|
||||||
# To render both night and day versions of tiles (when ambientlight is set), set true
|
# To render both night and day versions of tiles (when ambientlight is set), set true
|
||||||
# night-and-day: true
|
# night-and-day: true
|
||||||
|
# Option to turn off transparency support (on by default) - speeds render
|
||||||
|
# transparency: false
|
||||||
# Sets the icon to 'images/block_custom.png'
|
# Sets the icon to 'images/block_custom.png'
|
||||||
# icon: custom
|
# icon: custom
|
||||||
#- class: org.dynmap.kzedmap.HighlightTileRenderer
|
#- class: org.dynmap.kzedmap.HighlightTileRenderer
|
||||||
@ -214,6 +218,8 @@ worlds:
|
|||||||
# # To render a world as a "night view", set shadowstrength and ambientlight
|
# # To render a world as a "night view", set shadowstrength and ambientlight
|
||||||
# # shadowstrength: 1.0
|
# # shadowstrength: 1.0
|
||||||
# # ambientlight: 4
|
# # ambientlight: 4
|
||||||
|
# # Option to turn on transparency support (off by default) - slows render
|
||||||
|
# # transparency: true
|
||||||
# - class: org.dynmap.kzedmap.KzedMap
|
# - class: org.dynmap.kzedmap.KzedMap
|
||||||
# renderers:
|
# renderers:
|
||||||
# - class: org.dynmap.kzedmap.DefaultTileRenderer
|
# - class: org.dynmap.kzedmap.DefaultTileRenderer
|
||||||
@ -228,6 +234,8 @@ worlds:
|
|||||||
# # ambientlight: 4
|
# # ambientlight: 4
|
||||||
# # To render both night and day versions of tiles (when ambientlight is set), set true
|
# # To render both night and day versions of tiles (when ambientlight is set), set true
|
||||||
# # night-and-day: true
|
# # night-and-day: true
|
||||||
|
# # Option to turn off transparency support (on by default) - speeds render
|
||||||
|
# # transparency: false
|
||||||
# # Sets the icon to 'images/block_custom.png'
|
# # Sets the icon to 'images/block_custom.png'
|
||||||
# # icon: custom
|
# # icon: custom
|
||||||
# #- class: org.dynmap.kzedmap.HighlightTileRenderer
|
# #- class: org.dynmap.kzedmap.HighlightTileRenderer
|
||||||
|
@ -38,6 +38,7 @@ public class FlatMap extends MapType {
|
|||||||
private int ambientlight = 15;;
|
private int ambientlight = 15;;
|
||||||
private int shadowscale[] = null;
|
private int shadowscale[] = null;
|
||||||
private boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
|
private boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
|
||||||
|
protected boolean transparency;
|
||||||
|
|
||||||
public FlatMap(ConfigurationNode configuration) {
|
public FlatMap(ConfigurationNode configuration) {
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
@ -69,6 +70,7 @@ public class FlatMap extends MapType {
|
|||||||
ambientlight = Integer.parseInt(String.valueOf(o));
|
ambientlight = Integer.parseInt(String.valueOf(o));
|
||||||
}
|
}
|
||||||
night_and_day = configuration.getBoolean("night-and-day", false);
|
night_and_day = configuration.getBoolean("night-and-day", false);
|
||||||
|
transparency = configuration.getBoolean("transparency", false); /* Default off */
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -115,8 +117,8 @@ public class FlatMap extends MapType {
|
|||||||
|
|
||||||
boolean rendered = false;
|
boolean rendered = false;
|
||||||
Color rslt = new Color();
|
Color rslt = new Color();
|
||||||
int[] pixel = new int[3];
|
int[] pixel = new int[4];
|
||||||
int[] pixel_day = new int[3];
|
int[] pixel_day = null;
|
||||||
KzedBufferedImage im = KzedMap.allocateBufferedImage(t.size, t.size);
|
KzedBufferedImage im = KzedMap.allocateBufferedImage(t.size, t.size);
|
||||||
int[] argb_buf = im.argb_buf;
|
int[] argb_buf = im.argb_buf;
|
||||||
KzedBufferedImage im_day = null;
|
KzedBufferedImage im_day = null;
|
||||||
@ -124,6 +126,7 @@ public class FlatMap extends MapType {
|
|||||||
if(night_and_day) {
|
if(night_and_day) {
|
||||||
im_day = KzedMap.allocateBufferedImage(t.size, t.size);
|
im_day = KzedMap.allocateBufferedImage(t.size, t.size);
|
||||||
argb_buf_day = im_day.argb_buf;
|
argb_buf_day = im_day.argb_buf;
|
||||||
|
pixel_day = new int[4];
|
||||||
}
|
}
|
||||||
MapChunkCache.MapIterator mapiter = cache.getIterator(t.x * t.size, 127, t.y * t.size);
|
MapChunkCache.MapIterator mapiter = cache.getIterator(t.x * t.size, 127, t.y * t.size);
|
||||||
for (int x = 0; x < t.size; x++) {
|
for (int x = 0; x < t.size; x++) {
|
||||||
@ -178,20 +181,27 @@ public class FlatMap extends MapType {
|
|||||||
pixel[0] = c.getRed();
|
pixel[0] = c.getRed();
|
||||||
pixel[1] = c.getGreen();
|
pixel[1] = c.getGreen();
|
||||||
pixel[2] = c.getBlue();
|
pixel[2] = c.getBlue();
|
||||||
|
pixel[3] = c.getAlpha();
|
||||||
|
|
||||||
|
/* If transparency needed, process it */
|
||||||
|
if(transparency && (pixel[3] < 255)) {
|
||||||
|
process_transparent(pixel, pixel_day, mapiter);
|
||||||
|
}
|
||||||
/* If ambient light less than 15, do scaling */
|
/* If ambient light less than 15, do scaling */
|
||||||
if((shadowscale != null) && (ambientlight < 15)) {
|
else if((shadowscale != null) && (ambientlight < 15)) {
|
||||||
if(mapiter.y < 127)
|
if(mapiter.y < 127)
|
||||||
mapiter.incrementY();
|
mapiter.incrementY();
|
||||||
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
|
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
|
||||||
pixel_day[0] = pixel[0];
|
pixel_day[0] = pixel[0];
|
||||||
pixel_day[1] = pixel[1];
|
pixel_day[1] = pixel[1];
|
||||||
pixel_day[2] = pixel[2];
|
pixel_day[2] = pixel[2];
|
||||||
|
pixel_day[3] = 255;
|
||||||
}
|
}
|
||||||
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
|
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
|
||||||
pixel[0] = (pixel[0] * shadowscale[light]) >> 8;
|
pixel[0] = (pixel[0] * shadowscale[light]) >> 8;
|
||||||
pixel[1] = (pixel[1] * shadowscale[light]) >> 8;
|
pixel[1] = (pixel[1] * shadowscale[light]) >> 8;
|
||||||
pixel[2] = (pixel[2] * shadowscale[light]) >> 8;
|
pixel[2] = (pixel[2] * shadowscale[light]) >> 8;
|
||||||
|
pixel[3] = 255;
|
||||||
}
|
}
|
||||||
else { /* Only do height keying if we're not messing with ambient light */
|
else { /* Only do height keying if we're not messing with ambient light */
|
||||||
boolean below = mapiter.y < 64;
|
boolean below = mapiter.y < 64;
|
||||||
@ -215,22 +225,25 @@ public class FlatMap extends MapType {
|
|||||||
pixel[0] -= pixel[0] * scale;
|
pixel[0] -= pixel[0] * scale;
|
||||||
pixel[1] -= pixel[1] * scale;
|
pixel[1] -= pixel[1] * scale;
|
||||||
pixel[2] -= pixel[2] * scale;
|
pixel[2] -= pixel[2] * scale;
|
||||||
|
pixel[3] = 255;
|
||||||
} else {
|
} else {
|
||||||
pixel[0] += (255-pixel[0]) * scale;
|
pixel[0] += (255-pixel[0]) * scale;
|
||||||
pixel[1] += (255-pixel[1]) * scale;
|
pixel[1] += (255-pixel[1]) * scale;
|
||||||
pixel[2] += (255-pixel[2]) * scale;
|
pixel[2] += (255-pixel[2]) * scale;
|
||||||
|
pixel[3] = 255;
|
||||||
}
|
}
|
||||||
if(night_and_day) {
|
if(night_and_day) {
|
||||||
pixel_day[0] = pixel[0];
|
pixel_day[0] = pixel[0];
|
||||||
pixel_day[1] = pixel[1];
|
pixel_day[1] = pixel[1];
|
||||||
pixel_day[2] = pixel[2];
|
pixel_day[2] = pixel[2];
|
||||||
|
pixel_day[3] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
rslt.setRGBA(pixel[0], pixel[1], pixel[2], 255);
|
rslt.setRGBA(pixel[0], pixel[1], pixel[2], pixel[3]);
|
||||||
argb_buf[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
|
argb_buf[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
|
||||||
if(night_and_day) {
|
if(night_and_day) {
|
||||||
rslt.setRGBA(pixel_day[0], pixel_day[1], pixel_day[2], 255);
|
rslt.setRGBA(pixel_day[0], pixel_day[1], pixel_day[2], pixel[3]);
|
||||||
argb_buf_day[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
|
argb_buf_day[(t.size-y-1) + (x*t.size)] = rslt.getARGB();
|
||||||
}
|
}
|
||||||
rendered = true;
|
rendered = true;
|
||||||
@ -291,6 +304,75 @@ public class FlatMap extends MapType {
|
|||||||
|
|
||||||
return rendered;
|
return rendered;
|
||||||
}
|
}
|
||||||
|
private void process_transparent(int[] pixel, int[] pixel_day, MapChunkCache.MapIterator mapiter) {
|
||||||
|
int r = pixel[0], g = pixel[1], b = pixel[2], a = pixel[3];
|
||||||
|
int r_day = 0, g_day = 0, b_day = 0, a_day = 0;
|
||||||
|
if(pixel_day != null) {
|
||||||
|
r_day = pixel[0]; g_day = pixel[1]; b_day = pixel[2]; a_day = pixel[3];
|
||||||
|
}
|
||||||
|
/* Handle lighting on cube */
|
||||||
|
if((shadowscale != null) && (ambientlight < 15)) {
|
||||||
|
boolean did_inc = false;
|
||||||
|
if(mapiter.y < 127) {
|
||||||
|
mapiter.incrementY();
|
||||||
|
did_inc = true;
|
||||||
|
}
|
||||||
|
if(night_and_day) { /* Use unscaled color for day (no shadows from above) */
|
||||||
|
r_day = r; g_day = g; b_day = b; a_day = a;
|
||||||
|
}
|
||||||
|
int light = Math.max(ambientlight, mapiter.getBlockEmittedLight());
|
||||||
|
r = (r * shadowscale[light]) >> 8;
|
||||||
|
g = (g * shadowscale[light]) >> 8;
|
||||||
|
b = (b * shadowscale[light]) >> 8;
|
||||||
|
if(did_inc)
|
||||||
|
mapiter.decrementY();
|
||||||
|
}
|
||||||
|
if(a < 255) { /* If not opaque */
|
||||||
|
pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0;
|
||||||
|
if(pixel_day != null)
|
||||||
|
pixel_day[0] = pixel_day[1] = pixel_day[2] = pixel_day[3] = 0;
|
||||||
|
mapiter.decrementY();
|
||||||
|
if(mapiter.y >= 0) {
|
||||||
|
int blockType = mapiter.getBlockTypeID();
|
||||||
|
int data = 0;
|
||||||
|
Color[] colors = colorScheme.colors[blockType];
|
||||||
|
if(colorScheme.datacolors[blockType] != null) {
|
||||||
|
data = mapiter.getBlockData();
|
||||||
|
colors = colorScheme.datacolors[blockType][data];
|
||||||
|
}
|
||||||
|
if (colors != null) {
|
||||||
|
Color c = colors[0];
|
||||||
|
if (c != null) {
|
||||||
|
pixel[0] = c.getRed();
|
||||||
|
pixel[1] = c.getGreen();
|
||||||
|
pixel[2] = c.getBlue();
|
||||||
|
pixel[3] = c.getAlpha();
|
||||||
|
/* Recurse to resolve color here */
|
||||||
|
process_transparent(pixel, pixel_day, mapiter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Blend colors from behind block and block, based on alpha */
|
||||||
|
r *= a;
|
||||||
|
g *= a;
|
||||||
|
b *= a;
|
||||||
|
int na = 255 - a;
|
||||||
|
pixel[0] = (pixel[0] * na + r) >> 8;
|
||||||
|
pixel[1] = (pixel[1] * na + g) >> 8;
|
||||||
|
pixel[2] = (pixel[2] * na + b) >> 8;
|
||||||
|
pixel[3] = 255;
|
||||||
|
if(pixel_day != null) {
|
||||||
|
r_day *= a_day;
|
||||||
|
g_day *= a_day;
|
||||||
|
b_day *= a_day;
|
||||||
|
na = 255 - a_day;
|
||||||
|
pixel_day[0] = (pixel_day[0] * na + r_day) >> 8;
|
||||||
|
pixel_day[1] = (pixel_day[1] * na + g_day) >> 8;
|
||||||
|
pixel_day[2] = (pixel_day[2] * na + b_day) >> 8;
|
||||||
|
pixel_day[3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return prefix;
|
return prefix;
|
||||||
|
@ -36,6 +36,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
|
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
|
||||||
protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */
|
protected int lightscale[]; /* scale skylight level (light = lightscale[skylight] */
|
||||||
protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
|
protected boolean night_and_day; /* If true, render both day (prefix+'-day') and night (prefix) tiles */
|
||||||
|
protected boolean transparency; /* Is transparency support active? */
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@ -78,6 +79,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
}
|
}
|
||||||
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
|
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
|
||||||
night_and_day = configuration.getBoolean("night-and-day", false);
|
night_and_day = configuration.getBoolean("night-and-day", false);
|
||||||
|
transparency = configuration.getBoolean("transparency", true); /* Default on */
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) {
|
public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) {
|
||||||
@ -438,10 +440,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
|||||||
if (colors != null) {
|
if (colors != null) {
|
||||||
Color c = colors[seq];
|
Color c = colors[seq];
|
||||||
if (c.getAlpha() > 0) {
|
if (c.getAlpha() > 0) {
|
||||||
/* we found something that isn't transparent! */
|
/* we found something that isn't transparent, or not doing transparency */
|
||||||
if (c.getAlpha() == 255) {
|
if ((!transparency) || (c.getAlpha() == 255)) {
|
||||||
/* it's opaque - the ray ends here */
|
/* it's opaque - the ray ends here */
|
||||||
result.setColor(c);
|
result.setARGB(c.getARGB() | 0xFF000000);
|
||||||
if(lightlevel < 15) { /* Not full light? */
|
if(lightlevel < 15) { /* Not full light? */
|
||||||
shadowColor(result, lightlevel);
|
shadowColor(result, lightlevel);
|
||||||
}
|
}
|
||||||
|
@ -113,15 +113,17 @@ public abstract class FileHandler implements HttpHandler {
|
|||||||
out.write(readBuffer, 0, readBytes);
|
out.write(readBuffer, 0, readBytes);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
fileInput.close();
|
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
freeReadBuffer(readBuffer);
|
freeReadBuffer(readBuffer);
|
||||||
|
if(fileInput != null) {
|
||||||
|
closeFileInput(path, fileInput);
|
||||||
|
fileInput = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
closeFileInput(path, fileInput);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (fileInput != null) {
|
if (fileInput != null) {
|
||||||
try { fileInput.close(); } catch (IOException ex) { }
|
try { closeFileInput(path, fileInput); fileInput = null; } catch (IOException ex) { }
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public class FilesystemHandler extends FileHandler {
|
|||||||
try {
|
try {
|
||||||
result = new FileInputStream(file);
|
result = new FileInputStream(file);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
|
FileLockManager.releaseReadLock(file);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
response.fields.put(HttpField.ContentLength, Long.toString(file.length()));
|
response.fields.put(HttpField.ContentLength, Long.toString(file.length()));
|
||||||
|
Loading…
Reference in New Issue
Block a user