From d8bd4e2347d61793ee5470ca870d69a0e839c34c Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 28 Aug 2021 10:38:44 +0200 Subject: [PATCH] Fixed a small loading bug, made the getDataToGenerate fully automatic, added an option to update the DetailDistanceUtil values --- .../worldGeneration/LodWorldGenerator.java | 102 ++++++++---------- .../com/seibel/lod/handlers/LodConfig.java | 2 +- .../com/seibel/lod/objects/LodDimension.java | 15 +-- .../com/seibel/lod/objects/LodRegion.java | 30 +++--- .../com/seibel/lod/proxy/ClientProxy.java | 5 +- .../seibel/lod/util/DetailDistanceUtil.java | 20 +++- 6 files changed, 84 insertions(+), 90 deletions(-) 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 a7f523b23..eb42a0194 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodWorldGenerator.java @@ -104,9 +104,6 @@ public class LodWorldGenerator // generation int minChunkDist = Integer.MAX_VALUE; - List levelPosListToGen; - List generationRequestList = new ArrayList<>(); - ArrayList chunksToGen = new ArrayList<>(maxChunkGenRequests); // if we don't have a full number of chunks to generate in chunksToGen // we can top it off from this reserve @@ -116,72 +113,67 @@ public class LodWorldGenerator int requesting = maxChunkGenRequests; - /** TODO can give a totally different generation */ - /* - * for (byte detail = LodUtil.BLOCK_DETAIL_LEVEL; detail <= - * LodUtil.REGION_DETAIL_LEVEL; detail++) { if (!posListToGenerate.isEmpty()) - * break; for (byte detailGen = LodUtil.BLOCK_DETAIL_LEVEL; detailGen <= - * LodUtil.REGION_DETAIL_LEVEL; detailGen++) { if (!posListToGenerate.isEmpty()) - * break; posListToGenerate.addAll(lodDim.getDataToGenerate( - * playerBlockPosRounded.getX(), playerBlockPosRounded.getZ(), (int) - * (distancesLinear[detailGen]*1.5), (int) (distancesLinear[detailGen+1]*1.5), - * (byte) distancesGenerators[detailGen].complexity, detail, 16)); - * System.out.println("HERE"); } } - */ - - //=======================================// // create the generation Request objects // //=======================================// + List farLevelPosListToGen; + List nearLevelPosListToGen; + List generationRequestList = new ArrayList<>(); + // start by generating half-region sized blocks... int farRequesting = maxChunkGenRequests / 4; - + byte maxDetailFar = (byte) 8; //we firstly make sure that the world is filled with half region wide block - for (byte detailGen = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++) - { - if (farRequesting <= 0) - { - break; - } - levelPosListToGen = lodDim.getDataToGenerate( - playerBlockPosRounded.getX(), - playerBlockPosRounded.getZ(), - DetailDistanceUtil.getDistanceGeneration(detailGen), - DetailDistanceUtil.getDistanceGeneration(detailGen + 1), - DetailDistanceUtil.getDistanceGenerationMode(detailGen).complexity, - (byte) 8, - farRequesting); - for (LevelPos levelPos : levelPosListToGen) - { - generationRequestList.add(new GenerationRequest(levelPos, DetailDistanceUtil.getDistanceGenerationMode(detailGen), DetailDistanceUtil.getLodDetail(detailGen))); - } - farRequesting = farRequesting - levelPosListToGen.size(); + farLevelPosListToGen = lodDim.getDataToGenerate( + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ(), + DetailDistanceUtil.getDistanceGenerationMode(maxDetailFar).complexity, + maxDetailFar, + farRequesting); + farRequesting = farRequesting - farLevelPosListToGen.size(); - } - - // ...then once the world is filled with half-region sized blocks + // ...then once the world is filled with big sized blocks // fill in the rest - int t = generationRequestList.size(); int nearRequesting = maxChunkGenRequests - maxChunkGenRequests / 4 + farRequesting; //we then fill the world with the rest of the block - for (byte detailGen = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++) - { - if (nearRequesting <= 0) break; - levelPosListToGen = lodDim.getDataToGenerate( - playerBlockPosRounded.getX(), - playerBlockPosRounded.getZ(), - DetailDistanceUtil.getDistanceGeneration(detailGen), - DetailDistanceUtil.getDistanceGeneration(detailGen + 1), - DetailDistanceUtil.getDistanceGenerationMode(detailGen).complexity, - DetailDistanceUtil.getLodDetail(detailGen).detailLevel, - nearRequesting); - for (LevelPos levelPos : levelPosListToGen) + + nearLevelPosListToGen = lodDim.getDataToGenerate( + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ(), + DetailDistanceUtil.getDistanceGenerationMode(0).complexity, + DetailDistanceUtil.getLodDetail(0).detailLevel, + nearRequesting); + + byte minDetail; + int maxDistance; + byte circle; + LevelPos levelPos; + //We alternate the generation between fast and near to make everything more smooth + while(!nearLevelPosListToGen.isEmpty() && !farLevelPosListToGen.isEmpty()){ + if(!farLevelPosListToGen.isEmpty()) { - generationRequestList.add(new GenerationRequest(levelPos, DetailDistanceUtil.getDistanceGenerationMode(detailGen), DetailDistanceUtil.getLodDetail(detailGen))); + levelPos = farLevelPosListToGen.get(0); + farLevelPosListToGen.remove(0); + minDetail = maxDetailFar; + maxDistance = levelPos.maxDistance( + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ()); + circle = DetailDistanceUtil.getDistanceGenerationInverse(maxDistance, minDetail); + generationRequestList.add(new GenerationRequest(levelPos, DetailDistanceUtil.getDistanceGenerationMode(circle), DetailDistanceUtil.getLodDetail(circle))); + } + if(!nearLevelPosListToGen.isEmpty()) + { + levelPos = nearLevelPosListToGen.get(0); + nearLevelPosListToGen.remove(0); + minDetail = (byte) 0; + maxDistance = levelPos.maxDistance( + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ()); + circle = DetailDistanceUtil.getDistanceGenerationInverse(maxDistance, minDetail); + generationRequestList.add(new GenerationRequest(levelPos, DetailDistanceUtil.getDistanceGenerationMode(circle), DetailDistanceUtil.getLodDetail(circle))); } - nearRequesting = nearRequesting - levelPosListToGen.size(); } diff --git a/src/main/java/com/seibel/lod/handlers/LodConfig.java b/src/main/java/com/seibel/lod/handlers/LodConfig.java index 6f5c151f0..603457a2d 100644 --- a/src/main/java/com/seibel/lod/handlers/LodConfig.java +++ b/src/main/java/com/seibel/lod/handlers/LodConfig.java @@ -173,7 +173,7 @@ public class LodConfig lodChunkRenderDistance = builder .comment("\n\n" + " This is the render distance of the mod \n") - .defineInRange("lodChunkRenderDistane", 128, 32, 256); + .defineInRange("lodChunkRenderDistane", 128, 32, 512); distanceGenerationMode = builder .comment("\n\n" diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 67b3f4dff..b5fb858c4 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -476,7 +476,7 @@ public class LodDimension * * @return list of quadTrees */ - public List getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel, int dataNumber) + public List getDataToGenerate(int playerPosX, int playerPosZ, byte generation, byte detailLevel, int dataNumber) { int n = regions.length; @@ -484,7 +484,6 @@ public class LodDimension int zIndex; LodRegion region; RegionPos regionPos; - LevelPos regionLevelPos = new LevelPos(); List listOfData = new ArrayList<>(); for (int xRegion = 0; xRegion < n; xRegion++) { @@ -495,13 +494,9 @@ public class LodDimension xIndex = (xRegion + center.x) - halfWidth; zIndex = (zRegion + center.z) - halfWidth; regionPos = new RegionPos(xIndex, zIndex); - regionLevelPos.changeParameters(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z); - if (end >= regionLevelPos.minDistance(playerPosX, playerPosZ) && - start <= regionLevelPos.maxDistance(playerPosX, playerPosZ)) - { - region = getRegion(regionPos); - listOfData.addAll(region.getDataToGenerate(playerPosX, playerPosZ, start, end, generation, detailLevel, dataNumber)); - } + region = getRegion(regionPos); + listOfData.addAll(region.getDataToGenerate(playerPosX, playerPosZ, generation, detailLevel, dataNumber)); + } catch (Exception e) { //e.printStackTrace(); @@ -526,7 +521,7 @@ public class LodDimension * * @return list of nodes */ - public void getDataToRender(Set dataToRender, RegionPos regionPos, int playerPosX, int playerPosZ) + public void getDataToRender(Set dataToRender, RegionPos regionPos, int playerPosX, int playerPosZ) { LevelPos regionLevelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z); try diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index b64342728..5233ec10a 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -197,11 +197,11 @@ public class LodRegion implements Serializable * * @return */ - public List getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel, int dataNumber) + public List getDataToGenerate(int playerPosX, int playerPosZ, byte generation, byte detailLevel, int dataNumber) { LevelPos levelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, 0, 0); List levelPosList = new ArrayList<>(); - getDataToGenerate(levelPosList, levelPos, playerPosX, playerPosZ, start, end, generation, detailLevel); + getDataToGenerate(levelPosList, levelPos, playerPosX, playerPosZ, generation, detailLevel); List levelMinPosList = new ArrayList<>(); dataNumber = Math.min(dataNumber, levelPosList.size()); @@ -217,30 +217,29 @@ public class LodRegion implements Serializable } - private void getDataToGenerate(List levelPosList, LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte generation, byte targetDetailLevel) + private void getDataToGenerate(List levelPosList, LevelPos levelPos, int playerPosX, int playerPosZ, byte generation, byte targetDetailLevel) { int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - levelPos.detailLevel); //here i calculate the the LevelPos is in range //This is important to avoid any kind of hole in the generation int maxDistance = levelPos.maxDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); - int minDistance = levelPos.minDistance(playerPosX, playerPosZ, regionPosX, regionPosZ); - if (!(start <= maxDistance && minDistance < end) || levelPos.detailLevel < targetDetailLevel) - { - return; - } int posX = levelPos.posX; int posZ = levelPos.posZ; byte detailLevel = levelPos.detailLevel; int childPosX = posX * 2; int childPosZ = posZ * 2; - LevelPos childPos = new LevelPos(); int childSize = 1 << (LodUtil.REGION_DETAIL_LEVEL - levelPos.detailLevel + 1); //we have reached the target detail level - if (targetDetailLevel == levelPos.detailLevel) + + if (DetailDistanceUtil.getDistanceGenerationInverse(maxDistance,targetDetailLevel) > detailLevel) + { + return; + } + else if (DetailDistanceUtil.getDistanceGenerationInverse(maxDistance,targetDetailLevel) == levelPos.detailLevel) { if (generationType[detailLevel][posX][posZ] < generation) { @@ -275,8 +274,8 @@ public class LodRegion implements Serializable for (int z = 0; z <= 1; z++) { levelPos.changeParameters((byte) (detailLevel - 1), childPosX + x, childPosZ + z); - getDataToGenerate(levelPosList, levelPos - , playerPosX, playerPosZ, start, end, generation, targetDetailLevel); + getDataToGenerate(levelPosList, levelPos, + playerPosX, playerPosZ, generation, targetDetailLevel); } } } @@ -292,7 +291,7 @@ public class LodRegion implements Serializable { if (levelPos.detailLevel != targetDetailLevel) { - getDataToGenerate(levelPosList, levelPos, playerPosX, playerPosZ, start, end, generation, targetDetailLevel); + getDataToGenerate(levelPosList, levelPos, playerPosX, playerPosZ, generation, targetDetailLevel); } } } @@ -633,11 +632,6 @@ public class LodRegion implements Serializable { if (detailLevel < minDetailLevel) { - for (byte tempLod = minDetailLevel; tempLod < LodUtil.REGION_DETAIL_LEVEL; tempLod++) - { - int size = (short) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod); - generationType[tempLod] = new byte[size][size]; - } for (byte tempLod = detailLevel; tempLod < minDetailLevel; tempLod++) { int size = (short) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - tempLod); diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index 7c263fc23..9d10dcd08 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -17,6 +17,7 @@ */ package com.seibel.lod.proxy; +import com.seibel.lod.util.DetailDistanceUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -100,6 +101,7 @@ public class ClientProxy */ public void renderLods(float partialTicks) { + DetailDistanceUtil.updateSettings(); if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded()) return; @@ -119,7 +121,7 @@ public class ClientProxy // comment out when creating a release - applyConfigOverrides(); + //applyConfigOverrides(); // Note to self: @@ -294,6 +296,7 @@ public class ClientProxy recalculateWidths = false; //LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth ); } + DetailDistanceUtil.updateSettings(); } diff --git a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java index 9936e6505..5cae77c0f 100644 --- a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java +++ b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java @@ -14,12 +14,10 @@ public class DetailDistanceUtil private static double genMultiplier = 1.0; private static double treeGenMultiplier = 1.0; private static double treeCutMultiplier = 1.0; - //private static int minDetail = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel; - private static int minDetail = LodDetail.FULL.detailLevel; + private static int minDetail = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel; private static int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1; private static int minDistance = 0; - //private static int maxDistance = LodConfig.CLIENT.lodChunkRenderDistance.get() * 16 * 2; - private static int maxDistance = 128 * 16 * 2; + private static int maxDistance = LodConfig.CLIENT.lodChunkRenderDistance.get() * 16 * 2; private static int base = 2; private static double logBase = Math.log(2); @@ -36,6 +34,12 @@ public class DetailDistanceUtil LodDetail.SINGLE, LodDetail.SINGLE}; + + public static void updateSettings(){ + minDetail = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel; + maxDistance = LodConfig.CLIENT.lodChunkRenderDistance.get() * 16 * 2; + } + public static int getDistanceRendering(int detail) { int initial; @@ -94,6 +98,12 @@ public class DetailDistanceUtil return (byte) Math.min(detail, LodUtil.REGION_DETAIL_LEVEL); } + public static byte getDistanceGenerationInverse(int distance, byte minDetailLevel) + { + return (byte) Math.max(getDistanceRenderingInverse((int) (distance * genMultiplier)) + ,minDetailLevel); + } + public static int getDistanceGeneration(int detail) { if (detail == maxDetail) @@ -147,7 +157,7 @@ public class DetailDistanceUtil } - public static boolean regionInView(int playerPosX, int playerPosY, int playerPosZ, int alpha, int beta, int fov, RegionPos regionPos) + public static boolean regionInView(int playerPosX, int playerPosY, int playerPosZ, int xRot, int yRot, int fov, RegionPos regionPos) { //System.out.println(Math.floorMod((int) mc.player.xRot,360) + " " + Math.floorMod((int) mc.player.yRot,360) + " " + mc.options.fov);