From 450f15ad3688de1ec4de560624d84427de920553 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sun, 29 Aug 2021 10:56:14 +0200 Subject: [PATCH] Finally fixed the regen problem --- .../seibel/lod/builders/LodBufferBuilder.java | 160 +++++++++--------- .../com/seibel/lod/objects/LodDimension.java | 12 ++ .../com/seibel/lod/render/LodRenderer.java | 19 ++- 3 files changed, 108 insertions(+), 83 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 4a1ecce85..0e1176a5f 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -190,99 +190,101 @@ public class LodBufferBuilder xRegion + lodDim.getCenterX() - Math.floorDiv(lodDim.getWidth(), 2), zRegion + lodDim.getCenterZ() - Math.floorDiv(lodDim.getWidth(), 2)); - // local position in the vbo and bufferBuilder arrays - BufferBuilder currentBuffer = buildableBuffers[xRegion][zRegion]; - - // make sure the buffers weren't - // changed while we were running this method - if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building())) - return; - - if (setsToRender[xRegion][zRegion] == null) + if(lodDim.regen[xRegion][zRegion]) { - setsToRender[xRegion][zRegion] = new ConcurrentHashMap(); - } - ConcurrentMap nodeToRender = (ConcurrentMap) setsToRender[xRegion][zRegion]; + // local position in the vbo and bufferBuilder arrays + BufferBuilder currentBuffer = buildableBuffers[xRegion][zRegion]; - Callable dataToRenderThread = () -> - { - lodDim.getDataToRender( - nodeToRender, - regionPos, - playerBlockPosRounded.getX(), - playerBlockPosRounded.getZ()); + // make sure the buffers weren't + // changed while we were running this method + if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building())) + return; - - int posX; - int posZ; - byte detailLevel; - for (LevelPos posToRender : nodeToRender.keySet()) + if (setsToRender[xRegion][zRegion] == null) { - if (!nodeToRender.get(posToRender).booleanValue()) - { - nodeToRender.remove(posToRender); - continue; - } - nodeToRender.get(posToRender).setFalse(); - // skip any chunks that Minecraft is going to render + setsToRender[xRegion][zRegion] = new ConcurrentHashMap(); + } + ConcurrentMap nodeToRender = (ConcurrentMap) setsToRender[xRegion][zRegion]; - if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())) - { - continue; - } - posX = posToRender.posX; - posZ = posToRender.posZ; - detailLevel = posToRender.detailLevel; + Callable dataToRenderThread = () -> + { + lodDim.getDataToRender( + nodeToRender, + regionPos, + playerBlockPosRounded.getX(), + playerBlockPosRounded.getZ()); - LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL); - // skip any chunks that Minecraft is going to render - if (renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkPos.posX, chunkPos.posZ))) + int posX; + int posZ; + byte detailLevel; + for (LevelPos posToRender : nodeToRender.keySet()) { - continue; - } - - try - { - boolean disableFix = false; - if (lodDim.doesDataExist(posToRender.clone())) + if (!nodeToRender.get(posToRender).booleanValue()) { - short[] lodData = lodDim.getData(posToRender); - short[][][] adjData = new short[2][2][]; - for (int x : new int[]{0, 1}) - { - posToRender.changeParameters(detailLevel, posX + x * 2 - 1, posZ); - if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) - && (nodeToRender.containsKey(posToRender) || disableFix)) - adjData[0][x] = lodDim.getData(posToRender); - } - - for (int z : new int[]{0, 1}) - { - posToRender.changeParameters(detailLevel, posX, posZ + z * 2 - 1); - if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) - && (nodeToRender.containsKey(posToRender) || disableFix)) - adjData[1][z] = lodDim.getData(posToRender); - } - posToRender.changeParameters(detailLevel, posX, posZ); - - LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData, - posToRender, renderer.previousDebugMode); + nodeToRender.remove(posToRender); + continue; } - } catch (ArrayIndexOutOfBoundsException e) - { - return false; - } + nodeToRender.get(posToRender).setFalse(); + // skip any chunks that Minecraft is going to render - }// for pos to in list to render + if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())) + { + continue; + } + posX = posToRender.posX; + posZ = posToRender.posZ; + detailLevel = posToRender.detailLevel; - // the thread executed successfully - return true; - };// buffer builder worker thread + LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL); + // skip any chunks that Minecraft is going to render + + if (renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkPos.posX, chunkPos.posZ))) + { + continue; + } + + try + { + boolean disableFix = false; + if (lodDim.doesDataExist(posToRender.clone())) + { + short[] lodData = lodDim.getData(posToRender); + short[][][] adjData = new short[2][2][]; + for (int x : new int[]{0, 1}) + { + posToRender.changeParameters(detailLevel, posX + x * 2 - 1, posZ); + if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) + && (nodeToRender.containsKey(posToRender) || disableFix)) + adjData[0][x] = lodDim.getData(posToRender); + } + + for (int z : new int[]{0, 1}) + { + posToRender.changeParameters(detailLevel, posX, posZ + z * 2 - 1); + if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()) + && (nodeToRender.containsKey(posToRender) || disableFix)) + adjData[1][z] = lodDim.getData(posToRender); + } + posToRender.changeParameters(detailLevel, posX, posZ); + + LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData, + posToRender, renderer.previousDebugMode); + } + } catch (ArrayIndexOutOfBoundsException e) + { + return false; + } + + }// for pos to in list to render + + // the thread executed successfully + return true; + };// buffer builder worker thread - nodeToRenderThreads.add(dataToRenderThread); - + nodeToRenderThreads.add(dataToRenderThread); + } }// region z }// region z long renderStart = System.currentTimeMillis(); diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 7072deebf..28b8113de 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -69,6 +69,7 @@ public class LodDimension public volatile LodRegion regions[][]; public volatile boolean isRegionDirty[][]; + public volatile boolean regen[][]; private volatile RegionPos center; private volatile ChunkPos lastGenChunk; @@ -124,6 +125,7 @@ public class LodDimension regions = new LodRegion[width][width]; isRegionDirty = new boolean[width][width]; + regen = new boolean[width][width]; //treeGenerator((int) mc.player.getX(),(int) mc.player.getZ()); @@ -192,7 +194,9 @@ public class LodDimension if (x + xOffset >= 0) regions[x][z] = regions[x + xOffset][z]; else + { regions[x][z] = null; + } } } } @@ -414,6 +418,7 @@ public class LodDimension { regions[x][z] = new LodRegion(levelToGen, regionPos, generationMode); } + regen[x][z] = true; } else if (region.getMinDetailLevel() > levelToGen) { @@ -455,6 +460,7 @@ public class LodDimension int xIndex = (regionPos.x - center.x) + halfWidth; int zIndex = (regionPos.z - center.z) + halfWidth; isRegionDirty[xIndex][zIndex] = true; + regen[xIndex][zIndex] = true; } catch (ArrayIndexOutOfBoundsException e) { // This method was probably called when the dimension was changing size. @@ -464,6 +470,11 @@ public class LodDimension return nodeAdded; } + public void setToRegen(int xRegion, int zRegion){ + int xIndex = (xRegion - center.x) + halfWidth; + int zIndex = (zRegion - center.z) + halfWidth; + regen[xIndex][zIndex] = true; + } /** * method to get all the quadtree level that have to be generated based on the position of the player @@ -679,6 +690,7 @@ public class LodDimension regions = new LodRegion[width][width]; isRegionDirty = new boolean[width][width]; + regen = new boolean[width][width]; // populate isRegionDirty for (int i = 0; i < width; i++) diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index 524fed60f..f266ab89b 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -23,6 +23,7 @@ import java.nio.FloatBuffer; import java.util.HashSet; import java.util.Iterator; +import net.minecraft.world.chunk.Chunk; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.NVFogDistance; @@ -209,6 +210,7 @@ public class LodRenderer prevChunkX = (int) player.getX() / LodUtil.CHUNK_WIDTH; prevChunkZ = (int) player.getZ() / LodUtil.CHUNK_WIDTH; prevFogDistance = LodConfig.CLIENT.fogDistance.get(); + vanillaRenderedChunks.clear(); } else { // nope, the player hasn't moved, the @@ -229,18 +231,27 @@ public class LodRenderer // set how how far the LODs will go int numbChunksWide =LodConfig.CLIENT.lodChunkRenderDistance.get() * 2; - + // determine which LODs should not be rendered close to the player HashSet chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, player.blockPosition()); - + + for(ChunkPos pos : chunkPosToSkip){ + if(!vanillaRenderedChunks.contains(pos)) + { + vanillaRenderedChunks.add(pos); + System.out.println(pos); + lodDim.setToRegen(pos.getRegionX(),pos.getRegionZ()); + } + } // see if the chunks Minecraft is going to render are the // same as last time + /* if (!vanillaRenderedChunks.containsAll(chunkPosToSkip) || vanillaRenderedChunks.size() != chunkPosToSkip.size()) { regen = true; vanillaRenderedChunks = chunkPosToSkip; - } - + }*/ + //=================// // create the LODs //