From 3420133bd3ca2412a135548519ffcb27ea163217 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 3 Sep 2021 19:34:04 +0200 Subject: [PATCH] Added LevelPosUtil, PosToGenerateContainer and PosToRenderContainer to be used in the future --- .../com/seibel/lod/objects/LevelPosUtil.java | 226 ++++++++++++++++++ .../lod/objects/PosToGenerateContainer.java | 101 ++++++++ .../lod/objects/PosToRenderContainer.java | 31 +++ 3 files changed, 358 insertions(+) create mode 100644 src/main/java/com/seibel/lod/objects/LevelPosUtil.java create mode 100644 src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java create mode 100644 src/main/java/com/seibel/lod/objects/PosToRenderContainer.java diff --git a/src/main/java/com/seibel/lod/objects/LevelPosUtil.java b/src/main/java/com/seibel/lod/objects/LevelPosUtil.java new file mode 100644 index 000000000..41ff5531a --- /dev/null +++ b/src/main/java/com/seibel/lod/objects/LevelPosUtil.java @@ -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)); + } +} diff --git a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java new file mode 100644 index 000000000..3ba3cc2d7 --- /dev/null +++ b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java @@ -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; + } + } + +} diff --git a/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java new file mode 100644 index 000000000..7e239ff6a --- /dev/null +++ b/src/main/java/com/seibel/lod/objects/PosToRenderContainer.java @@ -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) + ;*/ + } +}