Add shadowstrength attribute for surface renderer - enables shadows

based on top-down chunk sky light data
This commit is contained in:
Mike Primm 2011-05-20 20:52:34 -05:00
parent 920dea04ee
commit 992a905b0a
3 changed files with 257 additions and 199 deletions

View File

@ -1,195 +1,197 @@
# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/plugins/dynmap/ # All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/plugins/dynmap/
# Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false) # Treat hiddenplayers.txt as a whitelist for players to be shown on the map? (Default false)
display-whitelist: false display-whitelist: false
# How often a tile gets rendered (in seconds). # How often a tile gets rendered (in seconds).
renderinterval: 1 renderinterval: 1
# Do render on main thread - may generate more server load, but safer and fixes broken tiles # Do render on main thread - may generate more server load, but safer and fixes broken tiles
renderonsync: true renderonsync: true
render-triggers: render-triggers:
# - chunkloaded # - chunkloaded
# - playermove # - playermove
# - playerjoin # - playerjoin
- blockplaced - blockplaced
- blockbreak - blockbreak
# The path where the tile-files are placed. # The path where the tile-files are placed.
tilespath: web/tiles tilespath: web/tiles
# The path where the web-files are located. # The path where the web-files are located.
webpath: web webpath: web
# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access). # The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access).
webserver-bindaddress: 0.0.0.0 webserver-bindaddress: 0.0.0.0
# The TCP-port the webserver will listen on. # The TCP-port the webserver will listen on.
webserver-port: 8123 webserver-port: 8123
# Disables Webserver portion of Dynmap (Advanced users only) # Disables Webserver portion of Dynmap (Advanced users only)
disable-webserver: false disable-webserver: false
# Writes JSON to file in the webpath # Writes JSON to file in the webpath
jsonfile: false jsonfile: false
# How often the json file gets written to(in seconds) # How often the json file gets written to(in seconds)
jsonfile-interval: 1 jsonfile-interval: 1
# Output player health for web usage # Output player health for web usage
health-in-json: false health-in-json: false
# Use timesliced fullrender - takes a bit longer, but much more polite for server # Use timesliced fullrender - takes a bit longer, but much more polite for server
timeslicerender: true timeslicerender: true
# Period between tile renders for timesliced fullrender, in seconds # Period between tile renders for timesliced fullrender, in seconds
timesliceinterval: 0.5 timesliceinterval: 0.5
# The maptypes Dynmap will use to render. # The maptypes Dynmap will use to render.
worlds: worlds:
- name: world - name: world
maps: maps:
- class: org.dynmap.flat.FlatMap - class: org.dynmap.flat.FlatMap
prefix: flat prefix: flat
colorscheme: default colorscheme: default
- class: org.dynmap.kzedmap.KzedMap - class: org.dynmap.kzedmap.KzedMap
renderers: renderers:
- class: org.dynmap.kzedmap.DefaultTileRenderer - class: org.dynmap.kzedmap.DefaultTileRenderer
prefix: t prefix: t
maximumheight: 127 maximumheight: 127
colorscheme: default colorscheme: default
#- class: org.dynmap.kzedmap.HighlightTileRenderer # Add shadows to world (based on top-down shadows from chunk data)
# prefix: ht # shadowstrength: 1.0
# maximumheight: 127 #- class: org.dynmap.kzedmap.HighlightTileRenderer
# colorscheme: default # prefix: ht
# highlight: # For highlighting multiple block-types. # maximumheight: 127
# - 56 # Highlight diamond-ore # colorscheme: default
# - 66 # Highlight minecart track # highlight: # For highlighting multiple block-types.
# highlight: 56 # For highlighting a single block-type. # - 56 # Highlight diamond-ore
- class: org.dynmap.kzedmap.CaveTileRenderer # - 66 # Highlight minecart track
prefix: ct # highlight: 56 # For highlighting a single block-type.
maximumheight: 127 - class: org.dynmap.kzedmap.CaveTileRenderer
- name: nether prefix: ct
maps: maximumheight: 127
- class: org.dynmap.flat.FlatMap - name: nether
prefix: flat maps:
colorscheme: default - class: org.dynmap.flat.FlatMap
- class: org.dynmap.kzedmap.KzedMap prefix: flat
renderers: colorscheme: default
- class: org.dynmap.kzedmap.DefaultTileRenderer - class: org.dynmap.kzedmap.KzedMap
prefix: nt renderers:
maximumheight: 127 - class: org.dynmap.kzedmap.DefaultTileRenderer
colorscheme: default prefix: nt
maximumheight: 127
web: colorscheme: default
# Handles the clientside updates differently only enable if using jsonfile
jsonfile: false web:
# Handles the clientside updates differently only enable if using jsonfile
# Interval the browser should poll for updates. jsonfile: false
updaterate: 2000
# Interval the browser should poll for updates.
allowchat: true updaterate: 2000
allowwebchat: true
webchat-interval: 5 allowchat: true
# Set to true to enable HeroChat support allowwebchat: true
enableherochat: false webchat-interval: 5
# Control which HeroChat channel messages from web are directed to # Set to true to enable HeroChat support
herochatwebchannel: Global enableherochat: false
# Control which channels are monitored and reported to the web # Control which HeroChat channel messages from web are directed to
herochatchannels: herochatwebchannel: Global
- Global # Control which channels are monitored and reported to the web
#- Trade herochatchannels:
#- Haggle - Global
#- Trade
showplayerfacesinmenu: true #- Haggle
joinmessage: "%playername% joined" showplayerfacesinmenu: true
quitmessage: "%playername% quit"
spammessage: "You may only chat once every %interval% seconds." joinmessage: "%playername% joined"
quitmessage: "%playername% quit"
components: spammessage: "You may only chat once every %interval% seconds."
- type: chat
- type: chatballoon components:
focuschatballoons: false - type: chat
- type: chatbox - type: chatballoon
showplayerfaces: true focuschatballoons: false
messagettl: 5 - type: chatbox
- type: playermarkers showplayerfaces: true
showplayerfaces: true messagettl: 5
showplayerhealth: false - type: playermarkers
#- type: digitalclock showplayerfaces: true
- type: timeofdayclock showplayerhealth: false
showdigitalclock: true #- type: digitalclock
#showweather: true - type: timeofdayclock
#- type: regions showdigitalclock: true
# name: WorldGuard #showweather: true
# useworldpath: true #- type: regions
# filename: regions.yml # name: WorldGuard
# basenode: regions # useworldpath: true
# use3dregions: true # filename: regions.yml
# infowindow: '<div class="infowindow"><span style="font-size:120%;">%regionname% - %priority% (%parent%)</span><br /> Owners <span style="font-weight:bold;">%playerowners% %groupowners%</span><br />Members <span style="font-weight:bold;">%playermembers% %groupmembers%</span><br />Flags<br /><span style="font-weight:bold;">%flags%</span></div>' # basenode: regions
# regionstyle: # use3dregions: true
# strokeColor: "#FF0000" # infowindow: '<div class="infowindow"><span style="font-size:120%;">%regionname% - %priority% (%parent%)</span><br /> Owners <span style="font-weight:bold;">%playerowners% %groupowners%</span><br />Members <span style="font-weight:bold;">%playermembers% %groupmembers%</span><br />Flags<br /><span style="font-weight:bold;">%flags%</span></div>'
# strokeOpacity: 0.8 # regionstyle:
# strokeWeight: 3 # strokeColor: "#FF0000"
# fillColor: "#FF0000" # strokeOpacity: 0.8
# fillOpacity: 0.35 # strokeWeight: 3
# fillColor: "#FF0000"
defaultzoom: 0 # fillOpacity: 0.35
defaultworld: world
worlds: defaultzoom: 0
- title: World defaultworld: world
name: world worlds:
center: - title: World
x: 0 name: world
y: 64 center:
z: 0 x: 0
maps: y: 64
- type: FlatMapType z: 0
title: Flat maps:
name: flat - type: FlatMapType
prefix: flat title: Flat
- type: KzedMapType name: flat
title: Surface prefix: flat
name: surface - type: KzedMapType
prefix: t title: Surface
#- type: KzedMapType name: surface
# title: Highlighted Map prefix: t
# name: highlight #- type: KzedMapType
# prefix: ht # title: Highlighted Map
- type: KzedMapType # name: highlight
title: Cave # prefix: ht
name: cave - type: KzedMapType
prefix: ct title: Cave
- title: Nether name: cave
name: nether prefix: ct
center: - title: Nether
x: 0 name: nether
y: 64 center:
z: 0 x: 0
maps: y: 64
- type: FlatMapType z: 0
title: Flat maps:
name: flat - type: FlatMapType
prefix: flat title: Flat
- type: KzedMapType name: flat
title: Surface prefix: flat
name: nether - type: KzedMapType
prefix: nt title: Surface
# Example: name: nether
#- title: Other World # With what name the world is displayed. prefix: nt
# name: world_other # The actual name of the world (equal to your directory-name). # Example:
# maps: #- title: Other World # With what name the world is displayed.
# - type: KzedMapType # The type (or perspective) of the map. At the moment, there are no others than KzedMapType. # name: world_other # The actual name of the world (equal to your directory-name).
# title: Surface # The name of the map that will be displayed. # maps:
# name: surface # The actual name of the map (should be unique for this world). # - type: KzedMapType # The type (or perspective) of the map. At the moment, there are no others than KzedMapType.
# prefix: t # The prefix of the tile-files that are generated. # title: Surface # The name of the map that will be displayed.
# icon: images/block_other.png # Sets a custom icon for the map. (optional) # name: surface # The actual name of the map (should be unique for this world).
# - type: KzedMapType # prefix: t # The prefix of the tile-files that are generated.
# title: Cave # icon: images/block_other.png # Sets a custom icon for the map. (optional)
# name: cave # - type: KzedMapType
# prefix: ct # title: Cave
# Enables debugging. # name: cave
#debuggers: # prefix: ct
# - class: org.dynmap.debug.LogDebugger # Enables debugging.
#debuggers:
# - class: org.dynmap.debug.LogDebugger

