diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 9e5eb2a4c..b19878e33 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -216,6 +216,9 @@ public class LodBufferBuilder int posX; int posZ; byte detailLevel; + int chunkXdist; + int chunkZdist; + short gameChunkRenderDistance = (short) (renderer.vanillaRenderedChunks.length/2 - 1); for (LevelPos posToRender : nodeToRender.keySet()) { if (!nodeToRender.get(posToRender).booleanValue()) @@ -225,10 +228,14 @@ public class LodBufferBuilder } nodeToRender.get(posToRender).setFalse(); // skip any chunks that Minecraft is going to render - - if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())) + chunkXdist = posToRender.getChunkPosX() - playerChunkPos.x; + chunkZdist = posToRender.getChunkPosZ() - playerChunkPos.z; + if(gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist)) { - continue; + if (renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance][chunkZdist + gameChunkRenderDistance]) + { + continue; + } } posX = posToRender.posX; posZ = posToRender.posZ; @@ -237,10 +244,6 @@ public class LodBufferBuilder 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 { @@ -252,17 +255,43 @@ public class LodBufferBuilder 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); + chunkXdist = posToRender.getChunkPosX() - playerChunkPos.x; + chunkZdist = posToRender.getChunkPosZ() - playerChunkPos.z; + if(gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist)) + { + if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance][chunkZdist + gameChunkRenderDistance] + && (nodeToRender.containsKey(posToRender) || disableFix)) + { + adjData[0][x] = lodDim.getData(posToRender); + } + }else{ + if (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); + chunkXdist = posToRender.getChunkPosX() - playerChunkPos.x; + chunkZdist = posToRender.getChunkPosZ() - playerChunkPos.z; + if(gameChunkRenderDistance >= Math.abs(chunkXdist) && gameChunkRenderDistance >= Math.abs(chunkZdist)) + { + if (!renderer.vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance][chunkZdist + gameChunkRenderDistance] + && (nodeToRender.containsKey(posToRender) || disableFix)) + { + adjData[1][z] = lodDim.getData(posToRender); + } + }else{ + if (nodeToRender.containsKey(posToRender) || disableFix) + { + adjData[1][z] = lodDim.getData(posToRender); + + } + } } posToRender.changeParameters(detailLevel, posX, posZ); diff --git a/src/main/java/com/seibel/lod/objects/LevelPos/LevelPos.java b/src/main/java/com/seibel/lod/objects/LevelPos/LevelPos.java index 37ec14a21..0d20eb490 100644 --- a/src/main/java/com/seibel/lod/objects/LevelPos/LevelPos.java +++ b/src/main/java/com/seibel/lod/objects/LevelPos/LevelPos.java @@ -127,6 +127,32 @@ public class LevelPos implements Cloneable, ImmutableLevelPos, MutableLevelPos, return Math.floorDiv(posZ, width); } + public int getChunkPosX() + { + if (LodUtil.CHUNK_DETAIL_LEVEL >= detailLevel) + { + int width = 1 << (LodUtil.CHUNK_DETAIL_LEVEL - detailLevel); + return Math.floorDiv(posX, width); + } else + { + int width = 1 << (detailLevel - LodUtil.CHUNK_DETAIL_LEVEL); + return posX * width; + } + } + + public int getChunkPosZ() + { + if (LodUtil.CHUNK_DETAIL_LEVEL >= detailLevel) + { + int width = 1 << (LodUtil.CHUNK_DETAIL_LEVEL - detailLevel); + return Math.floorDiv(posZ, width); + } else + { + int width = 1 << (detailLevel - LodUtil.CHUNK_DETAIL_LEVEL); + return posZ * width; + } + } + public ChunkPos getChunkPos() { if (LodUtil.CHUNK_DETAIL_LEVEL >= detailLevel) diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index 4753b0f93..508ff1e18 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -146,8 +146,8 @@ public class LodRenderer * This HashSet contains every chunk that Vanilla Minecraft * is going to render */ - public HashSet vanillaRenderedChunks = new HashSet<>(); - public HashSet previousVanillaRenderedChunks = new HashSet<>(); + public boolean[][] vanillaRenderedChunks; + public boolean vanillaRenderedChunksChanged; public LodRenderer(LodBufferBuilder newLodNodeBufferBuilder) @@ -770,10 +770,11 @@ public class LodRenderer @SuppressWarnings("unchecked") private void determineIfLodsShouldRegenerate(LodDimension lodDim) { + + short renderDistance = (short) mc.options.renderDistance; //=============// // full regens // //=============// - // check if the view distance changed if (ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() || mc.options.renderDistance != prevRenderDistance @@ -784,8 +785,7 @@ public class LodRenderer prevFogDistance = LodConfig.CLIENT.fogDistance.get(); prevRenderDistance = mc.options.renderDistance; //should use this when it's ready - //vanillaRenderedChunks.stream().filter(pos -> ((Math.abs(pos.x - player.xChunk) > mc.options.renderDistance) || (Math.abs(pos.z - player.zChunk) > mc.options.renderDistance))); - vanillaRenderedChunks.clear(); + vanillaRenderedChunks = new boolean[renderDistance*2+2][renderDistance*2+2]; } // did the user change the debug setting? @@ -808,8 +808,7 @@ public class LodRenderer fullRegen = true; previousPos.changeParameters((byte) 4, mc.player.xChunk, mc.player.zChunk); //should use this when it's ready - //vanillaRenderedChunks.stream().filter(pos -> ((Math.abs(pos.x - player.xChunk) > mc.options.renderDistance) || (Math.abs(pos.z - player.zChunk) > mc.options.renderDistance))); - vanillaRenderedChunks.clear(); + vanillaRenderedChunks = new boolean[renderDistance*2+2][renderDistance*2+2]; } prevPlayerPosTime = newTime; } @@ -824,10 +823,11 @@ public class LodRenderer // check if the vanilla rendered chunks changed if (newTime - prevVanillaChunkTime > LodConfig.CLIENT.bufferRebuildChunkChangeTimeout.get()) { - if (!previousVanillaRenderedChunks.equals(vanillaRenderedChunks)) + if (vanillaRenderedChunksChanged) { partialRegen = true; - previousVanillaRenderedChunks = (HashSet) vanillaRenderedChunks.clone(); + vanillaRenderedChunksChanged = false; + } prevVanillaChunkTime = newTime; } @@ -853,11 +853,16 @@ public class LodRenderer // determine which LODs should not be rendered close to the player HashSet chunkPosToSkip = LodUtil.getNearbyLodChunkPosToSkip(lodDim, mc.player.blockPosition()); + int chunkX; + int chunkZ; for (ChunkPos pos : chunkPosToSkip) { - if (!vanillaRenderedChunks.contains(pos)) + chunkX = pos.x - mc.player.xChunk + renderDistance; + chunkZ = pos.z - mc.player.zChunk + renderDistance; + if(!vanillaRenderedChunks[chunkX][chunkZ]) { - vanillaRenderedChunks.add(pos); + vanillaRenderedChunks[chunkX][chunkZ] = true; + vanillaRenderedChunksChanged = true; lodDim.setToRegen(pos.getRegionX(), pos.getRegionZ()); } } @@ -866,7 +871,8 @@ public class LodRenderer // if the player is high enough, draw all LODs if(chunkPosToSkip.isEmpty() && mc.player.position().y > 256) { - vanillaRenderedChunks.clear(); + vanillaRenderedChunks = new boolean[renderDistance*2][renderDistance*2]; + vanillaRenderedChunksChanged = true; } }