From c4f864f0e383d7117c32708775f17734001e581a Mon Sep 17 00:00:00 2001 From: Leonardo Date: Tue, 24 Aug 2021 23:10:29 +0200 Subject: [PATCH] changed how the distance generation mode is determined and added zFix boolean in node to render to disable the zFighting fix --- .../seibel/lod/builders/LodBufferBuilder.java | 62 ++- .../worldGeneration/LodNodeGenWorker.java | 2 +- .../lod/handlers/LodDimensionFileHandler.java | 378 +++++++++--------- .../com/seibel/lod/objects/LodDimension.java | 52 +-- .../com/seibel/lod/objects/LodRegion.java | 14 +- .../com/seibel/lod/proxy/ClientProxy.java | 6 +- .../seibel/lod/util/DetailDistanceUtil.java | 56 ++- 7 files changed, 307 insertions(+), 263 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 902b65050..99eaa9ece 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -17,11 +17,7 @@ */ package com.seibel.lod.builders; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -217,17 +213,27 @@ public class LodBufferBuilder Callable bufferBuildingThread = () -> { - List posListToRender = new ArrayList<>(); + byte detailToRender; + boolean zFix; + Set posListToRender = new HashSet<>(); for (byte detail = detailLevel; detail <= LodUtil.REGION_DETAIL_LEVEL; detail++) { + detailToRender = detail; + if(detail > detailToRender){ + zFix = false; + }else{ + detailToRender = detail; + zFix = true; + } posListToRender.addAll(lodDim.getDataToRender( regionPos, playerBlockPosRounded.getX(), playerBlockPosRounded.getZ(), DetailDistanceUtil.getDistanceRendering(detail), DetailDistanceUtil.getDistanceRendering(detail + 1), - detail)); + detailToRender, + zFix)); } @@ -324,44 +330,64 @@ public class LodBufferBuilder if (LodConfig.CLIENT.distanceGenerationMode.get() != DistanceGenerationMode.NONE) { - int requesting = maxChunkGenRequests; + int farRequesting = maxChunkGenRequests/2; + int nearRequesting; genReqStart = System.currentTimeMillis(); //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 (requesting == 0) break; + if (farRequesting <= 0) break; posListToGenerate = lodDim.getDataToGenerate( playerBlockPosRounded.getX(), playerBlockPosRounded.getZ(), DetailDistanceUtil.getDistanceGeneration(detailGen), DetailDistanceUtil.getDistanceGeneration(detailGen + 1), - LodConfig.CLIENT.distanceGenerationMode.get().complexity, + DetailDistanceUtil.getDistanceGenerationMode(detailGen).complexity, (byte) 9, - requesting/2); + farRequesting); for(LevelPos levelPos : posListToGenerate){ - generationRequestList.add(new GenerationRequest(levelPos,LodConfig.CLIENT.distanceGenerationMode.get(), DetailDistanceUtil.getLodDetail(detailGen))); + generationRequestList.add(new GenerationRequest(levelPos,DetailDistanceUtil.getDistanceGenerationMode(detailGen), DetailDistanceUtil.getLodDetail(detailGen))); } - requesting = maxChunkGenRequests - generationRequestList.size(); + farRequesting = farRequesting - generationRequestList.size(); } +/* + for (byte detailGen = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++) + { + if (farRequesting <= 0) break; + posListToGenerate = lodDim.getDataToGenerate( + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ(), + DetailDistanceUtil.getDistanceGeneration(detailGen), + DetailDistanceUtil.getDistanceGeneration(detailGen + 1), + DetailDistanceUtil.getDistanceGenerationMode(detailGen).complexity, + (byte) 7, + farRequesting); + for(LevelPos levelPos : posListToGenerate){ + generationRequestList.add(new GenerationRequest(levelPos,DetailDistanceUtil.getDistanceGenerationMode(detailGen), DetailDistanceUtil.getLodDetail(detailGen))); + } + farRequesting = farRequesting - generationRequestList.size(); + }*/ + nearRequesting = maxChunkGenRequests - 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 (requesting == 0) break; + if (nearRequesting <= 0) break; posListToGenerate = lodDim.getDataToGenerate( playerBlockPosRounded.getX(), playerBlockPosRounded.getZ(), DetailDistanceUtil.getDistanceGeneration(detailGen), DetailDistanceUtil.getDistanceGeneration(detailGen + 1), - LodConfig.CLIENT.distanceGenerationMode.get().complexity, + DetailDistanceUtil.getDistanceGenerationMode(detailGen).complexity, DetailDistanceUtil.getLodDetail(detailGen).detailLevel, - maxChunkGenRequests); + nearRequesting); for(LevelPos levelPos : posListToGenerate){ - generationRequestList.add(new GenerationRequest(levelPos,LodConfig.CLIENT.distanceGenerationMode.get(), DetailDistanceUtil.getLodDetail(detailGen))); + generationRequestList.add(new GenerationRequest(levelPos,DetailDistanceUtil.getDistanceGenerationMode(detailGen), DetailDistanceUtil.getLodDetail(detailGen))); } - requesting = maxChunkGenRequests - generationRequestList.size(); + nearRequesting = nearRequesting - generationRequestList.size(); } // determine which points in the posListToGenerate diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java index 585146d97..01c69261c 100644 --- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java +++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodNodeGenWorker.java @@ -282,7 +282,7 @@ public class LodNodeGenWorker implements IWorker // generate fake height data for this LOD int seaLevel = serverWorld.getSeaLevel(); - boolean simulateHeight = LodConfig.CLIENT.distanceGenerationMode.get() == DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT; + boolean simulateHeight = generationMode == DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT; boolean inTheEnd = false; // add fake heightmap data so our LODs aren't at height 0 diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java index 66ae28747..1b9511245 100644 --- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java +++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java @@ -115,93 +115,105 @@ public class LodDimensionFileHandler * (null if the file doesn't exist) */ public LodRegion loadRegionFromFile(RegionPos regionPos, byte detailLevel) - { - int regionX = regionPos.x; - int regionZ = regionPos.z; - String fileName = getFileNameAndPathForRegion(regionX, regionZ, detailLevel); - - // if the fileName was null that means the folder is inaccessible - // for some reason - if (fileName == null) - return null; - - - File f = new File(fileName); - - if (!f.exists()) - { - // there wasn't a file, don't - // return anything - return null; - } - String data = ""; - try - { - BufferedReader bufferedReader = new BufferedReader(new FileReader(f)); - data = bufferedReader.readLine(); - int fileVersion = -1; - - if (data != null && !data.isEmpty()) - { - // try to get the file version - try - { - fileVersion = Integer.parseInt(data.substring(data.indexOf(' ')).trim()); - } - catch (NumberFormatException | StringIndexOutOfBoundsException e) - { - // this file doesn't have a version - // keep the version as -1 - fileVersion = -1; - } - - // check if this file can be read by this file handler - if (fileVersion < LOD_SAVE_FILE_VERSION) - { - // the file we are reading is an older version, - // close the reader and delete the file. - bufferedReader.close(); - f.delete(); - ClientProxy.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion + - ", version requested: " + LOD_SAVE_FILE_VERSION + - " File was been deleted."); - - return null; - } - else if (fileVersion > LOD_SAVE_FILE_VERSION) - { - // the file we are reading is a newer version, - // close the reader and ignore the file, we don't - // want to accidently delete anything the user may want. - bufferedReader.close(); - ClientProxy.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion + - ", version requested: " + LOD_SAVE_FILE_VERSION + - " this region will not be written to in order to protect the newer file."); - - return null; - } - } - else - { - // there is no data in this file - bufferedReader.close(); - return null; - } - - // this file is a readable version, begin reading the file - data = bufferedReader.readLine(); - - bufferedReader.close(); - } - catch (IOException e) - { - // the buffered reader encountered a - // problem reading the file - return null; - } - - return new LodRegion(new LevelContainer(data), regionPos); - } + { + int regionX = regionPos.x; + int regionZ = regionPos.z; + LodRegion region = null; + for (byte tempDetailLevel = detailLevel; tempDetailLevel <= LodUtil.REGION_DETAIL_LEVEL; tempDetailLevel++) + { + try + { + String fileName = getFileNameAndPathForRegion(regionX, regionZ, tempDetailLevel); + + // if the fileName was null that means the folder is inaccessible + // for some reason + if (fileName == null) + throw new IllegalArgumentException("Game folder is not accessible"); + + + File f = new File(fileName); + + if (!f.exists()) + { + // there wasn't a file, don't + // return anything + continue; + } + String data = ""; + BufferedReader bufferedReader = new BufferedReader(new FileReader(f)); + data = bufferedReader.readLine(); + int fileVersion = -1; + + if (data != null && !data.isEmpty()) + { + // try to get the file version + try + { + fileVersion = Integer.parseInt(data.substring(data.indexOf(' ')).trim()); + } catch (NumberFormatException | StringIndexOutOfBoundsException e) + { + // this file doesn't have a version + // keep the version as -1 + fileVersion = -1; + } + + // check if this file can be read by this file handler + if (fileVersion < LOD_SAVE_FILE_VERSION) + { + // the file we are reading is an older version, + // close the reader and delete the file. + bufferedReader.close(); + f.delete(); + ClientProxy.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion + + ", version requested: " + LOD_SAVE_FILE_VERSION + + " File was been deleted."); + + continue; + } else if (fileVersion > LOD_SAVE_FILE_VERSION) + { + // the file we are reading is a newer version, + // close the reader and ignore the file, we don't + // want to accidently delete anything the user may want. + bufferedReader.close(); + ClientProxy.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion + + ", version requested: " + LOD_SAVE_FILE_VERSION + + " this region will not be written to in order to protect the newer file."); + + continue; + } + } else + { + // there is no data in this file + bufferedReader.close(); + continue; + } + + // this file is a readable version, begin reading the file + data = bufferedReader.readLine(); + + bufferedReader.close(); + region = new LodRegion(new LevelContainer(data), regionPos); + if (tempDetailLevel >= detailLevel) + region.expand(detailLevel); + break; + } catch (Exception e) + { + // the buffered reader encountered a + // problem reading the file + e.printStackTrace(); + } + /*catch (IOException e) + { + // the buffered reader encountered a + // problem reading the file + e.printStackTrace(); + } catch (IllegalArgumentException e) + { + e.printStackTrace(); + }*/ + } + return region; + } //==============// @@ -218,22 +230,23 @@ public class LodDimensionFileHandler private Thread saveDirtyRegionsThread = new Thread(() -> { - try - { - for (int i = 0; i < loadedDimension.getWidth(); i++) - { - for (int j = 0; j < loadedDimension.getWidth(); j++) - { - if (loadedDimension.isRegionDirty[i][j] && loadedDimension.regions[i][j] != null) - { - saveRegionToFile(loadedDimension.regions[i][j]); - loadedDimension.isRegionDirty[i][j] = false; - } - } - } - }catch (Exception e){ - e.printStackTrace(); - } + try + { + for (int i = 0; i < loadedDimension.getWidth(); i++) + { + for (int j = 0; j < loadedDimension.getWidth(); j++) + { + if (loadedDimension.isRegionDirty[i][j] && loadedDimension.regions[i][j] != null) + { + saveRegionToFile(loadedDimension.regions[i][j]); + loadedDimension.isRegionDirty[i][j] = false; + } + } + } + } catch (Exception e) + { + e.printStackTrace(); + } }); /** @@ -246,90 +259,90 @@ public class LodDimensionFileHandler */ private void saveRegionToFile(LodRegion region) { - // convert to region coordinates - int x = region.regionPosX; - int z = region.regionPosZ; - for(byte detailLevel = region.getMinDetailLevel(); detailLevel <= LodUtil.REGION_DETAIL_LEVEL; detailLevel++) - { - String fileName = getFileNameAndPathForRegion(x, z, detailLevel); - File oldFile = new File(fileName); + // convert to region coordinates + int x = region.regionPosX; + int z = region.regionPosZ; + for (byte detailLevel = region.getMinDetailLevel(); detailLevel <= LodUtil.REGION_DETAIL_LEVEL; detailLevel++) + { + String fileName = getFileNameAndPathForRegion(x, z, detailLevel); + File oldFile = new File(fileName); - // if the fileName was null that means the folder is inaccessible - // for some reason - if (fileName == null) - { - ClientProxy.LOGGER.warn("Unable to save region [" + x + ", " + z + "] to file."); - return; - } + // if the fileName was null that means the folder is inaccessible + // for some reason + if (fileName == null) + { + ClientProxy.LOGGER.warn("Unable to save region [" + x + ", " + z + "] to file."); + return; + } - try - { - // make sure the file and folder exists - if (!oldFile.exists()) - { - // the file doesn't exist, - // create it and the folder if need be - if (!oldFile.getParentFile().exists()) - oldFile.getParentFile().mkdirs(); - oldFile.createNewFile(); - } else - { - // the file exists, make sure it - // is the correct version. - // (to make sure we don't overwrite a newer - // version file if it exists) + try + { + // make sure the file and folder exists + if (!oldFile.exists()) + { + // the file doesn't exist, + // create it and the folder if need be + if (!oldFile.getParentFile().exists()) + oldFile.getParentFile().mkdirs(); + oldFile.createNewFile(); + } else + { + // the file exists, make sure it + // is the correct version. + // (to make sure we don't overwrite a newer + // version file if it exists) - BufferedReader br = new BufferedReader(new FileReader(oldFile)); - String s = br.readLine(); - int fileVersion = LOD_SAVE_FILE_VERSION; + BufferedReader br = new BufferedReader(new FileReader(oldFile)); + String s = br.readLine(); + int fileVersion = LOD_SAVE_FILE_VERSION; - if (s != null && !s.isEmpty()) - { - // try to get the file version - try - { - fileVersion = Integer.parseInt(s.substring(s.indexOf(' ')).trim()); - } catch (NumberFormatException | StringIndexOutOfBoundsException e) - { - // this file doesn't have a correctly formated version - // just overwrite the file - } - } - br.close(); + if (s != null && !s.isEmpty()) + { + // try to get the file version + try + { + fileVersion = Integer.parseInt(s.substring(s.indexOf(' ')).trim()); + } catch (NumberFormatException | StringIndexOutOfBoundsException e) + { + // this file doesn't have a correctly formated version + // just overwrite the file + } + } + br.close(); - // check if this file can be written to by the file handler - if (fileVersion <= LOD_SAVE_FILE_VERSION) - { - // we are good to continue and overwrite the old file - } else // if(fileVersion > LOD_SAVE_FILE_VERSION) - { - // the file we are reading is a newer version, - // don't write anything, we don't want to accidently - // delete anything the user may want. - return; - } - } + // check if this file can be written to by the file handler + if (fileVersion <= LOD_SAVE_FILE_VERSION) + { + // we are good to continue and overwrite the old file + } else // if(fileVersion > LOD_SAVE_FILE_VERSION) + { + // the file we are reading is a newer version, + // don't write anything, we don't want to accidently + // delete anything the user may want. + return; + } + } - // the old file is good, now create a new save file - File newFile = new File(fileName + TMP_FILE_EXTENSION); - FileWriter fw = new FileWriter(newFile); + // the old file is good, now create a new save file + File newFile = new File(fileName + TMP_FILE_EXTENSION); + FileWriter fw = new FileWriter(newFile); - // add the version of this file - fw.write(LOD_FILE_VERSION_PREFIX + " " + LOD_SAVE_FILE_VERSION + "\n"); + // add the version of this file + fw.write(LOD_FILE_VERSION_PREFIX + " " + LOD_SAVE_FILE_VERSION + "\n"); - // add each LodChunk to the file - fw.write(region.getLevel(detailLevel).toString()); - fw.close(); + // add each LodChunk to the file + fw.write(region.getLevel(detailLevel).toString()); + fw.close(); - // overwrite the old file with the new one - Files.move(newFile.toPath(), oldFile.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); - } catch (Exception e) - { - ClientProxy.LOGGER.error("LOD file write error: "); - e.printStackTrace(); - } - } + // overwrite the old file with the new one + Files.move(newFile.toPath(), oldFile.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); + } catch (Exception e) + { + ClientProxy.LOGGER.error("LOD file write error: "); + e.printStackTrace(); + } + } } @@ -342,9 +355,9 @@ public class LodDimensionFileHandler * Return the name of the file that should contain the * region at the given x and z.
* Returns null if this object isn't ready to read and write.

- * + *

* example: "lod.0.0.txt"

- * + *

* Returns null if there is an IO Exception. */ private String getFileNameAndPathForRegion(int regionX, int regionZ, byte detailLevel) @@ -357,11 +370,10 @@ public class LodDimensionFileHandler // ".\Super Flat\data" return dimensionDataSaveFolder.getCanonicalPath() + detailLevel + File.separatorChar + FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION; - } - catch (IOException | SecurityException e) + } catch (IOException | SecurityException e) { - ClientProxy.LOGGER.warn("Unable to get the filename for the region [" + regionX + ", " + regionZ + "], error: [" + e.getMessage() + "], stacktrace: "); - e.printStackTrace(); + ClientProxy.LOGGER.warn("Unable to get the filename for the region [" + regionX + ", " + regionZ + "], error: [" + e.getMessage() + "], stacktrace: "); + e.printStackTrace(); return null; } } diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index f54f9c4d9..f0e0d1e68 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -36,7 +36,6 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.world.DimensionType; import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; -import org.lwjgl.system.CallbackI; /** * This object holds all loaded LOD regions @@ -324,10 +323,10 @@ public class LodDimension //we start checking from the first circle. If the whole region is in the circle //we proceed to cut all the level lower than the level of circle 1 and we break //if this is not the case w - for(byte index = LodUtil.BLOCK_DETAIL_LEVEL; index <= LodUtil.REGION_DETAIL_LEVEL; index++){ - if(DetailDistanceUtil.getDistanceCut(index + 1) > levelPos.minDistance(playerPosX, playerPosZ)){ + for(byte index = LodUtil.BLOCK_DETAIL_LEVEL; index <= LodUtil.DETAIL_OPTIONS; index++){ + if(DetailDistanceUtil.getDistanceTreeCut(index + 1) > levelPos.minDistance(playerPosX, playerPosZ)){ - byte cutDetailLevel = DetailDistanceUtil.getCutLodDetail(index).detailLevel; + byte cutDetailLevel = DetailDistanceUtil.getCutLodDetail(index); if(regions[x][z] != null) { @@ -365,7 +364,7 @@ public class LodDimension for(byte index = LodUtil.BLOCK_DETAIL_LEVEL; index <= LodUtil.REGION_DETAIL_LEVEL; index++){ //As soon as we find in which circle the region should be we analyze it - if(DetailDistanceUtil.getDistanceGeneration(index + 1) > levelPos.minDistance(playerPosX, playerPosZ)){ + if(DetailDistanceUtil.getDistanceTreeGen(index + 1) > levelPos.minDistance(playerPosX, playerPosZ)){ region = regions[x][z]; //We require that the region we are checking is loaded with at least this level @@ -502,46 +501,7 @@ public class LodDimension * * @return list of nodes */ - public List getDataToRender(int playerPosX, int playerPosZ, int start, int end, byte detailLevel) - { - int n = regions.length; - List listOfData = new ArrayList<>(); - int xIndex; - int zIndex; - LodRegion region; - RegionPos regionPos; - LevelPos regionLevelPos; - for (int xRegion = 0; xRegion < n; xRegion++) - { - for (int zRegion = 0; zRegion < n; zRegion++) - { - try - { - xIndex = (xRegion + center.x) - halfWidth; - zIndex = (zRegion + center.z) - halfWidth; - regionPos = new RegionPos(xIndex, zIndex); - regionLevelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z); - if (end >= regionLevelPos.minDistance(playerPosX, playerPosZ) && - start <= regionLevelPos.maxDistance(playerPosX, playerPosZ)) - { - region = getRegion(new LevelPos(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z).convert(detailLevel)); - listOfData.addAll(region.getDataToRender(playerPosX, playerPosZ, start, end, detailLevel)); - } - }catch (Exception e) - { - //e.printStackTrace(); - } - } - } - return listOfData; - } - - /** - * method to get all the nodes that have to be rendered based on the position of the player - * - * @return list of nodes - */ - public List getDataToRender(RegionPos regionPos, int playerPosX, int playerPosZ, int start, int end, byte detailLevel) + public List getDataToRender(RegionPos regionPos, int playerPosX, int playerPosZ, int start, int end, byte detailLevel, boolean zFix) { List listOfData = new ArrayList<>(); LevelPos regionLevelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z); @@ -551,7 +511,7 @@ public class LodDimension start <= regionLevelPos.maxDistance(playerPosX, playerPosZ)) { LodRegion region = getRegion(new LevelPos(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z).convert(detailLevel)); - listOfData.addAll(region.getDataToRender(playerPosX, playerPosZ, start, end, detailLevel)); + listOfData.addAll(region.getDataToRender(playerPosX, playerPosZ, start, end, detailLevel,zFix)); } }catch (Exception e){ //e.printStackTrace(); diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index af6a28f42..d16ec73fa 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -322,16 +322,16 @@ public class LodRegion implements Serializable /** * @return */ - public List getDataToRender(int playerPosX, int playerPosZ, int start, int end, byte detailLevel) + public List getDataToRender(int playerPosX, int playerPosZ, int start, int end, byte detailLevel, boolean zFix) { LevelPos levelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, 0, 0); - return getDataToRender(levelPos, playerPosX, playerPosZ, start, end, detailLevel); + return getDataToRender(levelPos, playerPosX, playerPosZ, start, end, detailLevel, zFix); } /** * @return */ - private List getDataToRender(LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte detailLevel) + private List getDataToRender(LevelPos levelPos, int playerPosX, int playerPosZ, int start, int end, byte detailLevel, boolean zFix) { List levelPosList = new ArrayList<>(); @@ -345,7 +345,7 @@ public class LodRegion implements Serializable //To avoid z fighting: if the pos is touching the end radius at detailLevel + 1 then we stop //cause this area will be occupied by bigger block - if(levelPos.detailLevel == detailLevel + 1 && end <= maxDistance && minDistance <= end){ + if(levelPos.detailLevel == detailLevel + 1 && end <= maxDistance && minDistance <= end && zFix){ return levelPosList; } @@ -382,7 +382,7 @@ public class LodRegion implements Serializable for (int z = 0; z <= 1; z++) { childPos = new LevelPos((byte) (levelPos.detailLevel - 1), childPosX + x, childPosZ + z); - levelPosList.addAll(getDataToRender(childPos, playerPosX, playerPosZ, start, end, detailLevel)); + levelPosList.addAll(getDataToRender(childPos, playerPosX, playerPosZ, start, end, detailLevel, zFix)); } } }else{ @@ -624,6 +624,10 @@ public class LodRegion implements Serializable public void expand(byte detailLevel) { 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); colors[tempLod] = new byte[size][size][3]; diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java index d44ab6a7f..b81c9d56c 100644 --- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java +++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java @@ -154,11 +154,11 @@ public class ClientProxy LodConfig.CLIENT.distanceGenerationMode.set(DistanceGenerationMode.SURFACE); LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false); - LodConfig.CLIENT.lodChunkRenderDistance.set(512); + LodConfig.CLIENT.lodChunkRenderDistance.set(128); LodConfig.CLIENT.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR); - LodConfig.CLIENT.lodQuality.set(2); + LodConfig.CLIENT.lodQuality.set(1); LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false); - LodConfig.CLIENT.numberOfWorldGenerationThreads.set(8); + LodConfig.CLIENT.numberOfWorldGenerationThreads.set(Runtime.getRuntime().availableProcessors()); // has to be set in the config file // LodConfig.CLIENT.numberOfWorldGenerationThreads.set(16); diff --git a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java index 44d0d0c5a..e4b98372b 100644 --- a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java +++ b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java @@ -6,12 +6,15 @@ import com.seibel.lod.handlers.LodConfig; public class DetailDistanceUtil { - private static double genMultiplier = 1; - private static double cutMultiplier = 1.5; + private static double genMultiplier = 2; + private static double treeGenMultiplier = 2; + private static double treeCutMultiplier = 1.5; 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 DistanceGenerationMode[] distancesGenerators = { DistanceGenerationMode.SURFACE, DistanceGenerationMode.SURFACE, @@ -24,6 +27,29 @@ public class DetailDistanceUtil DistanceGenerationMode.SURFACE, DistanceGenerationMode.SURFACE}; + /*private static DistanceGenerationMode[] distancesGenerators = { + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT};*/ + /*private static DistanceGenerationMode[] distancesGenerators = { + DistanceGenerationMode.FEATURES, + DistanceGenerationMode.SURFACE, + DistanceGenerationMode.SURFACE, + DistanceGenerationMode.SURFACE, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT, + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT};*/ + private static LodDetail[] lodDetails = { LodDetail.FULL, LodDetail.HALF, @@ -58,6 +84,8 @@ public class DetailDistanceUtil return minDistance; if(detail == maxDetail) return maxDistance; + if(detail == maxDetail+1) + return maxDistance*2; switch (LodConfig.CLIENT.lodDistanceCalculatorType.get()) { case LINEAR: @@ -70,11 +98,21 @@ public class DetailDistanceUtil public static int getDistanceGeneration(int detail) { + if(detail == maxDetail) + return maxDistance; return (int) (getDistanceRendering(detail) * genMultiplier); } - public static int getDistanceCut(int detail) + public static int getDistanceTreeCut(int detail) { - return (int) (getDistanceRendering(detail) * cutMultiplier); + if(detail == maxDetail) + return maxDistance; + return (int) (getDistanceRendering(detail) * treeCutMultiplier); + } + public static int getDistanceTreeGen(int detail) + { + if(detail == maxDetail) + return maxDistance; + return (int) (getDistanceRendering(detail) * treeGenMultiplier); } public static DistanceGenerationMode getDistanceGenerationMode(int detail) @@ -95,15 +133,19 @@ public class DetailDistanceUtil } - public static LodDetail getCutLodDetail(int detail) + public static byte getCutLodDetail(int detail) { if(detail < minDetail) { - return lodDetailsCut[minDetail]; + return lodDetailsCut[minDetail].detailLevel; + } + else if(detail == maxDetail) + { + return LodUtil.REGION_DETAIL_LEVEL; } else { - return lodDetailsCut[detail]; + return lodDetailsCut[detail].detailLevel; } } }