View File

@ -89,8 +89,8 @@ public class MapChunkCache {
Object cc = gethandle.invoke(c); Object cc = gethandle.invoke(c);
byte[] buf = new byte[32768 + 16384 + 16384 + 16384]; /* Get big enough buffer for whole chunk */ 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); getchunkdata.invoke(cc, buf, 0, 0, 0, 16, 128, 16, 0);
snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = CraftChunkSnapshot ss = new CraftChunkSnapshot(chunk.x, chunk.z, buf);
new CraftChunkSnapshot(chunk.x, chunk.z, buf); snaparray[(chunk.x-x_min) + (chunk.z - z_min)*x_dim] = ss;
} catch (Exception x) { } catch (Exception x) {
} }
} }
@ -195,4 +195,19 @@ public class MapChunkCache {
return w.getHighestBlockYAt(x, z); 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;
}
}
} }

View File

@ -29,6 +29,7 @@ public class DefaultTileRenderer implements MapTileRenderer {
protected HashSet<Integer> highlightBlocks = new HashSet<Integer>(); protected HashSet<Integer> highlightBlocks = new HashSet<Integer>();
protected Color highlightColor = new Color(255, 0, 0); protected Color highlightColor = new Color(255, 0, 0);
protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
@Override @Override
public String getName() { public String getName() {
return name; return name;
@ -42,6 +43,19 @@ public class DefaultTileRenderer implements MapTileRenderer {
if (maximumHeight > 127) if (maximumHeight > 127)
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")); colorScheme = ColorScheme.getScheme((String)configuration.get("colorscheme"));
} }
@ -210,9 +224,14 @@ public class DefaultTileRenderer implements MapTileRenderer {
new Client.Tile(zmtile.getFilename())); new Client.Tile(zmtile.getFilename()));
} }
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);
}
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) {
@ -234,6 +253,10 @@ public class DefaultTileRenderer implements MapTileRenderer {
if(colorScheme.datacolors[id] != null) { /* If data colored */ if(colorScheme.datacolors[id] != null) { /* If data colored */
data = cache.getBlockData(x, y, z); data = cache.getBlockData(x, y, z);
} }
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--;
@ -268,16 +291,25 @@ public class DefaultTileRenderer implements MapTileRenderer {
if (c.getAlpha() == 255) { if (c.getAlpha() == 255) {
/* it's opaque - the ray ends here */ /* it's opaque - the ray ends here */
result.setColor(c); result.setColor(c);
if(lightlevel < 15) { /* Not full light? */
shadowColor(result, lightlevel);
}
return; return;
} }
/* this block is transparent, so recurse */ /* 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 cr = c.getRed();
int cg = c.getGreen(); int cg = c.getGreen();
int cb = c.getBlue(); int cb = c.getBlue();
int ca = c.getAlpha(); 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; cr *= ca;
cg *= ca; cg *= ca;
cb *= 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());
}
} }