mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-28 13:15:30 +01:00
Add shadowstrength attribute for surface renderer - enables shadows
based on top-down chunk sky light data
This commit is contained in:
parent
920dea04ee
commit
992a905b0a
@ -59,6 +59,8 @@ worlds:
|
||||
prefix: t
|
||||
maximumheight: 127
|
||||
colorscheme: default
|
||||
# Add shadows to world (based on top-down shadows from chunk data)
|
||||
# shadowstrength: 1.0
|
||||
#- class: org.dynmap.kzedmap.HighlightTileRenderer
|
||||
# prefix: ht
|
||||
# maximumheight: 127
|
||||
|
@ -89,8 +89,8 @@ public class MapChunkCache {
|
||||
Object cc = gethandle.invoke(c);
|
||||
byte[] buf = new byte[32768 + 16384 + 16384 + 16384]; /* Get big enough buffer for whole chunk */
|
||||
getchunkdata.invoke(cc, buf, 0, 0, 0, 16, 128, 16, 0);
|
||||
snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] =
|
||||
new CraftChunkSnapshot(chunk.x, chunk.z, buf);
|
||||
CraftChunkSnapshot ss = new CraftChunkSnapshot(chunk.x, chunk.z, buf);
|
||||
snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss;
|
||||
} catch (Exception x) {
|
||||
}
|
||||
}
|
||||
@ -195,4 +195,19 @@ public class MapChunkCache {
|
||||
return w.getHighestBlockYAt(x, z);
|
||||
}
|
||||
}
|
||||
/* Get sky light level
|
||||
*/
|
||||
public int getBlockSkyLight(int x, int y, int z) {
|
||||
if(snaparray != null) {
|
||||
CraftChunkSnapshot ss = snaparray[((x>>4) - x_min) + ((z>>4) - z_min) * x_dim];
|
||||
if(ss == null) {
|
||||
return 15;
|
||||
}
|
||||
else
|
||||
return ss.getBlockSkyLight(x & 0xF, y, z & 0xF);
|
||||
}
|
||||
else {
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
|
||||
protected Color highlightColor = new Color(255, 0, 0);
|
||||
|
||||
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
@ -42,6 +43,19 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
if (maximumHeight > 127)
|
||||
maximumHeight = 127;
|
||||
}
|
||||
o = configuration.get("shadowstrength");
|
||||
if(o != null) {
|
||||
double shadowweight = Double.parseDouble(String.valueOf(o));
|
||||
if(shadowweight > 0.0) {
|
||||
shadowscale = new int[16];
|
||||
for(int i = 0; i < 16; i++) {
|
||||
double v = 256.0 * (1.0 - (shadowweight * (15-i) / 15.0));
|
||||
shadowscale[i] = (int)v;
|
||||
if(shadowscale[i] > 256) shadowscale[i] = 256;
|
||||
if(shadowscale[i] < 0) shadowscale[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
|
||||
}
|
||||
|
||||
@ -210,9 +224,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
new Client.Tile(zmtile.getFilename()));
|
||||
}
|
||||
|
||||
|
||||
protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result,
|
||||
MapChunkCache cache) {
|
||||
scan(world, x, y, z, seq, isnether, result, cache, 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();
|
||||
for (;;) {
|
||||
if (y < 0) {
|
||||
@ -234,6 +253,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
if(colorScheme.datacolors[id] != null) { /* If data colored */
|
||||
data = cache.getBlockData(x, y, z);
|
||||
}
|
||||
if(shadowscale != null) {
|
||||
newlightlevel = cache.getBlockSkyLight(x, y, z); /* Remember this - light path for next block */
|
||||
}
|
||||
|
||||
switch (seq) {
|
||||
case 0:
|
||||
x--;
|
||||
@ -268,16 +291,25 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
if (c.getAlpha() == 255) {
|
||||
/* it's opaque - the ray ends here */
|
||||
result.setColor(c);
|
||||
if(lightlevel < 15) { /* Not full light? */
|
||||
shadowColor(result, lightlevel);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* this block is transparent, so recurse */
|
||||
scan(world, x, y, z, seq, isnether, result, cache);
|
||||
scan(world, x, y, z, seq, isnether, result, cache, newlightlevel);
|
||||
|
||||
int cr = c.getRed();
|
||||
int cg = c.getGreen();
|
||||
int cb = c.getBlue();
|
||||
int ca = c.getAlpha();
|
||||
if(lightlevel < 15) {
|
||||
int scale = shadowscale[lightlevel];
|
||||
cr = (cr * scale) >> 8;
|
||||
cg = (cg * scale) >> 8;
|
||||
cb = (cb * scale) >> 8;
|
||||
}
|
||||
cr *= ca;
|
||||
cg *= ca;
|
||||
cb *= ca;
|
||||
@ -287,6 +319,15 @@ public class DefaultTileRenderer implements MapTileRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
lightlevel = newlightlevel; /* Advance - next block uses last block's light */
|
||||
}
|
||||
}
|
||||
private final void shadowColor(Color c, int lightlevel) {
|
||||
int scale = shadowscale[lightlevel];
|
||||
if(scale == 0)
|
||||
c.setRGBA(0, 0, 0, c.getAlpha());
|
||||
else if(scale < 256)
|
||||
c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
|
||||
(c.getBlue() * scale) >> 8, c.getAlpha());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user