diff --git a/src/main/java/com/seibel/lod/core/api/ClientApi.java b/src/main/java/com/seibel/lod/core/api/ClientApi.java index 84d6bfdbf..f1afb0638 100644 --- a/src/main/java/com/seibel/lod/core/api/ClientApi.java +++ b/src/main/java/com/seibel/lod/core/api/ClientApi.java @@ -184,7 +184,8 @@ public class ClientApi toBeLoaded.remove(pos); continue; } - //if (!chunk.isLightCorrect()) continue; + if (!chunk.isLightCorrect()) continue; + if (!chunk.doesNearbyChunksExist()) continue; toBeLoaded.remove(pos); generating.add(pos); //ApiShared.LOGGER.info("Lod Generation trying "+pos+". Remining: " +toBeLoaded.size()); diff --git a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java index 43bfc38c8..e3d9425d1 100644 --- a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java +++ b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java @@ -321,7 +321,7 @@ public class LodBufferBuilderFactory { CompletableFuture allFutures = CompletableFuture .allOf(futuresBuffer.toArray(new CompletableFuture[futuresBuffer.size()])); try { - allFutures.get(60, TimeUnit.SECONDS); + allFutures.get(5, TimeUnit.MINUTES); } catch (TimeoutException te) { ApiShared.LOGGER.error("LodBufferBuilder timed out: ", te); bufferBuilderThreadFactory.dumpAllThreadStacks(); 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 a9877f4fd..12cbeeb6e 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 @@ -22,27 +22,23 @@ package com.seibel.lod.core.builders.lodBuilding; 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; import com.seibel.lod.core.objects.lod.LodDimension; import com.seibel.lod.core.objects.lod.LodRegion; import com.seibel.lod.core.objects.lod.LodWorld; -import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.util.DataPointUtil; 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.util.SingletonHandler; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorSingletonWrapper; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper; +import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper; -import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; @@ -58,7 +54,6 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; public class LodBuilder { private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); - private static final IBlockColorSingletonWrapper BLOCK_COLOR = SingletonHandler.get(IBlockColorSingletonWrapper.class); /** This cannot be final! Different world have different height, and in menu, this causes Null Exceptions*/ @@ -137,7 +132,7 @@ public class LodBuilder } catch (RuntimeException e) { - e.printStackTrace(); + ClientApi.LOGGER.error("LodBuilder Thread Uncaught Exception: ", e); // // if the world changes while LODs are being generated // // they will throw errors as they try to access things that no longer // // exist. @@ -167,6 +162,7 @@ public class LodBuilder if (MC.getWrappedClientWorld() == null) return false; if (!chunk.isLightCorrect()) return false; + if (!chunk.doesNearbyChunksExist()) return false; // generate the LODs @@ -180,7 +176,7 @@ public class LodBuilder int subZ = i%16; writeVerticalData(data, i*maxVerticalData, maxVerticalData, chunk, config, subX, subZ); //if (DataPointUtil.isVoid(data[i*maxVerticalData])) - // ApiShared.LOGGER.debug("Datapoint is Void: {}, {}", chunk.getMinX()+subX, chunk.getMinZ()+subZ); + // ClientApi.LOGGER.debug("Datapoint is Void: {}, {}", chunk.getMinX()+subX, chunk.getMinZ()+subZ); if (!DataPointUtil.doesItExist(data[i*maxVerticalData])) throw new RuntimeException("writeVerticalData result: Datapoint does not exist at "+ chunk.getMinX()+subX +", "+ chunk.getMinZ()+subZ); if (DataPointUtil.getGenerationMode(data[i*maxVerticalData]) != config.distanceGenerationMode.complexity) @@ -193,6 +189,7 @@ public class LodBuilder } } if (!chunk.isLightCorrect()) return false; + if (!chunk.doesNearbyChunksExist()) return false; if (genAll) { return writeAllLodNodeData(lodDim, region, chunk.getChunkPosX(), chunk.getChunkPosZ(), data, config, override); @@ -200,7 +197,7 @@ public class LodBuilder return writePartialLodNodeData(lodDim, region, chunk.getChunkPosX(), chunk.getChunkPosZ(), data, config, override); } } catch (RuntimeException e) { - ApiShared.LOGGER.error("LodBuilder encountered an error on building lod for chunk {}: {}", chunk ,e); + ClientApi.LOGGER.error("LodBuilder encountered an error on building lod: ", e); return false; } @@ -213,7 +210,7 @@ public class LodBuilder try { if (region.getMinDetailLevel()!= 0) { if (!LodUtil.checkRamUsage(0.05, 16)) { - ApiShared.LOGGER.debug("LodBuilder: Not enough RAM avalible for loading files to build lods! Returning..."); + ClientApi.LOGGER.debug("LodBuilder: Not enough RAM avalible for loading files to build lods! Returning..."); return false; } @@ -221,7 +218,7 @@ public class LodBuilder if (region!=newRegion) throw new RuntimeException(); } - //ApiShared.LOGGER.info("Generate chunk: {}, {} ({}, {}) at genMode {}", + //ClientApi.LOGGER.info("Generate chunk: {}, {} ({}, {}) at genMode {}", // chunk.getChunkPosX(), chunk.getChunkPosZ(), chunk.getMinX(), chunk.getMinZ(), config.distanceGenerationMode); region.addChunkOfData((byte)0, chunkX*16, chunkZ*16, 16, 16, data, data.length/16/16, override); region.regenerateLodFromArea((byte)0, chunkX*16, chunkZ*16, 16, 16); @@ -269,7 +266,7 @@ public class LodBuilder for (int i=0; i= chunk.getMinBuildHeight(); y--) { if (!isLayerValidLodPoint(chunk, xAbs, y, zAbs) - || (strictEdge && hasCliffFace(chunk, xAbs, y, zAbs) && colorOfBlock != chunk.getBlockColorWrapper(xAbs, y, zAbs).getColor())) + || (strictEdge && hasCliffFace(chunk, xAbs, y, zAbs) && colorOfBlock != chunk.getBlockDetail(xAbs, y, zAbs).color)) { depth = (short) (y + 1); break; @@ -444,16 +438,20 @@ public class LodBuilder } else { - colorInt = getColorForBlock(chunk, x, y, z); + 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; - IBlockShapeWrapper block = chunk.getBlockShapeWrapper(x, y + 1, z); - if (block != null && ((config.client().worldGenerator().getBlocksToAvoid().nonFull && block.isNonFull()) - || (config.client().worldGenerator().getBlocksToAvoid().noCollision && block.hasNoCollision()))) - aboveColorInt = getColorForBlock(chunk, x, y + 1, z); + if (chunk.blockPosInsideChunk(x, y+1, z)) { + BlockDetail 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; + } + } //if (colorInt == 0 && yAbs > 0) // if this block is invisible, check the block below it @@ -545,65 +543,11 @@ public class LodBuilder return blockLight + (skyLight << 4); } - /** Returns a color int for the given block. */ - private int getColorForBlock(IChunkWrapper chunk, int x, int y, int z) - { - int colorOfBlock; - int colorInt; - - IBlockShapeWrapper blockShapeWrapper = chunk.getBlockShapeWrapper(x, y, z); - - if (blockShapeWrapper == null || blockShapeWrapper.isToAvoid()) - return 0; - - IBlockColorWrapper blockColorWrapper; - - if (chunk.isWaterLogged(x, y, z)) - blockColorWrapper = BLOCK_COLOR.getWaterColor(); - else - blockColorWrapper = chunk.getBlockColorWrapper(x, y, z); - - - - colorOfBlock = blockColorWrapper.getColor(); - - - if (blockColorWrapper.hasTint()) - { - IBiomeWrapper biome = chunk.getBiome(x, y, z); - int tintValue; - if (blockColorWrapper.hasGrassTint()) - // grass and green plants - tintValue = biome.getGrassTint(0,0); - else if (blockColorWrapper.hasFolliageTint()) - tintValue = biome.getFolliageTint(); - else - //we can reintroduce this with the wrappers - tintValue = biome.getWaterTint(); - - colorInt = ColorUtil.multiplyRGBcolors(tintValue | 0xFF000000, colorOfBlock); - } - else - colorInt = colorOfBlock; - return colorInt; - } - - /** Is the block at the given blockPos a valid LOD point? */ private boolean isLayerValidLodPoint(IChunkWrapper chunk, int x, int y, int z) { - if (chunk.isWaterLogged(x, y, z)) - return true; - - boolean nonFullAvoidance = config.client().worldGenerator().getBlocksToAvoid().nonFull; - boolean noCollisionAvoidance = config.client().worldGenerator().getBlocksToAvoid().noCollision; - - IBlockShapeWrapper block = chunk.getBlockShapeWrapper(x, y, z); - - return block != null - && !block.isToAvoid() - && !(nonFullAvoidance && block.isNonFull()) - && !(noCollisionAvoidance && block.hasNoCollision()); - + BlocksToAvoid avoid = config.client().worldGenerator().getBlocksToAvoid(); + BlockDetail block = chunk.getBlockDetail(x, y, z); + return block != null && block.shouldRender(avoid); } } diff --git a/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java b/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java index 7224b7ea6..2fda96335 100644 --- a/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java +++ b/src/main/java/com/seibel/lod/core/objects/BlockBiomeCouple.java @@ -1,6 +1,7 @@ package com.seibel.lod.core.objects; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; +/* +import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import java.util.Objects; @@ -9,15 +10,15 @@ import java.util.concurrent.ConcurrentMap; public class BlockBiomeCouple { - public static final ConcurrentMap noBiomeIstanceCache = new ConcurrentHashMap<>(); - public static ConcurrentMap> withBiomeIstanceCache = new ConcurrentHashMap<>(); + public static final ConcurrentMap noBiomeIstanceCache = new ConcurrentHashMap<>(); + public static ConcurrentMap> withBiomeIstanceCache = new ConcurrentHashMap<>(); String blockName; String biomeName; String coupleName; IBiomeWrapper biomeColor; - IBlockColorWrapper blockColor; + BlockDetail blockColor; public static void addBlockBiomeToCache(IBlockColorWrapper blockColor){ } @@ -101,3 +102,4 @@ public class BlockBiomeCouple } +*/ \ No newline at end of file diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java index a0f44edac..7803ddc11 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java @@ -17,7 +17,7 @@ public class LodQuadBuilder { static final int MAX_BUFFER_SIZE = (1024 * 1024 * 1); static final int QUAD_BYTE_SIZE = (12 * 6); static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE; - static final int MAX_MERGED_QUAD_SIZE = 64; + //static final int MAX_MERGED_QUAD_SIZE = 64; static class Quad { final short x; @@ -88,7 +88,7 @@ public class LodQuadBuilder { { if (dir != o.dir) return false; - if (w0 >= MAX_MERGED_QUAD_SIZE) return false; + //if (w0 >= MAX_MERGED_QUAD_SIZE) return false; switch (dir.getAxis()) { case X: @@ -157,7 +157,7 @@ public class LodQuadBuilder { { if (dir != o.dir) return false; - if (w1 >= MAX_MERGED_QUAD_SIZE) return false; + //if (w1 >= MAX_MERGED_QUAD_SIZE) return false; switch (dir.getAxis()) { case X: diff --git a/src/main/java/com/seibel/lod/core/util/ColorUtil.java b/src/main/java/com/seibel/lod/core/util/ColorUtil.java index e38d84398..92b7f2476 100644 --- a/src/main/java/com/seibel/lod/core/util/ColorUtil.java +++ b/src/main/java/com/seibel/lod/core/util/ColorUtil.java @@ -33,7 +33,6 @@ public class ColorUtil { private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); - public static int rgbToInt(int red, int green, int blue) { return (0xFF << 24) | (red << 16) | (green << 8) | blue; 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 new file mode 100644 index 000000000..868a8a771 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/BlockDetail.java @@ -0,0 +1,28 @@ +package com.seibel.lod.core.wrapperInterfaces.block; + +import com.seibel.lod.core.enums.config.BlocksToAvoid; +import com.seibel.lod.core.util.ColorUtil; + +public 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/IBlockColorSingletonWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorSingletonWrapper.java deleted file mode 100644 index aeef4ba9d..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorSingletonWrapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly the LOD Mod), - * licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.core.wrapperInterfaces.block; - -/** - * Contains methods that would have been static in BlockColorWrapper. - * Since interfaces can't create/implement static methods we have - * to split the object up in two. - * - * @author James Seibel - * @version 11-17-2021 - */ -public interface IBlockColorSingletonWrapper -{ - /** @returns the base color of water (grey) */ - IBlockColorWrapper getWaterColor(); -} - diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java deleted file mode 100644 index 257a688c6..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockColorWrapper.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly the LOD Mod), - * licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.core.wrapperInterfaces.block; - -/** - * @author James Seibel - * @version 11-17-2021 - */ -public interface IBlockColorWrapper -{ - //--------------// - //Colors getters// - //--------------// - - boolean hasColor(); - - String getName(); - - int getColor(); - - - //------------// - //Tint getters// - //------------// - - boolean hasTint(); - - boolean hasGrassTint(); - - boolean hasFolliageTint(); - - boolean hasWaterTint(); - -} - diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java deleted file mode 100644 index 4a3b3448b..000000000 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockShapeWrapper.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the Distant Horizon mod (formerly the LOD Mod), - * licensed under the GNU GPL v3 License. - * - * Copyright (C) 2020 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.core.wrapperInterfaces.block; - -/** - * @author James Seibel - * @version 11-20-2021 - */ -public interface IBlockShapeWrapper -{ - boolean ofBlockToAvoid(); - - //-----------------// - //Avoidance getters// - //-----------------// - - boolean isNonFull(); - - boolean hasNoCollision(); - - boolean isToAvoid(); -} \ No newline at end of file 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 66478e61b..5aa7d3c46 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 @@ -19,10 +19,15 @@ package com.seibel.lod.core.wrapperInterfaces.chunk; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; -import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper; +import org.jetbrains.annotations.Nullable; + +import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; + /** * @author James Seibel * @version 11-17-2021 @@ -38,8 +43,8 @@ public interface IChunkWrapper int getHeightMapValue(int xRel, int zRel); IBiomeWrapper getBiome(int x, int y, int z); - IBlockColorWrapper getBlockColorWrapper(int x, int y, int z); - IBlockShapeWrapper getBlockShapeWrapper(int x, int y, int z); + + BlockDetail getBlockDetail(int x, int y, int z); int getChunkPosX(); int getChunkPosZ(); @@ -68,4 +73,6 @@ public interface IChunkWrapper && y>=getMinBuildHeight() && y=getMinZ() && z<=getMaxZ()); } + + boolean doesNearbyChunksExist(); }