Added LevelPosUtil, PosToGenerateContainer and PosToRenderContainer to be used in the future

This commit is contained in:
Leonardo
2021-09-03 19:34:04 +02:00
parent c79bf7c3f7
commit 3420133bd3
3 changed files with 358 additions and 0 deletions
@@ -0,0 +1,226 @@
package com.seibel.lod.objects;
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 int[] createLevelPos(byte detailLevel, int posX, int posZ, int distance)
{
return new int[]{detailLevel, posX, posZ, distance};
}
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 getDistance(int[] levelPos)
{
return levelPos[3];
}
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 int getChunkPosX(int[] levelPos)
{
levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL);
return getPosX(levelPos);
}
public static int getChunkPosZ(int[] levelPos)
{
levelPos = convert(levelPos, LodUtil.CHUNK_DETAIL_LEVEL);
return getPosZ(levelPos);
}
public static int maxDistance(int[] levelPos, int playerPosX, int playerPosZ)
{
return maxDistance(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), playerPosX, playerPosZ);
}
public static int 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 = 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)
{
return minDistance(getDetailLevel(levelPos), getPosX(levelPos), getPosZ(levelPos), playerPosX, playerPosZ);
}
public static int minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ)
{
int width = 1 << detailLevel;
int startPosX = posX * width;
int startPosZ = posZ * 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 compareDistance(int[] first, int[] second)
{
return Integer.compare(
getDistance(first),
getDistance(second));
}
public static int compareLevelAndDistance(int[] first, int[] second)
{
int compareResult = Integer.compare(getDetailLevel(second), getDetailLevel(first));
if (compareResult == 0)
{
compareResult = Integer.compare(
getDistance(first),
getDistance(second));
}
return compareResult;
}
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));
}
}
@@ -0,0 +1,101 @@
package com.seibel.lod.objects;
public class PosToGenerateContainer
{
public int playerPosX;
public int playerPosZ;
public byte farMinDetail;
public int maxSize;
public int maxNearSize;
public int maxFarSize;
public int nearSize;
public int farSize;
public int[][] posToGenerate;
public PosToGenerateContainer(byte farMinDetail, int maxDataToGenerate, int maxFarDataToGenerate, int playerPosX, int playerPosZ)
{
this.playerPosX = playerPosX;
this.playerPosZ = playerPosZ;
this.farMinDetail = farMinDetail;
maxNearSize = maxDataToGenerate;
maxFarSize = maxFarDataToGenerate;
maxSize = maxDataToGenerate;
nearSize = 0;
farSize = 0;
posToGenerate = new int[maxDataToGenerate][4];
}
public void addPosToGenerate(int[] levelPos)
{
addPosToGenerate(LevelPosUtil.getDetailLevel(levelPos), LevelPosUtil.getPosX(levelPos), LevelPosUtil.getPosZ(levelPos));
}
public void addPosToGenerate(byte detailLevel, int posX, int posZ)
{
int distance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ);
int index;
int[] tempPos = new int[]{
detailLevel,
posX,
posZ,
distance};
if (detailLevel >= farMinDetail)
{//We are introducing a position in the far array
if (farSize < maxFarSize)
{
farSize++;
if (nearSize == maxNearSize)
{
nearSize--;
}
maxNearSize--;
index = posToGenerate.length - farSize - 1;
if(farSize == 1)
posToGenerate[index] = tempPos;
} else //farSize == maxFarSize, the far section is full
{
index = posToGenerate.length - farSize;
//The max far pos is smaller than the one we want to insert
if (LevelPosUtil.compareLevelAndDistance(tempPos, posToGenerate[index]) >= 0)
{
index = posToGenerate.length;
}
}
while(index < posToGenerate.length - 1 && LevelPosUtil.compareLevelAndDistance(tempPos, posToGenerate[index + 1]) <= 0)
{
posToGenerate[index] = posToGenerate[index + 1];
index++;
}
if(index <= posToGenerate.length - 1)
posToGenerate[index] = tempPos;
} else
{//We are introducing a position in the near array
if (nearSize < maxNearSize)
{
nearSize++;
index = nearSize - 1;
} else //nearSize == maxNearSize, the far section is full
{
//The max near pos is smaller than the one we want to insert
//We remove the max
index = nearSize - 1;
if (LevelPosUtil.compareDistance(tempPos, posToGenerate[index]) >= 0)
{
index = -1;
}
}
while(index > 0 && LevelPosUtil.compareDistance(tempPos, posToGenerate[index - 1]) <= 0)
{
posToGenerate[index] = posToGenerate[index - 1];
index--;
}
if(index >= 0)
posToGenerate[index] = tempPos;
}
}
}
@@ -0,0 +1,31 @@
package com.seibel.lod.objects;
public class PosToRenderContainer
{
public int playerPosX;
public int playerPosZ;
public int numberOfPosToRender;
public int[][] posToRender;
public boolean[][] posToRenderAdjacency;
public PosToRenderContainer(byte minDetail)
{
this.playerPosX = playerPosX;
this.playerPosZ = playerPosZ;
this.numberOfPosToRender = 0;
posToRender = new int[1][4];
posToRenderAdjacency = new boolean[minDetail][minDetail];
}
public void addPosToRender(int[] levelPos)
{
addPosToRender(LevelPosUtil.getDetailLevel(levelPos), LevelPosUtil.getPosX(levelPos), LevelPosUtil.getPosZ(levelPos));
}
public void addPosToRender(byte detailLevel, int posX, int posZ)
{
/*
if(numberOfPosToRender >= posToRender.length)
;*/
}
}