Revert "Added LevelPosUtil, now the node are added using it and not with the LevelPos object"

LevelPos are useful and the small stutter in the buffer builder is probably caused by the creation of ChunkPos
This commit is contained in:
Leonardo
2021-09-01 16:33:34 +02:00
parent 1360edb459
commit 4e249e943a
6 changed files with 69 additions and 274 deletions
@@ -25,7 +25,6 @@ import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.objects.DataPoint;
import com.seibel.lod.objects.LevelPosUtil;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodWorld;
import com.seibel.lod.objects.LevelPos.LevelPos;
@@ -164,7 +163,7 @@ public class LodBuilder
short[] color;
short height;
short depth;
int[] levelPos;
LevelPos levelPos = new LevelPos((byte) 0, 0, 0);
short[] data;
try
{
@@ -187,23 +186,20 @@ public class LodBuilder
startZ, endX, endZ);
depth = 0;
}
levelPos = LevelPosUtil.convert(
LevelPosUtil.createLevelPos((byte) 0,
chunk.getPos().x * 16 + startX,
chunk.getPos().z * 16 + startZ),
detail.detailLevel
);
levelPos.changeParameters((byte) 0,
chunk.getPos().x * 16 + startX,
chunk.getPos().z * 16 + startZ);
levelPos.convert(detail.detailLevel);
boolean isServer = config.distanceGenerationMode == DistanceGenerationMode.SERVER;
data = DataPoint.createDataPoint(height, depth, color[0], color[1], color[2]);
boolean added = lodDim.addData(levelPos,
lodDim.addData(levelPos,
data,
false,
isServer);
System.out.println(added);
}
//levelPos.changeParameters(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z);
lodDim.updateData(LevelPosUtil.createLevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z));
lodDim.updateData(new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z));
} catch (Exception e)
{
//e.printStackTrace();
@@ -436,10 +432,12 @@ public class LodBuilder
Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
tmp = tmp.darker();
colorInt = LodUtil.colorToInt(tmp);
} else if (blockState == Blocks.STONE.defaultBlockState())
}
else if (blockState == Blocks.STONE.defaultBlockState())
{
colorInt = LodUtil.STONE_COLOR_INT;
} else if (blockState == Blocks.MYCELIUM.defaultBlockState())
}
else if (blockState == Blocks.MYCELIUM.defaultBlockState())
{
colorInt = LodUtil.MYCELIUM_COLOR_INT;
}
@@ -1,184 +0,0 @@
package com.seibel.lod.objects;
import com.seibel.lod.objects.LevelPos.ImmutableLevelPos;
import com.seibel.lod.objects.LevelPos.MutableLevelPos;
import com.seibel.lod.util.LodUtil;
import net.minecraft.util.math.ChunkPos;
import java.util.Comparator;
public class LevelPosUtil
{
public static int[] convert(int[] levelPos, byte newDetailLevel)
{
return convert(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), newDetailLevel);
}
public static int[] convert(byte detailLevel, int posX, int posZ, byte newDetailLevel)
{
int width;
if (newDetailLevel >= detailLevel)
{
width = 1 << (newDetailLevel - detailLevel);
return createLevelPos(
newDetailLevel,
Math.floorDiv(posX, width),
Math.floorDiv(posZ, width));
} else
{
width = 1 << (detailLevel - newDetailLevel);
return createLevelPos(
newDetailLevel,
posX * width,
posZ * width);
}
}
public static int[] createLevelPos(byte detailLevel, int posX, int posZ)
{
return new int[]{detailLevel, posX, posZ};
}
public static byte getDetailLevel(int[] levelPos)
{
return (byte) levelPos[0];
}
public static int getPosX(int[] levelPos)
{
return levelPos[1];
}
public static int getPosZ(int[] levelPos)
{
return levelPos[2];
}
public static int[] getRegionModule(int[] levelPos)
{
return getRegionModule(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos));
}
public static int[] getRegionModule(byte detailLevel, int posX, int posZ)
{
int width = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
return createLevelPos(
detailLevel,
Math.floorMod(posX, width),
Math.floorMod(posZ, width));
}
public static int[] applyOffset(int[] levelPos, int xOffset, int zOffset)
{
return createLevelPos(
getDetailLevel(levelPos),
getPosX(levelPos) + xOffset,
getPosZ(levelPos) + zOffset);
}
public static int[] applyLevelOffset(int[] levelPos, byte detailOffset, int xOffset, int zOffset)
{
return createLevelPos(
getDetailLevel(levelPos),
getPosX(levelPos) + xOffset * (1 << detailOffset),
getPosZ(levelPos) + zOffset * (1 << detailOffset));
}
public static int getRegionPosX(int[] levelPos)
{
int width = 1 << (LodUtil.REGION_DETAIL_LEVEL - getDetailLevel(levelPos));
return Math.floorDiv(getPosX(levelPos), width);
}
public static int getRegionPosZ(int[] levelPos)
{
int width = 1 << (LodUtil.REGION_DETAIL_LEVEL - getDetailLevel(levelPos));
return Math.floorDiv(getPosZ(levelPos), width);
}
public static ChunkPos getChunkPos(int[] levelPos)
{
levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL);
return new ChunkPos(
getPosX(levelPos),
getPosZ(levelPos));
}
public static int maxDistance(int[] levelPos, int playerPosX, int playerPosZ)
{
int width = 1 << getDetailLevel(levelPos);
int startPosX = getPosX(levelPos) * width;
int startPosZ = getPosX(levelPos) * width;
int endPosX = startPosX + width;
int endPosZ = startPosZ + width;
int maxDistance = (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - startPosZ, 2));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - startPosZ, 2)));
maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
return maxDistance;
}
public static int minDistance(int[] levelPos, int playerPosX, int playerPosZ)
{
int width = 1 << getDetailLevel(levelPos);
int startPosX = getPosX(levelPos) * width;
int startPosZ = getPosX(levelPos) * width;
int endPosX = startPosX + width;
int endPosZ = startPosZ + width;
boolean inXArea = playerPosX >= startPosX && playerPosX <= endPosX;
boolean inZArea = playerPosZ >= startPosZ && playerPosZ <= endPosZ;
if (inXArea && inZArea)
{
return 0;
} else if (inXArea)
{
return Math.min(
Math.abs(playerPosZ - startPosZ),
Math.abs(playerPosZ - endPosZ)
);
} else if (inZArea)
{
return Math.min(
Math.abs(playerPosX - startPosX),
Math.abs(playerPosX - endPosX)
);
} else
{
int minDistance = (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - startPosZ, 2));
minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - startPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - startPosZ, 2)));
minDistance = Math.min(minDistance, (int) Math.sqrt(Math.pow(playerPosX - endPosX, 2) + Math.pow(playerPosZ - endPosZ, 2)));
return minDistance;
}
}
public static int compareDistance(int posX, int posZ, int[] first, int[] second)
{
return Integer.compare(
minDistance(first, posX, posZ),
minDistance(second, posX, posZ));
}
public static int compareLevelAndDistance(int posX, int posZ, int[] first, int[] second)
{
int compareResult = Integer.compare(getDetailLevel(second), getDetailLevel(first));
if (compareResult == 0)
{
compareResult = Integer.compare(
minDistance(first, posX, posZ),
minDistance(second, posX, posZ));
}
return compareResult;
}
public static String toString(int[] levelPos)
{
return (getDetailLevel(levelPos) + " " + getPosX(levelPos) + " " + getPosZ(levelPos));
}
}
@@ -23,7 +23,6 @@ import java.security.InvalidParameterException;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import org.apache.commons.lang3.mutable.MutableBoolean;
@@ -285,27 +284,6 @@ public class LodDimension
return regions[xIndex][zIndex];
}
/**
* Gets the region at the given X and Z
* <br>
* Returns null if the region doesn't exist
* or is outside the loaded area.
*/
public LodRegion getRegion(int[] levelPos)
{
int xIndex = (LevelPosUtil.getRegionPosX(levelPos) - center.x) + halfWidth;
int zIndex = (LevelPosUtil.getRegionPosZ(levelPos) - center.z) + halfWidth;
if (!regionIsInRange(LevelPosUtil.getRegionPosX(levelPos), LevelPosUtil.getRegionPosZ(levelPos)))
throw new ArrayIndexOutOfBoundsException("Region for level pos " + levelPos + " out of range");
else if (regions[xIndex][zIndex] == null)
throw new InvalidParameterException("Region for level pos " + levelPos + " not currently initialized");
else if (regions[xIndex][zIndex].getMinDetailLevel() > LevelPosUtil.getDetailLevel(levelPos))
throw new InvalidParameterException("Region for level pos " + levelPos + " currently only reach level " + regions[xIndex][zIndex].getMinDetailLevel());
return regions[xIndex][zIndex];
}
/**
* Gets the region at the given X and Z
* <br>
@@ -461,13 +439,12 @@ public class LodDimension
* stored in the LOD. If an LOD already exists at the given
* coordinates it will be overwritten.
*/
public synchronized Boolean addData(int[] levelPos, short[] lodDataPoint, boolean dontSave, boolean serverQuality)
public synchronized Boolean addData(LevelPos levelPos, short[] lodDataPoint, boolean dontSave, boolean serverQuality)
{
// don't continue if the region can't be saved
int xRegion = LevelPosUtil.getRegionPosX(levelPos);
int zRegion = LevelPosUtil.getRegionPosZ(levelPos);
if (!regionIsInRange(xRegion, zRegion))
RegionPos regionPos = levelPos.getRegionPos();
if (!regionIsInRange(regionPos.x, regionPos.z))
{
return false;
}
@@ -481,8 +458,8 @@ public class LodDimension
try
{
// mark the region as dirty so it will be saved to disk
int xIndex = (xRegion - center.x) + halfWidth;
int zIndex = (zRegion - center.z) + halfWidth;
int xIndex = (regionPos.x - center.x) + halfWidth;
int zIndex = (regionPos.z - center.z) + halfWidth;
isRegionDirty[xIndex][zIndex] = true;
regen[xIndex][zIndex] = true;
regenDimension = true;
@@ -605,10 +582,10 @@ public class LodDimension
* Returns null if the LodChunk doesn't exist or
* is outside the loaded area.
*/
public void updateData(int[] levelPos)
public void updateData(LevelPos levelPos)
{
if (LevelPosUtil.getDetailLevel(levelPos) > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + LevelPosUtil.getDetailLevel(levelPos) + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
if (levelPos.detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + levelPos.detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodRegion region = getRegion(levelPos);
@@ -634,7 +611,7 @@ public class LodDimension
return false;
}
return region.doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel,levelPos.posX,levelPos.posZ));
return region.doesDataExist(levelPos.clone());
} catch (Exception e)
{
return false;
@@ -77,6 +77,7 @@ public class LodRegion implements Serializable
dataExistence[lod] = new boolean[size][size];
}
int width;
LevelPos levelPos = new LevelPos();
for (byte tempLod = (byte) (minDetailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++)
{
width = 1 << (LodUtil.REGION_DETAIL_LEVEL - tempLod);
@@ -84,7 +85,8 @@ public class LodRegion implements Serializable
{
for (int z = 0; z < width; z++)
{
update(LevelPosUtil.createLevelPos(tempLod, x, z));
levelPos.changeParameters(tempLod, x, z);
update(levelPos);
}
}
}
@@ -125,25 +127,22 @@ public class LodRegion implements Serializable
* @param dataPoint
* @return
*/
public boolean addData(int[] levelPos, short[] dataPoint, boolean serverQuality)
public boolean addData(LevelPos levelPos, short[] dataPoint, boolean serverQuality)
{
levelPos = LevelPosUtil.getRegionModule(levelPos);
byte detailLevel = LevelPosUtil.getDetailLevel(levelPos);
int posX = LevelPosUtil.getPosX(levelPos);
int posZ = LevelPosUtil.getPosZ(levelPos);
levelPos.performRegionModule();
if (!doesDataExist(levelPos) || serverQuality)
{
//update the number of node present
if (this.dataExistence[detailLevel][posX][posZ]) numberOfPoints++;
if (this.dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ]) numberOfPoints++;
//add the node data
this.height[detailLevel][posX][posZ] = DataPoint.getHeight(dataPoint);
this.depth[detailLevel][posX][posZ] = DataPoint.getDepth(dataPoint);
this.colors[detailLevel][posX][posZ][0] = (byte) (DataPoint.getRed(dataPoint) - 128);
this.colors[detailLevel][posX][posZ][1] = (byte) (DataPoint.getGreen(dataPoint) - 128);
this.colors[detailLevel][posX][posZ][2] = (byte) (DataPoint.getBlue(dataPoint) - 128);
this.dataExistence[detailLevel][posX][posZ] = true;
this.height[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = DataPoint.getHeight(dataPoint);
this.depth[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = DataPoint.getDepth(dataPoint);
this.colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][0] = (byte) (DataPoint.getRed(dataPoint) - 128);
this.colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][1] = (byte) (DataPoint.getGreen(dataPoint) - 128);
this.colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][2] = (byte) (DataPoint.getBlue(dataPoint) - 128);
this.dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = true;
return true;
} else
{
@@ -204,7 +203,7 @@ public class LodRegion implements Serializable
return;
} else if (DetailDistanceUtil.getDistanceGenerationInverse(minDistance) == detailLevel)
{
if (!doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ)))
if (!doesDataExist(levelPos))
{
levelPos.changeParameters(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size);
if (dataToGenerate.containsKey(levelPos))
@@ -228,7 +227,7 @@ public class LodRegion implements Serializable
{
levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x, childPosZ + z);
if (!doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ)))
if (!doesDataExist(levelPos))
{
num++;
levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x + regionPosX * childSize, childPosZ + z + regionPosZ * childSize);
@@ -262,7 +261,7 @@ public class LodRegion implements Serializable
{
levelPos.changeParameters(detailLevel, posX, posZ);
levelPos.convert(childDetailLevel);
if (!doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ)))
if (!doesDataExist(levelPos))
{
levelPos.changeParameters(levelPos.detailLevel, levelPos.posX + regionPosX * childSize, levelPos.posZ + regionPosZ * childSize);
if (dataToGenerate.containsKey(levelPos))
@@ -336,7 +335,7 @@ public class LodRegion implements Serializable
for (int z = 0; z <= 1; z++)
{
levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x, childPosZ + z);
if (doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ))) childrenCount++;
if (doesDataExist(levelPos)) childrenCount++;
}
}
@@ -372,36 +371,43 @@ public class LodRegion implements Serializable
/**
* @param levelPos
*/
public void updateArea(int[] levelPos)
public void updateArea(LevelPos levelPos)
{
int width;
levelPos = LevelPosUtil.getRegionModule(levelPos);
int detailLevel = LevelPosUtil.getDetailLevel(levelPos);
int[] bottomLevelPos;
int startX;
int startZ;
byte detailLevel = levelPos.detailLevel;
int posX = levelPos.posX;
int posZ = levelPos.posZ;
for (byte bottom = (byte) (minDetailLevel + 1); bottom <= detailLevel; bottom++)
{
bottomLevelPos = LevelPosUtil.convert(levelPos, bottom);
levelPos.convert(bottom);
startX = levelPos.posX;
startZ = levelPos.posZ;
width = 1 << (detailLevel - bottom);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < width; z++)
{
update(LevelPosUtil.applyOffset(bottomLevelPos, x, z));
levelPos.changeParameters(bottom, startX + x, startZ + z);
update(levelPos);
}
}
levelPos.changeParameters(detailLevel, posX, posZ);
}
for (byte up = (byte) (detailLevel + 1); up <= LodUtil.REGION_DETAIL_LEVEL; up++)
for (byte tempLod = (byte) (detailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++)
{
update(LevelPosUtil.convert(levelPos, up));
levelPos.convert(tempLod);
update(levelPos);
}
}
/**
* @param levelPos
*/
private void update(int[] levelPos)
private void update(LevelPos levelPos)
{
levelPos = LevelPosUtil.getRegionModule(levelPos);
levelPos.performRegionModule();
int numberOfChildren = 0;
int numberOfVoidChildren = 0;
@@ -413,9 +419,9 @@ public class LodRegion implements Serializable
int newPosX;
int newPosZ;
byte newDetailLevel;
int detailLevel = LevelPosUtil.getDetailLevel(levelPos);
int posX = LevelPosUtil.getPosX(levelPos);
int posZ = LevelPosUtil.getPosZ(levelPos);
int detailLevel = levelPos.detailLevel;
int posX = levelPos.posX;
int posZ = levelPos.posZ;
for (int x = 0; x <= 1; x++)
{
for (int z = 0; z <= 1; z++)
@@ -423,7 +429,7 @@ public class LodRegion implements Serializable
newPosX = 2 * posX + x;
newPosZ = 2 * posZ + z;
newDetailLevel = (byte) (detailLevel - 1);
levelPos = LevelPosUtil.createLevelPos(newDetailLevel, newPosX, newPosZ);
levelPos.changeParameters(newDetailLevel, newPosX, newPosZ);
if (doesDataExist(levelPos))
{
if (height[newDetailLevel][newPosX][newPosZ] != LodBuilder.DEFAULT_HEIGHT
@@ -471,12 +477,12 @@ public class LodRegion implements Serializable
* @param levelPos
* @return
*/
public boolean doesDataExist(int[] levelPos)
public boolean doesDataExist(LevelPos levelPos)
{
try
{
levelPos = LevelPosUtil.getRegionModule(levelPos);
return dataExistence[LevelPosUtil.getDetailLevel(levelPos)][LevelPosUtil.getPosX(levelPos)][LevelPosUtil.getPosZ(levelPos)];
levelPos = levelPos.getRegionModuleLevelPos();
return dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ];
} catch (NullPointerException e)
{
return false;
@@ -773,7 +773,7 @@ public class LodRenderer
//=============//
// full regens //
//=============//
// check if the view distance changed
if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get()
|| mc.options.renderDistance != prevRenderDistance
@@ -787,7 +787,13 @@ public class LodRenderer
//vanillaRenderedChunks.stream().filter(pos -> ((Math.abs(pos.x - player.xChunk) > mc.options.renderDistance) || (Math.abs(pos.z - player.zChunk) > mc.options.renderDistance)));
vanillaRenderedChunks.clear();
}
// did the user change the debug setting?
if (LodConfig.CLIENT.debugMode.get() != previousDebugMode)
{
previousDebugMode = LodConfig.CLIENT.debugMode.get();
fullRegen = true;
}
long newTime = System.currentTimeMillis();
@@ -862,14 +868,6 @@ public class LodRenderer
{
vanillaRenderedChunks.clear();
}
// did the user change the debug setting?
if (LodConfig.CLIENT.debugMode.get() != previousDebugMode)
{
previousDebugMode = LodConfig.CLIENT.debugMode.get();
fullRegen = true;
}
}
}
@@ -121,7 +121,7 @@ public class RenderUtil
{
// convert the vbo position into a direction vector
// starting from the player's position
Vector3d vboVec = new Vector3d(vboCenterPos.getX(), 64, vboCenterPos.getZ());
Vector3d vboVec = new Vector3d(vboCenterPos.getX(), 0, vboCenterPos.getZ());
Vector3d playerVec = new Vector3d(playerBlockPos.getX(), playerBlockPos.getY(), playerBlockPos.getZ());
Vector3d vboCenterVec = vboVec.subtract(playerVec);