diff --git a/lightings.txt b/lightings.txt
new file mode 100644
index 00000000..f8ec1899
--- /dev/null
+++ b/lightings.txt
@@ -0,0 +1,30 @@
+lightings:
+ # Default lighting - no effects, shadows, day/night
+ - class: org.dynmap.hdmap.DefaultHDLighting
+ name: default
+ # Shadows enabled day mode
+ - class: org.dynmap.hdmap.ShadowHDLighting
+ name: shadows
+ shadowstrength: 1.0
+ # Night view (default moonight level is 4)
+ - class: org.dynmap.hdmap.ShadowHDLighting
+ name: night
+ shadowstrength: 1.0
+ ambientlight: 4
+ # A 'bright' night view (easier to see unlit landscape dimly)
+ - class: org.dynmap.hdmap.ShadowHDLighting
+ name: brightnight
+ shadowstrength: 1.0
+ ambientlight: 8
+ # Night and day view
+ - class: org.dynmap.hdmap.ShadowHDLighting
+ name: nightandday
+ shadowstrength: 1.0
+ ambientlight: 4
+ night-and-day: true
+ # 'Bright' Night and day view
+ - class: org.dynmap.hdmap.ShadowHDLighting
+ name: brightnightandday
+ shadowstrength: 1.0
+ ambientlight: 8
+ night-and-day: true
diff --git a/shaders.txt b/shaders.txt
index 3e75bb75..1d3148df 100644
--- a/shaders.txt
+++ b/shaders.txt
@@ -1,18 +1,36 @@
shaders:
- - class: org.dynmap.hdmap.DefaultHDShader
- name: classic
- colorscheme: default
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: default
+ colorscheme: default
- - class: org.dynmap.hdmap.DefaultHDShader
- name: night
- colorscheme: default
- ambientlight: 4
- shadowstrength: 1.0
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: ovocean
+ colorscheme: ovocean
- - class: org.dynmap.hdmap.DefaultHDShader
- name: daynight
- colorscheme: default
- ambientlight: 4
- shadowstrength: 1.0
- night-and-day: true
-
\ No newline at end of file
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: flames
+ colorscheme: flames
+
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: sk89q
+ colorscheme: sk89q
+
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: biome
+ biomecolored: biome
+
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: temperature
+ biomecolored: temperature
+
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: rainfall
+ biomecolored: rainfall
+
+ - class: org.dynmap.hdmap.DefaultHDShader
+ name: no_transparency
+ colorscheme: default
+ transparency: false
+
+
+
\ No newline at end of file
diff --git a/src/main/assembly/package.xml b/src/main/assembly/package.xml
index 91a9506a..7e457682 100644
--- a/src/main/assembly/package.xml
+++ b/src/main/assembly/package.xml
@@ -29,7 +29,8 @@
configuration.txt
shaders.txt
- perspectives.txt
+ perspectives.txt
+ lightings.txt
diff --git a/src/main/java/org/dynmap/DynmapPlugin.java b/src/main/java/org/dynmap/DynmapPlugin.java
index 0bf23209..59a5df2a 100644
--- a/src/main/java/org/dynmap/DynmapPlugin.java
+++ b/src/main/java/org/dynmap/DynmapPlugin.java
@@ -48,6 +48,7 @@ public class DynmapPlugin extends JavaPlugin {
public ConfigurationNode configuration;
public ConfigurationNode shaderconfig;
public ConfigurationNode perspectiveconfig;
+ public ConfigurationNode lightingsconfig;
public HashSet enabledTriggers = new HashSet();
public PermissionProvider permissions;
public ComponentManager componentManager = new ComponentManager();
@@ -86,6 +87,9 @@ public class DynmapPlugin extends JavaPlugin {
org.bukkit.util.config.Configuration bukkitPerspectiveConfig = new org.bukkit.util.config.Configuration(new File(this.getDataFolder(), "perspectives.txt"));
bukkitPerspectiveConfig.load();
perspectiveconfig = new ConfigurationNode(bukkitPerspectiveConfig);
+ org.bukkit.util.config.Configuration bukkitLightingsConfig = new org.bukkit.util.config.Configuration(new File(this.getDataFolder(), "lightings.txt"));
+ bukkitLightingsConfig.load();
+ lightingsconfig = new ConfigurationNode(bukkitLightingsConfig);
Log.verbose = configuration.getBoolean("verbose", true);
@@ -99,7 +103,7 @@ public class DynmapPlugin extends JavaPlugin {
playerList = new PlayerList(getServer(), getFile("hiddenplayers.txt"), configuration);
playerList.load();
- mapManager = new MapManager(this, configuration, shaderconfig, perspectiveconfig);
+ mapManager = new MapManager(this, configuration, shaderconfig, perspectiveconfig, lightingsconfig);
mapManager.startRendering();
loadWebserver();
diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java
index d4fb68a1..42a0c4fe 100644
--- a/src/main/java/org/dynmap/MapManager.java
+++ b/src/main/java/org/dynmap/MapManager.java
@@ -319,13 +319,15 @@ public class MapManager {
}
}
- public MapManager(DynmapPlugin plugin, ConfigurationNode configuration, ConfigurationNode shadercfg, ConfigurationNode perspectivecfg) {
+ public MapManager(DynmapPlugin plugin, ConfigurationNode configuration, ConfigurationNode shadercfg, ConfigurationNode perspectivecfg,
+ ConfigurationNode lightingscfg) {
plug_in = plugin;
mapman = this;
/* Initialize HD map manager */
hdmapman = new HDMapManager();
hdmapman.loadHDShaders(shadercfg);
hdmapman.loadHDPerspectives(perspectivecfg);
+ hdmapman.loadHDLightings(lightingscfg);
this.tileQueue = new AsynchronousQueue(new Handler() {
@Override
diff --git a/src/main/java/org/dynmap/hdmap/DefaultHDLighting.java b/src/main/java/org/dynmap/hdmap/DefaultHDLighting.java
new file mode 100644
index 00000000..92b2fb8b
--- /dev/null
+++ b/src/main/java/org/dynmap/hdmap/DefaultHDLighting.java
@@ -0,0 +1,54 @@
+package org.dynmap.hdmap;
+
+import java.util.HashSet;
+
+import org.dynmap.Color;
+import org.dynmap.ColorScheme;
+import org.dynmap.ConfigurationNode;
+import org.dynmap.hdmap.DefaultHDShader.BiomeColorOption;
+import org.json.simple.JSONObject;
+import static org.dynmap.JSONUtils.s;
+
+public class DefaultHDLighting implements HDLighting {
+ private String name;
+
+ public DefaultHDLighting(ConfigurationNode configuration) {
+ name = (String) configuration.get("name");
+ }
+
+ /* Get lighting name */
+ public String getName() { return name; }
+
+ /* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */
+ public void applyLighting(HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor) {
+ for(Color oc: outcolor)
+ oc.setColor(incolor);
+ }
+
+ /* Test if Biome Data is needed for this renderer */
+ public boolean isBiomeDataNeeded() { return false; }
+
+ /* Test if raw biome temperature/rainfall data is needed */
+ public boolean isRawBiomeDataNeeded() { return false; }
+
+ /* Test if highest block Y data is needed */
+ public boolean isHightestBlockYDataNeeded() { return false; }
+
+ /* Tet if block type data needed */
+ public boolean isBlockTypeDataNeeded() { return false; }
+
+ /* Test if night/day is enabled for this renderer */
+ public boolean isNightAndDayEnabled() { return false; }
+
+ /* Test if sky light level needed */
+ public boolean isSkyLightLevelNeeded() { return false; }
+
+ /* Test if emitted light level needed */
+ public boolean isEmittedLightLevelNeeded() { return false; }
+
+ /* Add shader's contributions to JSON for map object */
+ public void addClientConfiguration(JSONObject mapObject) {
+ s(mapObject, "lighting", name);
+ s(mapObject, "nightandday", isNightAndDayEnabled());
+ }
+}
diff --git a/src/main/java/org/dynmap/hdmap/DefaultHDShader.java b/src/main/java/org/dynmap/hdmap/DefaultHDShader.java
index ca4a5067..b2461da0 100644
--- a/src/main/java/org/dynmap/hdmap/DefaultHDShader.java
+++ b/src/main/java/org/dynmap/hdmap/DefaultHDShader.java
@@ -1,7 +1,6 @@
package org.dynmap.hdmap;
import static org.dynmap.JSONUtils.s;
-import java.util.HashSet;
import org.bukkit.block.Biome;
import org.dynmap.Color;
import org.dynmap.ColorScheme;
@@ -14,12 +13,6 @@ public class DefaultHDShader implements HDShader {
private String name;
protected ColorScheme colorScheme;
- protected HashSet highlightBlocks = new HashSet();
- protected Color highlightColor = new Color(255, 0, 0);
-
- protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
- 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 transparency; /* Is transparency support active? */
public enum BiomeColorOption {
NONE, BIOME, TEMPERATURE, RAINFALL
@@ -28,30 +21,7 @@ public class DefaultHDShader implements HDShader {
public DefaultHDShader(ConfigurationNode configuration) {
name = (String) configuration.get("name");
- double shadowweight = configuration.getDouble("shadowstrength", 0.0);
- if(shadowweight > 0.0) {
- shadowscale = new int[16];
- shadowscale[15] = 256;
- /* Normal brightness weight in MC is a 20% relative dropoff per step */
- for(int i = 14; i >= 0; i--) {
- double v = shadowscale[i+1] * (1.0 - (0.2 * shadowweight));
- shadowscale[i] = (int)v;
- if(shadowscale[i] > 256) shadowscale[i] = 256;
- if(shadowscale[i] < 0) shadowscale[i] = 0;
- }
- }
- int v = configuration.getInteger("ambientlight", -1);
- if(v >= 0) {
- lightscale = new int[16];
- for(int i = 0; i < 16; i++) {
- if(i < (15-v))
- lightscale[i] = 0;
- else
- lightscale[i] = i - (15-v);
- }
- }
colorScheme = ColorScheme.getScheme(configuration.getString("colorscheme", "default"));
- night_and_day = configuration.getBoolean("night-and-day", false);
transparency = configuration.getBoolean("transparency", true); /* Default on */
String biomeopt = configuration.getString("biomecolored", "none");
if(biomeopt.equals("biome")) {
@@ -68,30 +38,60 @@ public class DefaultHDShader implements HDShader {
}
}
- public boolean isBiomeDataNeeded() { return biomecolored == BiomeColorOption.BIOME; }
- public boolean isRawBiomeDataNeeded() { return (biomecolored == BiomeColorOption.RAINFALL) || (biomecolored == BiomeColorOption.TEMPERATURE); };
- public boolean isNightAndDayEnabled() { return night_and_day; }
- public boolean isSkyLightLevelNeeded() { return (lightscale != null); }
- public boolean isEmittedLightLevelNeeded() { return (shadowscale != null); }
- public boolean isHightestBlockYDataNeeded() { return false; }
- public boolean isBlockTypeDataNeeded() { return true; }
-
- public String getName() { return name; }
+ @Override
+ public boolean isBiomeDataNeeded() {
+ return biomecolored == BiomeColorOption.BIOME;
+ }
- private class OurRendererState implements HDShaderState {
- private Color color = new Color();
- private Color daycolor;
+ @Override
+ public boolean isRawBiomeDataNeeded() {
+ return (biomecolored == BiomeColorOption.RAINFALL) || (biomecolored == BiomeColorOption.TEMPERATURE);
+ }
+
+ @Override
+ public boolean isHightestBlockYDataNeeded() {
+ return false;
+ }
+
+ @Override
+ public boolean isBlockTypeDataNeeded() {
+ return true;
+ }
+
+ @Override
+ public boolean isSkyLightLevelNeeded() {
+ return false;
+ }
+
+ @Override
+ public boolean isEmittedLightLevelNeeded() {
+ return false;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ private class OurShaderState implements HDShaderState {
+ private Color color[];
protected MapIterator mapiter;
protected HDMap map;
- private Color tmpcolor = new Color();
- private Color tmpdaycolor = new Color();
+ private Color tmpcolor[];
private int pixelodd;
+ private HDLighting lighting;
- private OurRendererState(MapIterator mapiter, HDMap map) {
+ private OurShaderState(MapIterator mapiter, HDMap map) {
this.mapiter = mapiter;
this.map = map;
- if(night_and_day) {
- daycolor = new Color();
+ this.lighting = map.getLighting();
+ if(lighting.isNightAndDayEnabled()) {
+ color = new Color[] { new Color(), new Color() };
+ tmpcolor = new Color[] { new Color(), new Color() };
+ }
+ else {
+ color = new Color[] { new Color() };
+ tmpcolor = new Color[] { new Color() };
}
}
/**
@@ -107,13 +107,18 @@ public class DefaultHDShader implements HDShader {
public HDMap getMap() {
return map;
}
+ /**
+ * Get our lighting
+ */
+ public HDLighting getLighting() {
+ return lighting;
+ }
/**
* Reset renderer state for new ray
*/
public void reset(HDPerspectiveState ps) {
- color.setTransparent();
- if(daycolor != null)
- daycolor.setTransparent();
+ for(Color c: color)
+ c.setTransparent();
pixelodd = (ps.getPixelX() & 0x3) + (ps.getPixelY()<<1);
}
@@ -129,6 +134,7 @@ public class DefaultHDShader implements HDShader {
* @return true if ray is done, false if ray needs to continue
*/
public boolean processBlock(HDPerspectiveState ps) {
+ int i;
int blocktype = ps.getBlockTypeID();
if(blocktype == 0)
return false;
@@ -140,75 +146,44 @@ public class DefaultHDShader implements HDShader {
switch(ps.getLastBlockStep()) {
case X_PLUS:
case X_MINUS:
- seq = 1;
+ seq = 0;
break;
case Z_PLUS:
case Z_MINUS:
- seq = 3;
+ seq = 2;
break;
default:
if(((pixelodd + mapiter.getY()) & 0x03) == 0)
- seq = 2;
+ seq = 3;
else
- seq = 0;
+ seq = 1;
break;
}
Color c = colors[seq];
if (c.getAlpha() > 0) {
/* Handle light level, if needed */
- int lightlevel = 15, lightlevel_day = 15;
- if(shadowscale != null) {
- lightlevel = lightlevel_day = ps.getSkyLightLevel();
- if(lightscale != null)
- lightlevel = lightscale[lightlevel];
- if((lightlevel < 15) || (lightlevel_day < 15)) {
- int emitted = ps.getEmittedLightLevel();
- lightlevel = Math.max(emitted, lightlevel);
- lightlevel_day = Math.max(emitted, lightlevel_day);
- }
- }
- /* Figure out our color, with lighting if needed */
- tmpcolor.setColor(c);
- if(lightlevel < 15) {
- shadowColor(tmpcolor, lightlevel);
- }
- if(daycolor != null) {
- if(lightlevel_day == lightlevel) {
- tmpdaycolor.setColor(tmpcolor);
- }
- else {
- tmpdaycolor.setColor(c);
- if(lightlevel_day < 15) {
- shadowColor(tmpdaycolor, lightlevel_day);
- }
- }
- }
+ lighting.applyLighting(ps, this, c, tmpcolor);
/* Blend color with accumulated color (weighted by alpha) */
if(!transparency) { /* No transparency support */
- color.setARGB(tmpcolor.getARGB() | 0xFF000000);
- if(daycolor != null)
- daycolor.setARGB(tmpdaycolor.getARGB() | 0xFF000000);
+ for(i = 0; i < color.length; i++)
+ color[i].setARGB(tmpcolor[i].getARGB() | 0xFF000000);
return true; /* We're done */
}
/* If no previous color contribution, use new color */
- else if(color.isTransparent()) {
- color.setColor(tmpcolor);
- if(daycolor != null)
- daycolor.setColor(tmpdaycolor);
- return (color.getAlpha() == 255);
+ else if(color[0].isTransparent()) {
+ for(i = 0; i < color.length; i++)
+ color[i].setColor(tmpcolor[i]);
+ return (color[0].getAlpha() == 255);
}
/* Else, blend and generate new alpha */
else {
- int alpha = color.getAlpha();
- int alpha2 = tmpcolor.getAlpha() * (255-alpha) / 255;
+ int alpha = color[0].getAlpha();
+ int alpha2 = tmpcolor[0].getAlpha() * (255-alpha) / 255;
int talpha = alpha + alpha2;
- color.setRGBA((tmpcolor.getRed()*alpha2 + color.getRed()*alpha) / talpha,
- (tmpcolor.getGreen()*alpha2 + color.getGreen()*alpha) / talpha,
- (tmpcolor.getBlue()*alpha2 + color.getBlue()*alpha) / talpha, talpha);
- if(daycolor != null)
- daycolor.setRGBA((tmpdaycolor.getRed()*alpha2 + daycolor.getRed()*alpha) / talpha,
- (tmpdaycolor.getGreen()*alpha2 + daycolor.getGreen()*alpha) / talpha,
- (tmpdaycolor.getBlue()*alpha2 + daycolor.getBlue()*alpha) / talpha, talpha);
+ for(i = 0; i < color.length; i++)
+ color[i].setRGBA((tmpcolor[i].getRed()*alpha2 + color[i].getRed()*alpha) / talpha,
+ (tmpcolor[i].getGreen()*alpha2 + color[i].getGreen()*alpha) / talpha,
+ (tmpcolor[i].getBlue()*alpha2 + color[i].getBlue()*alpha) / talpha, talpha);
return (talpha >= 254); /* If only one short, no meaningful contribution left */
}
}
@@ -226,27 +201,17 @@ public class DefaultHDShader implements HDShader {
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
*/
public void getRayColor(Color c, int index) {
- if(index == 0)
- c.setColor(color);
- else if((index == 1) && (daycolor != null))
- c.setColor(daycolor);
+ c.setColor(color[index]);
}
/**
* Clean up state object - called after last ray completed
*/
public void cleanup() {
}
-
- private final void shadowColor(Color c, int lightlevel) {
- int scale = shadowscale[lightlevel];
- if(scale < 256)
- c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
- (c.getBlue() * scale) >> 8, c.getAlpha());
- }
}
- private class OurBiomeRendererState extends OurRendererState {
- private OurBiomeRendererState(MapIterator mapiter, HDMap map) {
+ private class OurBiomeShaderState extends OurShaderState {
+ private OurBiomeShaderState(MapIterator mapiter, HDMap map) {
super(mapiter, map);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
@@ -257,8 +222,8 @@ public class DefaultHDShader implements HDShader {
}
}
- private class OurBiomeRainfallRendererState extends OurRendererState {
- private OurBiomeRainfallRendererState(MapIterator mapiter, HDMap map) {
+ private class OurBiomeRainfallShaderState extends OurShaderState {
+ private OurBiomeRainfallShaderState(MapIterator mapiter, HDMap map) {
super(mapiter, map);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
@@ -266,8 +231,8 @@ public class DefaultHDShader implements HDShader {
}
}
- private class OurBiomeTempRendererState extends OurRendererState {
- private OurBiomeTempRendererState(MapIterator mapiter, HDMap map) {
+ private class OurBiomeTempShaderState extends OurShaderState {
+ private OurBiomeTempShaderState(MapIterator mapiter, HDMap map) {
super(mapiter, map);
}
protected Color[] getBlockColors(int blocktype, int blockdata) {
@@ -284,13 +249,13 @@ public class DefaultHDShader implements HDShader {
public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) {
switch(biomecolored) {
case NONE:
- return new OurRendererState(mapiter, map);
+ return new OurShaderState(mapiter, map);
case BIOME:
- return new OurBiomeRendererState(mapiter, map);
+ return new OurBiomeShaderState(mapiter, map);
case RAINFALL:
- return new OurBiomeRainfallRendererState(mapiter, map);
+ return new OurBiomeRainfallShaderState(mapiter, map);
case TEMPERATURE:
- return new OurBiomeTempRendererState(mapiter, map);
+ return new OurBiomeTempShaderState(mapiter, map);
}
return null;
}
@@ -298,6 +263,5 @@ public class DefaultHDShader implements HDShader {
/* Add shader's contributions to JSON for map object */
public void addClientConfiguration(JSONObject mapObject) {
s(mapObject, "shader", name);
- s(mapObject, "nightandday", night_and_day);
}
}
diff --git a/src/main/java/org/dynmap/hdmap/HDLighting.java b/src/main/java/org/dynmap/hdmap/HDLighting.java
new file mode 100644
index 00000000..11e572d8
--- /dev/null
+++ b/src/main/java/org/dynmap/hdmap/HDLighting.java
@@ -0,0 +1,29 @@
+package org.dynmap.hdmap;
+
+import org.dynmap.Color;
+import org.dynmap.utils.MapChunkCache;
+import org.dynmap.utils.MapIterator;
+import org.json.simple.JSONObject;
+
+public interface HDLighting {
+ /* Get lighting name */
+ String getName();
+ /* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */
+ void applyLighting(HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor);
+ /* Test if Biome Data is needed for this renderer */
+ boolean isBiomeDataNeeded();
+ /* Test if raw biome temperature/rainfall data is needed */
+ boolean isRawBiomeDataNeeded();
+ /* Test if highest block Y data is needed */
+ boolean isHightestBlockYDataNeeded();
+ /* Tet if block type data needed */
+ boolean isBlockTypeDataNeeded();
+ /* Test if night/day is enabled for this renderer */
+ boolean isNightAndDayEnabled();
+ /* Test if sky light level needed */
+ boolean isSkyLightLevelNeeded();
+ /* Test if emitted light level needed */
+ boolean isEmittedLightLevelNeeded();
+ /* Add shader's contributions to JSON for map object */
+ void addClientConfiguration(JSONObject mapObject);
+}
diff --git a/src/main/java/org/dynmap/hdmap/HDMap.java b/src/main/java/org/dynmap/hdmap/HDMap.java
index 1113b448..0b8ff3d4 100644
--- a/src/main/java/org/dynmap/hdmap/HDMap.java
+++ b/src/main/java/org/dynmap/hdmap/HDMap.java
@@ -21,6 +21,7 @@ public class HDMap extends MapType {
private String prefix;
private HDPerspective perspective;
private HDShader shader;
+ private HDLighting lighting;
private ConfigurationNode configuration;
public HDMap(ConfigurationNode configuration) {
@@ -43,12 +44,20 @@ public class HDMap extends MapType {
name = null;
return;
}
+ String lightingid = configuration.getString("lighting", "default");
+ lighting = MapManager.mapman.hdmapman.lightings.get(lightingid);
+ if(lighting == null) {
+ Log.severe("HDMap '"+name+"' loading invalid lighting '" + lighting + "' - map disabled");
+ name = null;
+ return;
+ }
prefix = configuration.getString("prefix", name);
this.configuration = configuration;
}
public HDShader getShader() { return shader; }
public HDPerspective getPerspective() { return perspective; }
+ public HDLighting getLighting() { return lighting; }
@Override
public MapTile[] getTiles(Location loc) {
@@ -77,7 +86,7 @@ public class HDMap extends MapType {
public List baseZoomFilePrefixes() {
ArrayList s = new ArrayList();
s.add(prefix);
- if(shader.isNightAndDayEnabled())
+ if(lighting.isNightAndDayEnabled())
s.add(prefix + "_day");
return s;
}
@@ -117,6 +126,7 @@ public class HDMap extends MapType {
perspective.addClientConfiguration(o);
shader.addClientConfiguration(o);
+ lighting.addClientConfiguration(o);
a(worldObject, "maps", o);
diff --git a/src/main/java/org/dynmap/hdmap/HDMapManager.java b/src/main/java/org/dynmap/hdmap/HDMapManager.java
index 9ae2c875..590d76f3 100644
--- a/src/main/java/org/dynmap/hdmap/HDMapManager.java
+++ b/src/main/java/org/dynmap/hdmap/HDMapManager.java
@@ -20,16 +20,20 @@ import org.dynmap.utils.MapIterator;
public class HDMapManager {
public HashMap shaders = new HashMap();
public HashMap perspectives = new HashMap();
+ public HashMap lightings = new HashMap();
public HashSet maps = new HashSet();
public HashMap> maps_by_world_perspective = new HashMap>();
public void loadHDShaders(ConfigurationNode shadercfg) {
Log.verboseinfo("Loading shaders...");
for(HDShader shader : shadercfg.createInstances("shaders", new Class>[0], new Object[0])) {
+ if(shader.getName() == null) continue;
if(shaders.containsKey(shader.getName())) {
Log.severe("Duplicate shader name '" + shader.getName() + "' - shader ignored");
}
- shaders.put(shader.getName(), shader);
+ else {
+ shaders.put(shader.getName(), shader);
+ }
}
Log.info("Loaded " + shaders.size() + " shaders.");
}
@@ -37,14 +41,31 @@ public class HDMapManager {
public void loadHDPerspectives(ConfigurationNode perspectivecfg) {
Log.verboseinfo("Loading perspectives...");
for(HDPerspective perspective : perspectivecfg.createInstances("perspectives", new Class>[0], new Object[0])) {
+ if(perspective.getName() == null) continue;
if(perspectives.containsKey(perspective.getName())) {
Log.severe("Duplicate perspective name '" + perspective.getName() + "' - perspective ignored");
}
- perspectives.put(perspective.getName(), perspective);
+ else {
+ perspectives.put(perspective.getName(), perspective);
+ }
}
Log.info("Loaded " + perspectives.size() + " perspectives.");
}
+ public void loadHDLightings(ConfigurationNode lightingcfg) {
+ Log.verboseinfo("Loading lightings...");
+ for(HDLighting lighting : lightingcfg.createInstances("lightings", new Class>[0], new Object[0])) {
+ if(lighting.getName() == null) continue;
+ if(lightings.containsKey(lighting.getName())) {
+ Log.severe("Duplicate lighting name '" + lighting.getName() + "' - lighting ignored");
+ }
+ else {
+ lightings.put(lighting.getName(), lighting);
+ }
+ }
+ Log.info("Loaded " + lightings.size() + " lightings.");
+ }
+
/**
* Initialize shader states for all shaders for given tile
*/
@@ -102,10 +123,11 @@ public class HDMapManager {
HDMap hdmap = (HDMap)map;
if(hdmap.getPerspective() == t.perspective) {
HDShader sh = hdmap.getShader();
- flags[BIOMEDATAFLAG] |= sh.isBiomeDataNeeded();
- flags[HIGHESTZFLAG] |= sh.isHightestBlockYDataNeeded();
- flags[RAWBIOMEFLAG] |= sh.isRawBiomeDataNeeded();
- flags[BLOCKTYPEFLAG] |= sh.isBlockTypeDataNeeded();
+ HDLighting lt = hdmap.getLighting();
+ flags[BIOMEDATAFLAG] |= sh.isBiomeDataNeeded() | lt.isBiomeDataNeeded();
+ flags[HIGHESTZFLAG] |= sh.isHightestBlockYDataNeeded() | lt.isHightestBlockYDataNeeded();
+ flags[RAWBIOMEFLAG] |= sh.isRawBiomeDataNeeded() | lt.isRawBiomeDataNeeded();
+ flags[BLOCKTYPEFLAG] |= sh.isBlockTypeDataNeeded() | lt.isBlockTypeDataNeeded();
}
}
}
diff --git a/src/main/java/org/dynmap/hdmap/HDShader.java b/src/main/java/org/dynmap/hdmap/HDShader.java
index be16442f..08ac8e0d 100644
--- a/src/main/java/org/dynmap/hdmap/HDShader.java
+++ b/src/main/java/org/dynmap/hdmap/HDShader.java
@@ -8,7 +8,7 @@ import org.dynmap.utils.MapIterator;
import org.json.simple.JSONObject;
public interface HDShader {
- /* Get renderer name */
+ /* Get shader name */
String getName();
/**
* Get renderer state object for use rendering a tile
@@ -26,8 +26,6 @@ public interface HDShader {
boolean isHightestBlockYDataNeeded();
/* Tet if block type data needed */
boolean isBlockTypeDataNeeded();
- /* Test if night/day is enabled for this renderer */
- boolean isNightAndDayEnabled();
/* Test if sky light level needed */
boolean isSkyLightLevelNeeded();
/* Test if emitted light level needed */
diff --git a/src/main/java/org/dynmap/hdmap/HDShaderState.java b/src/main/java/org/dynmap/hdmap/HDShaderState.java
index 6a2e7fba..151aeea4 100644
--- a/src/main/java/org/dynmap/hdmap/HDShaderState.java
+++ b/src/main/java/org/dynmap/hdmap/HDShaderState.java
@@ -12,6 +12,10 @@ public interface HDShaderState {
* Get our shader
*/
HDShader getShader();
+ /**
+ * Get our lighting
+ */
+ HDLighting getLighting();
/**
* Get our map
*/
diff --git a/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java b/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java
index 75a207a3..d4d96c1f 100644
--- a/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java
+++ b/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java
@@ -363,13 +363,14 @@ public class IsoHDPerspective implements HDPerspective {
for(int i = 0; i < numshaders; i++) {
HDShader shader = shaderstate[i].getShader();
- if(shader.isEmittedLightLevelNeeded())
+ HDLighting lighting = shaderstate[i].getLighting();
+ if(shader.isEmittedLightLevelNeeded() || lighting.isEmittedLightLevelNeeded())
need_emittedlightlevel = true;
- if(shader.isSkyLightLevelNeeded())
+ if(shader.isSkyLightLevelNeeded() || lighting.isSkyLightLevelNeeded())
need_skylightlevel = true;
im[i] = KzedMap.allocateBufferedImage(tileWidth, tileHeight);
argb_buf[i] = im[i].argb_buf;
- if(shader.isNightAndDayEnabled()) {
+ if(lighting.isNightAndDayEnabled()) {
dayim[i] = KzedMap.allocateBufferedImage(tileWidth, tileHeight);
day_argb_buf[i] = dayim[i].argb_buf;
}
diff --git a/src/main/java/org/dynmap/hdmap/ShadowHDLighting.java b/src/main/java/org/dynmap/hdmap/ShadowHDLighting.java
new file mode 100644
index 00000000..3f740280
--- /dev/null
+++ b/src/main/java/org/dynmap/hdmap/ShadowHDLighting.java
@@ -0,0 +1,99 @@
+package org.dynmap.hdmap;
+
+import static org.dynmap.JSONUtils.s;
+
+import org.dynmap.Color;
+import org.dynmap.ConfigurationNode;
+import org.dynmap.Log;
+import org.json.simple.JSONObject;
+
+public class ShadowHDLighting extends DefaultHDLighting {
+
+ protected int shadowscale[]; /* index=skylight level, value = 256 * scaling value */
+ 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 */
+
+ public ShadowHDLighting(ConfigurationNode configuration) {
+ super(configuration);
+ double shadowweight = configuration.getDouble("shadowstrength", 0.0);
+ if(shadowweight > 0.0) {
+ shadowscale = new int[16];
+ shadowscale[15] = 256;
+ /* Normal brightness weight in MC is a 20% relative dropoff per step */
+ for(int i = 14; i >= 0; i--) {
+ double v = shadowscale[i+1] * (1.0 - (0.2 * shadowweight));
+ shadowscale[i] = (int)v;
+ if(shadowscale[i] > 256) shadowscale[i] = 256;
+ if(shadowscale[i] < 0) shadowscale[i] = 0;
+ }
+ }
+ int v = configuration.getInteger("ambientlight", -1);
+ if((v >= 0) && (v < 15)) {
+ lightscale = new int[16];
+ for(int i = 0; i < 16; i++) {
+ if(i < (15-v))
+ lightscale[i] = 0;
+ else
+ lightscale[i] = i - (15-v);
+ }
+ }
+ night_and_day = configuration.getBoolean("night-and-day", false);
+ if(night_and_day) {
+ if(lightscale == null) {
+ Log.severe("night-and-day in lighting '" + getName() + "' requires ambientlight<15");
+ night_and_day = false;
+ }
+ }
+ }
+
+ /* Apply lighting to given pixel colors (1 outcolor if normal, 2 if night/day) */
+ public void applyLighting(HDPerspectiveState ps, HDShaderState ss, Color incolor, Color[] outcolor) {
+ int lightlevel = 15, lightlevel_day = 15;
+ /* If processing for shadows, use sky light level as base lighting */
+ if(shadowscale != null) {
+ lightlevel = lightlevel_day = ps.getSkyLightLevel();
+ }
+ /* If ambient light, adjust base lighting for it */
+ if(lightscale != null)
+ lightlevel = lightscale[lightlevel];
+ /* If we're below max, see if emitted light helps */
+ if((lightlevel < 15) || (lightlevel_day < 15)) {
+ int emitted = ps.getEmittedLightLevel();
+ lightlevel = Math.max(emitted, lightlevel);
+ lightlevel_day = Math.max(emitted, lightlevel_day);
+ }
+ /* Figure out our color, with lighting if needed */
+ outcolor[0].setColor(incolor);
+ if(lightlevel < 15) {
+ shadowColor(outcolor[0], lightlevel);
+ }
+ if(outcolor.length > 1) {
+ if(lightlevel_day == lightlevel) {
+ outcolor[1].setColor(outcolor[0]);
+ }
+ else {
+ outcolor[1].setColor(incolor);
+ if(lightlevel_day < 15) {
+ shadowColor(outcolor[1], lightlevel_day);
+ }
+ }
+ }
+ }
+
+ private final void shadowColor(Color c, int lightlevel) {
+ int scale = shadowscale[lightlevel];
+ if(scale < 256)
+ c.setRGBA((c.getRed() * scale) >> 8, (c.getGreen() * scale) >> 8,
+ (c.getBlue() * scale) >> 8, c.getAlpha());
+ }
+
+ /* Test if night/day is enabled for this renderer */
+ public boolean isNightAndDayEnabled() { return night_and_day; }
+
+ /* Test if sky light level needed */
+ public boolean isSkyLightLevelNeeded() { return (shadowscale != null); }
+
+ /* Test if emitted light level needed */
+ public boolean isEmittedLightLevelNeeded() { return (shadowscale != null) || (lightscale != null); }
+
+}