Add DropoffQuality

This commit is contained in:
tom lee
2022-01-07 18:58:29 +08:00
parent cba75123c7
commit d4123a44ed
4 changed files with 129 additions and 8 deletions
@@ -0,0 +1,48 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2022 Tom Lee (TomTheFurry)
*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.enums.config;
/**
* AUTO <br>
* SMOOTH_DROPOFF <br>
* PERFORMANCE_FOCUSED <br>
* <br>
* Determines how lod level drop off should be done
*
* @author Tom Lee
* @version 7-1-2022
*/
public enum DropoffQuality {
/** SMOOTH_DROPOFF when <128 lod view distance, or PERFORMANCE_FOCUSED otherwise */
AUTO(-1),
SMOOTH_DROPOFF(10),
PERFORMANCE_FOCUSED(0);
public final int fastModeSwitch;
DropoffQuality(int fastModeSwitch) {
this.fastModeSwitch = fastModeSwitch;
}
}
@@ -26,6 +26,7 @@ import java.util.concurrent.Executors;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.DropoffQuality;
import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.handlers.LodDimensionFileHandler;
@@ -385,7 +386,11 @@ public class LodDimension
DistanceGenerationMode generationMode = CONFIG.client().worldGenerator().getDistanceGenerationMode();
VerticalQuality verticalQuality = CONFIG.client().graphics().quality().getVerticalQuality();
DropoffQuality dropoffQuality = CONFIG.client().graphics().quality().getDropoffQuality();
if (dropoffQuality == DropoffQuality.AUTO)
dropoffQuality = CONFIG.client().graphics().quality().getLodChunkRenderDistance() < 128 ?
DropoffQuality.SMOOTH_DROPOFF : DropoffQuality.PERFORMANCE_FOCUSED;
int dropoffSwitch = dropoffQuality.fastModeSwitch;
// don't run the expander multiple times
// for the same location
Runnable thread = () -> {
@@ -423,10 +428,10 @@ public class LodDimension
region = getRegionFromFile(regions[x][z], minDetail, generationMode, verticalQuality);
regions[x][z] = region;
updated = true;
} else if (region.lastMaxDetailLevel != maxDetail) {
} else if (minDetail <= dropoffSwitch && region.lastMaxDetailLevel != maxDetail) {
region.lastMaxDetailLevel = maxDetail;
updated = true;
} else if (region.lastMaxDetailLevel != region.getMinDetailLevel()) {
} else if (minDetail <= dropoffSwitch && region.lastMaxDetailLevel != region.getMinDetailLevel()) {
updated = true;
}
if (updated) {
@@ -503,11 +508,16 @@ public class LodDimension
GenerationPriority generationPriority = CONFIG.client().worldGenerator().getGenerationPriority();
if (generationPriority == GenerationPriority.AUTO)
generationPriority = MC.hasSinglePlayerServer() ? GenerationPriority.FAR_FIRST : GenerationPriority.NEAR_FIRST;
DropoffQuality dropoffQuality = CONFIG.client().graphics().quality().getDropoffQuality();
if (dropoffQuality == DropoffQuality.AUTO)
dropoffQuality = CONFIG.client().graphics().quality().getLodChunkRenderDistance() < 128 ?
DropoffQuality.SMOOTH_DROPOFF : DropoffQuality.PERFORMANCE_FOCUSED;
boolean requireCorrectDetailLevel = generationPriority == GenerationPriority.NEAR_FIRST;
if (region != null)
region.getPosToRender(posToRender, playerPosX, playerPosZ, requireCorrectDetailLevel);
region.getPosToRender(posToRender, playerPosX, playerPosZ, requireCorrectDetailLevel, dropoffQuality);
}
/**
@@ -20,6 +20,7 @@
package com.seibel.lod.core.objects.lod;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.DropoffQuality;
import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.enums.config.VerticalQuality;
import com.seibel.lod.core.objects.PosToGenerateContainer;
@@ -192,7 +193,6 @@ public class LodRegion {
int childPosX = childOffsetPosX * 2;
int childPosZ = childOffsetPosZ * 2;
int childSize = 1 << (LodUtil.REGION_DETAIL_LEVEL - childDetailLevel);
byte targetDetailLevel = DetailDistanceUtil.getGenerationDetailFromDistance(minDistance);
if (targetDetailLevel <= detailLevel) {
@@ -233,9 +233,15 @@ public class LodRegion {
* understand
*/
public void getPosToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ,
boolean requireCorrectDetailLevel) {
getPosToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ,
requireCorrectDetailLevel);
boolean requireCorrectDetailLevel, DropoffQuality dropoffQuality) {
int minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ, regionPosX, regionPosZ);
byte targetLevel = DetailDistanceUtil.getDrawDetailFromDistance(minDistance);
if (targetLevel <= dropoffQuality.fastModeSwitch) {
getPosToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ,
requireCorrectDetailLevel);
} else {
getPosToRenderFlat(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, targetLevel, requireCorrectDetailLevel);
}
}
/**
@@ -305,6 +311,47 @@ public class LodRegion {
}
}
/**
* This method will fill the posToRender array with all levelPos that are
* render-able. But the entire region try use the same detail level.
*/
private void getPosToRenderFlat(PosToRenderContainer posToRender, byte detailLevel, int posX, int posZ, byte targetLevel, boolean requireCorrectDetailLevel) {
// equivalent to 2^(...)
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
if (detailLevel == targetLevel) {
posToRender.addPosToRender(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size);
} else // case where (detailLevel > desiredLevel)
{
int childPosX = posX * 2;
int childPosZ = posZ * 2;
byte childDetailLevel = (byte) (detailLevel - 1);
int childrenCount = 0;
for (int x = 0; x <= 1; x++) {
for (int z = 0; z <= 1; z++) {
if (doesDataExist(childDetailLevel, childPosX + x, childPosZ + z)) {
if (!requireCorrectDetailLevel)
childrenCount++;
else
getPosToRenderFlat(posToRender, childDetailLevel, childPosX + x, childPosZ + z, targetLevel, requireCorrectDetailLevel);
}
}
}
if (!requireCorrectDetailLevel) {
// If all the four children exist go deeper
if (childrenCount == 4) {
for (int x = 0; x <= 1; x++)
for (int z = 0; z <= 1; z++)
getPosToRenderFlat(posToRender, childDetailLevel, childPosX + x, childPosZ + z, targetLevel, requireCorrectDetailLevel);
} else {
posToRender.addPosToRender(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size);
}
}
}
}
/**
* Updates all children.
* <p>
@@ -22,6 +22,7 @@ package com.seibel.lod.core.wrapperInterfaces.config;
import com.seibel.lod.core.enums.config.BlocksToAvoid;
import com.seibel.lod.core.enums.config.BufferRebuildTimes;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.enums.config.DropoffQuality;
import com.seibel.lod.core.enums.config.GenerationPriority;
import com.seibel.lod.core.enums.config.GpuUploadMethod;
import com.seibel.lod.core.enums.config.HorizontalQuality;
@@ -140,6 +141,21 @@ public interface ILodConfigWrapperSingleton
+ " Highest Quality: " + HorizontalQuality.HIGH;
HorizontalQuality getHorizontalQuality();
void setHorizontalQuality(HorizontalQuality newHorizontalQuality);
DropoffQuality DROPOFF_QUALITY_DEFAULT = DropoffQuality.AUTO;
String DROPOFF_QUALITY_DESC = ""
+ " This determines how lod level drop off will be done. \n"
+ "\n"
+ " " + DropoffQuality.SMOOTH_DROPOFF + ": \n"
+ " The lod level is calculated for each point, making the drop off a smooth circle. \n"
+ " " + DropoffQuality.PERFORMANCE_FOCUSED + ": \n"
+ " One detail level for an entire region. Minimize CPU usage and \n"
+ " improve terrain refresh delay, especially for high Lod render distance. \n"
+ " " + DropoffQuality.AUTO + ": \n"
+ " Use "+ DropoffQuality.SMOOTH_DROPOFF + " for less then 128 Lod render distance, \n"
+ " or "+ DropoffQuality.PERFORMANCE_FOCUSED +" otherwise. \n";
DropoffQuality getDropoffQuality();
void setDropoffQuality(DropoffQuality newDropoffQuality);
}
interface IFogQuality