diff --git a/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java b/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java index 029c4979..44a02236 100644 --- a/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java +++ b/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/FluidStateRenderer.java @@ -14,8 +14,7 @@ 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 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; @@ -28,14 +27,11 @@ public class FluidStateRenderer extends CustomRenderer { return false; ArrayList list = new ArrayList(); // Create meshes for flat topped blocks - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 10; i++) { list.clear(); - CustomRenderer.addBox(rpf, list, 0.0, 1.0, 0.0, 1.0 - ((i + 1) / 9.0), 0.0, 1.0, still_patches); + 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()]); } - 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; } @@ -57,13 +53,79 @@ public class FluidStateRenderer extends CustomRenderer { return (fbs != null) ? fbs : bs; } - private double getCornerHeight(DynmapBlockState b0, DynmapBlockState b1, DynmapBlockState b2, DynmapBlockState b3, + // Height of air, in ninths + private int getAirHeight(DynmapBlockState bs) { + int idx = bs.stateIndex; + return (idx > 7) ? 1 : (idx + 1); + } + + // 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) { // If any above blocks are match, return full height if (b0.matchingBaseState(u0) || b0.matchingBaseState(u1) || b0.matchingBaseState(u2) || b0.matchingBaseState(u3)) { - return 1.0; + return 9; } - return 0; + int accum = 0; + int cnt = 0; + // Check each of 4 neighbors + // First, self + int h = getAirHeight(b0); // Our block is always liquid + if (h == 1) { // Max + accum += (11 * h); + cnt += 11; + } + else { + accum += h; + cnt++; + } + // Others are all nieghbors + if (b1.matchingBaseState(b0)) { + h = getAirHeight(b1); + if (h == 1) { // Max + accum += (11 * h); + cnt += 11; + } + else { + accum += h; + cnt++; + } + } + else if (b1.isSolid() == false) { + accum += 9; + cnt += 1; + } + if (b2.matchingBaseState(b0)) { + h = getAirHeight(b2); + if (h == 1) { // Max + accum += (11 * h); + cnt += 11; + } + else { + accum += h; + cnt++; + } + } + else if (b2.isSolid() == false) { + accum += 9; + cnt += 1; + } + if (b3.matchingBaseState(b0)) { + h = getAirHeight(b3); + if (h == 1) { // Max + accum += (11 * h); + cnt += 11; + } + else { + accum += h; + cnt++; + } + } + else if (b3.isSolid() == false) { + accum += 9; + cnt += 1; + } + return 9 - ((accum + cnt/2) / cnt); } @@ -73,7 +135,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 full_mesh; + return flat_meshes[0]; } // Get other above blocks DynmapBlockState bs_0_1_1 = getFluidState(ctx, 0, 1, 1); @@ -94,7 +156,16 @@ public class FluidStateRenderer extends CustomRenderer { DynmapBlockState bs_1_0_n1 = getFluidState(ctx, 1, 0, -1); DynmapBlockState bs_n1_0_1 = getFluidState(ctx, -1, 0, 1); // Get each corner height - int idx = bs_0_0_0.stateIndex; - return (idx < 8) ? flat_meshes[idx] : flat_meshes[0]; + int bh_1_1 = getCornerHeight(bs_0_0_0, bs_0_0_1, bs_1_0_0, bs_1_0_1, bs_0_1_0, bs_1_1_0, bs_0_1_1, bs_1_1_1); + 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]; + } + else { // Return average flat mesh, for now + return flat_meshes[9 - ((bh_1_1 + bh_1_n1 + bh_n1_1 + bh_n1_n1) / 4)]; + } } }