Fixed detail level stuck at 0 in far pos caused by overflow issues
This commit is contained in:
@@ -53,21 +53,22 @@ public class PosToGenerateContainer
|
||||
// TODO what is going on in this method?
|
||||
public void addNearPosToGenerate(byte detailLevel, int posX, int posZ, boolean sort)
|
||||
{
|
||||
int distance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ);
|
||||
// FIXME: This is a cast from double to int!!! OVERFLOW MAY HAPPEN!
|
||||
int distance = (int)LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ);
|
||||
int index;
|
||||
|
||||
//We are introducing a position in the near array
|
||||
|
||||
index = nearSize;
|
||||
if (index == nearPosToGenerate.length) {
|
||||
if (LevelPosUtil.compareDistance(distance, nearPosToGenerate[index - 1][3]) > 0) {
|
||||
if (Integer.compare(distance, nearPosToGenerate[index - 1][3]) > 0) {
|
||||
return;
|
||||
}
|
||||
index--;
|
||||
} else nearSize++;
|
||||
|
||||
if (sort) {
|
||||
while (index > 0 && LevelPosUtil.compareDistance(distance, nearPosToGenerate[index - 1][3]) <= 0)
|
||||
while (index > 0 && Integer.compare(distance, nearPosToGenerate[index - 1][3]) <= 0)
|
||||
{
|
||||
nearPosToGenerate[index][0] = nearPosToGenerate[index - 1][0];
|
||||
nearPosToGenerate[index][1] = nearPosToGenerate[index - 1][1];
|
||||
@@ -85,21 +86,22 @@ public class PosToGenerateContainer
|
||||
// TODO what is going on in this method?
|
||||
public void addFarPosToGenerate(byte detailLevel, int posX, int posZ, boolean sort)
|
||||
{
|
||||
int distance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ);
|
||||
// FIXME: This is a cast from double to int!!! OVERFLOW MAY HAPPEN!
|
||||
int distance = (int)LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ);
|
||||
int index;
|
||||
|
||||
// We are introducing a position in the far array
|
||||
|
||||
index = farSize;
|
||||
if (index == farPosToGenerate.length) {
|
||||
if (LevelPosUtil.compareDistance(distance, farPosToGenerate[index - 1][3]) > 0) {
|
||||
if (Integer.compare(distance, farPosToGenerate[index - 1][3]) > 0) {
|
||||
return;
|
||||
}
|
||||
index--;
|
||||
} else farSize++;
|
||||
|
||||
if (sort) {
|
||||
while (index > 0 && LevelPosUtil.compareDistance(distance, farPosToGenerate[index - 1][3]) <= 0)
|
||||
while (index > 0 && Integer.compare(distance, farPosToGenerate[index - 1][3]) <= 0)
|
||||
{
|
||||
farPosToGenerate[index][0] = farPosToGenerate[index - 1][0];
|
||||
farPosToGenerate[index][1] = farPosToGenerate[index - 1][1];
|
||||
|
||||
@@ -290,7 +290,7 @@ public class LodDimension
|
||||
Pos minPos = regions.getMinInRange();
|
||||
// go over every region in the dimension
|
||||
iterateWithSpiral((int x, int z) -> {
|
||||
int minDistance;
|
||||
double minDistance;
|
||||
byte detail;
|
||||
|
||||
LodRegion region = regions.get(x+minPos.x, z+minPos.y);
|
||||
@@ -358,8 +358,8 @@ public class LodDimension
|
||||
int regionX;
|
||||
int regionZ;
|
||||
LodRegion region;
|
||||
int minDistance;
|
||||
int maxDistance;
|
||||
double minDistance;
|
||||
double maxDistance;
|
||||
byte minDetail;
|
||||
byte maxDetail;
|
||||
regionX = x + minPos.x;
|
||||
@@ -372,6 +372,19 @@ public class LodDimension
|
||||
playerPosZ);
|
||||
maxDistance = LevelPosUtil.maxDistance(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ, playerPosX,
|
||||
playerPosZ);
|
||||
{
|
||||
double debugRPosX = LevelPosUtil.convert(LodUtil.REGION_DETAIL_LEVEL, regionX, (byte) 0) + LodUtil.REGION_WIDTH/2;
|
||||
double debugRPosZ = LevelPosUtil.convert(LodUtil.REGION_DETAIL_LEVEL, regionZ, (byte) 0) + LodUtil.REGION_WIDTH/2;
|
||||
double deltaRPosX = debugRPosX - playerPosX;
|
||||
double deltaRPosZ = debugRPosZ - playerPosZ;
|
||||
double debugDistance = Math.sqrt(deltaRPosX*deltaRPosX + deltaRPosZ*deltaRPosZ);
|
||||
if (minDistance > debugDistance || maxDistance < debugDistance || minDistance > maxDistance) {
|
||||
ClientApi.LOGGER.error("MinDistance/MaxDistance is WRONG!!! minDist: [{}], maxDist: [{}], centerDist: [{}]\n"
|
||||
+ "At center block pos: {} {}, region pos: {}",
|
||||
minDistance, maxDistance, debugDistance, debugRPosX, debugRPosZ, regionPos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
minDetail = DetailDistanceUtil.getDetailLevelFromDistance(minDistance);
|
||||
maxDetail = DetailDistanceUtil.getDetailLevelFromDistance(maxDistance);
|
||||
boolean updated = false;
|
||||
@@ -695,6 +708,7 @@ public class LodDimension
|
||||
ramLogger.info("Dumping Ram Usage for LodDim in {} with {} regions...", dimension.getDimensionName(), regionCount);
|
||||
int nonNullRegionCount = 0;
|
||||
int dirtiedRegionCount = 0;
|
||||
int writingRegionCount = 0;
|
||||
long totalUsage = 0;
|
||||
int[] detailCount = new int[LodUtil.DETAIL_OPTIONS];
|
||||
long[] detailUsage = new long[LodUtil.DETAIL_OPTIONS];
|
||||
@@ -702,11 +716,15 @@ public class LodDimension
|
||||
if (r==null) continue;
|
||||
nonNullRegionCount++;
|
||||
if (r.needSaving) dirtiedRegionCount++;
|
||||
if (r.isWriting != 0) writingRegionCount++;
|
||||
LevelContainer[] container = r.debugGetDataContainers().clone();
|
||||
if (container == null || container.length != LodUtil.DETAIL_OPTIONS) {
|
||||
ClientApi.LOGGER.warn("DumpRamUsage encountered an invalid region!");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
if (container[i] == null) continue;
|
||||
detailCount[i]++;
|
||||
@@ -716,8 +734,8 @@ public class LodDimension
|
||||
}
|
||||
}
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.info("Non Null Regions: [{}], Dirtied Regions: [{}], Bytes: [{}]",
|
||||
nonNullRegionCount, dirtiedRegionCount, new UnitBytes(totalUsage));
|
||||
ramLogger.info("Non Null Regions: [{}], Dirtied Regions: [{}], Writing Regions: [{}], Bytes: [{}]",
|
||||
nonNullRegionCount, dirtiedRegionCount, writingRegionCount, new UnitBytes(totalUsage));
|
||||
ramLogger.info("------------------------------------------------");
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
ramLogger.info("DETAIL {}: Containers: [{}], Bytes: [{}]", i, detailCount[i], new UnitBytes(detailUsage[i]));
|
||||
|
||||
@@ -228,7 +228,7 @@ public class LodRegion {
|
||||
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
|
||||
|
||||
// calculate what LevelPos are in range to generate
|
||||
int minDistance = LevelPosUtil.minDistance(detailLevel, offsetPosX + regionPosX*size, offsetPosZ + regionPosZ*size, playerPosX, playerPosZ);
|
||||
double minDistance = LevelPosUtil.minDistance(detailLevel, offsetPosX + regionPosX*size, offsetPosZ + regionPosZ*size, playerPosX, playerPosZ);
|
||||
|
||||
// determine this child's levelPos
|
||||
byte childDetailLevel = (byte) (detailLevel - 1);
|
||||
@@ -276,14 +276,14 @@ public class LodRegion {
|
||||
*/
|
||||
public void getPosToRender(PosToRenderContainer posToRender, int playerPosX, int playerPosZ,
|
||||
GenerationPriority priority, DropoffQuality dropoffQuality) {
|
||||
int minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ, playerPosX, playerPosZ);
|
||||
double minDistance = LevelPosUtil.minDistance(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ, playerPosX, playerPosZ);
|
||||
byte targetLevel = DetailDistanceUtil.getDetailLevelFromDistance(minDistance);
|
||||
if (targetLevel <= dropoffQuality.fastModeSwitch) {
|
||||
getPosToRender(posToRender, LodUtil.REGION_DETAIL_LEVEL, 0, 0, playerPosX, playerPosZ,
|
||||
priority);
|
||||
} else {
|
||||
// FarModeSwitchLevel or above is the level where a giant block of lod is not acceptable even if not all child data exist.
|
||||
int maxDistance = LevelPosUtil.maxDistance(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ, playerPosX, playerPosZ);
|
||||
double maxDistance = LevelPosUtil.maxDistance(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ, playerPosX, playerPosZ);
|
||||
byte farModeSwitchLevel = (priority == GenerationPriority.NEAR_FIRST) ? 0 :
|
||||
calculateFarModeSwitch(DetailDistanceUtil.getDetailLevelFromDistance(maxDistance));
|
||||
if (priority == GenerationPriority.FAR_FIRST) farModeSwitchLevel = 8;
|
||||
@@ -305,7 +305,7 @@ public class LodRegion {
|
||||
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
|
||||
|
||||
// calculate the LevelPos that are in range
|
||||
int minDistance = LevelPosUtil.minDistance(detailLevel, offsetPosX + regionPosX*size, offsetPosZ + regionPosZ*size, playerPosX, playerPosZ);
|
||||
double minDistance = LevelPosUtil.minDistance(detailLevel, offsetPosX + regionPosX*size, offsetPosZ + regionPosZ*size, playerPosX, playerPosZ);
|
||||
byte minLevel = DetailDistanceUtil.getDetailLevelFromDistance(minDistance);
|
||||
// FarModeSwitchLevel or above is the level where a giant block of lod is not acceptable even if not all child data exist.
|
||||
byte farModeSwitchLevel = (priority == GenerationPriority.NEAR_FIRST) ? 0 : calculateFarModeSwitch(minLevel);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.lod.core.util;
|
||||
|
||||
import com.seibel.lod.core.api.ClientApi;
|
||||
import com.seibel.lod.core.enums.config.HorizontalQuality;
|
||||
import com.seibel.lod.core.enums.config.HorizontalResolution;
|
||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
||||
@@ -42,10 +43,10 @@ public class DetailDistanceUtil
|
||||
private static final double treeCutMultiplier = 1.0;
|
||||
private static byte minGenDetail = CONFIG.client().graphics().quality().getDrawResolution().detailLevel;
|
||||
private static byte minDrawDetail = CONFIG.client().graphics().quality().getDrawResolution().detailLevel;
|
||||
private static final int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1;
|
||||
private static final int minDistance = 0;
|
||||
private static int minDetailDistance = (int) (MC_RENDER.getRenderDistance()*16 * 1.42f);
|
||||
private static int maxDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 16 * 2;
|
||||
private static final byte maxDetail = LodUtil.DETAIL_OPTIONS;
|
||||
private static final double minDistance = 0;
|
||||
private static double minDetailDistance = (int) (MC_RENDER.getRenderDistance()*16 * 1.42f);
|
||||
private static double maxDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 16 * 2;
|
||||
|
||||
|
||||
public static void updateSettings()
|
||||
@@ -56,8 +57,7 @@ public class DetailDistanceUtil
|
||||
maxDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 16 * 8;
|
||||
}
|
||||
|
||||
/*// Need UPDATE and BUG FIX
|
||||
public static int baseDistanceFunction(int detail)
|
||||
public static double baseDistanceFunction(int detail)
|
||||
{
|
||||
if (detail <= minGenDetail)
|
||||
return minDistance;
|
||||
@@ -69,21 +69,27 @@ public class DetailDistanceUtil
|
||||
|
||||
int distanceUnit = CONFIG.client().graphics().quality().getHorizontalScale() * 16;
|
||||
if (CONFIG.client().graphics().quality().getHorizontalQuality() == HorizontalQuality.LOWEST)
|
||||
return (detail * distanceUnit);
|
||||
return ((double)detail * distanceUnit);
|
||||
else
|
||||
{
|
||||
double base = CONFIG.client().graphics().quality().getHorizontalQuality().quadraticBase;
|
||||
return (int) (Math.pow(base, detail) * distanceUnit);
|
||||
return Math.pow(base, detail) * distanceUnit;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDrawDistanceFromDetail(int detail)
|
||||
public static double getDrawDistanceFromDetail(int detail)
|
||||
{
|
||||
return baseDistanceFunction(detail);
|
||||
}*/
|
||||
}
|
||||
|
||||
public static byte baseInverseFunction(int distance, byte minDetail)
|
||||
public static byte baseInverseFunction(double distance, byte minDetail)
|
||||
{
|
||||
double maxDetailDistance = getDrawDistanceFromDetail(maxDetail-1);
|
||||
if (distance > maxDetailDistance) {
|
||||
//ClientApi.LOGGER.info("DEBUG: Scale as max: {}", distance);
|
||||
return maxDetail-1;
|
||||
}
|
||||
|
||||
int detail;
|
||||
distance -= minDetailDistance;
|
||||
|
||||
@@ -103,34 +109,10 @@ public class DetailDistanceUtil
|
||||
return (byte) LodUtil.clamp(minDetail, detail+minDetail, maxDetail - 1);
|
||||
}
|
||||
|
||||
public static byte getDetailLevelFromDistance(int distance)
|
||||
public static byte getDetailLevelFromDistance(double distance)
|
||||
{
|
||||
return baseInverseFunction(distance, minDrawDetail);
|
||||
}
|
||||
|
||||
@Deprecated //Reason: All merged into `getDetailLevelFromDistance`
|
||||
public static byte getDrawDetailFromDistance(int distance)
|
||||
{
|
||||
return baseInverseFunction(distance, minDrawDetail);
|
||||
}
|
||||
|
||||
@Deprecated //Reason: Same as 'getDrawDetailFromDistance'
|
||||
public static byte getGenerationDetailFromDistance(int distance)
|
||||
{
|
||||
return baseInverseFunction((int) (distance * genMultiplier), minGenDetail);
|
||||
}
|
||||
|
||||
@Deprecated //Reason: Same as 'getDrawDetailFromDistance'
|
||||
public static byte getTreeCutDetailFromDistance(int distance)
|
||||
{
|
||||
return baseInverseFunction((int) (distance * treeCutMultiplier), minGenDetail);
|
||||
}
|
||||
|
||||
@Deprecated //Reason: Same as 'getDrawDetailFromDistance'
|
||||
public static byte getTreeGenDetailFromDistance(int distance)
|
||||
{
|
||||
return baseInverseFunction((int) (distance * treeGenMultiplier), minGenDetail);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: The recent LodWorldGenerator changes assumes that this value doesn't change with 'detail'.
|
||||
@@ -141,15 +123,6 @@ public class DetailDistanceUtil
|
||||
return CONFIG.client().worldGenerator().getDistanceGenerationMode();
|
||||
}*/
|
||||
|
||||
@Deprecated
|
||||
public static byte getLodDrawDetail(byte detail)
|
||||
{
|
||||
detail += minDrawDetail;
|
||||
if (detail > 10)
|
||||
detail = 10;
|
||||
return detail;
|
||||
}
|
||||
|
||||
public static int getMaxVerticalData(int detail)
|
||||
{
|
||||
return CONFIG.client().graphics().quality().getVerticalQuality().maxVerticalData[LodUtil.clamp(minGenDetail, detail, LodUtil.REGION_DETAIL_LEVEL)];
|
||||
|
||||
@@ -149,32 +149,32 @@ public class LevelPosUtil
|
||||
return convert(detailLevel, pos, LodUtil.CHUNK_DETAIL_LEVEL);
|
||||
}
|
||||
|
||||
public static int myPow2(int x)
|
||||
public static double myPow2(double x)
|
||||
{
|
||||
return x*x;
|
||||
}
|
||||
|
||||
public static int maxDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
|
||||
public static double maxDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
|
||||
{
|
||||
int width = 1 << detailLevel;
|
||||
|
||||
int startPosX = posX * width;
|
||||
int startPosZ = posZ * width;
|
||||
int endPosX = myPow2(playerPosX - startPosX - width);
|
||||
int endPosZ = myPow2(playerPosZ - startPosZ - width);
|
||||
double startPosX = posX * width;
|
||||
double startPosZ = posZ * width;
|
||||
double endPosX = myPow2(playerPosX - startPosX - width);
|
||||
double endPosZ = myPow2(playerPosZ - startPosZ - width);
|
||||
startPosX = myPow2(playerPosX - startPosX);
|
||||
startPosZ = myPow2(playerPosZ - startPosZ);
|
||||
|
||||
int maxDistance = (int) Math.sqrt(startPosX + startPosZ);
|
||||
maxDistance = Math.max(maxDistance, (int) Math.sqrt(startPosX + endPosZ));
|
||||
maxDistance = Math.max(maxDistance, (int) Math.sqrt(endPosX + startPosZ));
|
||||
maxDistance = Math.max(maxDistance, (int) Math.sqrt(endPosX + endPosZ));
|
||||
double maxDistance = Math.sqrt(startPosX + startPosZ);
|
||||
maxDistance = Math.max(maxDistance, Math.sqrt(startPosX + endPosZ));
|
||||
maxDistance = Math.max(maxDistance, Math.sqrt(endPosX + startPosZ));
|
||||
maxDistance = Math.max(maxDistance, Math.sqrt(endPosX + endPosZ));
|
||||
|
||||
return maxDistance;
|
||||
}
|
||||
|
||||
|
||||
public static int minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
|
||||
public static double minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
|
||||
{
|
||||
int width = 1 << detailLevel;
|
||||
|
||||
@@ -203,35 +203,27 @@ public class LevelPosUtil
|
||||
}
|
||||
else
|
||||
{
|
||||
startPosX = myPow2(playerPosX - startPosX);
|
||||
startPosZ = myPow2(playerPosZ - startPosZ);
|
||||
endPosX = myPow2(playerPosX - endPosX);
|
||||
endPosZ = myPow2(playerPosZ - endPosZ);
|
||||
double startPosX2 = myPow2(playerPosX - startPosX);
|
||||
double startPosZ2 = myPow2(playerPosZ - startPosZ);
|
||||
double endPosX2 = myPow2(playerPosX - endPosX);
|
||||
double endPosZ2 = myPow2(playerPosZ - endPosZ);
|
||||
|
||||
int minDistance = (int) Math.sqrt(startPosX + startPosZ);
|
||||
minDistance = Math.min(minDistance, (int) Math.sqrt(startPosX + endPosZ));
|
||||
minDistance = Math.min(minDistance, (int) Math.sqrt(endPosX + startPosZ));
|
||||
minDistance = Math.min(minDistance, (int) Math.sqrt(endPosX + endPosZ));
|
||||
double minDistance = Math.sqrt(startPosX2 + startPosZ2);
|
||||
minDistance = Math.min(minDistance, Math.sqrt(startPosX2 + endPosZ2));
|
||||
minDistance = Math.min(minDistance, Math.sqrt(endPosX2 + startPosZ2));
|
||||
minDistance = Math.min(minDistance, Math.sqrt(endPosX2 + endPosZ2));
|
||||
return minDistance;
|
||||
}
|
||||
}
|
||||
|
||||
public static int compareDistance(int firstDistance, int secondDistance)
|
||||
public static double compareLevelAndDistance(byte firstDetail, double firstDistance, byte secondDetail, double secondDistance)
|
||||
{
|
||||
return Integer.compare(
|
||||
firstDistance,
|
||||
secondDistance);
|
||||
}
|
||||
|
||||
|
||||
public static int compareLevelAndDistance(byte firstDetail, int firstDistance, byte secondDetail, int secondDistance)
|
||||
{
|
||||
int compareResult = Integer.compare(
|
||||
int compareResult = Byte.compare(
|
||||
secondDetail,
|
||||
firstDetail);
|
||||
if (compareResult == 0)
|
||||
{
|
||||
compareResult = Integer.compare(
|
||||
compareResult = Double.compare(
|
||||
firstDistance,
|
||||
secondDistance);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user