diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java index aeb9951d1..d0b252c80 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/SharedApi.java @@ -25,6 +25,7 @@ import com.seibel.distanthorizons.core.dataObjects.transformers.ChunkToLodBuilde import com.seibel.distanthorizons.core.dataObjects.transformers.FullDataToRenderDataTransformer; import com.seibel.distanthorizons.core.file.fullDatafile.FullDataFileHandler; import com.seibel.distanthorizons.core.generation.WorldGenerationQueue; +import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; import com.seibel.distanthorizons.core.world.*; /** Contains code and variables used by both {@link ClientApi} and {@link ServerApi} */ @@ -67,6 +68,8 @@ public class SharedApi WorldGenerationQueue.shutdownWorldGenThreadPool(); ChunkToLodBuilder.shutdownExecutorService(); + DebugRenderer.clearRenderables(); + // recommend that the garbage collector cleans up any objects from the old world System.gc(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java index fc799d477..e231289c7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnBox.java @@ -69,7 +69,7 @@ public class ColumnBox || (RenderDataPointUtil.getYMin(topData) >= builder.skyLightCullingBelow) || !RenderDataPointUtil.doesDataPointExist(topData) ) - ) + ) { maxY = builder.skyLightCullingBelow; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java index d0709934e..469504ffe 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java @@ -80,7 +80,7 @@ public class ColumnRenderBufferBuilder { return null; }*/ - //LOGGER.info("RenderRegion startBuild @ {}", renderSource.sectionPos); + //LOGGER.info("RenderRegion startBuild @ "+renderSource.sectionPos); return CompletableFuture.supplyAsync(() -> { try diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java index 6cf16c1aa..77217e141 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/LodQuadBuilder.java @@ -25,7 +25,6 @@ import java.util.*; import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; -import com.seibel.distanthorizons.core.pos.Pos2D; import com.seibel.distanthorizons.core.render.AbstractRenderBuffer; import com.seibel.distanthorizons.core.render.glObject.buffer.GLVertexBuffer; import com.seibel.distanthorizons.core.util.ColorUtil; @@ -51,12 +50,16 @@ public class LodQuadBuilder private final ArrayList[] opaqueQuads = (ArrayList[]) new ArrayList[6]; @SuppressWarnings("unchecked") private final ArrayList[] transparentQuads = (ArrayList[]) new ArrayList[6]; - private final boolean doTransparency; /** Used to turn transparent LODs above the void opaque to prevent seeing the void. */ - private final HashMap minOpaqueHeightByRelativePos = new HashMap<>(64 * 64); // the 64*64 capacity was the smallest James saw the builder work with, so it should be a good starting point + private final short[] minOpaqueHeightByRelativePos = new short[SECTION_WIDTH * SECTION_WIDTH]; /** See {@link LodQuadBuilder#minOpaqueHeightByRelativePos} */ - private final HashMap minTransparentHeightByRelativePos = new HashMap<>(64 * 64); + private final short[] minTransparentHeightByRelativePos = new short[SECTION_WIDTH * SECTION_WIDTH]; + + private final boolean doTransparency; + + private static int SECTION_WIDTH = 4096; + public static final int[][][] DIRECTION_VERTEX_IBO_QUAD = new int[][][] @@ -128,6 +131,13 @@ public class LodQuadBuilder this.skipQuadsWithZeroSkylight = enableSkylightCulling; this.skyLightCullingBelow = skyLightCullingBelow; + // set the default values + for (int i = 0; i < SECTION_WIDTH * SECTION_WIDTH; i++) + { + // the default height is MAX_VALUE to preserve the comparison logic later + this.minOpaqueHeightByRelativePos[i] = Short.MAX_VALUE; + this.minTransparentHeightByRelativePos[i] = Short.MAX_VALUE; + } } @@ -185,14 +195,21 @@ public class LodQuadBuilder { for (int zRel = z; zRel < (z + widthNorthSouthOrUpDown); zRel++) { - Pos2D relPos = new Pos2D(xRel, zRel); + int relPosIndex = relativeQuadPosToIndex(xRel, zRel); - HashMap minHeightByRelativePos = isTransparent ? this.minTransparentHeightByRelativePos : this.minOpaqueHeightByRelativePos; - Short currentHeight = minHeightByRelativePos.get(relPos); - // the default height is MAX_VALUE to preserve the comparison logic later - currentHeight = (currentHeight == null) ? Short.MAX_VALUE : currentHeight; + short[] minHeightByRelativePos = isTransparent ? this.minTransparentHeightByRelativePos : this.minOpaqueHeightByRelativePos; - minHeightByRelativePos.put(relPos, (short) Math.min(currentHeight, quad.y)); + try + { + short currentHeight = minHeightByRelativePos[relPosIndex]; + minHeightByRelativePos[relPosIndex] = (short) Math.min(currentHeight, quad.y); + } + catch (IndexOutOfBoundsException e) + { + // shouldn't happen normally, just in case James screwed up something. + // This can be removed once the indexes have been proven not to go outside the expected range + LOGGER.error("Relative Pos index out of bounds. Array length: ["+minHeightByRelativePos.length+"], given index: ["+relPosIndex+"], xRel: ["+xRel+"], zRel: ["+zRel+"], max expected rel value: ["+ SECTION_WIDTH +"].", e); + } } } @@ -362,8 +379,7 @@ public class LodQuadBuilder } long postQuadsCount = this.getCurrentOpaqueQuadsCount() + this.getCurrentTransparentQuadsCount(); - //if (mergeCount != 0) - LOGGER.debug("Merged {}/{}({}) quads", mergeCount, preQuadsCount, mergeCount / (double) preQuadsCount); + LOGGER.debug("Merged "+mergeCount+"/"+preQuadsCount+"("+(mergeCount / (double) preQuadsCount)+") quads"); } /** Merges all of this builder's quads for the given directionIndex (up, down, left, etc.) in the given direction */ @@ -408,13 +424,10 @@ public class LodQuadBuilder BufferQuad currentQuad = iter.next(); while (iter.hasNext()) { - Pos2D relPos = new Pos2D(currentQuad.x, currentQuad.z); + int relPosIndex = relativeQuadPosToIndex(currentQuad.x, currentQuad.z); - Short minOpaqueHeight = this.minOpaqueHeightByRelativePos.get(relPos); - minOpaqueHeight = (minOpaqueHeight == null) ? Short.MAX_VALUE : minOpaqueHeight; - - Short minTransHeight = this.minTransparentHeightByRelativePos.get(relPos); - minTransHeight = (minTransHeight == null) ? Short.MAX_VALUE : minTransHeight; + short minOpaqueHeight = this.minOpaqueHeightByRelativePos[relPosIndex]; + short minTransHeight = this.minTransparentHeightByRelativePos[relPosIndex]; if (currentQuad.y < minOpaqueHeight && currentQuad.y == minTransHeight) @@ -786,4 +799,14 @@ public class LodQuadBuilder return MathUtil.ceilDiv(this.getCurrentTransparentQuadsCount(), AbstractRenderBuffer.MAX_QUADS_PER_BUFFER); } + + + //================// + // helper methods // + //================// + + /** Converts a 2D position into a 1D array index. */ + public static int relativeQuadPosToIndex(int xRel, int zRel) { return xRel + zRel * SECTION_WIDTH; } + + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java index 87ad793e0..7ddfbd51e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/DebugRenderer.java @@ -264,26 +264,28 @@ public class DebugRenderer private void removeRenderer(IDebugRenderable r) { - synchronized (renderers) + synchronized (this.renderers) { - Iterator> it = renderers.iterator(); - while (it.hasNext()) + Iterator> iterator = this.renderers.iterator(); + while (iterator.hasNext()) { - WeakReference ref = it.next(); - if (ref.get() == null) + WeakReference renderableRef = iterator.next(); + if (renderableRef.get() == null) { - it.remove(); + iterator.remove(); continue; } - if (ref.get() == r) + if (renderableRef.get() == r) { - it.remove(); + iterator.remove(); return; } } } } + public static void clearRenderables() { INSTANCE.renderers.clear(); } + public void init() { if (init) return;