mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-11-05 10:09:53 +01:00
First pass of new flowing fluid models
This commit is contained in:
parent
28bb9eea87
commit
ff54f1abe0
@ -446,10 +446,10 @@ public class IsoHDPerspective implements HDPerspective {
|
||||
vS.crossProduct(pd.u);
|
||||
/* Compute V using slope times inner product of direction and cross product */
|
||||
double v = inv_det * direction.innerProduct(vS);
|
||||
// Check constrains: v must be below line from (0, vmax) to (umax, vmaxatumax)
|
||||
double urel = (u > pd.umin) ? ((pd.umax - pd.umin) / (u - pd.umin)) : 0.0;
|
||||
// Check constrains: v must be below line from (umin, vmax) to (umax, vmaxatumax)
|
||||
double urel = (u > pd.umin) ? ((u - pd.umin) / (pd.umax - pd.umin)) : 0.0;
|
||||
double vmaxatu = pd.vmax + (pd.vmaxatumax - pd.vmax) * urel;
|
||||
// Check constrains: v must be above line from (0, vmin) to (umax, vminatumax)
|
||||
// Check constrains: v must be above line from (umin, vmin) to (umax, vminatumax)
|
||||
double vminatu = pd.vmin + (pd.vminatumax - pd.vmin) * urel;
|
||||
if ((v <= vminatu) || (v >= vmaxatu)) {
|
||||
return hitcnt;
|
||||
|
@ -4,22 +4,29 @@ import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dynmap.Log;
|
||||
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;
|
||||
import org.dynmap.renderer.RenderPatchFactory.SideVisible;
|
||||
import org.dynmap.utils.DynIntHashMap;
|
||||
|
||||
/**
|
||||
* 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[10][]; // Meshes for each level from 0 (full) to 7 (most empty), no surface incline
|
||||
|
||||
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 };
|
||||
|
||||
private static final int[] flow_patches = { PATCH_STILL, PATCH_FLOWING, PATCH_FLOWING, PATCH_FLOWING, PATCH_FLOWING, PATCH_FLOWING };
|
||||
|
||||
private static RenderPatch bottom = null; // Common bottom patch
|
||||
|
||||
private static DynIntHashMap meshcache = new DynIntHashMap();
|
||||
|
||||
@Override
|
||||
public boolean initializeRenderer(RenderPatchFactory rpf, String blkname, BitSet blockdatamask, Map<String,String> custparm) {
|
||||
@ -30,12 +37,14 @@ public class FluidStateRenderer extends CustomRenderer {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
list.clear();
|
||||
CustomRenderer.addBox(rpf, list, 0.0, 1.0, 0.0, 1.0 - (i / 9.0), 0.0, 1.0, still_patches);
|
||||
flat_meshes[i] = list.toArray(new RenderPatch[list.size()]);
|
||||
putCachedModel(9 - i, 9 - i, 9 - i, 9 - i, list.toArray(new RenderPatch[list.size()]));
|
||||
}
|
||||
if (bottom == null) {
|
||||
bottom = rpf.getPatch(0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, SideVisible.TOP, PATCH_STILL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getMaximumTextureCount() {
|
||||
return 2;
|
||||
@ -59,6 +68,21 @@ public class FluidStateRenderer extends CustomRenderer {
|
||||
return (idx > 7) ? 1 : (idx + 1);
|
||||
}
|
||||
|
||||
private static final int getIntKey(int h_1_1, int h_n1_1, int h_1_n1, int h_n1_n1) {
|
||||
return (h_1_1) + (h_n1_1 << 4) + (h_1_n1 << 8) + (h_n1_n1 << 12);
|
||||
}
|
||||
|
||||
// Get cached model
|
||||
private static RenderPatch[] getCachedModel(int h_1_1, int h_n1_1, int h_1_n1, int h_n1_n1) {
|
||||
return (RenderPatch[]) meshcache.get(getIntKey(h_1_1, h_n1_1, h_1_n1, h_n1_n1));
|
||||
}
|
||||
|
||||
// Put cached model
|
||||
private static void putCachedModel(int h_1_1, int h_n1_1, int h_1_n1, int h_n1_n1, RenderPatch[] model) {
|
||||
meshcache.put(getIntKey(h_1_1, h_n1_1, h_1_n1, h_n1_n1), model);
|
||||
}
|
||||
|
||||
|
||||
// Return height in ninths (round to nearest - 0-9)
|
||||
private int getCornerHeight(DynmapBlockState b0, DynmapBlockState b1, DynmapBlockState b2, DynmapBlockState b3,
|
||||
DynmapBlockState u0, DynmapBlockState u1, DynmapBlockState u2, DynmapBlockState u3) {
|
||||
@ -135,7 +159,7 @@ public class FluidStateRenderer extends CustomRenderer {
|
||||
// Check above block - if matching fluid, block will be full
|
||||
DynmapBlockState bs_0_1_0 = getFluidState(ctx, 0, 1, 0);
|
||||
if (bs_0_1_0.matchingBaseState(bs_0_0_0)) {
|
||||
return flat_meshes[0];
|
||||
return getCachedModel(9, 9, 9, 9);
|
||||
}
|
||||
// Get other above blocks
|
||||
DynmapBlockState bs_0_1_1 = getFluidState(ctx, 0, 1, 1);
|
||||
@ -160,12 +184,77 @@ public class FluidStateRenderer extends CustomRenderer {
|
||||
int bh_1_n1 = getCornerHeight(bs_0_0_0, bs_0_0_n1, bs_1_0_0, bs_1_0_n1, bs_0_1_0, bs_1_1_0, bs_0_1_n1, bs_1_1_n1);
|
||||
int bh_n1_1 = getCornerHeight(bs_0_0_0, bs_0_0_1, bs_n1_0_0, bs_n1_0_1, bs_0_1_0, bs_n1_1_0, bs_0_1_1, bs_n1_1_1);
|
||||
int bh_n1_n1 = getCornerHeight(bs_0_0_0, bs_0_0_n1, bs_n1_0_0, bs_n1_0_n1, bs_0_1_0, bs_n1_1_0, bs_0_1_n1, bs_n1_1_n1);
|
||||
// If all same, use flat mesh
|
||||
if ((bh_1_1 == bh_1_n1) && (bh_1_1 == bh_n1_1) && (bh_1_1 == bh_n1_n1)) {
|
||||
return flat_meshes[9 - bh_1_1];
|
||||
// Do cached lookup of model
|
||||
RenderPatch[] mod = getCachedModel(bh_1_1, bh_n1_1, bh_1_n1, bh_n1_n1);
|
||||
// If not found, create model
|
||||
if (mod == null) {
|
||||
RenderPatchFactory rpf = ctx.getPatchFactory();
|
||||
ArrayList<RenderPatch> list = new ArrayList<RenderPatch>();
|
||||
list.add(bottom); // All models have bottom patch
|
||||
// Add side for each face
|
||||
addSide(list, rpf, 0, 0, 0, 1, bh_n1_n1, bh_n1_1); // Xminus
|
||||
addSide(list, rpf, 1, 1, 1, 0, bh_1_1, bh_1_n1); // Xplus
|
||||
addSide(list, rpf, 1, 0, 0, 0, bh_1_n1, bh_n1_n1); // Zminus
|
||||
addSide(list, rpf, 0, 1, 1, 1, bh_n1_1, bh_1_1); // Zplus
|
||||
|
||||
int edge_xm = bh_n1_n1 + bh_n1_1;
|
||||
int edge_xp = bh_1_n1 + bh_1_1;
|
||||
int edge_zm = bh_n1_n1 + bh_1_n1;
|
||||
int edge_zp = bh_1_1 + bh_n1_1;
|
||||
|
||||
// See which edge is lowest
|
||||
if ((edge_xp <= edge_xm) && (edge_xp <= edge_zm) && (edge_xp <= edge_zp)) { // bh_1_1 and bh_1_n1 (Xplus)
|
||||
addTop(list, rpf, 1, 1, 1, 0, bh_1_1, bh_1_n1, bh_n1_1, bh_n1_n1);
|
||||
}
|
||||
else if ((edge_zp <= edge_zm) && (edge_zp <= edge_xm) && (edge_zp <= edge_xp)) {// bh_n1_1 and bh_1_1 (zPlus)
|
||||
addTop(list, rpf, 0, 1, 1, 1, bh_n1_1, bh_1_1, bh_n1_n1, bh_1_n1);
|
||||
}
|
||||
else if ((edge_xm <= edge_xp) && (edge_xm <= edge_zm) && (edge_xm <= edge_zp)) { // bh_n1_n1 and bh_n1_1 (xMinus)
|
||||
addTop(list, rpf, 0, 0, 0, 1, bh_n1_n1, bh_n1_1, bh_1_n1, bh_1_1);
|
||||
}
|
||||
else { // bh_1_n1 and bh_n1_n1 (zMinus)
|
||||
addTop(list, rpf, 1, 0, 0, 0, bh_1_n1, bh_n1_n1, bh_1_1, bh_n1_1);
|
||||
}
|
||||
mod = list.toArray(new RenderPatch[list.size()]);
|
||||
putCachedModel(bh_1_1, bh_n1_1, bh_1_n1, bh_n1_n1, mod);
|
||||
|
||||
//Log.info(String.format("%d:%d:%d::bh_1_1=%d,bh_1_n1=%d,bh_n1_1=%d,bh_n1_n1=%d", ctx.getX(), ctx.getY(), ctx.getZ(), bh_1_1, bh_1_n1, bh_n1_1, bh_n1_n1));
|
||||
//for (RenderPatch rp : list) {
|
||||
// Log.info(rp.toString());
|
||||
//}
|
||||
}
|
||||
else { // Return average flat mesh, for now
|
||||
return flat_meshes[9 - ((bh_1_1 + bh_1_n1 + bh_n1_1 + bh_n1_n1) / 4)];
|
||||
return mod;
|
||||
}
|
||||
|
||||
private void addSide(ArrayList<RenderPatch> list, RenderPatchFactory rpf, double x0, double z0, double x1, double z1, int h0, int h1) {
|
||||
if ((h0 == 0) && (h1 == 0))
|
||||
return;
|
||||
list.add(rpf.getPatch(x0, 0, z0, x1, 0, z1, x0, 1, z0, 0, 1, 0, 0, (double) h0 / 9.0, (double) h1 / 9.0, SideVisible.TOP, PATCH_FLOWING));
|
||||
}
|
||||
|
||||
private void addTop(ArrayList<RenderPatch> list, RenderPatchFactory rpf, double x0, double z0, double x1, double z1, int h0, int h1, int h2, int h3) {
|
||||
int h0_upper = h1 + h2 - h3;
|
||||
if (x0 == x1) { // edge is Z+/-
|
||||
if (h0_upper == h0) { // If single surface
|
||||
list.add(rpf.getPatch(x0, (double) h0 / 9.0, z0, x1, (double) h1 / 9.0, z1, 1-x0, (double) h2 / 9.0, z0, 0, 1, 0, 0, 1, 1, SideVisible.TOP, PATCH_FLOWING));
|
||||
}
|
||||
else {
|
||||
// Lower triangle
|
||||
list.add(rpf.getPatch(x0, (double) h0 / 9.0, z0, x1, (double) h1 / 9.0, z1, 1-x0, (double) h2 / 9.0, z0, 0, 1, 0, 0, 1, 0, SideVisible.TOP, PATCH_FLOWING));
|
||||
// Upper triangle
|
||||
list.add(rpf.getPatch(x0, (double) h0_upper / 9.0, z0, x1, (double) h1 / 9.0, z1, 1-x0, (double) h2 / 9.0, z0, 0, 1, 1, 0, 1, 1, SideVisible.TOP, PATCH_FLOWING));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (h0_upper == h0) { // If single surface
|
||||
list.add(rpf.getPatch(x0, (double) h0 / 9.0, z0, x1, (double) h1 / 9.0, z1, x0, (double) h2 / 9.0, 1 - z0, 0, 1, 0, 0, 1, 1, SideVisible.TOP, PATCH_FLOWING));
|
||||
}
|
||||
else {
|
||||
// Lower triangle
|
||||
list.add(rpf.getPatch(x0, (double) h0 / 9.0, z0, x1, (double) h1 / 9.0, z1, x0, (double) h2 / 9.0, 1 - z0, 0, 1, 0, 0, 1, 0, SideVisible.TOP, PATCH_FLOWING));
|
||||
// Upper triangle
|
||||
list.add(rpf.getPatch(x0, (double) h0_upper / 9.0, z0, x1, (double) h1 / 9.0, z1, x0, (double) h2 / 9.0, 1 - z0, 0, 1, 1, 0, 1, 1, SideVisible.TOP, PATCH_FLOWING));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,4 +272,9 @@ public class PatchDefinition implements RenderPatch {
|
||||
public int getTextureIndex() {
|
||||
return textureindex;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("xyz0=%f/%f/%f,xyzU=%f/%f/%f,xyzV=%f/%f/%f,minU=%f,maxU=%f,vMin=%f/%f,vmax=%f/%f,side=%s,txtidx=%d",
|
||||
x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vminatumax, vmax, vmaxatumax, sidevis, textureindex);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user