From b0ad8fa637d3d150a1c3028842a3ee4c9e5e9e3e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 18 Oct 2023 07:50:59 -0500 Subject: [PATCH] Fix LOD render distance measured as the diameter instead of radius --- .../config/client/DhApiGraphicsConfig.java | 2 +- .../distanthorizons/core/config/Config.java | 5 ++--- .../core/level/ClientLevelModule.java | 4 ++-- .../core/render/LodQuadTree.java | 12 +++++------ .../distanthorizons/core/util/RenderUtil.java | 2 +- .../core/util/objects/quadTree/QuadTree.java | 20 +++++++++---------- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java index df8f8d280..c43ed456f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/config/client/DhApiGraphicsConfig.java @@ -54,7 +54,7 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig @Override public IDhApiConfigValue chunkRenderDistance() - { return new DhApiConfigValue(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance); } + { return new DhApiConfigValue(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius); } @Override public IDhApiConfigValue renderingEnabled() diff --git a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java index cb8cf1fd7..98f69b3d7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java @@ -31,7 +31,6 @@ import com.seibel.distanthorizons.core.config.types.enums.*; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.jar.EPlatform; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.util.EnumUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.util.StringUtil; @@ -71,7 +70,7 @@ public class Config .setAppearance(EConfigEntryAppearance.ONLY_IN_GUI) .build(); - public static ConfigLinkedEntry quickLodChunkRenderDistance = new ConfigLinkedEntry(Advanced.Graphics.Quality.lodChunkRenderDistance); + public static ConfigLinkedEntry quickLodChunkRenderDistance = new ConfigLinkedEntry(Advanced.Graphics.Quality.lodChunkRenderDistanceRadius); public static ConfigEntry qualityPresetSetting = new ConfigEntry.Builder() .set(EQualityPreset.MEDIUM) // the default value is set via the listener when accessed @@ -155,7 +154,7 @@ public class Config .setPerformance(EConfigEntryPerformance.MEDIUM) .build(); - public static ConfigEntry lodChunkRenderDistance = new ConfigEntry.Builder() + public static ConfigEntry lodChunkRenderDistanceRadius = new ConfigEntry.Builder() .setMinDefaultMax(32, 128, 4096) .comment("The radius of the mod's render distance. (measured in chunks)") .setPerformance(EConfigEntryPerformance.HIGH) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java index 45c90d51a..0c33a2bfc 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java @@ -79,7 +79,7 @@ public class ClientLevelModule implements Closeable } // TODO this should probably be handled via a config change listener // recreate the RenderState if the render distance changes - if (clientRenderState.quadtree.blockRenderDistanceRadius != Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH) + if (clientRenderState.quadtree.blockRenderDistanceDiameter != Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH * 2) { if (!this.ClientRenderStateRef.compareAndSet(clientRenderState, null)) { @@ -286,7 +286,7 @@ public class ClientLevelModule implements Closeable this.clientLevelWrapper = dhClientLevel.getClientLevelWrapper(); this.renderSourceFileHandler = new RenderSourceFileHandler(fullDataSourceProvider, dhClientLevel, saveStructure); - this.quadtree = new LodQuadTree(dhClientLevel, Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH, + this.quadtree = new LodQuadTree(dhClientLevel, Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH * 2, // initial position is (0,0) just in case the player hasn't loaded in yet, the tree will be moved once the level starts ticking 0, 0, this.renderSourceFileHandler); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java index 6e4de26ed..04fc23659 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java @@ -48,7 +48,7 @@ public class LodQuadTree extends QuadTree implements AutoClose private static final Logger LOGGER = DhLoggerBuilder.getLogger(); - public final int blockRenderDistanceRadius; + public final int blockRenderDistanceDiameter; private final IRenderSourceProvider renderSourceProvider; /** @@ -77,15 +77,15 @@ public class LodQuadTree extends QuadTree implements AutoClose //==============// public LodQuadTree( - IDhClientLevel level, int viewDistanceInBlocks, + IDhClientLevel level, int viewDiameterInBlocks, int initialPlayerBlockX, int initialPlayerBlockZ, IRenderSourceProvider provider) { - super(viewDistanceInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), TREE_LOWEST_DETAIL_LEVEL); + super(viewDiameterInBlocks, new DhBlockPos2D(initialPlayerBlockX, initialPlayerBlockZ), TREE_LOWEST_DETAIL_LEVEL); this.level = level; this.renderSourceProvider = provider; - this.blockRenderDistanceRadius = viewDistanceInBlocks; + this.blockRenderDistanceDiameter = viewDiameterInBlocks; this.horizontalScaleChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.Quality.horizontalQuality, (newHorizontalScale) -> this.onHorizontalQualityChange()); } @@ -364,7 +364,7 @@ public class LodQuadTree extends QuadTree implements AutoClose } else if (detail >= Byte.MAX_VALUE) { - return this.blockRenderDistanceRadius * 2; + return this.blockRenderDistanceDiameter * 2; } @@ -381,7 +381,7 @@ public class LodQuadTree extends QuadTree implements AutoClose // The minimum detail level is done to prevent single corner sections rendering 1 detail level lower than the others. // If not done corners may not be flush with the other LODs, which looks bad. - byte minSectionDetailLevel = this.getDetailLevelFromDistance(this.blockRenderDistanceRadius); // get the minimum allowed detail level + byte minSectionDetailLevel = this.getDetailLevelFromDistance(this.blockRenderDistanceDiameter); // get the minimum allowed detail level minSectionDetailLevel -= 1; // -1 so corners can't render lower than their adjacent neighbors. space minSectionDetailLevel = (byte) Math.min(minSectionDetailLevel, this.treeMinDetailLevel); // don't allow rendering lower detail sections than what the tree contains this.minRenderDetailLevel = (byte) Math.max(minSectionDetailLevel, this.maxRenderDetailLevel); // respect the user's selected max resolution if it is lower detail (IE they want 2x2 block, but minSectionDetailLevel is specifically for 1x1 block render resolution) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java index 2f831f649..c8ef5565e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderUtil.java @@ -235,7 +235,7 @@ public class RenderUtil } public static int getFarClipPlaneDistanceInBlocks() { - int lodChunkDist = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get(); + int lodChunkDist = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get(); return lodChunkDist * LodUtil.CHUNK_WIDTH; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java index 9dcaf72e7..1b4dc969b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java @@ -56,7 +56,7 @@ public class QuadTree */ public final byte treeMaxDetailLevel; - private final int widthInBlocks; // diameterInBlocks + private final int diameterInBlocks; // diameterInBlocks /** contain the actual data in the quad tree structure */ private final MovableGridRingList> topRingList; @@ -68,18 +68,18 @@ public class QuadTree /** * Constructor of the quadTree * - * @param widthInBlocks equivalent to the distance between two opposing sides + * @param diameterInBlocks equivalent to the distance between the two opposing sides */ - public QuadTree(int widthInBlocks, DhBlockPos2D centerBlockPos, byte treeMaxDetailLevel) + public QuadTree(int diameterInBlocks, DhBlockPos2D centerBlockPos, byte treeMaxDetailLevel) { this.centerBlockPos = centerBlockPos; - this.widthInBlocks = widthInBlocks; + this.diameterInBlocks = diameterInBlocks; this.treeMaxDetailLevel = treeMaxDetailLevel; // the min detail level must be greater than 0 (to prevent divide by 0 errors) and greater than the maximum detail level - this.treeMinDetailLevel = (byte) Math.max(Math.max(1, this.treeMaxDetailLevel), MathUtil.log2(widthInBlocks)); + this.treeMinDetailLevel = (byte) Math.max(Math.max(1, this.treeMaxDetailLevel), MathUtil.log2(diameterInBlocks)); - int halfSizeInRootNodes = Math.floorDiv(this.widthInBlocks, 2) / BitShiftUtil.powerOfTwo(this.treeMinDetailLevel); + int halfSizeInRootNodes = Math.floorDiv(this.diameterInBlocks, 2) / BitShiftUtil.powerOfTwo(this.treeMinDetailLevel); halfSizeInRootNodes = halfSizeInRootNodes + 1; // always add 1 so nodes will always have a parent, even if the tree's center is offset from the root node grid Pos2D ringListCenterPos = new Pos2D( @@ -171,14 +171,14 @@ public class QuadTree // check if the testPos is within the X,Z boundary of the tree - DhBlockPos2D treeBlockCorner = this.centerBlockPos.add(new DhBlockPos2D(-this.widthInBlocks / 2, -this.widthInBlocks / 2)); + DhBlockPos2D treeBlockCorner = this.centerBlockPos.add(new DhBlockPos2D(-this.diameterInBlocks / 2, -this.diameterInBlocks / 2)); DhLodPos treeCornerPos = new DhLodPos((byte) 0, treeBlockCorner.x, treeBlockCorner.z); DhSectionPos inputSectionCorner = testPos.convertNewToDetailLevel((byte) 0); DhLodPos inputCornerPos = new DhLodPos((byte) 0, inputSectionCorner.getX(), inputSectionCorner.getZ()); int inputBlockWidth = BitShiftUtil.powerOfTwo(testPos.getDetailLevel()); - return DoSquaresOverlap(treeCornerPos, this.widthInBlocks, inputCornerPos, inputBlockWidth); + return DoSquaresOverlap(treeCornerPos, this.diameterInBlocks, inputCornerPos, inputBlockWidth); } private static boolean DoSquaresOverlap(DhLodPos square1Min, int square1Width, DhLodPos square2Min, int square2Width) { @@ -368,7 +368,7 @@ public class QuadTree // TODO comment, currently a tree will always have 9 root nodes, because the tree will grow all the way up to the top, if this is ever changed then these values must also change public int ringListWidth() { return 3; } public int ringListHalfWidth() { return 1; } - public int diameterInBlocks() { return this.widthInBlocks; } + public int diameterInBlocks() { return this.diameterInBlocks; } // public String getDebugString() // { @@ -384,7 +384,7 @@ public class QuadTree // } @Override - public String toString() { return "center block: " + this.centerBlockPos + ", block width: " + this.widthInBlocks + ", detail level range: [" + this.treeMaxDetailLevel + "-" + this.treeMinDetailLevel + "], leaf #: " + this.leafNodeCount(); } + public String toString() { return "center block: " + this.centerBlockPos + ", block width: " + this.diameterInBlocks + ", detail level range: [" + this.treeMaxDetailLevel + "-" + this.treeMinDetailLevel + "], leaf #: " + this.leafNodeCount(); }