Start work on new water model - shift over to using basic version

This commit is contained in:
Mike Primm 2018-09-01 16:55:00 -05:00
parent 88816b176e
commit 6da97c5e3f
20 changed files with 325 additions and 182 deletions

View File

@ -251,6 +251,9 @@ public class CaveHDShader implements HDShader {
public int[] getLightingTable() {
return lightingTable;
}
@Override
public void setLastBlockState(DynmapBlockState new_lastbs) {
}
}
/**

View File

@ -12,18 +12,18 @@ import org.dynmap.renderer.RenderPatch;
public class CustomBlockModel extends HDBlockModel {
public CustomRenderer render;
public CustomBlockModel(String blockname, BitSet databits, String classname, Map<String,String> classparm, String blockset) {
super(blockname, databits, blockset);
public CustomBlockModel(DynmapBlockState bstate, BitSet databits, String classname, Map<String,String> classparm, String blockset) {
super(bstate, databits, blockset);
try {
Class<?> cls = Class.forName(classname); /* Get class */
render = (CustomRenderer) cls.newInstance();
if(render.initializeRenderer(HDBlockModels.pdf, blockname, databits, classparm) == false) {
if(render.initializeRenderer(HDBlockModels.pdf, bstate.blockName, databits, classparm) == false) {
Log.severe("Error loading custom renderer - " + classname);
render = null;
}
else {
if(render.getTileEntityFieldsNeeded() != null) {
DynmapBlockState bbs = DynmapBlockState.getBaseStateByName(blockname);
DynmapBlockState bbs = bstate.baseState;
for(int i = 0; i < bbs.getStateCount(); i++) {
if (databits.isEmpty() || databits.get(i)) {
DynmapBlockState bs = bbs.getState(i);

View File

@ -245,6 +245,9 @@ public class DefaultHDShader implements HDShader {
public int[] getLightingTable() {
return lightingTable;
}
@Override
public void setLastBlockState(DynmapBlockState new_lastbs) {
}
}
private class OurBiomeShaderState extends OurShaderState {

View File

@ -8,13 +8,13 @@ public abstract class HDBlockModel {
private String blockset;
/**
* Block definition - positions correspond to Bukkit coordinates (+X is south, +Y is up, +Z is west)
* @param blockname - block name
* @param bstate - block state
* @param databits - bitmap of block data bits matching this model (bit N is set if data=N would match)
* @param blockset - ID of block definition set
*/
protected HDBlockModel(String blockname, BitSet databits, String blockset) {
protected HDBlockModel(DynmapBlockState bstate, BitSet databits, String blockset) {
this.blockset = blockset;
DynmapBlockState bblk = DynmapBlockState.getBaseStateByName(blockname);
DynmapBlockState bblk = bstate.baseState;
if (bblk.isNotAir()) {
for (int i = 0; i < bblk.getStateCount(); i++) {
if (databits.isEmpty() || databits.get(i)) {

View File

@ -43,7 +43,7 @@ public class HDBlockModels {
private static HashSet<String> loadedmods = new HashSet<String>();
private static HashMap<Integer, HDScaledBlockModels> scaled_models_by_scale = new HashMap<Integer, HDScaledBlockModels>();
public static final int getMaxPatchCount() { return max_patches; }
public static final int getMaxPatchCount() { return max_patches; }
public static final PatchDefinitionFactory getPatchDefinitionFactory() { return pdf; }
/* Reset model if defined by different block set */
@ -390,7 +390,7 @@ public class HDBlockModels {
for(String bname : blknames) {
DynmapBlockState bblk = DynmapBlockState.getBaseStateByName(bname);
if (bblk.isNotAir()) {
modlist.add(new HDBlockVolumetricModel(bblk.blockName, databits, scale, new long[0], blockset));
modlist.add(new HDBlockVolumetricModel(bblk, databits, scale, new long[0], blockset));
cnt++;
}
else {
@ -740,7 +740,7 @@ public class HDBlockModels {
for(String nm : blknames) {
DynmapBlockState bs = DynmapBlockState.getBaseStateByName(nm);
if (bs.isNotAir()) {
pmodlist.add(new HDBlockPatchModel(bs.blockName, databits, patcharray, blockset));
pmodlist.add(new HDBlockPatchModel(bs, databits, patcharray, blockset));
cnt++;
}
else {
@ -804,7 +804,7 @@ public class HDBlockModels {
for(String nm : blknames) {
DynmapBlockState bs = DynmapBlockState.getBaseStateByName(nm);
if (bs.isNotAir()) {
pmodlist.add(new HDBlockPatchModel(bs.blockName, databits, patcharray, blockset));
pmodlist.add(new HDBlockPatchModel(bs, databits, patcharray, blockset));
cnt++;
}
else {
@ -852,7 +852,7 @@ public class HDBlockModels {
for (String nm : blknames) {
DynmapBlockState bs = DynmapBlockState.getBaseStateByName(nm);
if (bs.isNotAir()) {
CustomBlockModel cbm = new CustomBlockModel(bs.blockName, databits, cls, custargs, blockset);
CustomBlockModel cbm = new CustomBlockModel(bs, databits, cls, custargs, blockset);
if(cbm.render == null) {
Log.severe("Custom block model failed to initialize = line " + rdr.getLineNumber() + " of " + fname);
}

View File

@ -2,6 +2,7 @@ package org.dynmap.hdmap;
import java.util.BitSet;
import org.dynmap.renderer.DynmapBlockState;
import org.dynmap.utils.PatchDefinition;
public class HDBlockPatchModel extends HDBlockModel {
@ -11,13 +12,13 @@ public class HDBlockPatchModel extends HDBlockModel {
/**
* Block definition - positions correspond to Bukkit coordinates (+X is south, +Y is up, +Z is west)
* (for patch models)
* @param blockname - block name
* @param bs - block state
* @param databits - bitmap of block data bits matching this model (bit N is set if data=N would match)
* @param patches - list of patches (surfaces composing model)
* @param blockset - ID of set of blocks defining model
*/
public HDBlockPatchModel(String blockname, BitSet databits, PatchDefinition[] patches, String blockset) {
super(blockname, databits, blockset);
public HDBlockPatchModel(DynmapBlockState bs, BitSet databits, PatchDefinition[] patches, String blockset) {
super(bs, databits, blockset);
this.patches = patches;
int max = 0;
for(int i = 0; i < patches.length; i++) {

View File

@ -3,6 +3,8 @@ package org.dynmap.hdmap;
import java.util.BitSet;
import java.util.HashMap;
import org.dynmap.renderer.DynmapBlockState;
public class HDBlockVolumetricModel extends HDBlockModel {
/* Volumetric model specific attributes */
private long blockflags[];
@ -11,15 +13,15 @@ public class HDBlockVolumetricModel extends HDBlockModel {
/**
* Block definition - positions correspond to Bukkit coordinates (+X is south, +Y is up, +Z is west)
* (for volumetric models)
* @param blockname - block name
* @param bs - block state
* @param databits - bitmap of block data bits matching this model (bit N is set if data=N would match)
* @param nativeres - native subblocks per edge of cube (up to 64)
* @param blockflags - array of native^2 long integers representing volume of block (bit X of element (nativeres*Y+Z) is set if that subblock is filled)
* if array is short, other elements area are assumed to be zero (fills from bottom of block up)
* @param blockset - ID of set of blocks defining model
*/
public HDBlockVolumetricModel(String blockname, BitSet databits, int nativeres, long[] blockflags, String blockset) {
super(blockname, databits, blockset);
public HDBlockVolumetricModel(DynmapBlockState bs, BitSet databits, int nativeres, long[] blockflags, String blockset) {
super(bs, databits, blockset);
this.nativeres = nativeres;
this.blockflags = new long[nativeres * nativeres];

View File

@ -63,6 +63,10 @@ public interface HDPerspectiveState {
* @return coordinates of ray
*/
int[] getSubblockCoord();
/**
* Check if point is on face
*/
boolean isOnFace();
/**
* Get map iterator
* @return iterator

View File

@ -1,6 +1,7 @@
package org.dynmap.hdmap;
import org.dynmap.Color;
import org.dynmap.renderer.DynmapBlockState;
import org.dynmap.utils.DynLongHashMap;
/**
@ -59,4 +60,8 @@ public interface HDShaderState {
* @return array of lighting values
*/
int[] getLightingTable();
/**
* Update last block state (called before moving to next block)
*/
void setLastBlockState(DynmapBlockState new_lastbs);
}

View File

@ -210,6 +210,9 @@ public class InhabitedHDShader implements HDShader {
public int[] getLightingTable() {
return lightingTable;
}
@Override
public void setLastBlockState(DynmapBlockState new_lastbs) {
}
}
/**

View File

@ -80,6 +80,7 @@ public class IsoHDPerspective implements HDPerspective {
private static final BlockStep [] semi_steps = { BlockStep.Y_PLUS, BlockStep.X_MINUS, BlockStep.X_PLUS, BlockStep.Z_MINUS, BlockStep.Z_PLUS };
private DynmapBlockState full_water = null;
private RenderPatch full_water_patch = null;
private class OurPerspectiveState implements HDPerspectiveState {
DynmapBlockState blocktype = DynmapBlockState.AIR;
@ -122,11 +123,12 @@ public class IsoHDPerspective implements HDPerspective {
Vector3D v0 = new Vector3D();
Vector3D vS = new Vector3D();
Vector3D d_cross_uv = new Vector3D();
double patch_t[] = new double[HDBlockModels.getMaxPatchCount()];
double patch_u[] = new double[HDBlockModels.getMaxPatchCount()];
double patch_v[] = new double[HDBlockModels.getMaxPatchCount()];
BlockStep patch_step[] = new BlockStep[HDBlockModels.getMaxPatchCount()];
int patch_id[] = new int[HDBlockModels.getMaxPatchCount()];
// Double max patch count to be safe for patches + water patches
double patch_t[] = new double[2*HDBlockModels.getMaxPatchCount()];
double patch_u[] = new double[2*HDBlockModels.getMaxPatchCount()];
double patch_v[] = new double[2*HDBlockModels.getMaxPatchCount()];
BlockStep patch_step[] = new BlockStep[2*HDBlockModels.getMaxPatchCount()];
int patch_id[] = new int[2*HDBlockModels.getMaxPatchCount()];
int cur_patch = -1;
double cur_patch_u;
double cur_patch_v;
@ -142,6 +144,7 @@ public class IsoHDPerspective implements HDPerspective {
/* Cache for custom model patch lists */
private final DynLongHashMap custom_meshes;
private final DynLongHashMap custom_fluid_meshes;
public OurPerspectiveState(MapIterator mi, boolean isnether, int scaled) {
mapiter = mi;
@ -154,6 +157,7 @@ public class IsoHDPerspective implements HDPerspective {
for(int i = 0; i < llcache.length; i++)
llcache[i] = new LightLevels();
custom_meshes = new DynLongHashMap();
custom_fluid_meshes = new DynLongHashMap();
modscale = basemodscale << scaled;
scalemodels = HDBlockModels.getModelsForScale(basemodscale << scaled);
}
@ -394,83 +398,112 @@ public class IsoHDPerspective implements HDPerspective {
nonairhit = true;
firststep = false;
}
// Set current block as last block for any incomplete shaders
for(int i = 0; i < shaderstate.length; i++) {
if(!shaderdone[i])
// Update with current block as last block
shaderstate[i].setLastBlockState(blocktype);
}
return false;
}
private final boolean handlePatches(RenderPatch[] patches, HDShaderState[] shaderstate, boolean[] shaderdone) {
private final int handlePatch(PatchDefinition pd, int hitcnt) {
/* Compute origin of patch */
v0.x = (double)x + pd.x0;
v0.y = (double)y + pd.y0;
v0.z = (double)z + pd.z0;
/* Compute cross product of direction and V vector */
d_cross_uv.set(direction);
d_cross_uv.crossProduct(pd.v);
/* Compute determinant - inner product of this with U */
double det = pd.u.innerProduct(d_cross_uv);
/* If parallel to surface, no intercept */
switch(pd.sidevis) {
case TOP:
if (det < 0.000001) {
return hitcnt;
}
break;
case BOTTOM:
if (det > -0.000001) {
return hitcnt;
}
break;
case BOTH:
case FLIP:
if((det > -0.000001) && (det < 0.000001)) {
return hitcnt;
}
break;
}
double inv_det = 1.0 / det; /* Calculate inverse determinant */
/* Compute distance from patch to ray origin */
vS.set(top);
vS.subtract(v0);
/* Compute u - slope times inner product of offset and cross product */
double u = inv_det * vS.innerProduct(d_cross_uv);
if((u <= pd.umin) || (u >= pd.umax)) {
return hitcnt;
}
/* Compute cross product of offset and U */
vS.crossProduct(pd.u);
/* Compute V using slope times inner product of direction and cross product */
double v = inv_det * direction.innerProduct(vS);
if((v <= pd.vmin) || (v >= pd.vmax) || ((u + v) >= pd.uplusvmax)) {
return hitcnt;
}
/* Compute parametric value of intercept */
double t = inv_det * pd.v.innerProduct(vS);
if (t > 0.000001) { /* We've got a hit */
patch_t[hitcnt] = t;
patch_u[hitcnt] = u;
patch_v[hitcnt] = v;
patch_id[hitcnt] = pd.textureindex;
if(det > 0) {
patch_step[hitcnt] = pd.step.opposite();
}
else {
if (pd.sidevis == SideVisible.FLIP) {
patch_u[hitcnt] = 1 - u;
}
patch_step[hitcnt] = pd.step;
}
hitcnt++;
}
return hitcnt;
}
private final boolean handlePatches(RenderPatch[] patches, HDShaderState[] shaderstate, boolean[] shaderdone, RenderPatch[] fluidpatches) {
int hitcnt = 0;
int water_hit = Integer.MAX_VALUE; // hit index of first water hit
/* Loop through patches : compute intercept values for each */
for(int i = 0; i < patches.length; i++) {
PatchDefinition pd = (PatchDefinition)patches[i];
/* Compute origin of patch */
v0.x = (double)x + pd.x0;
v0.y = (double)y + pd.y0;
v0.z = (double)z + pd.z0;
/* Compute cross product of direction and V vector */
d_cross_uv.set(direction);
d_cross_uv.crossProduct(pd.v);
/* Compute determinant - inner product of this with U */
double det = pd.u.innerProduct(d_cross_uv);
/* If parallel to surface, no intercept */
switch(pd.sidevis) {
case TOP:
if (det < 0.000001) {
continue;
}
break;
case BOTTOM:
if (det > -0.000001) {
continue;
}
break;
case BOTH:
case FLIP:
if((det > -0.000001) && (det < 0.000001)) {
continue;
}
break;
hitcnt = handlePatch((PatchDefinition)patches[i], hitcnt);
}
if ((fluidpatches != null) && (fluidpatches.length > 0)) {
if (full_water == null) {
full_water = DynmapBlockState.getBaseStateByName(DynmapBlockState.WATER_BLOCK);
}
double inv_det = 1.0 / det; /* Calculate inverse determinant */
/* Compute distance from patch to ray origin */
vS.set(top);
vS.subtract(v0);
/* Compute u - slope times inner product of offset and cross product */
double u = inv_det * vS.innerProduct(d_cross_uv);
if((u <= pd.umin) || (u >= pd.umax)) {
continue;
int prev_hitcnt = hitcnt;
for(int i = 0; i < fluidpatches.length; i++) {
hitcnt = handlePatch((PatchDefinition)fluidpatches[i], hitcnt);
}
/* Compute cross product of offset and U */
vS.crossProduct(pd.u);
/* Compute V using slope times inner product of direction and cross product */
double v = inv_det * direction.innerProduct(vS);
if((v <= pd.vmin) || (v >= pd.vmax) || ((u + v) >= pd.uplusvmax)) {
continue;
}
/* Compute parametric value of intercept */
double t = inv_det * pd.v.innerProduct(vS);
if (t > 0.000001) { /* We've got a hit */
patch_t[hitcnt] = t;
patch_u[hitcnt] = u;
patch_v[hitcnt] = v;
patch_id[hitcnt] = pd.textureindex;
if(det > 0) {
patch_step[hitcnt] = pd.step.opposite();
}
else {
if (pd.sidevis == SideVisible.FLIP) {
patch_u[hitcnt] = 1 - u;
}
patch_step[hitcnt] = pd.step;
}
hitcnt++;
if (prev_hitcnt < hitcnt) { // At least one water hit?
water_hit = prev_hitcnt; // Remember index
}
}
/* If no hits, we're done */
if(hitcnt == 0) {
// Set current block as last block for any incomplete shaders
for(int i = 0; i < shaderstate.length; i++) {
if(!shaderdone[i])
// Update with current block as last block
shaderstate[i].setLastBlockState(blocktype);
}
return false;
}
BlockStep old_laststep = laststep; /* Save last step */
DynmapBlockState cur_bt = blocktype;
for(int i = 0; i < hitcnt; i++) {
/* Find closest hit (lowest parametric value) */
double best_t = Double.MAX_VALUE;
@ -486,6 +519,10 @@ public class IsoHDPerspective implements HDPerspective {
cur_patch_v = patch_v[best_patch];
laststep = patch_step[best_patch];
cur_patch_t = best_t;
// If the water patch, switch to water state and patch index
if (best_patch >= water_hit) {
blocktype = full_water;
}
/* Process the shaders */
boolean done = true;
for(int j = 0; j < shaderstate.length; j++) {
@ -493,6 +530,10 @@ public class IsoHDPerspective implements HDPerspective {
shaderdone[j] = shaderstate[j].processBlock(this);
done = done && shaderdone[j];
}
// If water, restore block type
if (best_patch >= water_hit) {
blocktype = cur_bt;
}
cur_patch = -1;
/* If all are done, we're out */
if(done) {
@ -504,10 +545,41 @@ public class IsoHDPerspective implements HDPerspective {
patch_t[best_patch] = Double.MAX_VALUE;
}
laststep = old_laststep;
// Set current block as last block for any incomplete shaders
for(int i = 0; i < shaderstate.length; i++) {
if(!shaderdone[i])
// Update with current block as last block
shaderstate[i].setLastBlockState(blocktype);
}
return false;
}
private RenderPatch[] getPatches(DynmapBlockState bt, boolean isFluid) {
RenderPatch[] patches = scalemodels.getPatchModel(bt);
/* If no patches, see if custom model */
if (patches == null) {
CustomBlockModel cbm = scalemodels.getCustomBlockModel(bt);
if (cbm != null) { /* If found, see if cached already */
if (isFluid) {
patches = this.getCustomFluidMesh();
if (patches == null) {
patches = cbm.getMeshForBlock(mapiter);
this.setCustomFluidMesh(patches);
}
}
else {
patches = this.getCustomMesh();
if (patches == null) {
patches = cbm.getMeshForBlock(mapiter);
this.setCustomMesh(patches);
}
}
}
}
return patches;
}
/**
* Process visit of ray to block
*/
@ -520,45 +592,17 @@ public class IsoHDPerspective implements HDPerspective {
}
}
else if(nonairhit || blocktype.isNotAir()) {
// If waterlogged, start by rendering as if full water block
if (blocktype.isWaterlogged()) {
boolean done = true;
DynmapBlockState saved_type = blocktype;
if (full_water == null) {
full_water = DynmapBlockState.getBaseStateByName(DynmapBlockState.WATER_BLOCK);
}
blocktype = full_water; // Switch to water state
subalpha = -1;
for (int i = 0; i < shaderstate.length; i++) {
if(!shaderdone[i]) {
shaderdone[i] = shaderstate[i].processBlock(this);
}
done = done && shaderdone[i];
}
// Restore block type
blocktype = saved_type;
/* If all are done, we're out */
if (done) {
return true;
}
nonairhit = true;
}
short[] model;
RenderPatch[] patches = scalemodels.getPatchModel(blocktype);
/* If no patches, see if custom model */
if (patches == null) {
CustomBlockModel cbm = scalemodels.getCustomBlockModel(blocktype);
if (cbm != null) { /* If found, see if cached already */
patches = this.getCustomMesh();
if (patches == null) {
patches = cbm.getMeshForBlock(mapiter);
this.setCustomMesh(patches);
}
}
}
RenderPatch[] patches = getPatches(blocktype, false);
/* Look up to see if block is modelled */
if(patches != null) {
return handlePatches(patches, shaderstate, shaderdone);
RenderPatch[] fluidpatches = null;
// If so, check for waterlogged
DynmapBlockState fluidstate = blocktype.getLiquidState();
if (fluidstate != null) {
fluidpatches = getPatches(fluidstate, true);
}
return handlePatches(patches, shaderstate, shaderdone, fluidpatches);
}
else if ((model = scalemodels.getScaledModel(blocktype)) != null) {
return handleSubModel(model, shaderstate, shaderdone);
@ -569,6 +613,8 @@ public class IsoHDPerspective implements HDPerspective {
for(int i = 0; i < shaderstate.length; i++) {
if(!shaderdone[i]) {
shaderdone[i] = shaderstate[i].processBlock(this);
// Update with current block as last block
shaderstate[i].setLastBlockState(blocktype);
}
done = done && shaderdone[i];
}
@ -825,6 +871,27 @@ public class IsoHDPerspective implements HDPerspective {
return subblock_xyz;
}
// Is the hit on a cullable face?
public final boolean isOnFace() {
double tt;
if(cur_patch >= 0) { /* If patch hit */
tt = cur_patch_t;
}
else if(subalpha < 0) {
tt = t + 0.0000001;
}
else { // Full blocks always on face
return true;
}
double xx = top.x + tt * direction.x;
double yy = top.y + tt * direction.y;
double zz = top.z + tt * direction.z;
double xoff = xx - fastFloor(xx);
double yoff = yy - fastFloor(yy);
double zoff = zz - fastFloor(zz);
return ((xoff < 0.0001) || (xoff > 0.9999) || (yoff < 0.0001) || (yoff > 0.9999) || (zoff < 0.0001) || (zoff > 0.9999));
}
/**
* Get current texture index
*/
@ -870,6 +937,20 @@ public class IsoHDPerspective implements HDPerspective {
long key = this.mapiter.getBlockKey(); /* Get key for current block */
custom_meshes.put(key, mesh);
}
/**
* Get custom fluid mesh for block, if defined (null if not)
*/
public final RenderPatch[] getCustomFluidMesh() {
long key = this.mapiter.getBlockKey(); /* Get key for current block */
return (RenderPatch[])custom_fluid_meshes.get(key);
}
/**
* Save custom mesh for block
*/
public final void setCustomFluidMesh(RenderPatch[] mesh) {
long key = this.mapiter.getBlockKey(); /* Get key for current block */
custom_fluid_meshes.put(key, mesh);
}
}
public IsoHDPerspective(DynmapCore core, ConfigurationNode configuration) {

View File

@ -2652,6 +2652,7 @@ public class TexturePack {
}
}
}
/**
* Read color for given subblock coordinate, with given block id and data and face
*/
@ -2664,6 +2665,7 @@ public class TexturePack {
boolean hasblockcoloring = ss.do_biome_shading && this.blockColoring.hasBlkStateValue(blk);
// Test if we have no texture modifications
boolean simplemap = (textid < COLORMOD_MULT_INTERNAL) && (!hasblockcoloring);
int[] xyz = null;
if (simplemap) { /* If simple mapping */
int[] texture = getTileARGB(textid);
@ -2671,7 +2673,7 @@ public class TexturePack {
int u = 0, v = 0;
/* If not patch, compute U and V */
if(patchid < 0) {
int[] xyz = ps.getSubblockCoord();
xyz = ps.getSubblockCoord();
switch(laststep) {
case X_MINUS: /* South face: U = East (Z-), V = Down (Y-) */
@ -2729,7 +2731,7 @@ public class TexturePack {
/* If clear-inside op, get out early */
if((textop == COLORMOD_CLEARINSIDE) || (textop == COLORMOD_MULTTONED_CLEARINSIDE)) {
/* Check if previous block is same block type as we are: surface is transparent if it is */
if (blk.matchingBaseState(lastblocktype) || (blk.isWater() && lastblocktype.isWaterlogged())) {
if ((blk.matchingBaseState(lastblocktype) || (blk.isWater() && lastblocktype.isWaterlogged())) && ps.isOnFace()) {
rslt.setTransparent();
return;
}
@ -2747,8 +2749,7 @@ public class TexturePack {
int u = 0, v = 0, tmp;
if(patchid < 0) {
int[] xyz = ps.getSubblockCoord();
if (xyz == null) xyz = ps.getSubblockCoord();
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;

View File

@ -172,7 +172,7 @@ public class TexturePackHDShader implements HDShader {
public void reset(HDPerspectiveState ps) {
for(int i = 0; i < color.length; i++)
color[i].setTransparent();
lastblk = DynmapBlockState.AIR;
setLastBlockState(DynmapBlockState.AIR);
}
/**
@ -184,13 +184,13 @@ public class TexturePackHDShader implements HDShader {
if ((hiddenids != null) && hiddenids.get(blocktype.globalStateIndex)) {
blocktype = DynmapBlockState.AIR;
}
DynmapBlockState lastblocktype = lastblk;
lastblk = blocktype;
if (blocktype.isAir()) {
return false;
}
DynmapBlockState lastblocktype = lastblk;
/* Get color from textures */
if (scaledtp != null) {
scaledtp.readColor(ps, mapiter, c, blocktype, lastblocktype, ShaderState.this);
@ -314,6 +314,10 @@ public class TexturePackHDShader implements HDShader {
public int[] getLightingTable() {
return lightingTable;
}
@Override
public void setLastBlockState(DynmapBlockState new_lastbs) {
lastblk = new_lastbs;
}
}
/**

View File

@ -318,6 +318,9 @@ public class TopoHDShader implements HDShader {
public int[] getLightingTable() {
return lightingTable;
}
@Override
public void setLastBlockState(DynmapBlockState new_lastbs) {
}
}
/**

View File

@ -0,0 +1,58 @@
package org.dynmap.hdmap.renderer;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Map;
import org.dynmap.renderer.CustomRenderer;
import org.dynmap.renderer.DynmapBlockState;
import org.dynmap.renderer.MapDataContext;
import org.dynmap.renderer.RenderPatch;
import org.dynmap.renderer.RenderPatchFactory;
/**
* Renderer for vanilla fluids - will attempt to emulate vanilla rendering behavior, but still WIP
*/
public class FluidStateRenderer extends CustomRenderer {
private RenderPatch[][] flat_meshes = new RenderPatch[8][]; // Meshes for each level from 0 (full) to 7 (most empty), no surface incline
private RenderPatch[] full_mesh;
private static final int PATCH_STILL = 0;
private static final int PATCH_FLOWING = 1;
private static final int[] still_patches = { PATCH_STILL, PATCH_STILL, PATCH_FLOWING, PATCH_FLOWING, PATCH_FLOWING, PATCH_FLOWING };
@Override
public boolean initializeRenderer(RenderPatchFactory rpf, String blkname, BitSet blockdatamask, Map<String,String> custparm) {
if(!super.initializeRenderer(rpf, blkname, blockdatamask, custparm))
return false;
ArrayList<RenderPatch> list = new ArrayList<RenderPatch>();
// Create meshes for flat topped blocks
for (int i = 0; i < 8; i++) {
list.clear();
CustomRenderer.addBox(rpf, list, 0.0, 1.0, 0.0, 0.875 - (0.12 * i), 0.0, 1.0, still_patches);
flat_meshes[i] = list.toArray(new RenderPatch[list.size()]);
}
list.clear();
CustomRenderer.addBox(rpf, list, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, still_patches);
full_mesh = list.toArray(new RenderPatch[list.size()]);
return true;
}
@Override
public int getMaximumTextureCount() {
return 2;
}
@Override
public RenderPatch[] getRenderPatchList(MapDataContext ctx) {
int idx = ctx.getBlockType().stateIndex;
if ((idx == 0) || (idx >= 8)) {
DynmapBlockState up = ctx.getBlockTypeAt(0, 1, 0);
if (up.isWater() || up.isWaterlogged())
return full_mesh;
}
return (idx < 8) ? flat_meshes[idx] : flat_meshes[0];
}
}

View File

@ -763,27 +763,9 @@ layer:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
----------------
# Lily pad
patchblock:id=waterlily,data=*,patch0=HorizY001ZTop
# Water (1 down)
# Lava (1 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=1,ymax=0.875
# Water (2 down)
# Lava (2 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=2,ymax=0.75
# Water (3 down)
# Lava (3 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=3,ymax=0.625
# Water (4 down)
# Lava (4 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=4,ymax=0.5
# Water (5 down)
# Lava (5 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=5,ymax=0.375
# Water (6 down)
# Lava (6 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=6,ymax=0.25
# Water (7 down)
# Lava (7 down)
boxblock:id=flowing_water,id=water,id=flowing_lava,id=lava,data=7,ymax=0.125
# Water
# Lava
customblock:id=flowing_water,id=water,id=flowing_lava,id=lava,class=org.dynmap.hdmap.renderer.FluidStateRenderer
# Enchantment Table
boxblock:id=enchanting_table,data=*,ymax=0.75

View File

@ -804,27 +804,9 @@ layer:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
----------------
# Lily pad
patchblock:id=lily_pad,patch0=HorizY001ZTop
# Water (1 down)
# Lava (1 down)
boxblock:id=water,id=lava,data=1,ymax=0.875
# Water (2 down)
# Lava (2 down)
boxblock:id=water,id=lava,data=2,ymax=0.75
# Water (3 down)
# Lava (3 down)
boxblock:id=water,id=lava,data=3,ymax=0.625
# Water (4 down)
# Lava (4 down)
boxblock:id=water,id=lava,data=4,ymax=0.5
# Water (5 down)
# Lava (5 down)
boxblock:id=water,id=lava,data=5,ymax=0.375
# Water (6 down)
# Lava (6 down)
boxblock:id=water,id=lava,data=6,ymax=0.25
# Water (7 down)
# Lava (7 down)
boxblock:id=water,id=lava,data=7,ymax=0.125
# Water
customblock:id=water,id=lava,class=org.dynmap.hdmap.renderer.FluidStateRenderer
# Enchantment Table
boxblock:id=enchanting_table,ymax=0.75

View File

@ -390,14 +390,11 @@ block:id=sapling,data=3,data=11,patch0-1=0:sapling_jungle,transparency=TRANSPARE
# Bedrock
block:id=bedrock,allfaces=0:bedrock,stdrot=true
# Water
block:id=flowing_water,allfaces=12000:water_flow,stdrot=true,transparency=SEMITRANSPARENT
# Stationary water
block:id=water,data=0,data=8,data=9,data=10,data=11,data=12,data=13,data=14,data=15,topbottom=12000:water_still,allsides=12000:water_flow,stdrot=true,transparency=SEMITRANSPARENT
block:id=water,data=1,data=2,data=3,data=4,data=5,data=6,data=7,allfaces=12000:water_flow,stdrot=true,transparency=SEMITRANSPARENT
block:id=water,id=flowing_water,patch0=12000:water_still,patch1=12000:water_flow,transparency=SEMITRANSPARENT
# Lava
block:id=flowing_lava,allfaces=0:lava_flow,stdrot=true,transparency=SEMITRANSPARENT
# Stationary Lava
block:id=lava,allfaces=0:lava_still,stdrot=true,transparency=SEMITRANSPARENT
block:id=lava,id=flowing_lava,patch0=0:lava_still,patch1=0:lava_flow,transparency=SEMITRANSPARENT
# Sand
block:id=sand,allfaces=0:sand,stdrot=true
[1.7.0-]block:id=sand,data=1,allfaces=0:red_sand,stdrot=true

View File

@ -133,10 +133,7 @@ texture:id=birch_sapling
texture:id=jungle_sapling
texture:id=bedrock
texture:id=water_still,material=WATER
#TODO: fix when I figure out 1.13 biome shading logic
#texturefile:id=water_still,filename=assets/minecraft/textures/blocks/water_still.png,xcount=1,ycount=1
texture:id=water_flow,material=WATER
#texturefile:id=water_flow,filename=assets/minecraft/textures/blocks/water_flow.png,xcount=1,ycount=1
texture:id=lava_still
texture:id=lava_flow
texture:id=sand
@ -599,9 +596,11 @@ block:id=dark_oak_sapling,data=1,patch0-1=0:dark_oak_sapling,transparency=TRANSP
# Bedrock
block:id=bedrock,allfaces=0:bedrock,stdrot=true
# Water
block:id=water,topbottom=12000:water_still,allsides=12000:water_flow,stdrot=true,transparency=SEMITRANSPARENT
#block:id=water,topbottom=12000:water_still,allsides=12000:water_flow,stdrot=true,transparency=SEMITRANSPARENT
block:id=water,patch0=12000:water_still,patch1=12000:water_flow,transparency=SEMITRANSPARENT
# Lava
block:id=lava,allfaces=0:lava_still,stdrot=true,transparency=SEMITRANSPARENT
#block:id=lava,allfaces=0:lava_still,stdrot=true,transparency=SEMITRANSPARENT
block:id=lava,patch0=0:lava_still,patch1=0:lava_flow,transparency=SEMITRANSPARENT
# Sand
block:id=sand,allfaces=0:sand,stdrot=true
# Red Sand

View File

@ -76,6 +76,8 @@ public class DynmapBlockState {
// Well known base blocks - air
public static final DynmapBlockState AIR = new DynmapBlockState(null, 0, AIR_BLOCK, "");
private static DynmapBlockState still_water = null;
/**
* Constructor for block state
* @param base - base block state (null if first/only state for block)
@ -126,6 +128,10 @@ public class DynmapBlockState {
matchflags |= (blockName.equals(SNOW_BLOCK) || blockName.equals(SNOW_LAYER_BLOCK)) ? MATCH_SNOW : 0;
matchflags |= blockName.equals(GRASS_BLOCK) ? MATCH_GRASS : 0;
matchflags |= log_blocks.contains(blockName) ? MATCH_LOG : 0;
// If water block, set singleton
if (this.blockName.equals(WATER_BLOCK) && (this == this.baseState)) {
still_water = this;
}
}
/**
* Get state for same base block with given index
@ -310,6 +316,15 @@ public class DynmapBlockState {
public boolean matchingBaseState(DynmapBlockState blk) {
return this.baseState == blk.baseState;
}
/**
* Get liquid state (null if not waterlogged or otherwise immmersed)
*/
public DynmapBlockState getLiquidState() {
if (isWaterlogged()) {
return still_water;
}
return null;
}
/**
* To printable string
*/