From 9e0abd06fbe88ad4169841eaf8918f9391b938a8 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 30 Sep 2021 14:48:52 +0200 Subject: [PATCH] Better fake chunk/ real chunk blending, less holes --- .../bufferBuilding/LodBufferBuilder.java | 26 ++++++----- .../lodTemplates/AbstractLodTemplate.java | 2 +- .../bufferBuilding/lodTemplates/Box.java | 46 +++++++++++-------- .../lodTemplates/CubicLodTemplate.java | 10 ++-- .../lodTemplates/DynamicLodTemplate.java | 2 +- .../lodTemplates/TriangularLodTemplate.java | 2 +- .../java/com/seibel/lod/util/LodUtil.java | 6 ++- 7 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java index 096efbd57..f7a25bd88 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/LodBufferBuilder.java @@ -18,10 +18,7 @@ package com.seibel.lod.builders.bufferBuilding; import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -245,6 +242,7 @@ public class LodBufferBuilder Callable dataToRenderThread = () -> { Map adjData = new HashMap<>(); + boolean[] adjShadeDisabled = new boolean[Box.DIRECTIONS.length]; // determine how many LODs we can stack vertically int maxVerticalData = 1; @@ -279,6 +277,7 @@ public class LodBufferBuilder int chunkXdist; int chunkZdist; int bufferIndex; + boolean disableShading; // keep a local version so we don't have to worry about indexOutOfBounds Exceptions // if it changes in the LodRenderer while we are working here boolean[][] vanillaRenderedChunks = renderer.vanillaRenderedChunks; @@ -295,7 +294,7 @@ public class LodBufferBuilder chunkXdist = LevelPosUtil.getChunkPos(detailLevel, posX) - playerChunkPos.x; chunkZdist = LevelPosUtil.getChunkPos(detailLevel, posZ) - playerChunkPos.z; - boolean isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks,chunkXdist + gameChunkRenderDistance + 1,chunkZdist + gameChunkRenderDistance + 1); + boolean isItBorderPos = LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1); if (gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist) && detailLevel <= LodUtil.CHUNK_DETAIL_LEVEL @@ -304,7 +303,7 @@ public class LodBufferBuilder { continue; } - + Arrays.fill(adjShadeDisabled, false); // skip any chunks that Minecraft is going to render for (Direction direction : Box.ADJ_DIRECTIONS) { @@ -312,14 +311,11 @@ public class LodBufferBuilder zAdj = posZ + direction.getNormal().getZ(); chunkXdist = LevelPosUtil.getChunkPos(detailLevel, xAdj) - playerChunkPos.x; chunkZdist = LevelPosUtil.getChunkPos(detailLevel, zAdj) - playerChunkPos.z; - boolean performFaceCulling = true; - - if (performFaceCulling - && posToRender.contains(detailLevel, xAdj, zAdj) + if (posToRender.contains(detailLevel, xAdj, zAdj) && (gameChunkRenderDistance < Math.abs(chunkXdist) || gameChunkRenderDistance < Math.abs(chunkZdist) || !(vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1] - && !LodUtil.isBorderChunk(vanillaRenderedChunks,chunkXdist + gameChunkRenderDistance + 1,chunkZdist + gameChunkRenderDistance + 1)))) + && !LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1)))) { if (!adjData.containsKey(direction) || adjData.get(direction) == null) adjData.put(direction, new long[maxVerticalData]); @@ -330,6 +326,12 @@ public class LodBufferBuilder } } else { + if (gameChunkRenderDistance >= Math.abs(chunkXdist) + && gameChunkRenderDistance >= Math.abs(chunkZdist) + && !LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1) + && vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1] + && !DataPointUtil.isVoid(lodDim.getSingleData(detailLevel, xAdj, zAdj))) + adjShadeDisabled[Box.DIRECTION_INDEX.get(direction)] = true; adjData.put(direction, null); } } @@ -342,7 +344,7 @@ public class LodBufferBuilder break; LodConfig.CLIENT.graphics.lodTemplate.get().template.addLodToBuffer(currentBuffers[bufferIndex], playerBlockPosRounded, data, adjData, - detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, renderer.lightMap); + detailLevel, posX, posZ, boxCache[xR][zR], renderer.previousDebugMode, renderer.lightMap, adjShadeDisabled); } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java index 8c47febaa..11e0cc17d 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/AbstractLodTemplate.java @@ -41,7 +41,7 @@ public abstract class AbstractLodTemplate * Uploads the given LOD to the buffer. */ public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap); + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled); /** * add the given position and color to the buffer diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java index 62b50de35..e0e71f1d2 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/Box.java @@ -12,7 +12,6 @@ import com.seibel.lod.wrappers.MinecraftWrapper; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import org.lwjgl.system.CallbackI; /** * Similar to Minecraft's AxisAlignedBoundingBox. @@ -99,6 +98,7 @@ public class Box put(Direction.NORTH, new int[]{Z, MIN}); }}; + @SuppressWarnings("serial") public static final Map DIRECTION_NORMAL_MAP = new HashMap() {{ @@ -110,13 +110,30 @@ public class Box put(Direction.NORTH, new int[]{0, 0, -1}); }}; + public static final Map DIRECTION_INDEX = new HashMap() + {{ + put(Direction.UP, 0); + put(Direction.DOWN, 1); + put(Direction.EAST, 2); + put(Direction.WEST, 3); + put(Direction.SOUTH, 4); + put(Direction.NORTH, 5); + }}; + + public static final Map ADJ_DIRECTION_INDEX = new HashMap() + {{ + put(Direction.EAST, 0); + put(Direction.WEST, 1); + put(Direction.SOUTH, 2); + put(Direction.NORTH, 3); + }}; /** holds the box's x, y, z offset */ public int[] boxOffset; /** holds the box's x, y, z width */ public int[] boxWidth; /** Holds each direction's color */ - public Map colorMap; + public int[] colorMap; /** The original color (before shading) of this box */ public int color; /** */ @@ -134,15 +151,7 @@ public class Box boxOffset = new int[3]; boxWidth = new int[3]; - colorMap = new HashMap() - {{ - put(Direction.UP, 0); - put(Direction.DOWN, 0); - put(Direction.EAST, 0); - put(Direction.WEST, 0); - put(Direction.SOUTH, 0); - put(Direction.NORTH, 0); - }}; + colorMap = new int[6]; // TODO what does the 32 represent? adjHeight = new HashMap() @@ -173,12 +182,15 @@ public class Box - public void setColor(int color) + public void setColor(int color, boolean[] adjShadeDisabled) { this.color = color; for (Direction direction : DIRECTIONS) { - colorMap.put(direction, ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientWorld().getShade(direction, true))); + if (!adjShadeDisabled[DIRECTION_INDEX.get(direction)]) + colorMap[DIRECTION_INDEX.get(direction)] = ColorUtil.applyShade(color, MinecraftWrapper.INSTANCE.getClientWorld().getShade(direction, true)); + else + colorMap[DIRECTION_INDEX.get(direction)] = color; } } @@ -186,7 +198,7 @@ public class Box { if (LodConfig.CLIENT.debugging.debugMode.get() != DebugMode.SHOW_DETAIL) { - return colorMap.get(direction); + return colorMap[DIRECTION_INDEX.get(direction)]; } else { @@ -200,11 +212,7 @@ public class Box { Arrays.fill(boxWidth, 0); Arrays.fill(boxOffset, 0); - - for (Direction direction : DIRECTIONS) - { - colorMap.put(direction, 0); - } + Arrays.fill(colorMap, 0); for (Direction direction : ADJ_DIRECTIONS) { diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java index 810d19129..52f6f7bd2 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/CubicLodTemplate.java @@ -44,7 +44,7 @@ public class CubicLodTemplate extends AbstractLodTemplate @Override public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap) + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled) { if (box == null) return; @@ -67,7 +67,8 @@ public class CubicLodTemplate extends AbstractLodTemplate posX * blockWidth, 0, posZ * blockWidth, // x, y, z offset bufferCenterBlockPos, adjData, - color); + color, + adjShadeDisabled); addBoundingBoxToBuffer(buffer, box); } @@ -77,7 +78,8 @@ public class CubicLodTemplate extends AbstractLodTemplate double xOffset, double yOffset, double zOffset, BlockPos bufferCenterBlockPos, Map adjData, - int color) + int color, + boolean[] adjShadeDisabled) { // don't add an LOD if it is empty if (height == -1 && depth == -1) @@ -96,7 +98,7 @@ public class CubicLodTemplate extends AbstractLodTemplate double x = -bufferCenterBlockPos.getX(); double z = -bufferCenterBlockPos.getZ(); box.reset(); - box.setColor(color); + box.setColor(color, adjShadeDisabled); box.setWidth(width, height - depth, width); box.setOffset((int) (xOffset + x), (int) (depth + yOffset), (int) (zOffset + z)); box.setUpCulling(32, bufferCenterBlockPos); diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java index 395020bca..399a7a87f 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/DynamicLodTemplate.java @@ -40,7 +40,7 @@ public class DynamicLodTemplate extends AbstractLodTemplate { @Override public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap) + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled) { ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!"); } diff --git a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java index 195469514..874339aa0 100644 --- a/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/bufferBuilding/lodTemplates/TriangularLodTemplate.java @@ -38,7 +38,7 @@ public class TriangularLodTemplate extends AbstractLodTemplate { @Override public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map adjData, - byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap) + byte detailLevel, int posX, int posZ, Box box, DebugMode debugging, NativeImage lightMap, boolean[] adjShadeDisabled) { ClientProxy.LOGGER.error(DynamicLodTemplate.class.getSimpleName() + " is not implemented!"); } diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index 7b6e1303b..f72b02fc8 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -492,7 +492,11 @@ public class LodUtil } /** - * + * This method find if a given chunk is a border chunk of the renderable ones + * @param vanillaRenderedChunks matrix of the vanilla rendered chunks + * @param x relative (to the matrix) x chunk to check + * @param z relative (to the matrix) z chunk to check + * @return true if and only if the chunk is a the border of the rendereble chunks */ public static boolean isBorderChunk(boolean[][] vanillaRenderedChunks, int x, int z) {