diff --git a/src/main/java/com/seibel/lod/objects/LevelPos.java b/src/main/java/com/seibel/lod/objects/LevelPos.java index ef5d8fea8..1cb7709ac 100644 --- a/src/main/java/com/seibel/lod/objects/LevelPos.java +++ b/src/main/java/com/seibel/lod/objects/LevelPos.java @@ -45,6 +45,9 @@ public class LevelPos implements Cloneable{ return new LevelPos(detailLevel,posX,posZ); } + + /**TODO add max and min distance to point calculator*/ + public String toString(){ String s = (detailLevel + " " + posX + " " + posZ); return s; diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index c35732b61..9adb5a4a6 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -28,7 +28,11 @@ import net.minecraft.world.server.ServerWorld; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * This object holds all loaded LOD regions @@ -353,27 +357,28 @@ public class LodDimension * method to get all the quadtree level that have to be generated based on the position of the player * @return list of quadTrees */ - public List getDataToGenerate(int x, int z, byte level, DistanceGenerationMode complexity, int maxDistance, int minDistance){ + public List getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel){ int n = regions.length; int xIndex; int zIndex; - LodQuadTree region; - List> listOfQuadTree = new ArrayList<>(); + LodRegion region; + List> listOfData = new ArrayList<>(); for(int xRegion=0; xRegion entry.getKey()).collect(Collectors.toList()); + Collections.sort(listOfData,Map.Entry.comparingByValue()); + return listOfData.stream().map(entry -> entry.getKey()).collect(Collectors.toList()); } @@ -381,12 +386,24 @@ public class LodDimension * method to get all the nodes that have to be rendered based on the position of the player * @return list of nodes */ - public List getNodeToRender(int x, int z, byte level, Set complexityMask, int maxDistance, int minDistance){ + public List getDataToRender(int playerPosX, int playerPosZ, int start, int end, byte detailLevel){ int n = regions.length; - List listOfData = new ArrayList<>(); - for(int i=0; i listOfData = new ArrayList<>(); + int xIndex; + int zIndex; + LodRegion region; + for(int xRegion=0; xRegion getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel) + public List> getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel) { LevelPos levelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, 0, 0); return getDataToGenerate(levelPos, playerPosX, playerPosZ, start, end, generation, detailLevel); } - public List getDataToGenerate(LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel) + public List> getDataToGenerate(LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel) { - List levelPosList = new ArrayList<>(); + List> levelPosList = new ArrayList<>(); int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - levelPos.detailLevel); int width = (int) Math.pow(2, levelPos.detailLevel); //here i calculate the the LevelPos is in range //This is important to avoid any kind of hole in the generation - int posX = regionPosX * 512 + playerPosX * width + width / 2; - int posZ = regionPosZ * 512 + playerPosZ * width + width / 2; + int posX = regionPosX * 512 + levelPos.posX * width + width / 2; + int posZ = regionPosZ * 512 + levelPos.posZ * width + width / 2; int distance = (int) Math.sqrt(Math.pow(playerPosX - posX, 2) + Math.pow(playerPosZ - posZ, 2)); int maxDistance = distance; int minDistance = distance; @@ -230,15 +232,15 @@ public class LodRegion implements Serializable { for (int z = 0; z <= 1; z++) { - posX = regionPosX * 512 + playerPosX * width + width * x; - posZ = regionPosZ * 512 + playerPosZ * width + width * z; + posX = regionPosX * 512 + levelPos.posX * width + width * x; + posZ = regionPosZ * 512 + levelPos.posZ * width + width * z; distance = (int) Math.sqrt(Math.pow(playerPosX - posX, 2) + Math.pow(playerPosZ - posZ, 2)); minDistance = Math.min(minDistance, distance); maxDistance = Math.max(maxDistance, distance); } } - if (minDistance < start || distance > maxDistance || levelPos.detailLevel < detailLevel) + if (!(minDistance >= start && distance <= maxDistance) || levelPos.detailLevel < detailLevel) { return levelPosList; } @@ -251,7 +253,10 @@ public class LodRegion implements Serializable //we have reached the target detail level if (detailLevel == levelPos.detailLevel || generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] < generation) { - levelPosList.add(new LevelPos(levelPos.detailLevel, levelPos.posX + regionPosX * size, levelPos.posZ + regionPosZ * size)); + levelPosList.add( + new AbstractMap.SimpleEntry( + new LevelPos(levelPos.detailLevel, levelPos.posX + regionPosX * size, levelPos.posZ + regionPosZ * size), + maxDistance)); } else { //we want max a request per chunk. So for lod smaller than chunk we explore only the top rigth child @@ -263,9 +268,28 @@ public class LodRegion implements Serializable for (int z = 0; z <= 1; z++) { childPos = new LevelPos((byte) (levelPos.detailLevel - 1), childPosX + x, childPosZ + z); - if (generationType[childPos.detailLevel][childPos.posX][childPos.posZ] < generation) + + /**TODO remove this distance calculator in some way, from here*/ + posX = regionPosX * 512 + childPos.posX * width + width / 2; + posZ = regionPosZ * 512 + childPos.posZ * width + width / 2; + maxDistance = (int) Math.sqrt(Math.pow(playerPosX - posX, 2) + Math.pow(playerPosZ - posZ, 2)); + for (int xi = 0; xi <= 1; xi++) { - levelPosList.add(new LevelPos(childPos.detailLevel, childPos.posX + regionPosX * childSize, childPos.posZ + regionPosZ * childSize)); + for (int zi = 0; zi <= 1; zi++) + { + posX = regionPosX * 512 + childPos.posX * width + width * xi; + posZ = regionPosZ * 512 + childPos.posZ * width + width * zi; + maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - posX, 2) + Math.pow(playerPosZ - posZ, 2))); + } + } + /**to here*/ + + if (generationType[childPos.detailLevel][childPos.posX][childPos.posZ] < generation || !doesDataExist(childPos)) + { + levelPosList.add( + new AbstractMap.SimpleEntry( + new LevelPos(childPos.detailLevel, childPos.posX + regionPosX * childSize, childPos.posZ + regionPosZ * childSize), + maxDistance)); } } } @@ -287,7 +311,25 @@ public class LodRegion implements Serializable childPos = levelPos.convert((byte) (levelPos.detailLevel - 1)); if (generationType[childPos.detailLevel][childPos.posX][childPos.posZ] < generation) { - levelPosList.add(new LevelPos(childPos.detailLevel, childPos.posX + regionPosX * childSize, childPos.posZ + regionPosZ * childSize)); + /**TODO remove this distance calculator in some way, from here*/ + posX = regionPosX * 512 + childPos.posX * width + width / 2; + posZ = regionPosZ * 512 + childPos.posZ * width + width / 2; + maxDistance = (int) Math.sqrt(Math.pow(playerPosX - posX, 2) + Math.pow(playerPosZ - posZ, 2)); + for (int x = 0; x <= 1; x++) + { + for (int z = 0; z <= 1; z++) + { + posX = regionPosX * 512 + childPos.posX * width + width * x; + posZ = regionPosZ * 512 + childPos.posZ * width + width * z; + maxDistance = Math.max(maxDistance, (int) Math.sqrt(Math.pow(playerPosX - posX, 2) + Math.pow(playerPosZ - posZ, 2))); + } + } + /**to here*/ + + levelPosList.add( + new AbstractMap.SimpleEntry( + new LevelPos(childPos.detailLevel, childPos.posX + regionPosX * childSize, childPos.posZ + regionPosZ * childSize), + maxDistance)); } else { if (childPos.detailLevel != detailLevel)