Add block transparency attributes to improve lighting accuracy
This commit is contained in:
parent
913a92a010
commit
644c8d0213
6 changed files with 170 additions and 134 deletions
|
|
@ -24,6 +24,8 @@ import org.dynmap.MapTile;
|
|||
import org.dynmap.TileHashManager;
|
||||
import org.dynmap.debug.Debug;
|
||||
import org.dynmap.utils.MapIterator.BlockStep;
|
||||
import org.dynmap.hdmap.TexturePack.BlockTransparency;
|
||||
import org.dynmap.hdmap.TexturePack.HDTextureMap;
|
||||
import org.dynmap.kzedmap.KzedMap.KzedBufferedImage;
|
||||
import org.dynmap.kzedmap.KzedMap;
|
||||
import org.dynmap.utils.FileLockManager;
|
||||
|
|
@ -75,6 +77,7 @@ public class IsoHDPerspective implements HDPerspective {
|
|||
private class OurPerspectiveState implements HDPerspectiveState {
|
||||
int blocktypeid = 0;
|
||||
int blockdata = 0;
|
||||
int lastblocktypeid = 0;
|
||||
Vector3D top, bottom;
|
||||
int px, py;
|
||||
BlockStep laststep = BlockStep.Y_MINUS;
|
||||
|
|
@ -92,67 +95,54 @@ public class IsoHDPerspective implements HDPerspective {
|
|||
MapIterator mapiter;
|
||||
boolean isnether;
|
||||
boolean skiptoair;
|
||||
int skylevel = -1;
|
||||
int emitlevel = -1;
|
||||
|
||||
public OurPerspectiveState(MapIterator mi, boolean isnether) {
|
||||
mapiter = mi;
|
||||
this.isnether = isnether;
|
||||
}
|
||||
/**
|
||||
* Update sky and emitted light
|
||||
*/
|
||||
private final void updateLightLevel() {
|
||||
/* Look up transparency for current block */
|
||||
BlockTransparency bt = HDTextureMap.getTransparency(blocktypeid);
|
||||
if(bt == BlockTransparency.TRANSPARENT) {
|
||||
skylevel = mapiter.getBlockSkyLight();
|
||||
emitlevel = mapiter.getBlockEmittedLight();
|
||||
}
|
||||
else if(HDTextureMap.getTransparency(lastblocktypeid) != BlockTransparency.SEMITRANSPARENT) {
|
||||
mapiter.unstepPosition(laststep); /* Back up to block we entered on */
|
||||
emitlevel = mapiter.getBlockEmittedLight();
|
||||
skylevel = mapiter.getBlockSkyLight();
|
||||
mapiter.stepPosition(laststep);
|
||||
}
|
||||
else {
|
||||
mapiter.unstepPosition(laststep); /* Back up to block we entered on */
|
||||
mapiter.stepPosition(BlockStep.Y_PLUS); /* Look above */
|
||||
emitlevel = mapiter.getBlockEmittedLight();
|
||||
skylevel = mapiter.getBlockSkyLight();
|
||||
mapiter.stepPosition(BlockStep.Y_MINUS);
|
||||
mapiter.stepPosition(laststep);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get sky light level - only available if shader requested it
|
||||
*/
|
||||
public final int getSkyLightLevel() {
|
||||
int ll;
|
||||
BlockStep ls;
|
||||
/* Some blocks are light blocking, but not fully blocking - this sucks */
|
||||
switch(mapiter.getBlockTypeID()) {
|
||||
case 53: /* Wood stairs */
|
||||
case 44: /* Slabs */
|
||||
case 67: /* Cobblestone stairs */
|
||||
ls = mapiter.unstepPosition();
|
||||
mapiter.stepPosition(BlockStep.Y_PLUS); /* Look above */
|
||||
ll = mapiter.getBlockSkyLight();
|
||||
mapiter.stepPosition(BlockStep.Y_MINUS);
|
||||
mapiter.stepPosition(ls);
|
||||
break;
|
||||
case 78: /* Snow */
|
||||
ll = mapiter.getBlockSkyLight();
|
||||
break;
|
||||
default:
|
||||
ls = mapiter.unstepPosition();
|
||||
ll = mapiter.getBlockSkyLight();
|
||||
mapiter.stepPosition(ls);
|
||||
break;
|
||||
if(skylevel < 0) {
|
||||
updateLightLevel();
|
||||
}
|
||||
|
||||
return ll;
|
||||
return skylevel;
|
||||
}
|
||||
/**
|
||||
* Get emitted light level - only available if shader requested it
|
||||
*/
|
||||
public final int getEmittedLightLevel() {
|
||||
int ll;
|
||||
BlockStep ls;
|
||||
/* Some blocks are light blocking, but not fully blocking - this sucks */
|
||||
switch(mapiter.getBlockTypeID()) {
|
||||
case 53: /* Wood stairs */
|
||||
case 44: /* Slabs */
|
||||
case 67: /* Cobblestone stairs */
|
||||
ls = mapiter.unstepPosition();
|
||||
mapiter.stepPosition(BlockStep.Y_PLUS); /* Look above */
|
||||
ll = mapiter.getBlockEmittedLight();
|
||||
mapiter.stepPosition(BlockStep.Y_MINUS);
|
||||
mapiter.stepPosition(ls);
|
||||
break;
|
||||
case 78: /* Snow */
|
||||
ll = mapiter.getBlockEmittedLight();
|
||||
break;
|
||||
default:
|
||||
ls = mapiter.unstepPosition();
|
||||
ll = mapiter.getBlockEmittedLight();
|
||||
mapiter.stepPosition(ls);
|
||||
break;
|
||||
}
|
||||
return ll;
|
||||
if(emitlevel < 0)
|
||||
updateLightLevel();
|
||||
return emitlevel;
|
||||
}
|
||||
/**
|
||||
* Get current block type ID
|
||||
|
|
@ -321,6 +311,7 @@ public class IsoHDPerspective implements HDPerspective {
|
|||
* Process visit of ray to block
|
||||
*/
|
||||
private boolean visit_block(MapIterator mapiter, HDShaderState[] shaderstate, boolean[] shaderdone) {
|
||||
lastblocktypeid = blocktypeid;
|
||||
blocktypeid = mapiter.getBlockTypeID();
|
||||
if(skiptoair) { /* If skipping until we see air */
|
||||
if(blocktypeid == 0) /* If air, we're done */
|
||||
|
|
@ -346,6 +337,7 @@ public class IsoHDPerspective implements HDPerspective {
|
|||
}
|
||||
if(!missed) {
|
||||
boolean done = true;
|
||||
skylevel = emitlevel = -1;
|
||||
for(int i = 0; i < shaderstate.length; i++) {
|
||||
if(!shaderdone[i])
|
||||
shaderdone[i] = shaderstate[i].processBlock(this);
|
||||
|
|
|
|||
|
|
@ -98,18 +98,27 @@ public class TexturePack {
|
|||
|
||||
private HashMap<Integer, TexturePack> scaled_textures;
|
||||
|
||||
|
||||
public enum BlockTransparency {
|
||||
OPAQUE, /* Block is opaque - blocks light - lit by light from adjacent blocks */
|
||||
TRANSPARENT, /* Block is transparent - passes light - lit by light level in own block */
|
||||
SEMITRANSPARENT /* Opaque block that doesn't block all rays (steps, slabs) - use light above for face lighting on opaque blocks */
|
||||
}
|
||||
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 BlockTransparency bt;
|
||||
private static HDTextureMap[] texmaps;
|
||||
private static BlockTransparency transp[];
|
||||
|
||||
private static void initializeTable() {
|
||||
texmaps = new HDTextureMap[16*BLOCKTABLELEN];
|
||||
transp = new BlockTransparency[BLOCKTABLELEN];
|
||||
HDTextureMap blank = new HDTextureMap();
|
||||
for(int i = 0; i < texmaps.length; i++)
|
||||
texmaps[i] = blank;
|
||||
for(int i = 0; i < transp.length; i++)
|
||||
transp[i] = BlockTransparency.OPAQUE;
|
||||
}
|
||||
|
||||
private HDTextureMap() {
|
||||
|
|
@ -122,10 +131,11 @@ public class TexturePack {
|
|||
}
|
||||
}
|
||||
|
||||
public HDTextureMap(List<Integer> blockids, int databits, int[] faces) {
|
||||
public HDTextureMap(List<Integer> blockids, int databits, int[] faces, BlockTransparency trans) {
|
||||
this.faces = faces;
|
||||
this.blockids = blockids;
|
||||
this.databits = databits;
|
||||
this.bt = trans;
|
||||
}
|
||||
|
||||
public void addToTable() {
|
||||
|
|
@ -136,12 +146,17 @@ public class TexturePack {
|
|||
texmaps[16*blkid + i] = this;
|
||||
}
|
||||
}
|
||||
transp[blkid] = bt; /* Transparency is only blocktype based right now */
|
||||
}
|
||||
}
|
||||
|
||||
public static HDTextureMap getMap(int blkid, int blkdata) {
|
||||
return texmaps[(blkid<<4) + blkdata];
|
||||
}
|
||||
|
||||
public static BlockTransparency getTransparency(int blkid) {
|
||||
return transp[blkid];
|
||||
}
|
||||
}
|
||||
/** Get or load texture pack */
|
||||
public static TexturePack getTexturePack(String tpname) {
|
||||
|
|
@ -573,6 +588,7 @@ public class TexturePack {
|
|||
int databits = -1;
|
||||
int faces[] = new int[] { -1, -1, -1, -1, -1, -1 };
|
||||
line = line.substring(6);
|
||||
BlockTransparency trans = BlockTransparency.OPAQUE;
|
||||
String[] args = line.split(",");
|
||||
for(String a : args) {
|
||||
String[] av = a.split("=");
|
||||
|
|
@ -622,12 +638,19 @@ public class TexturePack {
|
|||
faces[BlockStep.Y_MINUS.ordinal()] =
|
||||
faces[BlockStep.Y_PLUS.ordinal()] = Integer.parseInt(av[1]);
|
||||
}
|
||||
else if(av[0].equals("transparency")) {
|
||||
trans = BlockTransparency.valueOf(av[1]);
|
||||
if(trans == null) {
|
||||
trans = BlockTransparency.OPAQUE;
|
||||
Log.severe("Texture mapping has invalid transparency setting - " + av[1] + " - line " + rdr.getLineNumber() + " of " + txtfile.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If no data bits, assume all */
|
||||
if(databits < 0) databits = 0xFFFF;
|
||||
/* If we have everything, build block */
|
||||
if(blkids.size() > 0) {
|
||||
HDTextureMap map = new HDTextureMap(blkids, databits, faces);
|
||||
HDTextureMap map = new HDTextureMap(blkids, databits, faces, trans);
|
||||
map.addToTable();
|
||||
cnt++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,6 +159,12 @@ public class LegacyMapChunkCache implements MapChunkCache {
|
|||
stepPosition(unstep[ls.ordinal()]);
|
||||
return ls;
|
||||
}
|
||||
/**
|
||||
* Unstep current position in oppisite director of given step
|
||||
*/
|
||||
public void unstepPosition(BlockStep s) {
|
||||
stepPosition(unstep[s.ordinal()]);
|
||||
}
|
||||
public final void setY(int y) {
|
||||
if(y > this.y)
|
||||
laststep = BlockStep.Y_PLUS;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ public interface MapIterator {
|
|||
* Step current position in given direction
|
||||
*/
|
||||
void stepPosition(BlockStep step);
|
||||
/**
|
||||
* Step current position in opposite of given direction
|
||||
*/
|
||||
void unstepPosition(BlockStep step);
|
||||
/**
|
||||
* Unstep current position to previous position : return step to take to return
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||
private ChunkSnapshot snap;
|
||||
private BlockStep laststep;
|
||||
private int typeid = -1;
|
||||
private int blkdata = -1;
|
||||
|
||||
OurMapIterator(int x0, int y0, int z0) {
|
||||
initialize(x0, y0, z0);
|
||||
|
|
@ -72,7 +73,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||
snap = EMPTY;
|
||||
}
|
||||
laststep = BlockStep.Y_MINUS;
|
||||
typeid = -1;
|
||||
typeid = blkdata = -1;
|
||||
}
|
||||
public final int getBlockTypeID() {
|
||||
if(typeid < 0)
|
||||
|
|
@ -80,7 +81,9 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||
return typeid;
|
||||
}
|
||||
public final int getBlockData() {
|
||||
return snap.getBlockData(bx, y, bz);
|
||||
if(blkdata < 0)
|
||||
blkdata = snap.getBlockData(bx, y, bz);
|
||||
return blkdata;
|
||||
}
|
||||
public final int getHighestBlockYAt() {
|
||||
return snap.getHighestBlockYAt(bx, bz);
|
||||
|
|
@ -166,6 +169,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||
}
|
||||
laststep = step;
|
||||
typeid = -1;
|
||||
blkdata = -1;
|
||||
}
|
||||
/**
|
||||
* Unstep current position to previous position
|
||||
|
|
@ -175,6 +179,12 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||
stepPosition(unstep[ls.ordinal()]);
|
||||
return ls;
|
||||
}
|
||||
/**
|
||||
* Unstep current position in oppisite director of given step
|
||||
*/
|
||||
public void unstepPosition(BlockStep s) {
|
||||
stepPosition(unstep[s.ordinal()]);
|
||||
}
|
||||
public final void setY(int y) {
|
||||
if(y > this.y)
|
||||
laststep = BlockStep.Y_PLUS;
|
||||
|
|
@ -182,6 +192,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
|||
laststep = BlockStep.Y_PLUS;
|
||||
this.y = y;
|
||||
typeid = -1;
|
||||
blkdata = -1;
|
||||
}
|
||||
public final int getX() {
|
||||
return x;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue