From 72b89814b67cb1241cdba20c6d2d0a2c07c26602 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 11 Jun 2023 15:10:16 -0500 Subject: [PATCH] Merge Horizontal Quality and Scale The separation was confusing most of the time --- .../api/enums/config/EHorizontalQuality.java | 32 ++++---- .../api/enums/config/EHorizontalScale.java | 49 ------------ .../com/seibel/lod/core/config/Config.java | 9 --- .../RenderCacheConfigEventHandler.java | 4 +- ...RenderQualityPresetConfigEventHandler.java | 18 +---- .../seibel/lod/core/render/LodQuadTree.java | 11 ++- .../lod/core/util/DetailDistanceUtil.java | 76 +++++++++---------- 7 files changed, 62 insertions(+), 137 deletions(-) delete mode 100644 api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalScale.java diff --git a/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalQuality.java b/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalQuality.java index 6c75fd58c..1720731e7 100644 --- a/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalQuality.java +++ b/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalQuality.java @@ -23,12 +23,7 @@ package com.seibel.lod.api.enums.config; * LOWEST
* LOW
* MEDIUM
- * HIGH

- * - * this indicates the base of the quadratic function we use for the quality drop-off - * - * @author Leonardo Amato - * @version 9-29-2021 + * HIGH
*/ public enum EHorizontalQuality { @@ -37,22 +32,27 @@ public enum EHorizontalQuality // when removing items up the API major version - /** 1.0 AKA Linear */ - LOWEST(1.0f), + // FIXME any quadraticBase less than 2.0f has issues with DetailDistanceUtil, and will always return the lowest detail level. + // So for now we are limiting the lowest value to 2.0 + // LOWEST was originally 1.0f and LOW was 1.5f - /** exponent 1.5 */ - LOW(1.5f), + LOWEST(2.0f, 4), + LOW(2.0f, 8), + MEDIUM(2.0f, 12), + HIGH(2.2f, 24), + EXTREME(2.4f, 64), + + UNLIMITED(-1, -1); - /** exponent 2.0 */ - MEDIUM(2.0f), - /** exponent 2.2 */ - HIGH(2.2f); public final double quadraticBase; + public final int distanceUnitInBlocks; - EHorizontalQuality(double distanceUnit) + EHorizontalQuality(double quadraticBase, int distanceUnitInBlocks) { - this.quadraticBase = distanceUnit; + this.quadraticBase = quadraticBase; + this.distanceUnitInBlocks = distanceUnitInBlocks; } + } \ No newline at end of file diff --git a/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalScale.java b/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalScale.java deleted file mode 100644 index ca3fe5b0f..000000000 --- a/api/src/main/java/com/seibel/lod/api/enums/config/EHorizontalScale.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the Distant Horizons mod (formerly the LOD Mod), - * licensed under the GNU LGPL v3 License. - * - * Copyright (C) 2020-2022 James Seibel - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.seibel.lod.api.enums.config; - -/** - * Low
- * Medium
- * High
- *
- * this is a quality scale for the detail drop-off - * - * @author Leonardo Amato - * @version 9-25-2021 - */ -public enum EHorizontalScale -{ - /** Lods are 2D with heightMap */ - LOW(64), - - /** Lods expand in three dimension */ - MEDIUM(128), - - /** Lods expand in three dimension */ - HIGH(256); - - public final int distanceUnit; - - EHorizontalScale(int distanceUnit) - { - this.distanceUnit = distanceUnit; - } -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/lod/core/config/Config.java b/core/src/main/java/com/seibel/lod/core/config/Config.java index 47291ff59..82e60bcc8 100644 --- a/core/src/main/java/com/seibel/lod/core/config/Config.java +++ b/core/src/main/java/com/seibel/lod/core/config/Config.java @@ -178,15 +178,6 @@ public class Config .addListener(RenderCacheConfigEventHandler.INSTANCE) .build(); - // TODO merge with horizontal quality - public static ConfigEntry horizontalScale = new ConfigEntry.Builder() - .setMinDefaultMax(2, 12, 64) - .comment("" - + "This indicates how quickly fake chunks decrease in quality the further away they are. \n" - + "Higher settings will render higher quality fake chunks farther away, \n" - + " but will increase memory and GPU usage.") - .build(); - public static ConfigEntry horizontalQuality = new ConfigEntry.Builder() .set(EHorizontalQuality.MEDIUM) .comment("" diff --git a/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderCacheConfigEventHandler.java b/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderCacheConfigEventHandler.java index 922cb7695..3417b9438 100644 --- a/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderCacheConfigEventHandler.java +++ b/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderCacheConfigEventHandler.java @@ -4,9 +4,7 @@ import com.seibel.lod.api.DhApiMain; import com.seibel.lod.api.enums.config.EHorizontalResolution; import com.seibel.lod.api.enums.config.EVerticalQuality; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.config.listeners.ConfigChangeListener; import com.seibel.lod.core.config.listeners.IConfigListener; -import com.seibel.lod.core.config.types.ConfigEntry; import com.seibel.lod.core.util.DetailDistanceUtil; /** @@ -59,7 +57,7 @@ public class RenderCacheConfigEventHandler implements IConfigListener if (refreshRenderData) { // TODO add a timeout to prevent rapidly changing settings causing the render data thrashing. - DetailDistanceUtil.minDetail = newHorizontalResolution.detailLevel; + DetailDistanceUtil.updateSettings(); DhApiMain.Delayed.renderProxy.clearRenderDataCache(); } diff --git a/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderQualityPresetConfigEventHandler.java b/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderQualityPresetConfigEventHandler.java index c4bcd3433..a46ad2a7b 100644 --- a/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderQualityPresetConfigEventHandler.java +++ b/core/src/main/java/com/seibel/lod/core/config/eventHandlers/RenderQualityPresetConfigEventHandler.java @@ -47,29 +47,15 @@ public class RenderQualityPresetConfigEventHandler implements IConfigListener this.put(EQualityPreset.HIGH, EVerticalQuality.HIGH); this.put(EQualityPreset.EXTREME, EVerticalQuality.HIGH); }}); - - private final ConfigEntryWithPresetOptions horizontalQuality = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.horizontalQuality, new HashMap() {{ - this.put(EQualityPreset.MINIMUM, EHorizontalQuality.MEDIUM); // TODO Lowest and Low have a bug, making "chunk" the highest detail level - this.put(EQualityPreset.LOW, EHorizontalQuality.MEDIUM); // I should look into why this is instead of just removing the option + this.put(EQualityPreset.MINIMUM, EHorizontalQuality.LOWEST); + this.put(EQualityPreset.LOW, EHorizontalQuality.LOW); this.put(EQualityPreset.MEDIUM, EHorizontalQuality.MEDIUM); this.put(EQualityPreset.HIGH, EHorizontalQuality.HIGH); this.put(EQualityPreset.EXTREME, EHorizontalQuality.HIGH); }}); -// // TODO merge horizontal scale and quality (merge the numbers into quality) -// private final ConfigEntryWithPresetOptions horizontalScale = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.horizontalScale, -// new HashMap() -// {{ -// this.put(EQualityPreset.MINIMUM, 4); -// this.put(EQualityPreset.LOW, 8); -// this.put(EQualityPreset.MEDIUM, 12); -// this.put(EQualityPreset.HIGH, 24); -// this.put(EQualityPreset.EXTREME, 64); -// }}); - - private final ConfigEntryWithPresetOptions transparency = new ConfigEntryWithPresetOptions<>(Config.Client.Advanced.Graphics.Quality.transparency, new HashMap() {{ diff --git a/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java b/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java index ea116d88a..22f5a76c8 100644 --- a/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java +++ b/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java @@ -1,5 +1,6 @@ package com.seibel.lod.core.render; +import com.seibel.lod.api.enums.config.EHorizontalQuality; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.config.listeners.ConfigChangeListener; import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; @@ -9,12 +10,10 @@ import com.seibel.lod.core.pos.DhSectionPos; import com.seibel.lod.core.file.renderfile.ILodRenderSourceProvider; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.util.DetailDistanceUtil; -import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.objects.quadTree.QuadNode; import com.seibel.lod.core.util.objects.quadTree.QuadTree; import org.apache.logging.log4j.Logger; -import java.util.HashSet; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; @@ -39,7 +38,7 @@ public class LodQuadTree extends QuadTree implements AutoClose private final IDhClientLevel level; //FIXME: Proper hierarchy to remove this reference! - private final ConfigChangeListener horizontalScaleChangeListener; + private final ConfigChangeListener horizontalScaleChangeListener; @@ -56,7 +55,7 @@ public class LodQuadTree extends QuadTree implements AutoClose this.renderSourceProvider = provider; this.blockRenderDistance = viewDistanceInBlocks; - this.horizontalScaleChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.Quality.horizontalScale, (newHorizontalScale) -> this.onHorizontalScaleChange()); + this.horizontalScaleChangeListener = new ConfigChangeListener<>(Config.Client.Advanced.Graphics.Quality.horizontalQuality, (newHorizontalScale) -> this.onHorizontalQualityChange()); } @@ -362,10 +361,10 @@ public class LodQuadTree extends QuadTree implements AutoClose // config listeners // //==================// - private void onHorizontalScaleChange() + private void onHorizontalQualityChange() { // TODO this Util should probably be somewhere else or handled differently, but it works for now - // Updating the util is necessary whenever the horizontal quality or scale are changed, otherwise they won't be applied + // Updating this util is necessary whenever the horizontal quality is changed, since it handles the detail drop-off DetailDistanceUtil.updateSettings(); diff --git a/core/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java b/core/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java index 05bc405b2..081d10bbd 100644 --- a/core/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java +++ b/core/src/main/java/com/seibel/lod/core/util/DetailDistanceUtil.java @@ -19,8 +19,8 @@ package com.seibel.lod.core.util; -import com.seibel.lod.core.config.Config; import com.seibel.lod.api.enums.config.EHorizontalQuality; +import com.seibel.lod.core.config.Config; import com.seibel.lod.coreapi.util.MathUtil; /** @@ -31,67 +31,67 @@ import com.seibel.lod.coreapi.util.MathUtil; @Deprecated public class DetailDistanceUtil { - public static byte minDetail = Config.Client.Advanced.Graphics.Quality.drawResolution.get().detailLevel; + /** smallest numerical detail level */ + private static byte maxDetailLevel = Config.Client.Advanced.Graphics.Quality.drawResolution.get().detailLevel; - private static final byte maxDetail = Byte.MAX_VALUE; + /** largest numerical detail level */ + private static final byte minDetailLevel = Byte.MAX_VALUE; private static final double minDistance = 0; - private static double distanceUnit = 16 * Config.Client.Advanced.Graphics.Quality.horizontalScale.get(); - private static double maxDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * 16 * 2; + + // TODO merge with updateSettings() below + private static double distanceUnit = Config.Client.Advanced.Graphics.Quality.horizontalQuality.get().distanceUnitInBlocks * LodUtil.CHUNK_WIDTH; + private static double maxDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH * 2; private static double logBase = Math.log(Config.Client.Advanced.Graphics.Quality.horizontalQuality.get().quadraticBase); + public static void updateSettings() { - distanceUnit = 16 * Config.Client.Advanced.Graphics.Quality.horizontalScale.get(); - minDetail = Config.Client.Advanced.Graphics.Quality.drawResolution.get().detailLevel; - maxDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * 16 * 8; + maxDetailLevel = Config.Client.Advanced.Graphics.Quality.drawResolution.get().detailLevel; + + distanceUnit = Config.Client.Advanced.Graphics.Quality.horizontalQuality.get().distanceUnitInBlocks * LodUtil.CHUNK_WIDTH; + maxDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH * 2; logBase = Math.log(Config.Client.Advanced.Graphics.Quality.horizontalQuality.get().quadraticBase); } public static double baseDistanceFunction(int detail) { - if (detail <= minDetail) - return minDistance; - if (detail >= maxDetail) - return maxDistance; - - detail-=minDetail; - - if (Config.Client.Advanced.Graphics.Quality.horizontalQuality.get() == EHorizontalQuality.LOWEST) - return ((double)detail * distanceUnit); - else + if (detail <= maxDetailLevel) { - double base = Config.Client.Advanced.Graphics.Quality.horizontalQuality.get().quadraticBase; - return Math.pow(base, detail) * distanceUnit; + return minDistance; } + else if (detail >= minDetailLevel) + { + return maxDistance; + } + + + double base = Config.Client.Advanced.Graphics.Quality.horizontalQuality.get().quadraticBase; + return Math.pow(base, detail) * distanceUnit; } - public static double getDrawDistanceFromDetail(int detail) - { - return baseDistanceFunction(detail); - } + public static double getDrawDistanceFromDetail(int detail) { return baseDistanceFunction(detail); } public static byte baseInverseFunction(double distance) { - double maxDetailDistance = getDrawDistanceFromDetail(maxDetail-1); - if (distance > maxDetailDistance) { - //ApiShared.LOGGER.info("DEBUG: Scale as max: {}", distance); - return maxDetail-1; + // special case, never drop the quality + if (Config.Client.Advanced.Graphics.Quality.horizontalQuality.get() == EHorizontalQuality.UNLIMITED) + { + return maxDetailLevel; } - int detail; - if (Config.Client.Advanced.Graphics.Quality.horizontalQuality.get() == EHorizontalQuality.LOWEST) - detail = (int) (distance/distanceUnit); - else - detail = (int) (Math.log(distance/distanceUnit) / logBase); + double maxDetailDistance = getDrawDistanceFromDetail(minDetailLevel -1); + if (distance > maxDetailDistance) + { + return minDetailLevel - 1; + } - return (byte) MathUtil.clamp(minDetail, detail+minDetail, maxDetail - 1); + + int detailLevel = (int) (Math.log(distance / distanceUnit) / logBase); + return (byte) MathUtil.clamp(maxDetailLevel, detailLevel, minDetailLevel - 1); } - public static byte getDetailLevelFromDistance(double distance) - { - return baseInverseFunction(distance); - } + public static byte getDetailLevelFromDistance(double distance) { return baseInverseFunction(distance); } }