Better fake chunk/ real chunk blending, less holes

This commit is contained in:
Leonardo
2021-09-30 14:48:52 +02:00
parent 0f56a98499
commit 9e0abd06fb
7 changed files with 55 additions and 39 deletions
@@ -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<Boolean> dataToRenderThread = () ->
{
Map<Direction, long[]> 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);
}
@@ -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<Direction, long[]> 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
@@ -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, int[]> DIRECTION_NORMAL_MAP = new HashMap<Direction, int[]>()
{{
@@ -110,13 +110,30 @@ public class Box
put(Direction.NORTH, new int[]{0, 0, -1});
}};
public static final Map<Direction, Integer> DIRECTION_INDEX = new HashMap<Direction, Integer>()
{{
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<Direction, Integer> ADJ_DIRECTION_INDEX = new HashMap<Direction, Integer>()
{{
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<Direction, Integer> 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<Direction, Integer>()
{{
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<Direction, int[]>()
@@ -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)
{
@@ -44,7 +44,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map<Direction, long[]> 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<Direction, long[]> 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);
@@ -40,7 +40,7 @@ public class DynamicLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map<Direction, long[]> 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!");
}
@@ -38,7 +38,7 @@ public class TriangularLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos bufferCenterBlockPos, long data, Map<Direction, long[]> 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!");
}
@@ -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)
{