diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java index c5ca2f81d..7365ef00c 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -125,7 +125,7 @@ public class LodWorldGenerator for (int index = 0; index < posToGenerate.getNumberOfPos(); index++) { - if (posToGenerate.getNthDetail(near, true) != 0 && far < posToGenerate.getNumberOfNearPos()) + if (posToGenerate.getNthDetail(near, true) != 0 && near < posToGenerate.getNumberOfNearPos()) { detailLevel = (byte) (posToGenerate.getNthDetail(near, true) - 1); posX = posToGenerate.getNthPosX(near, true); diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 3dc6c2ddd..bf6c81080 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -531,9 +531,20 @@ public class LodDimension int posX; int posZ; long data; - int numbChunksWide = (width) * 32 * 2; + int numbChunksWide = (width) * 32 ; + int circleLimit = Integer.MAX_VALUE; for (int i = 0; i < numbChunksWide * numbChunksWide; i++) { + // use this for square generation + + // use this for circular generation + if (circleLimit < Math.abs(x) && circleLimit < Math.abs(z)) + break; + if (maxDataToGenerate == 0) + { + circleLimit = (int) (Math.abs(x) * 1.41f); + } + xChunkToCheck = x + playerChunkX; zChunkToCheck = z + playerChunkZ; //distance = LevelPosUtil.maxDistance(LodUtil.CHUNK_DETAIL_LEVEL, xChunkToCheck, zChunkToCheck, playerChunkX, playerChunkZ); @@ -548,8 +559,8 @@ public class LodDimension if (DataPointUtil.getGenerationMode(data) < LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get().complexity) { posToGenerate.addPosToGenerate(detailLevel, posX, posZ); - //if (maxDataToGenerate >= 0) - // maxDataToGenerate--; + if (maxDataToGenerate >= 0) + maxDataToGenerate--; } if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) { diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index 426d388af..dd8ea26df 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -2,6 +2,7 @@ package com.seibel.lod.objects; import com.seibel.lod.config.LodConfig; +import com.seibel.lod.enums.DetailDropOff; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.LodTemplate; import com.seibel.lod.enums.VerticalQuality; @@ -231,12 +232,17 @@ public class LodRegion //This is important to avoid any kind of hole in the rendering byte supposedLevel; int maxDistance; + boolean stopNow = false; switch (LodConfig.CLIENT.graphics.detailDropOff.get()) { default: case BY_BLOCK: maxDistance = LevelPosUtil.maxDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); supposedLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(maxDistance)); + int minDistance = LevelPosUtil.minDistance(detailLevel, posX, posZ, playerPosX, playerPosZ, regionPosX, regionPosZ); + int childLevel = DetailDistanceUtil.getLodDrawDetail(DetailDistanceUtil.getDrawDetailFromDistance(minDistance)); + stopNow = detailLevel == childLevel - 1; + break; case BY_REGION_FANCY: supposedLevel = minDetailLevel; @@ -254,8 +260,15 @@ public class LodRegion break; } - if (supposedLevel > detailLevel) + if(stopNow){ + posToRender.addPosToRender(detailLevel, + posX + regionPosX * size, + posZ + regionPosZ * size); + } + else if (supposedLevel > detailLevel) + { return; + } else if (supposedLevel == detailLevel) { posToRender.addPosToRender(detailLevel, diff --git a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java index ecd51449f..fd0c530cc 100644 --- a/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java +++ b/src/main/java/com/seibel/lod/objects/PosToGenerateContainer.java @@ -12,19 +12,22 @@ public class PosToGenerateContainer private int maxFarSize; private int nearSize; private int farSize; - private int[][] posToGenerate; + private int[][] nearPosToGenerate; + private int[][] farPosToGenerate; + public PosToGenerateContainer(byte farMinDetail, int maxDataToGenerate, int maxFarDataToGenerate, int playerPosX, int playerPosZ) { this.playerPosX = playerPosX; this.playerPosZ = playerPosZ; this.farMinDetail = farMinDetail; - maxNearSize = maxDataToGenerate; + maxNearSize = maxDataToGenerate-maxFarDataToGenerate; maxFarSize = maxFarDataToGenerate; maxSize = maxDataToGenerate; nearSize = 0; farSize = 0; - posToGenerate = new int[maxDataToGenerate][4]; + nearPosToGenerate = new int[maxDataToGenerate][4]; + farPosToGenerate = new int[maxDataToGenerate][4]; } public void addPosToGenerate(byte detailLevel, int posX, int posZ) @@ -33,52 +36,45 @@ public class PosToGenerateContainer int index; if (detailLevel >= farMinDetail) {//We are introducing a position in the far array - if (farSize < maxFarSize) - { + + if(farSize < farPosToGenerate.length) farSize++; - if (nearSize == maxNearSize) - { - nearSize--; - } - maxNearSize--; - } - index = posToGenerate.length - farSize; - while (index < posToGenerate.length - 1 && LevelPosUtil.compareDistance(distance, posToGenerate[index + 1][3]) <= 0) - //while (index < posToGenerate.length - 1 && LevelPosUtil.compareLevelAndDistance(detailLevel, distance, (byte) (posToGenerate[index + 1][0] - 1), posToGenerate[index + 1][3]) <= 0) + index = farSize; + //while (index > 0 && LevelPosUtil.compareDistance(distance, farPosToGenerate[index - 1][3]) <= 0) + while (index > 0 && LevelPosUtil.compareDistance(distance, farPosToGenerate[index - 1][3]) <= 0) { - posToGenerate[index][0] = posToGenerate[index + 1][0]; - posToGenerate[index][1] = posToGenerate[index + 1][1]; - posToGenerate[index][2] = posToGenerate[index + 1][2]; - posToGenerate[index][3] = posToGenerate[index + 1][3]; - index++; + farPosToGenerate[index][0] = farPosToGenerate[index - 1][0]; + farPosToGenerate[index][1] = farPosToGenerate[index - 1][1]; + farPosToGenerate[index][2] = farPosToGenerate[index - 1][2]; + farPosToGenerate[index][3] = farPosToGenerate[index - 1][3]; + index--; } - if (index <= posToGenerate.length - 1) + if (index != farSize-1 || farSize != farPosToGenerate.length) { - posToGenerate[index][0] = detailLevel + 1; - posToGenerate[index][1] = posX; - posToGenerate[index][2] = posZ; - posToGenerate[index][3] = distance; + farPosToGenerate[index][0] = detailLevel + 1; + farPosToGenerate[index][1] = posX; + farPosToGenerate[index][2] = posZ; + farPosToGenerate[index][3] = distance; } } else {//We are introducing a position in the near array - if (nearSize < maxNearSize) + if(nearSize < nearPosToGenerate.length) nearSize++; - index = nearSize - 1; - - while (index > 0 && LevelPosUtil.compareDistance(distance, posToGenerate[index - 1][3]) <= 0) + index = nearSize-1; + while (index > 0 && LevelPosUtil.compareDistance(distance, nearPosToGenerate[index - 1][3]) <= 0) { - posToGenerate[index][0] = posToGenerate[index - 1][0]; - posToGenerate[index][1] = posToGenerate[index - 1][1]; - posToGenerate[index][2] = posToGenerate[index - 1][2]; - posToGenerate[index][3] = posToGenerate[index - 1][3]; + nearPosToGenerate[index][0] = nearPosToGenerate[index - 1][0]; + nearPosToGenerate[index][1] = nearPosToGenerate[index - 1][1]; + nearPosToGenerate[index][2] = nearPosToGenerate[index - 1][2]; + nearPosToGenerate[index][3] = nearPosToGenerate[index - 1][3]; index--; } - if (index >= 0) + if (index != nearSize-1 || nearSize != nearPosToGenerate.length) { - posToGenerate[index][0] = detailLevel + 1; - posToGenerate[index][1] = posX; - posToGenerate[index][2] = posZ; - posToGenerate[index][3] = distance; + nearPosToGenerate[index][0] = detailLevel + 1; + nearPosToGenerate[index][1] = posX; + nearPosToGenerate[index][2] = posZ; + nearPosToGenerate[index][3] = distance; } } } @@ -101,34 +97,34 @@ public class PosToGenerateContainer public int getNthDetail(int n, boolean near) { if (near) - return posToGenerate[n][0]; + return nearPosToGenerate[n][0]; else - return posToGenerate[maxSize-1-n][0]; + return farPosToGenerate[n][0]; } public int getNthPosX(int n, boolean near) { if (near) - return posToGenerate[n][1]; + return nearPosToGenerate[n][1]; else - return posToGenerate[maxSize-1-n][1]; + return farPosToGenerate[n][1]; } public int getNthPosZ(int n, boolean near) { if (near) - return posToGenerate[n][2]; + return nearPosToGenerate[n][2]; else - return posToGenerate[maxSize-1-n][2]; + return farPosToGenerate[n][2]; } public int getNthGeneration(int n, boolean near) { if (near) - return posToGenerate[n][3]; + return nearPosToGenerate[n][3]; else - return posToGenerate[maxSize-1-n][3]; + return farPosToGenerate[n][3]; } public String toString() - { + {/* StringBuilder builder = new StringBuilder(); builder.append("Number of pos to generate "); builder.append(farSize + nearSize); @@ -168,6 +164,7 @@ public class PosToGenerateContainer builder.append('\n'); } builder.append('\n'); - return builder.toString(); + return builder.toString();*/ + return " "; } } diff --git a/src/main/java/com/seibel/lod/util/LevelPosUtil.java b/src/main/java/com/seibel/lod/util/LevelPosUtil.java index 8b6104726..e8e7c059d 100644 --- a/src/main/java/com/seibel/lod/util/LevelPosUtil.java +++ b/src/main/java/com/seibel/lod/util/LevelPosUtil.java @@ -123,22 +123,6 @@ public class LevelPosUtil return convert(detailLevel,pos, LodUtil.CHUNK_DETAIL_LEVEL); } - 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) { @@ -175,11 +159,6 @@ public class LevelPosUtil } - 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; @@ -216,6 +195,42 @@ public class LevelPosUtil } } + public static int minDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ, int xRegion, int zRegion) + { + int width = 1 << detailLevel; + + int startPosX = xRegion * 512 + posX * width; + int startPosZ = zRegion * 512 + 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 firstDistance, int secondDistance) { return Integer.compare(