mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-26 18:47:40 +01:00
Merge pull request #283 from mikeprimm/hdrender
Add texture pack shader support
This commit is contained in:
commit
d4ecd05af9
411
models.txt
411
models.txt
@ -39,61 +39,127 @@ layer:0
|
||||
# Torch - up
|
||||
# Redstone torch on - up
|
||||
# Redstone torch off - up
|
||||
block:id=50,id=75,id=76,data=5,data=0,scale=8
|
||||
layer:0,1,2,3,4
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
---**---
|
||||
---**---
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
block:id=50,id=75,id=76,data=5,data=0,scale=16
|
||||
layer:0,1,2,3,4,5,6,7,8,9
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
-------**-------
|
||||
-------**-------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
# Torch - pointing south
|
||||
# Redstone torch on - pointing south
|
||||
# Redstone torch off - pointing south
|
||||
block:id=50,id=75,id=76,data=1,scale=8
|
||||
layer:2
|
||||
---**---
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
block:id=50,id=75,id=76,data=1,scale=16
|
||||
layer:3,4
|
||||
---**---
|
||||
---**---
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
layer:5
|
||||
--------
|
||||
---**---
|
||||
---**---
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
--------
|
||||
-------**-------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
layer:5,6
|
||||
-------**-------
|
||||
-------**-------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
layer:7,8
|
||||
----------------
|
||||
-------**-------
|
||||
-------**-------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
layer:9,10
|
||||
----------------
|
||||
----------------
|
||||
-------**-------
|
||||
-------**-------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
layer:11,12
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
-------**-------
|
||||
-------**-------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
# Torch - pointing north
|
||||
# Redstone torch on - pointing north
|
||||
# Redstone torch off - pointing north
|
||||
block:id=50,id=75,id=76,data=2,scale=8
|
||||
block:id=50,id=75,id=76,data=2,scale=16
|
||||
rotate:id=50,data=1,rot=180
|
||||
# Torch - pointing west
|
||||
# Redstone torch on - pointing west
|
||||
# Redstone torch off - pointing west
|
||||
block:id=50,id=75,id=76,data=3,scale=8
|
||||
block:id=50,id=75,id=76,data=3,scale=16
|
||||
rotate:id=50,data=1,rot=90
|
||||
# Torch - pointing east
|
||||
# Redstone torch on - pointing east
|
||||
# Redstone torch off - pointing east
|
||||
block:id=50,id=75,id=76,data=4,scale=8
|
||||
block:id=50,id=75,id=76,data=4,scale=16
|
||||
rotate:id=50,data=1,rot=270
|
||||
# Fence - (data is faked: 1=north,2=east,4=south,8=west)
|
||||
# Fence - no neighbors
|
||||
@ -1232,57 +1298,74 @@ layer:6,7
|
||||
--------
|
||||
Tall grass
|
||||
block:id=31,data=1,scale=16
|
||||
layer:0,1
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
-*-*-*-*-*-*-*-*
|
||||
*-*-*-*-*-*-*-*-
|
||||
layer:2,3
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
---*---*---*---*
|
||||
-*---*---*---*--
|
||||
layer:4
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
-----*-------*--
|
||||
-*-------*------
|
||||
layer:0,1,2,3,4,5,6,7,8,9
|
||||
*--------------*
|
||||
-*------------*-
|
||||
--*----------*--
|
||||
---*--------*---
|
||||
----*------*----
|
||||
-----*----*-----
|
||||
------*--*------
|
||||
-------**-------
|
||||
-------**-------
|
||||
------*--*------
|
||||
-----*----*-----
|
||||
----*------*----
|
||||
---*--------*---
|
||||
--*----------*--
|
||||
-*------------*-
|
||||
*--------------*
|
||||
layer:10,11
|
||||
----------------
|
||||
-*------------*-
|
||||
--*----------*--
|
||||
---*--------*---
|
||||
----*------*----
|
||||
-----*----*-----
|
||||
------*--*------
|
||||
-------**-------
|
||||
-------**-------
|
||||
------*--*------
|
||||
-----*----*-----
|
||||
----*------*----
|
||||
---*--------*---
|
||||
--*----------*--
|
||||
-*------------*-
|
||||
----------------
|
||||
layer:12,13
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
---*--------*---
|
||||
----*------*----
|
||||
-----*----*-----
|
||||
------*--*------
|
||||
----------------
|
||||
----------------
|
||||
------*--*------
|
||||
-----*----*-----
|
||||
----*------*----
|
||||
---*--------*---
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
layer:14,15
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
---*--------*---
|
||||
----------------
|
||||
----------------
|
||||
------*--*------
|
||||
----------------
|
||||
----------------
|
||||
------*--*------
|
||||
----------------
|
||||
----------------
|
||||
---*--------*---
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
# Sapling
|
||||
block:id=6,data=*,scale=8
|
||||
layer:0
|
||||
@ -1340,71 +1423,111 @@ layer:5
|
||||
-**-**--
|
||||
--------
|
||||
# Bed - head - pointing west
|
||||
block:id=26,data=8,scale=8
|
||||
layer:0,1
|
||||
--------
|
||||
*-------
|
||||
*-------
|
||||
*-------
|
||||
*-------
|
||||
*-------
|
||||
*-------
|
||||
--------
|
||||
layer:2,3
|
||||
--------
|
||||
********
|
||||
********
|
||||
********
|
||||
********
|
||||
********
|
||||
********
|
||||
--------
|
||||
layer:4
|
||||
--------
|
||||
*-------
|
||||
*-**----
|
||||
*-**----
|
||||
*-**----
|
||||
*-**----
|
||||
*-------
|
||||
--------
|
||||
block:id=26,data=8,scale=16
|
||||
layer:0,1,2
|
||||
***-------------
|
||||
***-------------
|
||||
***-------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
***-------------
|
||||
***-------------
|
||||
***-------------
|
||||
layer:3,4,5,6,7,8
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
layer:9
|
||||
----------------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
-******---------
|
||||
----------------
|
||||
# Bed - head - pointing north
|
||||
block:id=26,data=9,scale=8
|
||||
block:id=26,data=9,scale=16
|
||||
rotate:id=26,data=8,rot=90
|
||||
# Bed - head - pointing east
|
||||
block:id=26,data=10,scale=8
|
||||
block:id=26,data=10,scale=16
|
||||
rotate:id=26,data=8,rot=180
|
||||
# Bed - head - pointing south
|
||||
block:id=26,data=11,scale=8
|
||||
block:id=26,data=11,scale=16
|
||||
rotate:id=26,data=8,rot=270
|
||||
# Bed - foot - pointing west
|
||||
block:id=26,data=0,scale=8
|
||||
layer:0,1
|
||||
--------
|
||||
------*-
|
||||
------*-
|
||||
------*-
|
||||
------*-
|
||||
------*-
|
||||
------*-
|
||||
--------
|
||||
layer:2,3
|
||||
--------
|
||||
*******-
|
||||
*******-
|
||||
*******-
|
||||
*******-
|
||||
*******-
|
||||
*******-
|
||||
--------
|
||||
block:id=26,data=0,scale=16
|
||||
layer:0,1,2
|
||||
-------------***
|
||||
-------------***
|
||||
-------------***
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
-------------***
|
||||
-------------***
|
||||
-------------***
|
||||
layer:3,4,5,6,7,8
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
# Bed - foot - pointing north
|
||||
block:id=26,data=1,scale=8
|
||||
block:id=26,data=1,scale=16
|
||||
rotate:id=26,data=0,rot=90
|
||||
# Bed - foot - pointing east
|
||||
block:id=26,data=2,scale=8
|
||||
block:id=26,data=2,scale=16
|
||||
rotate:id=26,data=0,rot=180
|
||||
# Bed - foot - pointing south
|
||||
block:id=26,data=3,scale=8
|
||||
block:id=26,data=3,scale=16
|
||||
rotate:id=26,data=0,rot=270
|
||||
# Wooden/Iron Door - bottom - northeast corner hinge, not swung
|
||||
# Wooden/Iron Door - bottom - northwest corner hinge, swung
|
||||
|
@ -34,3 +34,8 @@ shaders:
|
||||
|
||||
- class: org.dynmap.hdmap.CaveHDShader
|
||||
name: cave
|
||||
|
||||
- class: org.dynmap.hdmap.TexturePackHDShader
|
||||
name: stdtexture
|
||||
texturepack: standard
|
||||
|
@ -32,7 +32,11 @@
|
||||
<include>perspectives.txt</include>
|
||||
<include>lightings.txt</include>
|
||||
<include>configuration.txt.sample-hd</include>
|
||||
<include>models.txt</include></includes></fileSet>
|
||||
<include>models.txt</include>
|
||||
<include>texture.txt</include></includes></fileSet>
|
||||
<fileSet>
|
||||
<directory>${project.basedir}/texturepacks</directory>
|
||||
<outputDirectory>/dynmap/texturepacks</outputDirectory></fileSet>
|
||||
</fileSets>
|
||||
<files>
|
||||
<file>
|
||||
|
@ -55,4 +55,20 @@ public class Color {
|
||||
public final void setAlpha(int v) {
|
||||
val = (val & 0x00FFFFFF) | (v << 24);
|
||||
}
|
||||
/**
|
||||
* Scale each color component, based on the corresponding component
|
||||
*/
|
||||
public final void blendColor(Color c) {
|
||||
blendColor(c.val);
|
||||
}
|
||||
/**
|
||||
* Scale each color component, based on the corresponding component
|
||||
*/
|
||||
public final void blendColor(int argb) {
|
||||
int nval = (((((val >> 24) & 0xFF) * ((argb >> 24) & 0xFF)) / 255) << 24);
|
||||
nval = nval | (((((val >> 16) & 0xFF) * ((argb >> 16) & 0xFF)) / 255) << 16);
|
||||
nval = nval | (((((val >> 8) & 0xFF) * ((argb >> 8) & 0xFF)) / 255) << 8);
|
||||
nval = nval | (((val & 0xFF) * (argb & 0xFF)) / 255);
|
||||
val = nval;
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.dynmap.debug.Debug;
|
||||
import org.dynmap.debug.Debugger;
|
||||
import org.dynmap.hdmap.HDBlockModels;
|
||||
import org.dynmap.hdmap.TexturePack;
|
||||
import org.dynmap.permissions.NijikokunPermissions;
|
||||
import org.dynmap.permissions.OpPermissions;
|
||||
import org.dynmap.permissions.PermissionProvider;
|
||||
@ -79,6 +80,9 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
dataDirectory = this.getDataFolder();
|
||||
/* Load block models */
|
||||
HDBlockModels.loadModels(dataDirectory);
|
||||
/* Load texture mappings */
|
||||
TexturePack.loadTextureMapping(dataDirectory);
|
||||
|
||||
org.bukkit.util.config.Configuration bukkitConfiguration = new org.bukkit.util.config.Configuration(new File(this.getDataFolder(), "configuration.txt"));
|
||||
bukkitConfiguration.load();
|
||||
configuration = new ConfigurationNode(bukkitConfiguration);
|
||||
|
@ -317,7 +317,8 @@ public class MapManager {
|
||||
private class DoZoomOutProcessing implements Runnable {
|
||||
public void run() {
|
||||
Debug.debug("DoZoomOutProcessing started");
|
||||
for(DynmapWorld w : worlds) {
|
||||
ArrayList<DynmapWorld> wl = new ArrayList<DynmapWorld>(worlds);
|
||||
for(DynmapWorld w : wl) {
|
||||
w.freshenZoomOutFiles();
|
||||
}
|
||||
renderpool.schedule(this, zoomout_period, TimeUnit.SECONDS);
|
||||
@ -362,7 +363,7 @@ public class MapManager {
|
||||
}
|
||||
|
||||
scheduler.scheduleSyncRepeatingTask(plugin, new CheckWorldTimes(), 5*20, 5*20); /* Check very 5 seconds */
|
||||
scheduler.scheduleSyncRepeatingTask(plugin, new ProcessChunkLoads(), 1, 1); /* Chunk loader task */
|
||||
scheduler.scheduleSyncRepeatingTask(plugin, new ProcessChunkLoads(), 1, 2); /* Chunk loader task - do every 2 to work around bukkit issue */
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package org.dynmap.hdmap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.ArrayList;
|
||||
@ -133,6 +135,7 @@ public class HDBlockModels {
|
||||
}
|
||||
else { /* Else, see how much is in first one */
|
||||
weights[idx] = (offsets[idx] + res) - v;
|
||||
weights[idx] = (offsets[idx]*res + res) - v;
|
||||
}
|
||||
}
|
||||
/* Now, use weights and indices to fill in scaled map */
|
||||
@ -182,7 +185,7 @@ public class HDBlockModels {
|
||||
weights[idx] = res;
|
||||
}
|
||||
else { /* Else, see how much is in first one */
|
||||
weights[idx] = (offsets[idx] + nativeres) - v;
|
||||
weights[idx] = (offsets[idx]*nativeres + nativeres) - v;
|
||||
}
|
||||
}
|
||||
/* Now, use weights and indices to fill in scaled map */
|
||||
@ -255,9 +258,28 @@ public class HDBlockModels {
|
||||
return model;
|
||||
}
|
||||
/**
|
||||
* Load models from model.txt file
|
||||
* Load models
|
||||
*/
|
||||
public static void loadModels(File plugindir) {
|
||||
public static void loadModels(File datadir) {
|
||||
/* Load block models */
|
||||
HDBlockModels.loadModelFile(new File(datadir, "models.txt"));
|
||||
File custom = new File(datadir, "custom-models.txt");
|
||||
if(custom.canRead()) {
|
||||
HDBlockModels.loadModels(custom);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
FileWriter fw = new FileWriter(custom);
|
||||
fw.write("# The user is free to add new and custom models here - Dynmap's install will not overwrite it\n");
|
||||
fw.close();
|
||||
} catch (IOException iox) {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Load models from file
|
||||
*/
|
||||
private static void loadModelFile(File modelfile) {
|
||||
LineNumberReader rdr = null;
|
||||
int cnt = 0;
|
||||
try {
|
||||
@ -266,7 +288,7 @@ public class HDBlockModels {
|
||||
int layerbits = 0;
|
||||
int rownum = 0;
|
||||
int scale = 0;
|
||||
rdr = new LineNumberReader(new FileReader(new File(plugindir, "models.txt")));
|
||||
rdr = new LineNumberReader(new FileReader(modelfile));
|
||||
while((line = rdr.readLine()) != null) {
|
||||
if(line.startsWith("block:")) {
|
||||
ArrayList<Integer> blkids = new ArrayList<Integer>();
|
||||
@ -299,7 +321,7 @@ public class HDBlockModels {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log.severe("Block model missing required parameters = line " + rdr.getLineNumber() + " of models.txt");
|
||||
Log.severe("Block model missing required parameters = line " + rdr.getLineNumber() + " of " + modelfile.getPath());
|
||||
}
|
||||
layerbits = 0;
|
||||
}
|
||||
@ -378,11 +400,11 @@ public class HDBlockModels {
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.info("Loaded " + cnt + " block models");
|
||||
Log.verboseinfo("Loaded " + cnt + " block models from " + modelfile.getPath());
|
||||
} catch (IOException iox) {
|
||||
Log.severe("Error reading models.txt - " + iox.toString());
|
||||
} catch (NumberFormatException nfx) {
|
||||
Log.severe("Format error - line " + rdr.getLineNumber() + " of models.txt");
|
||||
Log.severe("Format error - line " + rdr.getLineNumber() + " of " + modelfile.getPath());
|
||||
} finally {
|
||||
if(rdr != null) {
|
||||
try {
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.dynmap.hdmap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -26,6 +26,7 @@ public interface HDPerspective {
|
||||
public boolean isBlockTypeDataNeeded();
|
||||
|
||||
double getScale();
|
||||
int getModelScale();
|
||||
|
||||
public void addClientConfiguration(JSONObject mapObject);
|
||||
}
|
||||
|
@ -56,4 +56,8 @@ public interface HDPerspectiveState {
|
||||
* Return submodel alpha value (-1 if no submodel rendered)
|
||||
*/
|
||||
int getSubmodelAlpha();
|
||||
/**
|
||||
* Return subblock coordinates of current ray position
|
||||
*/
|
||||
int[] getSubblockCoord();
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ public class IsoHDPerspective implements HDPerspective {
|
||||
double t_next_y, t_next_x, t_next_z;
|
||||
boolean nonairhit;
|
||||
int subalpha;
|
||||
double mt;
|
||||
int[] subblock_xyz = new int[3];
|
||||
/**
|
||||
* Get sky light level - only available if shader requested it
|
||||
*/
|
||||
@ -363,7 +365,7 @@ public class IsoHDPerspective implements HDPerspective {
|
||||
private boolean raytraceSubblock(short[] model) {
|
||||
int mx = 0, my = 0, mz = 0;
|
||||
double xx, yy, zz;
|
||||
double mt = t + 0.0000001;
|
||||
mt = t + 0.0000001;
|
||||
xx = top.x + mt *(bottom.x - top.x);
|
||||
yy = top.y + mt *(bottom.y - top.y);
|
||||
zz = top.z + mt *(bottom.z - top.z);
|
||||
@ -453,7 +455,18 @@ public class IsoHDPerspective implements HDPerspective {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int[] getSubblockCoord() {
|
||||
double tt = t + 0.000001;
|
||||
if(subalpha >= 0)
|
||||
tt = mt;
|
||||
double xx = top.x + tt * (bottom.x - top.x);
|
||||
double yy = top.y + tt * (bottom.y - top.y);
|
||||
double zz = top.z + tt * (bottom.z - top.z);
|
||||
subblock_xyz[0] = (int)((xx - Math.floor(xx)) * modscale);
|
||||
subblock_xyz[1] = (int)((yy - Math.floor(yy)) * modscale);
|
||||
subblock_xyz[2] = (int)((zz - Math.floor(zz)) * modscale);
|
||||
return subblock_xyz;
|
||||
}
|
||||
}
|
||||
|
||||
public IsoHDPerspective(ConfigurationNode configuration) {
|
||||
@ -856,6 +869,10 @@ public class IsoHDPerspective implements HDPerspective {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public int getModelScale() {
|
||||
return modscale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
|
805
src/main/java/org/dynmap/hdmap/TexturePack.java
Normal file
805
src/main/java/org/dynmap/hdmap/TexturePack.java
Normal file
@ -0,0 +1,805 @@
|
||||
package org.dynmap.hdmap;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.dynmap.Color;
|
||||
import org.dynmap.DynmapPlugin;
|
||||
import org.dynmap.Log;
|
||||
import org.dynmap.hdmap.HDPerspectiveState.BlockStep;
|
||||
import org.dynmap.kzedmap.KzedMap;
|
||||
import org.dynmap.utils.MapIterator;
|
||||
|
||||
/**
|
||||
* Loader and processor class for minecraft texture packs
|
||||
* Texture packs are found in dynmap/texturepacks directory, and either are either ZIP files
|
||||
* or are directories whose content matches the structure of a zipped texture pack:
|
||||
* ./terrain.png - main color data (required)
|
||||
* misc/water.png - still water tile (required))
|
||||
* misc/grasscolor.png - tone for grass color, biome sensitive (required)
|
||||
* misc/foliagecolor.png - tone for leaf color, biome sensitive (required)
|
||||
* misc/watercolor.png - tone for water color, biome sensitive (required)
|
||||
* custom_lava_still.png - custom still lava animation (optional)
|
||||
* custom_lava_flowing.png - custom flowing lava animation (optional)
|
||||
* custom_water_still.png - custom still water animation (optional)
|
||||
* custom_water_flowing.png - custom flowing water animation (optional)
|
||||
* BetterGlass/*.png - mod-based improved windows (future optional)
|
||||
*/
|
||||
public class TexturePack {
|
||||
/* Loaded texture packs */
|
||||
private static HashMap<String, TexturePack> packs = new HashMap<String, TexturePack>();
|
||||
|
||||
private static final String TERRAIN_PNG = "terrain.png";
|
||||
private static final String GRASSCOLOR_PNG = "misc/grasscolor.png";
|
||||
private static final String FOLIAGECOLOR_PNG = "misc/foliagecolor.png";
|
||||
private static final String WATERCOLOR_PNG = "misc/watercolor.png";
|
||||
private static final String WATER_PNG = "misc/water.png";
|
||||
private static final String CUSTOMLAVASTILL_PNG = "custom_lava_still.png";
|
||||
private static final String CUSTOMLAVAFLOWING_PNG = "custom_lava_flowing.png";
|
||||
private static final String CUSTOMWATERSTILL_PNG = "custom_water_still.png";
|
||||
private static final String CUSTOMWATERFLOWING_PNG = "custom_water_flowing.png";
|
||||
|
||||
/* Color modifier codes (x1000 for value in mapping code) */
|
||||
private static final int COLORMOD_GRASSTONED = 1;
|
||||
private static final int COLORMOD_FOLIAGETONED = 2;
|
||||
private static final int COLORMOD_WATERTONED = 3;
|
||||
private static final int COLORMOD_ROT90 = 4;
|
||||
private static final int COLORMOD_ROT180 = 5;
|
||||
private static final int COLORMOD_ROT270 = 6;
|
||||
private static final int COLORMOD_FLIPHORIZ = 7;
|
||||
private static final int COLORMOD_SHIFTDOWNHALF = 8;
|
||||
private static final int COLORMOD_SHIFTDOWNHALFANDFLIPHORIZ = 9;
|
||||
private static final int COLORMOD_INCLINEDTORCH = 10;
|
||||
private static final int COLORMOD_GRASSSIDE = 11;
|
||||
private static final int COLORMOD_CLEARINSIDE = 12;
|
||||
|
||||
/* Special tile index values */
|
||||
private static final int BLOCKINDEX_BLANK = -1;
|
||||
private static final int BLOCKINDEX_STATIONARYWATER = 257;
|
||||
private static final int BLOCKINDEX_MOVINGWATER = 258;
|
||||
private static final int BLOCKINDEX_STATIONARYLAVA = 259;
|
||||
private static final int BLOCKINDEX_MOVINGLAVA = 260;
|
||||
private static final int MAX_BLOCKINDEX = 260;
|
||||
private static final int BLOCKTABLELEN = MAX_BLOCKINDEX+1;
|
||||
|
||||
private int[][] terrain_argb;
|
||||
private int terrain_width, terrain_height;
|
||||
private int native_scale;
|
||||
|
||||
private int[] grasscolor_argb;
|
||||
private int grasscolor_width, grasscolor_height;
|
||||
private int trivial_grasscolor;
|
||||
|
||||
private int[] foliagecolor_argb;
|
||||
private int foliagecolor_width, foliagecolor_height;
|
||||
private int trivial_foliagecolor;
|
||||
|
||||
private int[] watercolor_argb;
|
||||
private int watercolor_width, watercolor_height;
|
||||
private int trivial_watercolor;
|
||||
|
||||
private int[] water_argb;
|
||||
private int water_width, water_height;
|
||||
|
||||
private HashMap<Integer, TexturePack> scaled_textures;
|
||||
|
||||
|
||||
public static class HDTextureMap {
|
||||
private int faces[]; /* index in terrain.png of image for each face (indexed by BlockStep.ordinal()) */
|
||||
private List<Integer> blockids;
|
||||
private int databits;
|
||||
private static HDTextureMap[] texmaps;
|
||||
|
||||
private static void initializeTable() {
|
||||
texmaps = new HDTextureMap[16*BLOCKTABLELEN];
|
||||
HDTextureMap blank = new HDTextureMap();
|
||||
for(int i = 0; i < texmaps.length; i++)
|
||||
texmaps[i] = blank;
|
||||
}
|
||||
|
||||
private HDTextureMap() {
|
||||
blockids = Collections.singletonList(Integer.valueOf(0));
|
||||
databits = 0xFFFF;
|
||||
faces = new int[] { -1, -1, -1, -1, -1, -1 };
|
||||
|
||||
for(int i = 0; i < texmaps.length; i++) {
|
||||
texmaps[i] = this;
|
||||
}
|
||||
}
|
||||
|
||||
public HDTextureMap(List<Integer> blockids, int databits, int[] faces) {
|
||||
this.faces = faces;
|
||||
this.blockids = blockids;
|
||||
this.databits = databits;
|
||||
}
|
||||
|
||||
public void addToTable() {
|
||||
/* Add entries to lookup table */
|
||||
for(Integer blkid : blockids) {
|
||||
for(int i = 0; i < 16; i++) {
|
||||
if((databits & (1 << i)) != 0) {
|
||||
texmaps[16*blkid + i] = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static HDTextureMap getMap(int blkid, int blkdata) {
|
||||
return texmaps[(blkid<<4) + blkdata];
|
||||
}
|
||||
}
|
||||
/** Get or load texture pack */
|
||||
public static TexturePack getTexturePack(String tpname) {
|
||||
TexturePack tp = packs.get(tpname);
|
||||
if(tp != null)
|
||||
return tp;
|
||||
try {
|
||||
tp = new TexturePack(tpname); /* Attempt to load pack */
|
||||
packs.put(tpname, tp);
|
||||
return tp;
|
||||
} catch (FileNotFoundException fnfx) {
|
||||
Log.severe("Error loading texture pack '" + tpname + "' - not found");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Constructor for texture pack, by name
|
||||
*/
|
||||
private TexturePack(String tpname) throws FileNotFoundException {
|
||||
ZipFile zf = null;
|
||||
File texturedir = getTexturePackDirectory();
|
||||
try {
|
||||
/* Try to open zip */
|
||||
zf = new ZipFile(new File(texturedir, tpname + ".zip"));
|
||||
/* Find and load terrain.png */
|
||||
ZipEntry ze = zf.getEntry(TERRAIN_PNG); /* Try to find terrain.png */
|
||||
if(ze == null) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
InputStream is = zf.getInputStream(ze); /* Get input stream for terrain.png */
|
||||
loadTerrainPNG(is);
|
||||
is.close();
|
||||
/* Try to find and load misc/grasscolor.png */
|
||||
ze = zf.getEntry(GRASSCOLOR_PNG);
|
||||
if(ze == null)
|
||||
throw new FileNotFoundException();
|
||||
is = zf.getInputStream(ze);
|
||||
loadGrassColorPNG(is);
|
||||
is.close();
|
||||
/* Try to find and load misc/foliagecolor.png */
|
||||
ze = zf.getEntry(FOLIAGECOLOR_PNG);
|
||||
if(ze == null)
|
||||
throw new FileNotFoundException();
|
||||
is = zf.getInputStream(ze);
|
||||
loadFoliageColorPNG(is);
|
||||
is.close();
|
||||
/* Try to find and load misc/watercolor.png */
|
||||
ze = zf.getEntry(WATERCOLOR_PNG);
|
||||
if(ze == null)
|
||||
throw new FileNotFoundException();
|
||||
is = zf.getInputStream(ze);
|
||||
loadWaterColorPNG(is);
|
||||
is.close();
|
||||
/* Try to find and load misc/water.png */
|
||||
ze = zf.getEntry(WATER_PNG);
|
||||
if(ze == null)
|
||||
throw new FileNotFoundException();
|
||||
is = zf.getInputStream(ze);
|
||||
loadWaterPNG(is);
|
||||
is.close();
|
||||
|
||||
zf.close();
|
||||
return;
|
||||
} catch (IOException iox) {
|
||||
if(zf != null) {
|
||||
try { zf.close(); } catch (IOException io) {}
|
||||
}
|
||||
/* No zip, or bad - try directory next */
|
||||
}
|
||||
/* Try loading terrain.png from directory of name */
|
||||
File f = null;
|
||||
FileInputStream fis = null;
|
||||
try {
|
||||
/* Open and load terrain.png */
|
||||
f = new File(texturedir, tpname + "/" + TERRAIN_PNG);
|
||||
fis = new FileInputStream(f);
|
||||
loadTerrainPNG(fis);
|
||||
fis.close();
|
||||
/* Check for misc/grasscolor.png */
|
||||
f = new File(texturedir, tpname + "/" + GRASSCOLOR_PNG);
|
||||
fis = new FileInputStream(f);
|
||||
loadGrassColorPNG(fis);
|
||||
fis.close();
|
||||
/* Check for misc/foliagecolor.png */
|
||||
f = new File(texturedir, tpname + "/" + FOLIAGECOLOR_PNG);
|
||||
fis = new FileInputStream(f);
|
||||
loadFoliageColorPNG(fis);
|
||||
fis.close();
|
||||
/* Check for misc/waterecolor.png */
|
||||
f = new File(texturedir, tpname + "/" + WATERCOLOR_PNG);
|
||||
fis = new FileInputStream(f);
|
||||
loadWaterColorPNG(fis);
|
||||
fis.close();
|
||||
/* Check for misc/water.png */
|
||||
f = new File(texturedir, tpname + "/" + WATER_PNG);
|
||||
fis = new FileInputStream(f);
|
||||
loadWaterPNG(fis);
|
||||
fis.close();
|
||||
} catch (IOException iox) {
|
||||
if(fis != null) {
|
||||
try { fis.close(); } catch (IOException io) {}
|
||||
}
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
}
|
||||
/* Copy texture pack */
|
||||
private TexturePack(TexturePack tp) {
|
||||
this.terrain_argb = new int[tp.terrain_argb.length][];
|
||||
System.arraycopy(tp.terrain_argb, 0, this.terrain_argb, 0, this.terrain_argb.length);
|
||||
this.terrain_width = tp.terrain_width;
|
||||
this.terrain_height = tp.terrain_height;
|
||||
this.native_scale = tp.native_scale;
|
||||
|
||||
this.grasscolor_argb = tp.grasscolor_argb;
|
||||
this.grasscolor_height = tp.grasscolor_height;
|
||||
this.grasscolor_width = tp.grasscolor_width;
|
||||
this.trivial_grasscolor = tp.trivial_grasscolor;
|
||||
|
||||
this.watercolor_argb = tp.watercolor_argb;
|
||||
this.watercolor_height = tp.watercolor_height;
|
||||
this.watercolor_width = tp.watercolor_width;
|
||||
this.trivial_watercolor = tp.trivial_watercolor;
|
||||
|
||||
this.foliagecolor_argb = tp.foliagecolor_argb;
|
||||
this.foliagecolor_height = tp.foliagecolor_height;
|
||||
this.foliagecolor_width = tp.foliagecolor_width;
|
||||
this.trivial_foliagecolor = tp.trivial_foliagecolor;
|
||||
|
||||
this.water_argb = tp.water_argb;
|
||||
this.water_height = tp.water_height;
|
||||
this.water_width = tp.water_width;
|
||||
}
|
||||
|
||||
/* Load terrain.png */
|
||||
private void loadTerrainPNG(InputStream is) throws IOException {
|
||||
int i;
|
||||
/* Load image */
|
||||
BufferedImage img = ImageIO.read(is);
|
||||
if(img == null) { throw new FileNotFoundException(); }
|
||||
terrain_width = img.getWidth();
|
||||
terrain_height = img.getHeight();
|
||||
native_scale = terrain_width / 16;
|
||||
terrain_argb = new int[BLOCKTABLELEN][];
|
||||
for(i = 0; i < 256; i++) {
|
||||
terrain_argb[i] = new int[native_scale*native_scale];
|
||||
img.getRGB((i & 0xF)*native_scale, (i>>4)*native_scale, native_scale, native_scale, terrain_argb[i], 0, native_scale);
|
||||
}
|
||||
int[] blank = new int[native_scale*native_scale];
|
||||
for(i = 256; i < BLOCKTABLELEN; i++) {
|
||||
terrain_argb[i] = blank;
|
||||
}
|
||||
/* Fallbacks */
|
||||
terrain_argb[BLOCKINDEX_STATIONARYLAVA] = terrain_argb[255];
|
||||
terrain_argb[BLOCKINDEX_MOVINGLAVA] = terrain_argb[255];
|
||||
|
||||
img.flush();
|
||||
}
|
||||
|
||||
/* Load misc/grasscolor.png */
|
||||
private void loadGrassColorPNG(InputStream is) throws IOException {
|
||||
/* Load image */
|
||||
BufferedImage img = ImageIO.read(is);
|
||||
if(img == null) { throw new FileNotFoundException(); }
|
||||
grasscolor_width = img.getWidth();
|
||||
grasscolor_height = img.getHeight();
|
||||
grasscolor_argb = new int[grasscolor_width * grasscolor_height];
|
||||
img.getRGB(0, 0, grasscolor_width, grasscolor_height, grasscolor_argb, 0, grasscolor_width);
|
||||
img.flush();
|
||||
/* Figure out trivial color */
|
||||
trivial_grasscolor = grasscolor_argb[grasscolor_height*grasscolor_width*3/4 + grasscolor_width/2];
|
||||
boolean same = true;
|
||||
for(int j = 0; same && (j < grasscolor_height); j++) {
|
||||
for(int i = 0; same && (i <= j); i++) {
|
||||
if(grasscolor_argb[grasscolor_width*j+i] != trivial_grasscolor)
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
/* All the same - no biome lookup needed */
|
||||
if(same)
|
||||
grasscolor_argb = null;
|
||||
}
|
||||
|
||||
/* Load misc/foliagecolor.png */
|
||||
private void loadFoliageColorPNG(InputStream is) throws IOException {
|
||||
/* Load image */
|
||||
BufferedImage img = ImageIO.read(is);
|
||||
if(img == null) { throw new FileNotFoundException(); }
|
||||
foliagecolor_width = img.getWidth();
|
||||
foliagecolor_height = img.getHeight();
|
||||
foliagecolor_argb = new int[foliagecolor_width * foliagecolor_height];
|
||||
img.getRGB(0, 0, foliagecolor_width, foliagecolor_height, foliagecolor_argb, 0, foliagecolor_width);
|
||||
img.flush();
|
||||
/* Figure out trivial color */
|
||||
trivial_foliagecolor = foliagecolor_argb[foliagecolor_height*foliagecolor_width*3/4 + foliagecolor_width/2];
|
||||
boolean same = true;
|
||||
for(int j = 0; same && (j < foliagecolor_height); j++) {
|
||||
for(int i = 0; same && (i <= j); i++) {
|
||||
if(foliagecolor_argb[foliagecolor_width*j+i] != trivial_foliagecolor)
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
/* All the same - no biome lookup needed */
|
||||
if(same)
|
||||
foliagecolor_argb = null;
|
||||
}
|
||||
|
||||
/* Load misc/watercolor.png */
|
||||
private void loadWaterColorPNG(InputStream is) throws IOException {
|
||||
/* Load image */
|
||||
BufferedImage img = ImageIO.read(is);
|
||||
if(img == null) { throw new FileNotFoundException(); }
|
||||
watercolor_width = img.getWidth();
|
||||
watercolor_height = img.getHeight();
|
||||
watercolor_argb = new int[watercolor_width * watercolor_height];
|
||||
img.getRGB(0, 0, watercolor_width, watercolor_height, watercolor_argb, 0, watercolor_width);
|
||||
img.flush();
|
||||
/* Figure out trivial color */
|
||||
trivial_watercolor = watercolor_argb[watercolor_height*watercolor_width*3/4 + watercolor_width/2];
|
||||
boolean same = true;
|
||||
for(int j = 0; same && (j < watercolor_height); j++) {
|
||||
for(int i = 0; same && (i <= j); i++) {
|
||||
if(watercolor_argb[watercolor_width*j+i] != trivial_watercolor)
|
||||
same = false;
|
||||
}
|
||||
}
|
||||
/* All the same - no biome lookup needed */
|
||||
if(same)
|
||||
watercolor_argb = null;
|
||||
}
|
||||
|
||||
/* Load misc/water.png */
|
||||
private void loadWaterPNG(InputStream is) throws IOException {
|
||||
/* Load image */
|
||||
BufferedImage img = ImageIO.read(is);
|
||||
if(img == null) { throw new FileNotFoundException(); }
|
||||
water_width = img.getWidth();
|
||||
water_height = img.getHeight();
|
||||
water_argb = new int[water_width * water_height];
|
||||
img.getRGB(0, 0, water_width, water_height, water_argb, 0, water_width);
|
||||
img.flush();
|
||||
/* Now, patch in to block table */
|
||||
int new_water_argb[] = new int[native_scale*native_scale];
|
||||
scaleTerrainPNGSubImage(water_width, native_scale, water_argb, new_water_argb);
|
||||
terrain_argb[BLOCKINDEX_STATIONARYWATER] = new_water_argb;
|
||||
terrain_argb[BLOCKINDEX_MOVINGWATER] = new_water_argb;
|
||||
}
|
||||
/* Get texture pack directory */
|
||||
private static File getTexturePackDirectory() {
|
||||
return new File(DynmapPlugin.dataDirectory, "texturepacks");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resample terrain pack for given scale, and return copy using that scale
|
||||
*/
|
||||
public TexturePack resampleTexturePack(int scale) {
|
||||
if(scaled_textures == null) scaled_textures = new HashMap<Integer, TexturePack>();
|
||||
TexturePack stp = scaled_textures.get(scale);
|
||||
if(stp != null)
|
||||
return stp;
|
||||
stp = new TexturePack(this); /* Make copy */
|
||||
/* Scale terrain.png, if needed */
|
||||
if(stp.native_scale != scale) {
|
||||
stp.native_scale = scale;
|
||||
stp.terrain_height = 16*scale;
|
||||
stp.terrain_width = 16*scale;
|
||||
scaleTerrainPNG(stp);
|
||||
}
|
||||
/* Remember it */
|
||||
scaled_textures.put(scale, stp);
|
||||
return stp;
|
||||
}
|
||||
/**
|
||||
* Scale out terrain_argb into the terrain_argb of the provided destination, matching the scale of that destination
|
||||
* @param tp
|
||||
*/
|
||||
private void scaleTerrainPNG(TexturePack tp) {
|
||||
tp.terrain_argb = new int[256][];
|
||||
/* Terrain.png is 16x16 array of images : process one at a time */
|
||||
for(int idx = 0; idx < 256; idx++) {
|
||||
tp.terrain_argb[idx] = new int[tp.native_scale*tp.native_scale];
|
||||
scaleTerrainPNGSubImage(native_scale, tp.native_scale, terrain_argb[idx], tp.terrain_argb[idx]);
|
||||
}
|
||||
}
|
||||
private static void scaleTerrainPNGSubImage(int srcscale, int destscale, int[] src_argb, int[] dest_argb) {
|
||||
int nativeres = srcscale;
|
||||
int res = destscale;
|
||||
Color c = new Color();
|
||||
/* Same size, so just copy */
|
||||
if(res == nativeres) {
|
||||
System.arraycopy(src_argb, 0, dest_argb, 0, src_argb.length);
|
||||
}
|
||||
/* If we're scaling larger source pixels into smaller pixels, each destination pixel
|
||||
* receives input from 1 or 2 source pixels on each axis
|
||||
*/
|
||||
else if(res > nativeres) {
|
||||
int weights[] = new int[res];
|
||||
int offsets[] = new int[res];
|
||||
/* LCM of resolutions is used as length of line (res * nativeres)
|
||||
* Each native block is (res) long, each scaled block is (nativeres) long
|
||||
* Each scaled block overlaps 1 or 2 native blocks: starting with native block 'offsets[]' with
|
||||
* 'weights[]' of its (res) width in the first, and the rest in the second
|
||||
*/
|
||||
for(int v = 0, idx = 0; v < res*nativeres; v += nativeres, idx++) {
|
||||
offsets[idx] = (v/res); /* Get index of the first native block we draw from */
|
||||
if((v+nativeres-1)/res == offsets[idx]) { /* If scaled block ends in same native block */
|
||||
weights[idx] = nativeres;
|
||||
}
|
||||
else { /* Else, see how much is in first one */
|
||||
weights[idx] = (offsets[idx]*res + res) - v;
|
||||
}
|
||||
}
|
||||
/* Now, use weights and indices to fill in scaled map */
|
||||
for(int y = 0, off = 0; y < res; y++) {
|
||||
int ind_y = offsets[y];
|
||||
int wgt_y = weights[y];
|
||||
for(int x = 0; x < res; x++, off++) {
|
||||
int ind_x = offsets[x];
|
||||
int wgt_x = weights[x];
|
||||
int accum_red = 0;
|
||||
int accum_green = 0;
|
||||
int accum_blue = 0;
|
||||
int accum_alpha = 0;
|
||||
for(int xx = 0; xx < 2; xx++) {
|
||||
int wx = (xx==0)?wgt_x:(nativeres-wgt_x);
|
||||
if(wx == 0) continue;
|
||||
for(int yy = 0; yy < 2; yy++) {
|
||||
int wy = (yy==0)?wgt_y:(nativeres-wgt_y);
|
||||
if(wy == 0) continue;
|
||||
/* Accumulate */
|
||||
c.setARGB(src_argb[(ind_y+yy)*nativeres + ind_x + xx]);
|
||||
accum_red += c.getRed() * wx * wy;
|
||||
accum_green += c.getGreen() * wx * wy;
|
||||
accum_blue += c.getBlue() * wx * wy;
|
||||
accum_alpha += c.getAlpha() * wx * wy;
|
||||
}
|
||||
}
|
||||
/* Generate weighted compnents into color */
|
||||
c.setRGBA(accum_red / (nativeres*nativeres), accum_green / (nativeres*nativeres),
|
||||
accum_blue / (nativeres*nativeres), accum_alpha / (nativeres*nativeres));
|
||||
dest_argb[(y*res) + x] = c.getARGB();
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* nativeres > res */
|
||||
int weights[] = new int[nativeres];
|
||||
int offsets[] = new int[nativeres];
|
||||
/* LCM of resolutions is used as length of line (res * nativeres)
|
||||
* Each native block is (res) long, each scaled block is (nativeres) long
|
||||
* Each native block overlaps 1 or 2 scaled blocks: starting with scaled block 'offsets[]' with
|
||||
* 'weights[]' of its (res) width in the first, and the rest in the second
|
||||
*/
|
||||
for(int v = 0, idx = 0; v < res*nativeres; v += res, idx++) {
|
||||
offsets[idx] = (v/nativeres); /* Get index of the first scaled block we draw to */
|
||||
if((v+res-1)/nativeres == offsets[idx]) { /* If native block ends in same scaled block */
|
||||
weights[idx] = res;
|
||||
}
|
||||
else { /* Else, see how much is in first one */
|
||||
weights[idx] = (offsets[idx]*nativeres + nativeres) - v;
|
||||
}
|
||||
}
|
||||
int accum_red[] = new int[res*res];
|
||||
int accum_green[] = new int[res*res];
|
||||
int accum_blue[] = new int[res*res];
|
||||
int accum_alpha[] = new int[res*res];
|
||||
|
||||
/* Now, use weights and indices to fill in scaled map */
|
||||
for(int y = 0; y < nativeres; y++) {
|
||||
int ind_y = offsets[y];
|
||||
int wgt_y = weights[y];
|
||||
for(int x = 0; x < nativeres; x++) {
|
||||
int ind_x = offsets[x];
|
||||
int wgt_x = weights[x];
|
||||
c.setARGB(src_argb[(y*nativeres) + x]);
|
||||
for(int xx = 0; xx < 2; xx++) {
|
||||
int wx = (xx==0)?wgt_x:(res-wgt_x);
|
||||
if(wx == 0) continue;
|
||||
for(int yy = 0; yy < 2; yy++) {
|
||||
int wy = (yy==0)?wgt_y:(res-wgt_y);
|
||||
if(wy == 0) continue;
|
||||
accum_red[(ind_y+yy)*res + (ind_x+xx)] += c.getRed() * wx * wy;
|
||||
accum_green[(ind_y+yy)*res + (ind_x+xx)] += c.getGreen() * wx * wy;
|
||||
accum_blue[(ind_y+yy)*res + (ind_x+xx)] += c.getBlue() * wx * wy;
|
||||
accum_alpha[(ind_y+yy)*res + (ind_x+xx)] += c.getAlpha() * wx * wy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Produce normalized scaled values */
|
||||
for(int y = 0; y < res; y++) {
|
||||
for(int x = 0; x < res; x++) {
|
||||
int off = (y*res) + x;
|
||||
c.setRGBA(accum_red[off]/(nativeres*nativeres), accum_green[off]/(nativeres*nativeres),
|
||||
accum_blue[off]/(nativeres*nativeres), accum_alpha[off]/(nativeres*nativeres));
|
||||
dest_argb[y*res + x] = c.getARGB();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void saveTerrainPNG(File f) throws IOException {
|
||||
int[] outbuf = new int[256*native_scale*native_scale];
|
||||
for(int i = 0; i < 256; i++) {
|
||||
for(int y = 0; y < native_scale; y++) {
|
||||
System.arraycopy(terrain_argb[i],native_scale*y,outbuf,((i>>4)*native_scale+y)*terrain_width + (i & 0xF)*native_scale, native_scale);
|
||||
}
|
||||
}
|
||||
BufferedImage img = KzedMap.createBufferedImage(outbuf, terrain_width, terrain_height);
|
||||
ImageIO.write(img, "png", f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load texture pack mappings
|
||||
*/
|
||||
public static void loadTextureMapping(File datadir) {
|
||||
/* Load block models */
|
||||
loadTextureFile(new File(datadir, "texture.txt"));
|
||||
File custom = new File(datadir, "custom-texture.txt");
|
||||
if(custom.canRead()) {
|
||||
loadTextureFile(custom);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
FileWriter fw = new FileWriter(custom);
|
||||
fw.write("# The user is free to add new and custom texture mappings here - Dynmap's install will not overwrite it\n");
|
||||
fw.close();
|
||||
} catch (IOException iox) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load texture pack mappings from texture.txt file
|
||||
*/
|
||||
private static void loadTextureFile(File txtfile) {
|
||||
LineNumberReader rdr = null;
|
||||
int cnt = 0;
|
||||
/* Initialize map with blank map for all entries */
|
||||
HDTextureMap.initializeTable();
|
||||
|
||||
try {
|
||||
String line;
|
||||
rdr = new LineNumberReader(new FileReader(txtfile));
|
||||
while((line = rdr.readLine()) != null) {
|
||||
if(line.startsWith("block:")) {
|
||||
ArrayList<Integer> blkids = new ArrayList<Integer>();
|
||||
int databits = 0;
|
||||
int faces[] = new int[] { -1, -1, -1, -1, -1, -1 };
|
||||
line = line.substring(6);
|
||||
String[] args = line.split(",");
|
||||
for(String a : args) {
|
||||
String[] av = a.split("=");
|
||||
if(av.length < 2) continue;
|
||||
if(av[0].equals("id")) {
|
||||
blkids.add(Integer.parseInt(av[1]));
|
||||
}
|
||||
else if(av[0].equals("data")) {
|
||||
if(av[1].equals("*"))
|
||||
databits = 0xFFFF;
|
||||
else
|
||||
databits |= (1 << Integer.parseInt(av[1]));
|
||||
}
|
||||
else if(av[0].equals("top") || av[0].equals("y-")) {
|
||||
faces[BlockStep.Y_MINUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("bottom") || av[0].equals("y+")) {
|
||||
faces[BlockStep.Y_PLUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("north") || av[0].equals("x+")) {
|
||||
faces[BlockStep.X_PLUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("south") || av[0].equals("x-")) {
|
||||
faces[BlockStep.X_MINUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("west") || av[0].equals("z-")) {
|
||||
faces[BlockStep.Z_MINUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("east") || av[0].equals("z+")) {
|
||||
faces[BlockStep.Z_PLUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("allfaces")) {
|
||||
int id = Integer.parseInt(av[1]);
|
||||
for(int i = 0; i < 6; i++) {
|
||||
faces[i] = id;
|
||||
}
|
||||
}
|
||||
else if(av[0].equals("allsides")) {
|
||||
short id = Short.parseShort(av[1]);
|
||||
faces[BlockStep.X_PLUS.ordinal()] = id;
|
||||
faces[BlockStep.X_MINUS.ordinal()] = id;
|
||||
faces[BlockStep.Z_PLUS.ordinal()] = id;
|
||||
faces[BlockStep.Z_MINUS.ordinal()] = id;
|
||||
}
|
||||
else if(av[0].equals("topbottom")) {
|
||||
faces[BlockStep.Y_MINUS.ordinal()] =
|
||||
faces[BlockStep.Y_PLUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
}
|
||||
/* If we have everything, build block */
|
||||
if((blkids.size() > 0) && (databits != 0)) {
|
||||
HDTextureMap map = new HDTextureMap(blkids, databits, faces);
|
||||
map.addToTable();
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
Log.severe("Texture mapping missing required parameters = line " + rdr.getLineNumber() + " of " + txtfile.getPath());
|
||||
}
|
||||
}
|
||||
else if(line.startsWith("#") || line.startsWith(";")) {
|
||||
}
|
||||
}
|
||||
Log.verboseinfo("Loaded " + cnt + " texture mappings from " + txtfile.getPath());
|
||||
} catch (IOException iox) {
|
||||
Log.severe("Error reading " + txtfile.getPath() + " - " + iox.toString());
|
||||
} catch (NumberFormatException nfx) {
|
||||
Log.severe("Format error - line " + rdr.getLineNumber() + " of " + txtfile.getPath());
|
||||
} finally {
|
||||
if(rdr != null) {
|
||||
try {
|
||||
rdr.close();
|
||||
rdr = null;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Read color for given subblock coordinate, with given block id and data and face
|
||||
*/
|
||||
public void readColor(HDPerspectiveState ps, MapIterator mapiter, Color rslt, int blkid, int lastblocktype) {
|
||||
int blkdata = ps.getBlockData();
|
||||
HDTextureMap map = HDTextureMap.getMap(blkid, blkdata);
|
||||
BlockStep laststep = ps.getLastBlockStep();
|
||||
int textid = map.faces[laststep.ordinal()]; /* Get index of texture source */
|
||||
if(textid < 0) {
|
||||
rslt.setTransparent();
|
||||
return;
|
||||
}
|
||||
/* See if not basic block texture */
|
||||
int textop = textid / 1000;
|
||||
textid = textid % 1000;
|
||||
|
||||
/* If clear-inside op, get out early */
|
||||
if(textop == COLORMOD_CLEARINSIDE) {
|
||||
/* Check if previous block is same block type as we are: surface is transparent if it is */
|
||||
if(blkid == lastblocktype) {
|
||||
rslt.setTransparent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int[] texture = terrain_argb[textid];
|
||||
int[] xyz = ps.getSubblockCoord();
|
||||
/* Get texture coordinates (U=horizontal(left=0),V=vertical(top=0)) */
|
||||
int u = 0, v = 0, tmp;
|
||||
|
||||
switch(laststep) {
|
||||
case X_MINUS: /* South face: U = East (Z-), V = Down (Y-) */
|
||||
u = native_scale-xyz[2]-1; v = native_scale-xyz[1]-1;
|
||||
break;
|
||||
case X_PLUS: /* North face: U = West (Z+), V = Down (Y-) */
|
||||
u = xyz[2]; v = native_scale-xyz[1]-1;
|
||||
break;
|
||||
case Z_MINUS: /* West face: U = South (X+), V = Down (Y-) */
|
||||
u = xyz[0]; v = native_scale-xyz[1]-1;
|
||||
break;
|
||||
case Z_PLUS: /* East face: U = North (X-), V = Down (Y-) */
|
||||
u = native_scale-xyz[0]-1; v = native_scale-xyz[1]-1;
|
||||
break;
|
||||
case Y_MINUS: /* U = East(Z-), V = South(X+) */
|
||||
case Y_PLUS:
|
||||
u = native_scale-xyz[2]-1; v = xyz[0];
|
||||
break;
|
||||
}
|
||||
/* Handle U-V transorms before fetching color */
|
||||
if(textop > 0) {
|
||||
switch(textop) {
|
||||
case COLORMOD_ROT90:
|
||||
tmp = u; u = native_scale - v - 1; v = tmp;
|
||||
break;
|
||||
case COLORMOD_ROT180:
|
||||
u = native_scale - u - 1; v = native_scale - v - 1;
|
||||
break;
|
||||
case COLORMOD_ROT270:
|
||||
tmp = u; u = v; v = native_scale - tmp - 1;
|
||||
break;
|
||||
case COLORMOD_FLIPHORIZ:
|
||||
u = native_scale - u - 1;
|
||||
break;
|
||||
case COLORMOD_SHIFTDOWNHALF:
|
||||
case COLORMOD_SHIFTDOWNHALFANDFLIPHORIZ:
|
||||
if(v < native_scale/2) {
|
||||
rslt.setTransparent();
|
||||
return;
|
||||
}
|
||||
v -= native_scale/2;
|
||||
if(textop == COLORMOD_SHIFTDOWNHALFANDFLIPHORIZ)
|
||||
u = native_scale - u - 1;
|
||||
break;
|
||||
case COLORMOD_INCLINEDTORCH:
|
||||
if(v >= (3*native_scale/4)) {
|
||||
rslt.setTransparent();
|
||||
return;
|
||||
}
|
||||
v += native_scale/4;
|
||||
if(u < native_scale/2) u = native_scale/2-1;
|
||||
if(u > native_scale/2) u = native_scale/2;
|
||||
break;
|
||||
case COLORMOD_GRASSSIDE:
|
||||
/* Check if snow above block */
|
||||
if(mapiter.getBlockTypeIDAbove() == 78) {
|
||||
texture = terrain_argb[68]; /* Snow block */
|
||||
textid = 68;
|
||||
}
|
||||
else { /* Else, check the grass color overlay */
|
||||
int ovclr = terrain_argb[38][v*native_scale+u];
|
||||
if((ovclr & 0xFF000000) != 0) { /* Hit? */
|
||||
texture = terrain_argb[38]; /* Use it */
|
||||
textop = COLORMOD_GRASSTONED; /* Force grass toning */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Read color from texture */
|
||||
rslt.setARGB(texture[v*native_scale + u]);
|
||||
if(textop > 0) {
|
||||
/* Switch based on texture modifier */
|
||||
switch(textop) {
|
||||
case COLORMOD_GRASSTONED:
|
||||
if(grasscolor_argb == null) {
|
||||
rslt.blendColor(trivial_grasscolor);
|
||||
}
|
||||
else {
|
||||
rslt.blendColor(biomeLookup(grasscolor_argb, grasscolor_width, mapiter.getRawBiomeRainfall(), mapiter.getRawBiomeTemperature()));
|
||||
}
|
||||
break;
|
||||
case COLORMOD_FOLIAGETONED:
|
||||
if(foliagecolor_argb == null) {
|
||||
rslt.blendColor(trivial_foliagecolor);
|
||||
}
|
||||
else {
|
||||
rslt.blendColor(biomeLookup(foliagecolor_argb, foliagecolor_width, mapiter.getRawBiomeRainfall(), mapiter.getRawBiomeTemperature()));
|
||||
}
|
||||
break;
|
||||
case COLORMOD_WATERTONED:
|
||||
if(watercolor_argb == null) {
|
||||
rslt.blendColor(trivial_watercolor);
|
||||
}
|
||||
else {
|
||||
rslt.blendColor(biomeLookup(watercolor_argb, watercolor_width, mapiter.getRawBiomeRainfall(), mapiter.getRawBiomeTemperature()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int biomeLookup(int[] argb, int width, double rainfall, double temp) {
|
||||
int t = (int)((1.0-temp)*(width-1));
|
||||
int h = width - (int)(temp*rainfall*(width-1)) - 1;
|
||||
return argb[width*h + t];
|
||||
}
|
||||
}
|
214
src/main/java/org/dynmap/hdmap/TexturePackHDShader.java
Normal file
214
src/main/java/org/dynmap/hdmap/TexturePackHDShader.java
Normal file
@ -0,0 +1,214 @@
|
||||
package org.dynmap.hdmap;
|
||||
|
||||
import static org.dynmap.JSONUtils.s;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.dynmap.Color;
|
||||
import org.dynmap.ColorScheme;
|
||||
import org.dynmap.ConfigurationNode;
|
||||
import org.dynmap.Log;
|
||||
import org.dynmap.hdmap.HDPerspectiveState.BlockStep;
|
||||
import org.dynmap.utils.MapChunkCache;
|
||||
import org.dynmap.utils.MapIterator;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class TexturePackHDShader implements HDShader {
|
||||
private String tpname;
|
||||
private String name;
|
||||
private TexturePack tp;
|
||||
|
||||
public TexturePackHDShader(ConfigurationNode configuration) {
|
||||
tpname = configuration.getString("texturepack", "minecraft");
|
||||
name = configuration.getString("name", tpname);
|
||||
tp = TexturePack.getTexturePack(tpname);
|
||||
if(tp == null) {
|
||||
Log.severe("Error: shader '" + name + "' cannot load texture pack '" + tpname + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBiomeDataNeeded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRawBiomeDataNeeded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@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[];
|
||||
private Color tmpcolor[];
|
||||
private Color c;
|
||||
protected MapIterator mapiter;
|
||||
protected HDMap map;
|
||||
private TexturePack scaledtp;
|
||||
private HDLighting lighting;
|
||||
private int lastblkid;
|
||||
|
||||
private OurShaderState(MapIterator mapiter, HDMap map) {
|
||||
this.mapiter = mapiter;
|
||||
this.map = map;
|
||||
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() };
|
||||
}
|
||||
c = new Color();
|
||||
scaledtp = tp.resampleTexturePack(map.getPerspective().getModelScale());
|
||||
}
|
||||
/**
|
||||
* Get our shader
|
||||
*/
|
||||
public HDShader getShader() {
|
||||
return TexturePackHDShader.this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our map
|
||||
*/
|
||||
public HDMap getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our lighting
|
||||
*/
|
||||
public HDLighting getLighting() {
|
||||
return lighting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset renderer state for new ray
|
||||
*/
|
||||
public void reset(HDPerspectiveState ps) {
|
||||
for(Color c: color)
|
||||
c.setTransparent();
|
||||
lastblkid = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process next ray step - called for each block on route
|
||||
* @return true if ray is done, false if ray needs to continue
|
||||
*/
|
||||
public boolean processBlock(HDPerspectiveState ps) {
|
||||
int blocktype = ps.getBlockTypeID();
|
||||
int lastblocktype = lastblkid;
|
||||
lastblkid = blocktype;
|
||||
|
||||
if(blocktype == 0) {
|
||||
return false;
|
||||
}
|
||||
/* Get color from textures */
|
||||
scaledtp.readColor(ps, mapiter, c, blocktype, lastblocktype);
|
||||
|
||||
if (c.getAlpha() > 0) {
|
||||
int subalpha = ps.getSubmodelAlpha();
|
||||
/* Scale brightness depending upon face */
|
||||
switch(ps.getLastBlockStep()) {
|
||||
case X_MINUS:
|
||||
case X_PLUS:
|
||||
/* 60% brightness */
|
||||
c.blendColor(0xFFA0A0A0);
|
||||
break;
|
||||
case Y_MINUS:
|
||||
case Y_PLUS:
|
||||
/* 85% brightness for even, 90% for even*/
|
||||
if((mapiter.getY() & 0x01) == 0)
|
||||
c.blendColor(0xFFD9D9D9);
|
||||
else
|
||||
c.blendColor(0xFFE6E6E6);
|
||||
break;
|
||||
}
|
||||
/* Handle light level, if needed */
|
||||
lighting.applyLighting(ps, this, c, tmpcolor);
|
||||
/* If we got alpha from subblock model, use it instead */
|
||||
if(subalpha >= 0) {
|
||||
for(Color clr : tmpcolor)
|
||||
clr.setAlpha(Math.max(subalpha,clr.getAlpha()));
|
||||
}
|
||||
/* If no previous color contribution, use new color */
|
||||
if(color[0].isTransparent()) {
|
||||
for(int 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[0].getAlpha();
|
||||
int alpha2 = tmpcolor[0].getAlpha() * (255-alpha) / 255;
|
||||
int talpha = alpha + alpha2;
|
||||
for(int 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 */
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Ray ended - used to report that ray has exited map (called if renderer has not reported complete)
|
||||
*/
|
||||
public void rayFinished(HDPerspectiveState ps) {
|
||||
}
|
||||
/**
|
||||
* Get result color - get resulting color for ray
|
||||
* @param c - object to store color value in
|
||||
* @param index - index of color to request (renderer specific - 0=default, 1=day for night/day renderer
|
||||
*/
|
||||
public void getRayColor(Color c, int index) {
|
||||
c.setColor(color[index]);
|
||||
}
|
||||
/**
|
||||
* Clean up state object - called after last ray completed
|
||||
*/
|
||||
public void cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get renderer state object for use rendering a tile
|
||||
* @param map - map being rendered
|
||||
* @param cache - chunk cache containing data for tile to be rendered
|
||||
* @param mapiter - iterator used when traversing rays in tile
|
||||
* @return state object to use for all rays in tile
|
||||
*/
|
||||
public HDShaderState getStateInstance(HDMap map, MapChunkCache cache, MapIterator mapiter) {
|
||||
return new OurShaderState(mapiter, map);
|
||||
}
|
||||
|
||||
/* Add shader's contributions to JSON for map object */
|
||||
public void addClientConfiguration(JSONObject mapObject) {
|
||||
s(mapObject, "shader", name);
|
||||
}
|
||||
}
|
@ -145,6 +145,12 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
||||
public final int getZ() {
|
||||
return z;
|
||||
}
|
||||
public final int getBlockTypeIDAbove() {
|
||||
if(y < 127)
|
||||
return snap.getBlockTypeId(x & 0xF, y+1, z & 0xF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,4 +93,11 @@ public interface MapIterator {
|
||||
* Get Z coordinate
|
||||
*/
|
||||
int getZ();
|
||||
/**
|
||||
* Get block ID at one above current coordinates
|
||||
*
|
||||
* @return block id
|
||||
*/
|
||||
int getBlockTypeIDAbove();
|
||||
|
||||
}
|
||||
|
@ -145,6 +145,11 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
public final int getZ() {
|
||||
return z;
|
||||
}
|
||||
public final int getBlockTypeIDAbove() {
|
||||
if(y < 127)
|
||||
return snap.getBlockTypeId(x & 0xF, y+1, z & 0xF);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
365
texture.txt
Normal file
365
texture.txt
Normal file
@ -0,0 +1,365 @@
|
||||
# Mapping of texture resources to block ID and data values
|
||||
# block:id=<block-id>,data=<data-val|*>,top=<index>,bottom=<index>,north=<index>,south=<index>,east=<index>,west=<index>,allfaces=<index>,allsides=<index>
|
||||
# <index>=0-255 (index of patch in terrain.png), -1=clear, 1xxx=biome tint from grasscolor.png,257=stationary water,258=moving water,
|
||||
# 259=stationary lava,260=moving lava,2xxx=biome tint from foliagecolor.png,3xxx=biome tint from watercolor.png,4xxx=rotate texture 90,
|
||||
# 5xxx=rotate texture 180, 6xxx=rotate texture 270, 7xxx=flip texture horizontally, 8xxx=shift down 1/2 block, 9=shift down 1/2,flip horiz,
|
||||
# 10xxx=inclined-torch,11xxx=grass-side,12xxx=clear if same block
|
||||
######
|
||||
# Stone
|
||||
block:id=1,data=*,allfaces=1
|
||||
# Grass
|
||||
block:id=2,data=*,allsides=11003,top=1000,bottom=2
|
||||
# Dirt
|
||||
block:id=3,data=*,allfaces=2
|
||||
# Cobblestone
|
||||
block:id=4,data=*,allfaces=16
|
||||
# Wooden Plank
|
||||
block:id=5,data=*,allsides=4,topbottom=4004
|
||||
# Sapling
|
||||
block:id=6,data=0,data=3,allsides=15
|
||||
# Sapling (Spruce)
|
||||
block:id=6,data=1,allsides=63
|
||||
# Sapling (Birch)
|
||||
block:id=6,data=2,allsides=79
|
||||
# Bedrock
|
||||
block:id=7,data=*,allfaces=16
|
||||
# Water
|
||||
block:id=8,data=*,allfaces=12258
|
||||
# Stationary water
|
||||
block:id=9,data=*,allfaces=12257
|
||||
# Lava
|
||||
block:id=10,data=*,allfaces=260
|
||||
# Stationary Lava
|
||||
block:id=11,data=*,allfaces=259
|
||||
# Sand
|
||||
block:id=12,data=*,allfaces=18
|
||||
# Gravel
|
||||
block:id=13,data=*,allfaces=19
|
||||
# Gold Ore
|
||||
block:id=14,data=*,allfaces=32
|
||||
# Iron Ore
|
||||
block:id=15,data=*,allfaces=33
|
||||
# Coal Ore
|
||||
block:id=16,data=*,allfaces=34
|
||||
# Wood (std)
|
||||
block:id=17,data=0,allsides=20,top=21,bottom=21
|
||||
# Wood (spruce/pine)
|
||||
block:id=17,data=1,allsides=116,top=21,bottom=21
|
||||
# Wood (birch)
|
||||
block:id=17,data=2,allsides=117,top=21,bottom=21
|
||||
# Leaves (std)
|
||||
block:id=18,data=0,allfaces=2052
|
||||
# Leaves (spruce/pine)
|
||||
block:id=18,data=1,allfaces=2132
|
||||
# Leaves (birch)
|
||||
block:id=18,data=2,allfaces=2052
|
||||
# Sponge
|
||||
block:id=19,data=*,allfaces=48
|
||||
# Glass
|
||||
block:id=20,data=*,allfaces=12049
|
||||
# Lapis Lazuli Ore
|
||||
block:id=21,data=*,allfaces=160
|
||||
# Lapis Lazuli Block
|
||||
block:id=22,data=*,allfaces=144
|
||||
# Dispenser (facing east)
|
||||
block:id=23,data=2,top=62,east=46,south=45,north=45,west=45,bottom=62
|
||||
# Dispenser (facing west)
|
||||
block:id=23,data=3,top=62,west=46,south=45,north=45,east=45,bottom=62
|
||||
# Dispenser (facing north)
|
||||
block:id=23,data=4,top=62,north=46,south=45,east=45,west=45,bottom=62
|
||||
# Dispenser (facing south)
|
||||
block:id=23,data=5,top=62,south=46,north=45,east=45,west=45,bottom=62
|
||||
# Sandstone
|
||||
block:id=24,data=*,top=176,bottom=208,allsides=192
|
||||
# Note Block
|
||||
block:id=25,allfaces=74
|
||||
# Bed - head - pointing west
|
||||
block:id=26,data=8,top=5135,bottom=5135,south=7151,north=151,west=152
|
||||
# Bed - foot - pointing west
|
||||
block:id=26,data=0,top=5134,bottom=5134,south=7150,north=150,east=149
|
||||
# Bed - head - pointing north
|
||||
block:id=26,data=9,top=4135,bottom=4135,north=152,east=151,west=7151
|
||||
# Bed - foot - pointing north
|
||||
block:id=26,data=1,top=4134,bottom=4134,south=149,east=150,west=7150
|
||||
# Bed - head - pointing east
|
||||
block:id=26,data=10,top=135,bottom=135,south=151,north=7151,east=152
|
||||
# Bed - foot - pointing east
|
||||
block:id=26,data=2,top=134,bottom=134,south=150,north=7150,west=149
|
||||
# Bed - head - pointing south
|
||||
block:id=26,data=11,top=6135,bottom=6135,south=152,east=7151,west=151
|
||||
# Bed - foot - pointing south
|
||||
block:id=26,data=3,top=6134,bottom=6134,north=149,east=7150,west=150
|
||||
# Powered rail - heading east-west - unpowered
|
||||
# Powered rail - incline to east - unpowered
|
||||
# Powered rail - incline to west - unpowered
|
||||
block:id=27,data=0,data=4,data=5,top=4163,bottom=4163,allsides=4
|
||||
# Powered rail - heading east-west - powered
|
||||
# Powered rail - incline to east - powered
|
||||
# Powered rail - incline to west - powered
|
||||
block:id=27,data=8,data=12,data=13,top=4179,bottom=4179,allsides=4
|
||||
# Powered rail - heading north-south - unpowered
|
||||
# Powered rail - inclined to north - unpowered
|
||||
# Powered rail - inclined to south - unpowered
|
||||
block:id=27,data=1,data=2,data=3,top=163,bottom=163,allsides=4
|
||||
# Powered rail - heading north-sout - powered
|
||||
# Powered rail - inclined to north - powered
|
||||
# Powered rail - inclined to south - powered
|
||||
block:id=27,data=9,data=10,data=11,top=179,bottom=179,allsides=4
|
||||
# Detector rail - heading east-west
|
||||
# Detector rail - incline to east
|
||||
# Detector rail - incline to west
|
||||
block:id=28,data=0,data=4,data=5,top=4195,bottom=4195,allsides=4
|
||||
# Detector rail - heading north-south
|
||||
# Detector rail - incline to north
|
||||
# Detector rail - incline to south
|
||||
block:id=28,data=1,data=2,data=3,top=195,bottom=195,allsides=4
|
||||
# Sticky piston - facing down
|
||||
block:id=29,data=0,data=8,top=109,bottom=106,allsides=5108
|
||||
# Sticky piston - facing up
|
||||
block:id=29,data=1,data=9,top=106,bottom=109,allsides=108
|
||||
# Sticky piston - facing east
|
||||
block:id=29,data=2,data=10,east=106,west=109,top=6108,bottom=4108,north=4108,south=6108
|
||||
# Sticky piston - facing west
|
||||
block:id=29,data=3,data=11,west=106,east=109,top=4108,bottom=6108,north=6108,south=4108
|
||||
# Sticky piston - facing north
|
||||
block:id=29,data=4,data=12,north=106,south=109,top=108,bottom=5108,east=6108,west=4108
|
||||
# Sticky piston - facing south
|
||||
block:id=29,data=5,data=13,north=109,south=106,top=5108,bottom=108,east=4108,west=6108
|
||||
# Web
|
||||
block:id=30,data=*,allfaces=11
|
||||
# Dead shrub
|
||||
block:id=31,data=0,allsides=55,top=20
|
||||
# Tall Grass
|
||||
block:id=31,data=1,allfaces=1039
|
||||
# Fern
|
||||
block:id=31,data=2,allsides=1056,top=1000
|
||||
# Dead shrub
|
||||
block:id=32,data=*,allsides=55,top=20
|
||||
# Piston - facing down
|
||||
block:id=33,data=0,data=8,top=109,bottom=107,allsides=5108
|
||||
# Piston - facing up
|
||||
block:id=33,data=1,data=9,top=107,bottom=109,allsides=108
|
||||
# Piston - facing east
|
||||
block:id=33,data=2,data=10,east=107,west=109,top=6108,bottom=4108,north=4108,south=6108
|
||||
# Piston - facing west
|
||||
block:id=33,data=3,data=11,west=107,east=109,top=4108,bottom=6108,north=6108,south=4108
|
||||
# Piston - facing north
|
||||
block:id=33,data=4,data=12,north=107,south=109,top=108,bottom=5108,east=6108,west=4108
|
||||
# Piston - facing south
|
||||
block:id=33,data=5,data=13,north=109,south=107,top=5108,bottom=108,east=4108,west=6108
|
||||
# Piston extesions - skipped - render all as if closed
|
||||
block:id=34,data=*
|
||||
# Wool - white
|
||||
block:id=35,data=0,allfaces=64
|
||||
# Wool - orange
|
||||
block:id=35,data=1,allfaces=210
|
||||
# Wool - Magenta
|
||||
block:id=35,data=2,allfaces=194
|
||||
# Wool - Light Blue
|
||||
block:id=35,data=3,allfaces=178
|
||||
# Wool - Yellow
|
||||
block:id=35,data=4,allfaces=162
|
||||
# Wool - Light Green
|
||||
block:id=35,data=5,allfaces=146
|
||||
# Wool - Pink
|
||||
block:id=35,data=6,allfaces=130
|
||||
# Wool - Gray
|
||||
block:id=35,data=7,allfaces=114
|
||||
# Wool - Light Gray
|
||||
block:id=35,data=8,allfaces=225
|
||||
# Wool - Cyan
|
||||
block:id=35,data=9,allfaces=209
|
||||
# Wool - Purple
|
||||
block:id=35,data=10,allfaces=193
|
||||
# Wool - Blue
|
||||
block:id=35,data=11,allfaces=177
|
||||
# Wool - Brown
|
||||
block:id=35,data=12,allfaces=161
|
||||
# Wool - Dark Green
|
||||
block:id=35,data=13,allfaces=145
|
||||
# Wool - Red
|
||||
block:id=35,data=14,allfaces=129
|
||||
# Wool - Black
|
||||
block:id=35,data=15,allfaces=113
|
||||
# Block move by piston - don't render
|
||||
block:id=36,data=*
|
||||
# Dandelion
|
||||
block:id=37,data=*,allsides=13,top=162
|
||||
# Rose
|
||||
block:id=38,data=*,allsides=12,top=129
|
||||
# Brown mushroom
|
||||
block:id=39,data=*,allsides=29,top=161
|
||||
# Red mushroom
|
||||
block:id=40,data=*,allsides=28,top=129
|
||||
# Gold block
|
||||
block:id=41,data=*,allfaces=23
|
||||
# Iron block
|
||||
block:id=42,data=*,allfaces=22
|
||||
# Double Slab - stone
|
||||
block:id=43,data=0,allsides=5,topbottom=6
|
||||
# Double Slab - Sandstone
|
||||
block:id=43,data=1,top=176,bottom=208,allsides=192
|
||||
# Double Slab - Wood
|
||||
block:id=43,data=2,allsides=4,topbottom=4004
|
||||
# Double Slab - Cobblestone
|
||||
block:id=43,data=3,allfaces=16
|
||||
# Slab - stone
|
||||
block:id=44,data=0,allsides=5,topbottom=6
|
||||
# Slab - Sandstone
|
||||
block:id=44,data=1,top=176,bottom=208,allsides=192
|
||||
# Slab - Wood
|
||||
block:id=44,data=2,allsides=4,topbottom=4004
|
||||
# Slab - Cobblestone
|
||||
block:id=44,data=3,allfaces=16
|
||||
# Brick Block
|
||||
block:id=45,data=*,allfaces=7
|
||||
# TNT
|
||||
block:id=46,data=*,top=9,bottom=10,allsides=8
|
||||
# Bookshelf
|
||||
block:id=47,data=*,topbottom=4,allsides=35
|
||||
# Mossy Cobblestone
|
||||
block:id=48,data=*,allfaces=36
|
||||
# Obsidian
|
||||
block:id=49,data=*,allfaces=37
|
||||
# Torch - inclined
|
||||
block:id=50,data=1,data=2,data=3,data=4,allsides=10080,top=162,bottom=4
|
||||
# Torch - up
|
||||
block:id=50,data=5,allsides=80,top=162,bottom=4
|
||||
# Fire
|
||||
block:id=51,data=*,allsides=129,top=162
|
||||
# Monster spawner
|
||||
block:id=52,data=*,allfaces=65
|
||||
# Wooden stairs
|
||||
block:id=53,data=*,allsides=4,topbottom=4004
|
||||
# Chest - TODO: get entity data so we can see orientation
|
||||
block:id=54,data=*,top=25,south=27,north=27,east=26,west=26
|
||||
# Redstone wire (model handling shape - use red wool for color)
|
||||
block:id=55,data=*,allfaces=129
|
||||
# Diamond ore
|
||||
block:id=56,data=*,allfaces=50
|
||||
# Diamond block
|
||||
block:id=57,data=*,allfaces=24
|
||||
# Crafting table
|
||||
block:id=58,data=*,topbottom=43,east=59,west=59,north=60,south=60
|
||||
# Crops (size 1)
|
||||
block:id=59,data=0,allsides=88,top=1000
|
||||
# Crops (size 2)
|
||||
block:id=59,data=1,allsides=89,top=1000
|
||||
# Crops (size 3)
|
||||
block:id=59,data=2,allsides=90,top=1000
|
||||
# Crops (size 4)
|
||||
block:id=59,data=3,allsides=91,top=1000
|
||||
# Crops (size 5)
|
||||
block:id=59,data=4,allsides=92,top=1000
|
||||
# Crops (size 6)
|
||||
block:id=59,data=5,allsides=93,top=1000
|
||||
# Crops (size 7)
|
||||
block:id=59,data=6,allsides=94,top=1000
|
||||
# Crops (size 8)
|
||||
block:id=59,data=7,allsides=95,top=1000
|
||||
# Farmland (dry)
|
||||
block:id=60,data=0,allfaces=87
|
||||
# Farmland (wet)
|
||||
block:id=60,data=1,data=2,data=3,data=4,data=5,data=6,data=7,data=8,allfaces=88
|
||||
# Furnace (facing east)
|
||||
block:id=61,data=2,top=62,east=61,south=45,north=45,west=45,bottom=62
|
||||
# Furnace (facing west)
|
||||
block:id=61,data=3,top=62,west=61,south=45,north=45,east=45,bottom=62
|
||||
# Furnace (facing north)
|
||||
block:id=61,data=4,top=62,north=61,south=45,east=45,west=45,bottom=62
|
||||
# Furnace (facing south)
|
||||
block:id=61,data=5,top=62,south=61,north=45,east=45,west=45,bottom=62
|
||||
# Signpost
|
||||
block:id=62,data=*,allsides=4,topbottom=4004
|
||||
# Wooden Door - bottom
|
||||
block:id=64,data=0,data=1,data=2,data=3,data=4,data=5,data=6,data=7,allsides=97,topbottom=4
|
||||
# Wooden Door - top
|
||||
block:id=64,data=8,data=9,data=10,data=11,data=12,data=13,data=14,data=15,allsides=81,topbottom=4
|
||||
# Ladders
|
||||
block:id=65,data=*,allsides=83,topbottom=4
|
||||
# Rail - heading east-west
|
||||
# Rail - incline to east
|
||||
# Rail - incline to west
|
||||
block:id=66,data=0,data=4,data=5,top=4128,bottom=4128,allsides=4
|
||||
# Rail - heading north-south
|
||||
# Rail - incline to north
|
||||
# Rail - incline to south
|
||||
block:id=66,data=1,data=2,data=3,top=128,bottom=128,allsides=4
|
||||
# Rails - northeast corner
|
||||
block:id=66,data=6,topbottom=4112,allsides=4
|
||||
# Rails - southeast corner
|
||||
block:id=66,data=7,topbottom=5112,allsides=4
|
||||
# Rails - southwest corner
|
||||
block:id=66,data=8,topbottom=6112,allsides=4
|
||||
# Rails - northwest corner
|
||||
block:id=66,data=9,topbottom=112,allsides=4
|
||||
# Cobblestone Stairs
|
||||
block:id=67,data=*,allfaces=16
|
||||
# Wall sign
|
||||
block:id=68,data=*,allsides=4,topbottom=4004
|
||||
# Switch (just do stone for now)
|
||||
block:id=69,data=*,allfaces=1
|
||||
# Stone pressure plate
|
||||
block:id=70,data=*,allfaces=1
|
||||
# Iron Door - bottom
|
||||
block:id=71,data=0,data=1,data=2,data=3,data=4,data=5,data=6,data=7,allsides=98,topbottom=22
|
||||
# Iron Door - top
|
||||
block:id=71,data=8,data=9,data=10,data=11,data=12,data=13,data=14,data=15,allsides=82,topbottom=22
|
||||
# Wooden pressure plate
|
||||
block:id=72,data=*,allsides=4,topbottom=4004
|
||||
# Redstone Ore
|
||||
block:id=73,id=74,data=*,allfaces=51
|
||||
# Redstone Torch - unlit - inclined
|
||||
block:id=75,data=1,data=2,data=3,data=4,allsides=10115,top=162,bottom=4
|
||||
# Redstone Torch - unlit - up
|
||||
block:id=75,data=5,allsides=115,top=162,bottom=4
|
||||
# Redstone Torch - lit - inclined
|
||||
block:id=76,data=1,data=2,data=3,data=4,allsides=10099,top=162,bottom=4
|
||||
# Redstone Torch - lit - up
|
||||
block:id=76,data=5,allsides=99,top=162,bottom=4
|
||||
# Stone button
|
||||
block:id=77,data=*,allfaces=1
|
||||
# Snow
|
||||
block:id=78,data=*,allfaces=66
|
||||
# Ice
|
||||
block:id=79,data=*,allfaces=12067
|
||||
# Snow block
|
||||
block:id=80,data=*,allfaces=66
|
||||
# Cactus
|
||||
block:id=81,data=*,top=69,allsides=70,bottom=71
|
||||
# Clay block
|
||||
block:id=82,data=*,allfaces=72
|
||||
# Sugar Cane
|
||||
block:id=83,data=*,allsides=73,topbottom=21
|
||||
# Jukebox
|
||||
block:id=84,data=*,allsides=74,topbottom=75
|
||||
# Fence
|
||||
block:id=85,data=*,allsides=4,topbottom=4004
|
||||
# Pumpkin
|
||||
block:id=86,data=*,allsides=118,topbottom=102
|
||||
# Netherrock
|
||||
block:id=87,data=*,allfaces=103
|
||||
# SoulSand
|
||||
block:id=88,data=*,allfaces=104
|
||||
# Glowstone Block
|
||||
block:id=89,data=*,allfaces=105
|
||||
# Portal (no texture for this - using purple wool)
|
||||
block:id=90,data=*,allfaces=193
|
||||
# Jack O Lantern (east)
|
||||
block:id=91,data=0,north=118,south=118,east=120,west=118,topbottom=102
|
||||
# Jack O Lantern (south)
|
||||
block:id=91,data=1,north=118,south=120,east=118,west=118,topbottom=102
|
||||
# Jack O Lantern (west)
|
||||
block:id=91,data=2,north=118,south=118,east=118,west=120,topbottom=102
|
||||
# Jack O Lantern (north)
|
||||
block:id=91,data=3,north=120,south=118,east=118,west=118,topbottom=102
|
||||
# Cake Block
|
||||
block:id=92,data=*,allsides=122,top=121,bottom=124
|
||||
# Repeater (off)
|
||||
block:id=93,data=*,top=131,allsides=1,bottom=1
|
||||
# Repeater (on)
|
||||
block:id=94,data=*,top=147,allsides=1,bottom=1
|
||||
# Locked Chest - TODO: get entity data so we can see orientation
|
||||
block:id=95,data=*,top=25,south=27,north=27,east=26,west=26
|
||||
# Trap door
|
||||
block:id=96,data=*,topbottom=84,allsides=4
|
BIN
texturepacks/standard/misc/foliagecolor.png
Normal file
BIN
texturepacks/standard/misc/foliagecolor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
texturepacks/standard/misc/grasscolor.png
Normal file
BIN
texturepacks/standard/misc/grasscolor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
texturepacks/standard/misc/water.png
Normal file
BIN
texturepacks/standard/misc/water.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 306 B |
BIN
texturepacks/standard/misc/watercolor.png
Normal file
BIN
texturepacks/standard/misc/watercolor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
BIN
texturepacks/standard/terrain.png
Normal file
BIN
texturepacks/standard/terrain.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
Loading…
Reference in New Issue
Block a user