Rework BlockDetail and stuff.

This commit is contained in:
TomTheFurry
2022-03-08 23:26:41 +08:00
parent d731424e93
commit c9cabd8a32
5 changed files with 75 additions and 53 deletions
@@ -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);
}
}
@@ -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,
@@ -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+"]";
}
}
@@ -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()));
}
}
@@ -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();