mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-24 17:47:40 +01:00
Start work on new water model - shift over to using basic version
This commit is contained in:
parent
88816b176e
commit
6da97c5e3f
@ -251,6 +251,9 @@ public class CaveHDShader implements HDShader {
|
||||
public int[] getLightingTable() {
|
||||
return lightingTable;
|
||||
}
|
||||
@Override
|
||||
public void setLastBlockState(DynmapBlockState new_lastbs) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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++) {
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -210,6 +210,9 @@ public class InhabitedHDShader implements HDShader {
|
||||
public int[] getLightingTable() {
|
||||
return lightingTable;
|
||||
}
|
||||
@Override
|
||||
public void setLastBlockState(DynmapBlockState new_lastbs) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,6 +318,9 @@ public class TopoHDShader implements HDShader {
|
||||
public int[] getLightingTable() {
|
||||
return lightingTable;
|
||||
}
|
||||
@Override
|
||||
public void setLastBlockState(DynmapBlockState new_lastbs) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user