From 86d07eb62b23f8ba0e6ae901bb97e701361dcd18 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 1 Jul 2021 21:21:34 -0500 Subject: [PATCH] Close #30 and 31 (LODs rendering on top of the player and distance based rendering) --- .../com/seibel/lod/builders/LodBuilder.java | 8 +-- .../lodTemplates/CubicLodTemplate.java | 8 +-- .../java/com/seibel/lod/enums/LodDetail.java | 38 +++++++------- .../java/com/seibel/lod/objects/LodChunk.java | 27 ++++++++-- .../com/seibel/lod/render/LodRenderer.java | 51 +++++++++++++++++-- 5 files changed, 96 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index b695e4945..4965177d4 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -129,9 +129,9 @@ public class LodBuilder LodDetail detail = LodConfig.CLIENT.lodDetail.get(); - LodDataPoint[][] dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount]; + LodDataPoint[][] dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount]; - for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++) + for(int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++) { int startX = detail.startX[i]; int startZ = detail.startZ[i]; @@ -157,8 +157,8 @@ public class LodBuilder depth = 0; } - int x = i / detail.lengthCount; - int z = i % detail.lengthCount; + int x = i / detail.dataPointLengthCount; + int z = i % detail.dataPointLengthCount; dataPoints[x][z] = new LodDataPoint(height, depth, color); } diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java index 88e80eb9e..77f065b09 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java @@ -38,9 +38,9 @@ public class CubicLodTemplate extends AbstractLodTemplate // using the quality setting set by the config LodDetail detail = LodConfig.CLIENT.lodDetail.get(); - int halfWidth = detail.width / 2; + int halfWidth = detail.dataPointWidth / 2; - for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++) + for(int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++) { int startX = detail.startX[i]; int startZ = detail.startZ[i]; @@ -51,7 +51,7 @@ public class CubicLodTemplate extends AbstractLodTemplate bbox = generateBoundingBox( centerLod.getAverageHeightOverArea(startX, startZ, endX, endZ), centerLod.getAverageDepthOverArea(startX, startZ, endX, endZ), - detail.width, + detail.dataPointWidth, xOffset - (halfWidth / 2) + detail.startX[i], yOffset, zOffset - (halfWidth / 2) + detail.startZ[i]); @@ -165,7 +165,7 @@ public class CubicLodTemplate extends AbstractLodTemplate public int getBufferMemoryForSingleLod(LodDetail detail) { // (sidesOnACube * pointsInASquare * (positionPoints + colorPoints))) * howManyPointsPerLodChunk - return (6 * 4 * (3 + 4)) * detail.lengthCount * detail.lengthCount; + return (6 * 4 * (3 + 4)) * detail.dataPointLengthCount * detail.dataPointLengthCount; } diff --git a/src/main/java/com/seibel/lod/enums/LodDetail.java b/src/main/java/com/seibel/lod/enums/LodDetail.java index f4dd38eee..16f598acc 100644 --- a/src/main/java/com/seibel/lod/enums/LodDetail.java +++ b/src/main/java/com/seibel/lod/enums/LodDetail.java @@ -27,11 +27,11 @@ public enum LodDetail FULL(16); - /** How many LODs wide should - * be drawn per LodChunk */ - public final int lengthCount; - /** How wide each LOD is */ - public final int width; + /** How many DataPoints should + * be drawn per side per LodChunk */ + public final int dataPointLengthCount; + /** How wide each LOD DataPoint is */ + public final int dataPointWidth; /* Start/End X/Z give the block positions * for each individual dataPoint in a LodChunk */ @@ -50,8 +50,8 @@ public enum LodDetail private LodDetail(int newLengthCount) { - lengthCount = newLengthCount; - width = 16 / lengthCount; + dataPointLengthCount = newLengthCount; + dataPointWidth = 16 / dataPointLengthCount; if(newLengthCount == LodChunk.WIDTH) { @@ -59,11 +59,11 @@ public enum LodDetail newLengthCount = LodChunk.WIDTH - 1; } - startX = new int[lengthCount * lengthCount]; - endX = new int[lengthCount * lengthCount]; + startX = new int[dataPointLengthCount * dataPointLengthCount]; + endX = new int[dataPointLengthCount * dataPointLengthCount]; - startZ = new int[lengthCount * lengthCount]; - endZ = new int[lengthCount * lengthCount]; + startZ = new int[dataPointLengthCount * dataPointLengthCount]; + endZ = new int[dataPointLengthCount * dataPointLengthCount]; int index = 0; @@ -71,19 +71,19 @@ public enum LodDetail { for(int z = 0; z < newLengthCount; z++) { - startX[index] = x * width; - startZ[index] = z * width; + startX[index] = x * dataPointWidth; + startZ[index] = z * dataPointWidth; // special case for FULL - if(width != 1) + if(dataPointWidth != 1) { - endX[index] = (x*width) + width - 1; - endZ[index] = (z*width) + width - 1; + endX[index] = (x*dataPointWidth) + dataPointWidth - 1; + endZ[index] = (z*dataPointWidth) + dataPointWidth - 1; } else { - endX[index] = (x*width) + width; - endZ[index] = (z*width) + width; + endX[index] = (x*dataPointWidth) + dataPointWidth; + endZ[index] = (z*dataPointWidth) + dataPointWidth; } index++; @@ -91,7 +91,7 @@ public enum LodDetail } - lodChunkStringDelimiterCount = 2 + (lengthCount * lengthCount * LodDataPoint.NUMBER_OF_DELIMITERS); + lodChunkStringDelimiterCount = 2 + (dataPointLengthCount * dataPointLengthCount * LodDataPoint.NUMBER_OF_DELIMITERS); }// constructor } diff --git a/src/main/java/com/seibel/lod/objects/LodChunk.java b/src/main/java/com/seibel/lod/objects/LodChunk.java index 1a08d1792..2b6aacbcb 100644 --- a/src/main/java/com/seibel/lod/objects/LodChunk.java +++ b/src/main/java/com/seibel/lod/objects/LodChunk.java @@ -68,7 +68,7 @@ public class LodChunk detail = LodDetail.SINGLE; - dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount]; + dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount]; } /** @@ -127,7 +127,7 @@ public class LodChunk throw new IllegalArgumentException("LodChunk constructor givin an invalid string. The data given had " + count + " delimiters when it should have had " + detail.lodChunkStringDelimiterCount + "."); - dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount]; + dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount]; // index we will use when going through the String int index = 0; @@ -145,9 +145,9 @@ public class LodChunk // LodDataPoints - for(int blockX = 0; blockX < detail.lengthCount; blockX++) + for(int blockX = 0; blockX < detail.dataPointLengthCount; blockX++) { - for(int blockZ = 0; blockZ < detail.lengthCount; blockZ++) + for(int blockZ = 0; blockZ < detail.dataPointLengthCount; blockZ++) { // height lastIndex = index; @@ -281,7 +281,7 @@ public class LodChunk */ public LodDataPoint getDataPointForBlockPos(int blockX, int blockZ) { - return dataPoints[blockX / detail.width][blockZ / detail.width]; + return dataPoints[blockX / detail.dataPointWidth][blockZ / detail.dataPointWidth]; } public Color getColorForBlockPos(int blockX, int blockZ) @@ -315,6 +315,22 @@ public class LodChunk return dataPoints[xIndex][zIndex].depth; } + public short calculateHighestPoint() + { + short highest = 0; + + for(int x = 0; x < detail.dataPointLengthCount; x++) + { + for(int z = 0; z < detail.dataPointLengthCount; z++) + { + if (getHeight(x,z) > highest) + highest = getHeight(x,z); + } + } + + return highest; + } + /** @@ -461,4 +477,5 @@ public class LodChunk return s; } + } diff --git a/src/main/java/com/seibel/lod/render/LodRenderer.java b/src/main/java/com/seibel/lod/render/LodRenderer.java index 91a6aa0a2..efa05894d 100644 --- a/src/main/java/com/seibel/lod/render/LodRenderer.java +++ b/src/main/java/com/seibel/lod/render/LodRenderer.java @@ -188,14 +188,15 @@ public class LodRenderer int totalLength = (int) farPlaneDistance * LodConfig.CLIENT.lodChunkRadiusMultiplier.get() * 2; int numbChunksWide = (totalLength / LodChunk.WIDTH); + // determine which LODs should not be rendered close to the player + HashSet chunkPosToSkip = getNearbyLodChunkPosToSkip(lodDim, player.getPosition()); + // see if the chunks Minecraft is going to render are the // same as last time - // (This is done so we only render LODs ) - HashSet newRenderedChunks = getRenderedChunks(); - if (!vanillaRenderedChunks.containsAll(newRenderedChunks)) + if (!vanillaRenderedChunks.containsAll(chunkPosToSkip)) { regen = true; - vanillaRenderedChunks = newRenderedChunks; + vanillaRenderedChunks = chunkPosToSkip; } @@ -679,6 +680,48 @@ public class LodRenderer + /** + * Get a HashSet of all ChunkPos within the normal render distance + * that should not be rendered. + */ + private HashSet getNearbyLodChunkPosToSkip(LodDimension lodDim, BlockPos playerPos) + { + int chunkRenderDist = mc.gameSettings.renderDistanceChunks; + int blockRenderDist = chunkRenderDist * 16; + ChunkPos centerChunk = new ChunkPos(playerPos); + + // skip chunks that are already going to be rendered by Minecraft + HashSet posToSkip = getRenderedChunks(); + + + // go through each chunk within the normal view distance + for(int x = centerChunk.x - chunkRenderDist; x < centerChunk.x + chunkRenderDist; x++) + { + for(int z = centerChunk.z - chunkRenderDist; z < centerChunk.z + chunkRenderDist; z++) + { + LodChunk lod = lodDim.getLodFromCoordinates(x, z); + if (lod != null) + { + short lodHighestPoint = lod.calculateHighestPoint(); + + if (playerPos.getY() < lodHighestPoint) + { + // don't draw Lod's that are taller than the player + // to prevent LODs being drawn on top of the player + posToSkip.add(new ChunkPos(x, z)); + } + else if (blockRenderDist < Math.abs(playerPos.getY() - lodHighestPoint)) + { + // draw Lod's that are lower than the player's view range + posToSkip.remove(new ChunkPos(x, z)); + } + } + } + } + + return posToSkip; + } + /** * This method returns the ChunkPos of all chunks that Minecraft * is going to render this frame.