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

View File

@ -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;
}
}
}

View File

@ -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());
}
}