Fix LOD render distance measured as the diameter instead of radius

This commit is contained in:
James Seibel
2023-10-18 07:50:59 -05:00
parent b014317e1a
commit b0ad8fa637
6 changed files with 22 additions and 23 deletions
@@ -54,7 +54,7 @@ public class DhApiGraphicsConfig implements IDhApiGraphicsConfig
@Override
public IDhApiConfigValue<Integer> chunkRenderDistance()
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance); }
{ return new DhApiConfigValue<Integer, Integer>(Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius); }
@Override
public IDhApiConfigValue<Boolean> renderingEnabled()
@@ -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<EQualityPreset> qualityPresetSetting = new ConfigEntry.Builder<EQualityPreset>()
.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<Integer> lodChunkRenderDistance = new ConfigEntry.Builder<Integer>()
public static ConfigEntry<Integer> lodChunkRenderDistanceRadius = new ConfigEntry.Builder<Integer>()
.setMinDefaultMax(32, 128, 4096)
.comment("The radius of the mod's render distance. (measured in chunks)")
.setPerformance(EConfigEntryPerformance.HIGH)
@@ -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);
@@ -48,7 +48,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> 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<LodRenderSection> 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<LodRenderSection> 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<LodRenderSection> 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)
@@ -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;
}
@@ -56,7 +56,7 @@ public class QuadTree<T>
*/
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<QuadNode<T>> topRingList;
@@ -68,18 +68,18 @@ public class QuadTree<T>
/**
* 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<T>
// 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<T>
// 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<T>
// }
@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(); }