From 57a2b956dd43a8f5a34556e3276a4a0974dbb084 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 11 Oct 2021 23:05:49 -0500 Subject: [PATCH] Improve the VanillaOverdraw config to work better in roofed dimensions --- .../java/com/seibel/lod/config/LodConfig.java | 16 ++-- .../com/seibel/lod/enums/VanillaOverdraw.java | 6 +- .../java/com/seibel/lod/util/LodUtil.java | 82 ++++++++++--------- 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java index caffa670d..6cae3b764 100644 --- a/src/main/java/com/seibel/lod/config/LodConfig.java +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -51,7 +51,7 @@ import net.minecraftforge.fml.config.ModConfig; * This handles any configuration the user has access to. * * @author James Seibel - * @version 10-10-2021 + * @version 10-11-2021 */ @Mod.EventBusSubscriber public class LodConfig @@ -189,12 +189,14 @@ public class LodConfig vanillaOverdraw = builder .comment("\n\n" + " How often should LODs be drawn on top of regular chunks? \n" - + " HALF and ALWAYS will prevent holes in the world, but may look odd on transparent blocks. \n" - + VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n" - + VanillaOverdraw.HALF + ": LODs will render on top of distant vanilla chunks to hide holes in the world. \n" - + " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " " + VanillaOverdraw.HALF + " defaults works the same as " + VanillaOverdraw.ALWAYS + ". \n" - + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n") - .defineEnum("vanillaOverdraw", VanillaOverdraw.HALF); + + " HALF and ALWAYS will prevent holes in the world, but may look odd for transparent blocks or in caves. \n\n" + + " " + VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n" + + " " + VanillaOverdraw.DYNAMIC + ": LODs will render on top of distant vanilla chunks to hide delayed loading. \n" + + " " + " More effective on higher render distances. \n" + + " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " \n" + + " " + " " + VanillaOverdraw.NEVER + " or " + VanillaOverdraw.ALWAYS + " may be used depending on the dimension. \n" + + " " + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n") + .defineEnum("vanillaOverdraw", VanillaOverdraw.DYNAMIC); builder.pop(); } diff --git a/src/main/java/com/seibel/lod/enums/VanillaOverdraw.java b/src/main/java/com/seibel/lod/enums/VanillaOverdraw.java index 4167e0cf6..2ce00c91c 100644 --- a/src/main/java/com/seibel/lod/enums/VanillaOverdraw.java +++ b/src/main/java/com/seibel/lod/enums/VanillaOverdraw.java @@ -1,14 +1,14 @@ package com.seibel.lod.enums; /** - * None, Half, Always + * None, Dynamic, Always * *

* This represents how far the LODs should overlap with * the vanilla Minecraft terrain. * * @author James Seibel - * @version 10-10-2021 + * @version 10-11-2021 */ public enum VanillaOverdraw { @@ -16,7 +16,7 @@ public enum VanillaOverdraw NEVER, /** Draw LODs over the farther minecraft chunks. */ - HALF, + DYNAMIC, /** Draw LODs over all minecraft chunks. */ ALWAYS, diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index 6c9c468ef..bef53ec50 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -50,7 +50,7 @@ import net.minecraft.world.server.ServerWorld; * This class holds methods and constants that may be used in multiple places. * * @author James Seibel - * @version 10-10-2021 + * @version 10-11-2021 */ public class LodUtil { @@ -367,30 +367,43 @@ public class LodUtil int chunkRenderDist = mc.getRenderDistance(); ChunkPos centerChunk = new ChunkPos(playerPos); - int skipRadius; VanillaOverdraw overdraw = LodConfig.CLIENT.graphics.vanillaOverdraw.get(); + + // apply distance based rules for dynamic + if (overdraw == VanillaOverdraw.DYNAMIC + && chunkRenderDist <= MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW) + { + // The vanilla render distance isn't far enough + // for partial skipping to make sense... + + if (!lodDim.dimension.hasCeiling()) + { + // ...and the dimension is open, so we don't have to worry about + // LODs rendering on top of the player. + overdraw = VanillaOverdraw.ALWAYS; + } + else + { + // ...but we are underground, so we don't want + // LODs rendering on top of the player. + overdraw = VanillaOverdraw.NEVER; + } + } + + + // determine the skipping type based + // on the overdraw type switch (overdraw) { case ALWAYS: // don't skip any positions return new HashSet(); - case HALF: - // for small render distances just skip everything - // since the distance isn't far enough - // where partial skipping doesn't make sense - if (chunkRenderDist <= MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW) - { - // don't skip any positions - return new HashSet(); - } - else - { - // only skip positions that are greater than - // half the render distance - skipRadius = (int) Math.ceil(chunkRenderDist / 2.0); - } + case DYNAMIC: + // only skip positions that are greater than + // half the render distance + skipRadius = (int) Math.ceil(chunkRenderDist / 2.0); break; default: @@ -406,32 +419,21 @@ public class LodUtil HashSet posToSkip = getRenderedChunks(); - // apply special cases to those positions - for (int x = centerChunk.x - chunkRenderDist; x < centerChunk.x + chunkRenderDist; x++) + // remove everything outside the skipRadius, + // if the skipRadius is being used + if (skipRadius != 0) { - for (int z = centerChunk.z - chunkRenderDist; z < centerChunk.z + chunkRenderDist; z++) + for (int x = centerChunk.x - chunkRenderDist; x < centerChunk.x + chunkRenderDist; x++) { - // if the skipRadius is being used... - if (skipRadius != 0 && - ((x <= centerChunk.x - skipRadius || x >= centerChunk.x + skipRadius) - || (z <= centerChunk.z - skipRadius || z >= centerChunk.z + skipRadius))) + for (int z = centerChunk.z - chunkRenderDist; z < centerChunk.z + chunkRenderDist; z++) { - // ...remove everything outside the skipRadius - posToSkip.remove(new ChunkPos(x, z)); - continue; - } - - - if (!lodDim.doesDataExist(LodUtil.CHUNK_DETAIL_LEVEL, x, z)) - continue; - - long data = lodDim.getSingleData(LodUtil.CHUNK_DETAIL_LEVEL, x, z); - short lodAverageHeight = DataPointUtil.getHeight(data); - if (playerPos.getY() <= lodAverageHeight) - { - // don't draw LODs that are taller than the player - // to prevent LODs being drawn on top of the player - posToSkip.add(new ChunkPos(x, z)); + if (x <= centerChunk.x - skipRadius || x >= centerChunk.x + skipRadius + || + z <= centerChunk.z - skipRadius || z >= centerChunk.z + skipRadius) + { + posToSkip.remove(new ChunkPos(x, z)); + continue; + } } } }