From c9cabd8a321a63cbd971bfae41b54d224feb43c2 Mon Sep 17 00:00:00 2001 From: TomTheFurry <46843632+TomTheFurry@users.noreply.github.com> Date: Tue, 8 Mar 2022 23:26:41 +0800 Subject: [PATCH] Rework BlockDetail and stuff. --- .../core/builders/lodBuilding/LodBuilder.java | 50 ++++++++++--------- .../seibel/lod/core/enums/LodDirection.java | 7 +++ .../wrapperInterfaces/block/BlockDetail.java | 28 ----------- .../block/IBlockDetailWrapper.java | 39 +++++++++++++++ .../chunk/IChunkWrapper.java | 4 +- 5 files changed, 75 insertions(+), 53 deletions(-) delete mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java create mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockDetailWrapper.java diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index 0bb38ee31..b18fa9e54 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -23,7 +23,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.seibel.lod.core.api.ApiShared; -import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.enums.LodDirection; import com.seibel.lod.core.enums.config.BlocksToAvoid; import com.seibel.lod.core.enums.config.DistanceGenerationMode; @@ -36,7 +35,8 @@ import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodUtil; -import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; +import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; @@ -55,6 +55,7 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; public class LodBuilder { private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class); /** This cannot be final! Different world have different height, and in menu, this causes Null Exceptions*/ @@ -363,8 +364,8 @@ public class LodBuilder int cy = y+dir.getNormal().y; int cz = z+dir.getNormal().z; if (!chunk.blockPosInsideChunk(cx, cy, cz)) return true; - BlockDetail block = chunk.getBlockDetail(cx, cy, cz); - if (block == null || !block.isFullBlock) + IBlockDetailWrapper block = chunk.getBlockDetail(cx, cy, cz); + if (block == null || !block.hasFaceCullingFor(LodDirection.OPPOSITE_DIRECTIONS[dir.ordinal()])) return true; } return false; @@ -377,21 +378,22 @@ public class LodBuilder private int determineBottomPointFrom(IChunkWrapper chunk, LodBuilderConfig builderConfig, int xAbs, int yAbs, int zAbs, boolean strictEdge) { int depth = chunk.getMinBuildHeight(); - int colorOfBlock = 0; + IBlockDetailWrapper currentBlockDetail = null; if (strictEdge) { - BlockDetail blockAbove = chunk.getBlockDetail(xAbs, yAbs + 1, zAbs); + IBlockDetailWrapper blockAbove = chunk.getBlockDetail(xAbs, yAbs + 1, zAbs); if (blockAbove != null && !blockAbove.shouldRender(config.client().worldGenerator().getBlocksToAvoid())) { // The above block is skipped. Lets use its skipped color for currrent block - colorOfBlock = blockAbove.color; + currentBlockDetail = blockAbove; } - if (colorOfBlock == 0) colorOfBlock = chunk.getBlockDetail(xAbs, yAbs, zAbs).color; + if (currentBlockDetail == null) currentBlockDetail = chunk.getBlockDetail(xAbs, yAbs, zAbs); } for (int y = yAbs - 1; y >= chunk.getMinBuildHeight(); y--) { - if (!isLayerValidLodPoint(chunk, xAbs, y, zAbs) - || (strictEdge && hasCliffFace(chunk, xAbs, y, zAbs) && colorOfBlock != chunk.getBlockDetail(xAbs, y, zAbs).color)) + IBlockDetailWrapper nextBlock = chunk.getBlockDetail(xAbs, y, zAbs); + if (!isLayerValidLodPoint(nextBlock) + || (strictEdge && hasCliffFace(chunk, xAbs, y, zAbs) && !currentBlockDetail.equals(nextBlock)) ) { depth = (short) (y + 1); break; @@ -437,29 +439,24 @@ public class LodBuilder } else { - BlockDetail detail = chunk.getBlockDetail(x, y, z); - colorInt = detail == null ? 0 : detail.color; - // if we are skipping non-full and non-solid blocks that means we ignore // snow, flowers, etc. Get the above block so we can still get the color // of the snow, flower, etc. that may be above this block - int aboveColorInt = 0; + colorInt = 0; if (chunk.blockPosInsideChunk(x, y+1, z)) { - BlockDetail blockAbove = chunk.getBlockDetail(x, y+1, z); + IBlockDetailWrapper blockAbove = chunk.getBlockDetail(x, y+1, z); if (blockAbove != null && !blockAbove.shouldRender(config.client().worldGenerator().getBlocksToAvoid())) { // The above block is skipped. Lets use its skipped color for currrent block - aboveColorInt = blockAbove.color; + colorInt = blockAbove.getAndResolveFaceColor(null, chunk, FACTORY.createBlockPos(x, y+1, z)); } } - //if (colorInt == 0 && yAbs > 0) - // if this block is invisible, check the block below it - // colorInt = generateLodColor(chunk, config, xRel, yAbs - 1, zRel, blockPos); - // override this block's color if there was a block above this // and we were avoiding non-full/non-solid blocks - if (aboveColorInt != 0) - colorInt = aboveColorInt; + if (colorInt == 0) { + IBlockDetailWrapper detail = chunk.getBlockDetail(x, y, z); + colorInt = detail.getAndResolveFaceColor(null, chunk, FACTORY.createBlockPos(x, y, z)); + } } return colorInt; @@ -541,12 +538,19 @@ public class LodBuilder blockLight = LodUtil.clamp(0, Math.max(blockLight, blockBrightness), DEFAULT_MAX_LIGHT); return blockLight + (skyLight << 4); } + + /** Is the block at the given blockPos a valid LOD point? */ + private boolean isLayerValidLodPoint(IBlockDetailWrapper blockDetail) + { + BlocksToAvoid avoid = config.client().worldGenerator().getBlocksToAvoid(); + return blockDetail != null && blockDetail.shouldRender(avoid); + } /** Is the block at the given blockPos a valid LOD point? */ private boolean isLayerValidLodPoint(IChunkWrapper chunk, int x, int y, int z) { BlocksToAvoid avoid = config.client().worldGenerator().getBlocksToAvoid(); - BlockDetail block = chunk.getBlockDetail(x, y, z); + IBlockDetailWrapper block = chunk.getBlockDetail(x, y, z); return block != null && block.shouldRender(avoid); } } diff --git a/src/main/java/com/seibel/lod/core/enums/LodDirection.java b/src/main/java/com/seibel/lod/core/enums/LodDirection.java index 640d0ff6b..d0396df40 100644 --- a/src/main/java/com/seibel/lod/core/enums/LodDirection.java +++ b/src/main/java/com/seibel/lod/core/enums/LodDirection.java @@ -31,6 +31,13 @@ public enum LodDirection LodDirection.NORTH, LodDirection.SOUTH }; + public static final LodDirection[] OPPOSITE_DIRECTIONS = new LodDirection[] { + LodDirection.UP, + LodDirection.DOWN, + LodDirection.SOUTH, + LodDirection.NORTH, + LodDirection.EAST, + LodDirection.WEST }; /** North, South, East, West */ public static final LodDirection[] ADJ_DIRECTIONS = new LodDirection[] { LodDirection.EAST, diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java deleted file mode 100644 index 3ad213e4e..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.seibel.lod.core.wrapperInterfaces.block; - -import com.seibel.lod.core.enums.config.BlocksToAvoid; -import com.seibel.lod.core.util.ColorUtil; - -public final class BlockDetail -{ - public final int color; - public final boolean isFullBlock; - public final boolean hasNoCollision; - public final boolean hasOnlyNonFullFace; - - public BlockDetail(int c, boolean full, boolean noCol, boolean nonFullFace) { - color = c; - isFullBlock = full; - hasNoCollision = noCol; - hasOnlyNonFullFace = nonFullFace; - } - - public boolean shouldRender(BlocksToAvoid mode) { - return !((mode.noCollision && hasNoCollision) || (mode.nonFull && hasOnlyNonFullFace)); - } - - public String toString() { - return "[color: "+ColorUtil.toString(color)+", isFullBlock: "+isFullBlock - +", hasNoCollision: "+hasNoCollision+", hasOnlyNonFullFace: "+hasOnlyNonFullFace+"]"; - } -} diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockDetailWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockDetailWrapper.java new file mode 100644 index 000000000..435ad66ff --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockDetailWrapper.java @@ -0,0 +1,39 @@ +package com.seibel.lod.core.wrapperInterfaces.block; + +import com.seibel.lod.core.enums.LodDirection; +import com.seibel.lod.core.enums.config.BlocksToAvoid; +import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; + + +public abstract class IBlockDetailWrapper +{ + // Note: ALL value should be lazily-calculated + + // Note: This should be lazily-calculated if block needs tinting to be resolved + public abstract int getAndResolveFaceColor(LodDirection dir, IChunkWrapper chunk, AbstractBlockPosWrapper blockPos); + public abstract boolean hasFaceCullingFor(LodDirection dir); + public abstract boolean hasNoCollision(); + public abstract boolean noFaceIsFullFace(); + + public abstract String serialize(); + + protected abstract boolean isSame(IBlockDetailWrapper iBlockDetail); + + @Override + public boolean equals(Object o) { + if (!(o instanceof IBlockDetailWrapper)) return false; + return isSame((IBlockDetailWrapper)o); + } + + @Override + public String toString() { + return serialize(); + } + + public boolean shouldRender(BlocksToAvoid mode) + { + return !((mode.noCollision && hasNoCollision()) || (mode.nonFull && noFaceIsFullFace())); + } + + +} diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java index e0ba72288..85a963c9a 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java @@ -20,7 +20,7 @@ package com.seibel.lod.core.wrapperInterfaces.chunk; import com.seibel.lod.core.handlers.dependencyInjection.IBindable; -import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; +import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; /** @@ -39,7 +39,7 @@ public interface IChunkWrapper extends IBindable IBiomeWrapper getBiome(int x, int y, int z); - BlockDetail getBlockDetail(int x, int y, int z); + IBlockDetailWrapper getBlockDetail(int x, int y, int z); int getChunkPosX(); int getChunkPosZ();