Added LevelPosUtil, now the node are added using it and not with the LevelPos object
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
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,6 +23,7 @@ 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;
|
||||
|
||||
@@ -284,6 +285,27 @@ 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>
|
||||
@@ -439,12 +461,13 @@ public class LodDimension
|
||||
* stored in the LOD. If an LOD already exists at the given
|
||||
* coordinates it will be overwritten.
|
||||
*/
|
||||
public synchronized Boolean addData(LevelPos levelPos, short[] lodDataPoint, boolean dontSave, boolean serverQuality)
|
||||
public synchronized Boolean addData(int[] levelPos, short[] lodDataPoint, boolean dontSave, boolean serverQuality)
|
||||
{
|
||||
|
||||
// don't continue if the region can't be saved
|
||||
RegionPos regionPos = levelPos.getRegionPos();
|
||||
if (!regionIsInRange(regionPos.x, regionPos.z))
|
||||
int xRegion = LevelPosUtil.getRegionPosX(levelPos);
|
||||
int zRegion = LevelPosUtil.getRegionPosZ(levelPos);
|
||||
if (!regionIsInRange(xRegion, zRegion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -458,8 +481,8 @@ public class LodDimension
|
||||
try
|
||||
{
|
||||
// mark the region as dirty so it will be saved to disk
|
||||
int xIndex = (regionPos.x - center.x) + halfWidth;
|
||||
int zIndex = (regionPos.z - center.z) + halfWidth;
|
||||
int xIndex = (xRegion - center.x) + halfWidth;
|
||||
int zIndex = (zRegion - center.z) + halfWidth;
|
||||
isRegionDirty[xIndex][zIndex] = true;
|
||||
regen[xIndex][zIndex] = true;
|
||||
regenDimension = true;
|
||||
@@ -582,10 +605,10 @@ public class LodDimension
|
||||
* Returns null if the LodChunk doesn't exist or
|
||||
* is outside the loaded area.
|
||||
*/
|
||||
public void updateData(LevelPos levelPos)
|
||||
public void updateData(int[] levelPos)
|
||||
{
|
||||
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.");
|
||||
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.");
|
||||
|
||||
LodRegion region = getRegion(levelPos);
|
||||
|
||||
@@ -611,7 +634,7 @@ public class LodDimension
|
||||
return false;
|
||||
}
|
||||
|
||||
return region.doesDataExist(levelPos.clone());
|
||||
return region.doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel,levelPos.posX,levelPos.posZ));
|
||||
} catch (Exception e)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -77,7 +77,6 @@ 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);
|
||||
@@ -85,8 +84,7 @@ public class LodRegion implements Serializable
|
||||
{
|
||||
for (int z = 0; z < width; z++)
|
||||
{
|
||||
levelPos.changeParameters(tempLod, x, z);
|
||||
update(levelPos);
|
||||
update(LevelPosUtil.createLevelPos(tempLod, x, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,22 +125,25 @@ public class LodRegion implements Serializable
|
||||
* @param dataPoint
|
||||
* @return
|
||||
*/
|
||||
public boolean addData(LevelPos levelPos, short[] dataPoint, boolean serverQuality)
|
||||
public boolean addData(int[] levelPos, short[] dataPoint, boolean serverQuality)
|
||||
{
|
||||
levelPos.performRegionModule();
|
||||
levelPos = LevelPosUtil.getRegionModule(levelPos);
|
||||
byte detailLevel = LevelPosUtil.getDetailLevel(levelPos);
|
||||
int posX = LevelPosUtil.getPosX(levelPos);
|
||||
int posZ = LevelPosUtil.getPosZ(levelPos);
|
||||
if (!doesDataExist(levelPos) || serverQuality)
|
||||
{
|
||||
|
||||
//update the number of node present
|
||||
if (this.dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ]) numberOfPoints++;
|
||||
if (this.dataExistence[detailLevel][posX][posZ]) numberOfPoints++;
|
||||
|
||||
//add the node data
|
||||
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;
|
||||
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;
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
@@ -203,7 +204,7 @@ public class LodRegion implements Serializable
|
||||
return;
|
||||
} else if (DetailDistanceUtil.getDistanceGenerationInverse(minDistance) == detailLevel)
|
||||
{
|
||||
if (!doesDataExist(levelPos))
|
||||
if (!doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ)))
|
||||
{
|
||||
levelPos.changeParameters(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size);
|
||||
if (dataToGenerate.containsKey(levelPos))
|
||||
@@ -227,7 +228,7 @@ public class LodRegion implements Serializable
|
||||
{
|
||||
levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x, childPosZ + z);
|
||||
|
||||
if (!doesDataExist(levelPos))
|
||||
if (!doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ)))
|
||||
{
|
||||
num++;
|
||||
levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x + regionPosX * childSize, childPosZ + z + regionPosZ * childSize);
|
||||
@@ -261,7 +262,7 @@ public class LodRegion implements Serializable
|
||||
{
|
||||
levelPos.changeParameters(detailLevel, posX, posZ);
|
||||
levelPos.convert(childDetailLevel);
|
||||
if (!doesDataExist(levelPos))
|
||||
if (!doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ)))
|
||||
{
|
||||
levelPos.changeParameters(levelPos.detailLevel, levelPos.posX + regionPosX * childSize, levelPos.posZ + regionPosZ * childSize);
|
||||
if (dataToGenerate.containsKey(levelPos))
|
||||
@@ -335,7 +336,7 @@ public class LodRegion implements Serializable
|
||||
for (int z = 0; z <= 1; z++)
|
||||
{
|
||||
levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x, childPosZ + z);
|
||||
if (doesDataExist(levelPos)) childrenCount++;
|
||||
if (doesDataExist(LevelPosUtil.createLevelPos(levelPos.detailLevel, levelPos.posX, levelPos.posZ))) childrenCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,43 +372,36 @@ public class LodRegion implements Serializable
|
||||
/**
|
||||
* @param levelPos
|
||||
*/
|
||||
public void updateArea(LevelPos levelPos)
|
||||
public void updateArea(int[] levelPos)
|
||||
{
|
||||
int width;
|
||||
int startX;
|
||||
int startZ;
|
||||
byte detailLevel = levelPos.detailLevel;
|
||||
int posX = levelPos.posX;
|
||||
int posZ = levelPos.posZ;
|
||||
levelPos = LevelPosUtil.getRegionModule(levelPos);
|
||||
int detailLevel = LevelPosUtil.getDetailLevel(levelPos);
|
||||
int[] bottomLevelPos;
|
||||
for (byte bottom = (byte) (minDetailLevel + 1); bottom <= detailLevel; bottom++)
|
||||
{
|
||||
levelPos.convert(bottom);
|
||||
startX = levelPos.posX;
|
||||
startZ = levelPos.posZ;
|
||||
bottomLevelPos = LevelPosUtil.convert(levelPos, bottom);
|
||||
width = 1 << (detailLevel - bottom);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int z = 0; z < width; z++)
|
||||
{
|
||||
levelPos.changeParameters(bottom, startX + x, startZ + z);
|
||||
update(levelPos);
|
||||
update(LevelPosUtil.applyOffset(bottomLevelPos, x, z));
|
||||
}
|
||||
}
|
||||
levelPos.changeParameters(detailLevel, posX, posZ);
|
||||
}
|
||||
for (byte tempLod = (byte) (detailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++)
|
||||
for (byte up = (byte) (detailLevel + 1); up <= LodUtil.REGION_DETAIL_LEVEL; up++)
|
||||
{
|
||||
levelPos.convert(tempLod);
|
||||
update(levelPos);
|
||||
update(LevelPosUtil.convert(levelPos, up));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param levelPos
|
||||
*/
|
||||
private void update(LevelPos levelPos)
|
||||
private void update(int[] levelPos)
|
||||
{
|
||||
levelPos.performRegionModule();
|
||||
levelPos = LevelPosUtil.getRegionModule(levelPos);
|
||||
int numberOfChildren = 0;
|
||||
int numberOfVoidChildren = 0;
|
||||
|
||||
@@ -419,9 +413,9 @@ public class LodRegion implements Serializable
|
||||
int newPosX;
|
||||
int newPosZ;
|
||||
byte newDetailLevel;
|
||||
int detailLevel = levelPos.detailLevel;
|
||||
int posX = levelPos.posX;
|
||||
int posZ = levelPos.posZ;
|
||||
int detailLevel = LevelPosUtil.getDetailLevel(levelPos);
|
||||
int posX = LevelPosUtil.getPosX(levelPos);
|
||||
int posZ = LevelPosUtil.getPosZ(levelPos);
|
||||
for (int x = 0; x <= 1; x++)
|
||||
{
|
||||
for (int z = 0; z <= 1; z++)
|
||||
@@ -429,7 +423,7 @@ public class LodRegion implements Serializable
|
||||
newPosX = 2 * posX + x;
|
||||
newPosZ = 2 * posZ + z;
|
||||
newDetailLevel = (byte) (detailLevel - 1);
|
||||
levelPos.changeParameters(newDetailLevel, newPosX, newPosZ);
|
||||
levelPos = LevelPosUtil.createLevelPos(newDetailLevel, newPosX, newPosZ);
|
||||
if (doesDataExist(levelPos))
|
||||
{
|
||||
if (height[newDetailLevel][newPosX][newPosZ] != LodBuilder.DEFAULT_HEIGHT
|
||||
@@ -477,12 +471,12 @@ public class LodRegion implements Serializable
|
||||
* @param levelPos
|
||||
* @return
|
||||
*/
|
||||
public boolean doesDataExist(LevelPos levelPos)
|
||||
public boolean doesDataExist(int[] levelPos)
|
||||
{
|
||||
try
|
||||
{
|
||||
levelPos = levelPos.getRegionModuleLevelPos();
|
||||
return dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ];
|
||||
levelPos = LevelPosUtil.getRegionModule(levelPos);
|
||||
return dataExistence[LevelPosUtil.getDetailLevel(levelPos)][LevelPosUtil.getPosX(levelPos)][LevelPosUtil.getPosZ(levelPos)];
|
||||
} catch (NullPointerException e)
|
||||
{
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user