diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java index 901aa8583..d349edb35 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/DhLightingEngine.java @@ -76,12 +76,12 @@ public class DhLightingEngine // try-finally to handle the stableArray resources - StableLightPosStack blockLightPosQueue = null; - StableLightPosStack skyLightPosQueue = null; + StableLightPosStack blockLightWorldPosQueue = null; + StableLightPosStack skyLightWorldPosQueue = null; try { - blockLightPosQueue = StableLightPosStack.borrowStableLightPosArray(); - skyLightPosQueue = StableLightPosStack.borrowStableLightPosArray(); + blockLightWorldPosQueue = StableLightPosStack.borrowStableLightPosArray(); + skyLightWorldPosQueue = StableLightPosStack.borrowStableLightPosArray(); @@ -114,11 +114,15 @@ public class DhLightingEngine + //==================// + // set block lights // + //==================// + // get and set the adjacent chunk's initial block lights final DhBlockPos relLightBlockPos = PRIMARY_BLOCK_POS_REF.get(); final DhBlockPos relBlockPos = SECONDARY_BLOCK_POS_REF.get(); - ArrayList blockLightPosList = chunk.getBlockLightPosList(); + ArrayList blockLightPosList = chunk.getWorldBlockLightPosList(); for (int blockLightIndex = 0; blockLightIndex < blockLightPosList.size(); blockLightIndex++) // using iterators in high traffic areas can cause GC issues due to allocating a bunch of iterators, use an indexed for-loop instead { DhBlockPos blockLightPos = blockLightPosList.get(blockLightIndex); @@ -127,14 +131,18 @@ public class DhLightingEngine // get the light IBlockStateWrapper blockState = chunk.getBlockState(relLightBlockPos); int lightValue = blockState.getLightEmission(); - blockLightPosQueue.push(blockLightPos.x, blockLightPos.y, blockLightPos.z, lightValue); + blockLightWorldPosQueue.push(blockLightPos.x, blockLightPos.y, blockLightPos.z, lightValue); // set the light - blockLightPos.mutateToChunkRelativePos(relBlockPos); chunk.setDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, lightValue); } + + //================// + // set sky lights // + //================// + // get and set the adjacent chunk's initial skylights, // if the dimension has skylights if (maxSkyLight > 0) @@ -160,7 +168,7 @@ public class DhLightingEngine // add sky light to the queue DhBlockPos skyLightPos = new DhBlockPos(chunk.getMinBlockX() + relX, y, chunk.getMinBlockZ() + relZ); - skyLightPosQueue.push(skyLightPos.x, skyLightPos.y, skyLightPos.z, maxSkyLight); + skyLightWorldPosQueue.push(skyLightPos.x, skyLightPos.y, skyLightPos.z, maxSkyLight); // set the chunk's sky light skyLightPos.mutateToChunkRelativePos(relBlockPos); @@ -180,12 +188,12 @@ public class DhLightingEngine } // block light - this.propagateLightPosList(blockLightPosQueue, adjacentChunkHolder, + this.propagateLightPosList(blockLightWorldPosQueue, adjacentChunkHolder, (neighbourChunk, relBlockPos) -> neighbourChunk.getDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z), (neighbourChunk, relBlockPos, newLightValue) -> neighbourChunk.setDhBlockLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, newLightValue)); // sky light - this.propagateLightPosList(skyLightPosQueue, adjacentChunkHolder, + this.propagateLightPosList(skyLightWorldPosQueue, adjacentChunkHolder, (neighbourChunk, relBlockPos) -> neighbourChunk.getDhSkyLight(relBlockPos.x, relBlockPos.y, relBlockPos.z), (neighbourChunk, relBlockPos, newLightValue) -> neighbourChunk.setDhSkyLight(relBlockPos.x, relBlockPos.y, relBlockPos.z, newLightValue)); } @@ -195,8 +203,8 @@ public class DhLightingEngine } finally { - StableLightPosStack.returnStableLightPosArray(blockLightPosQueue); - StableLightPosStack.returnStableLightPosArray(skyLightPosQueue); + StableLightPosStack.returnStableLightPosArray(blockLightWorldPosQueue); + StableLightPosStack.returnStableLightPosArray(skyLightWorldPosQueue); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java index ecb4e3010..9b22cbb08 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhBlockPos.java @@ -145,13 +145,17 @@ public class DhBlockPos } } - /** Returns a new {@link DhBlockPos} limits to a value between 0 and 15 (inclusive) */ - public DhBlockPos convertToChunkRelativePos() { return this.mutateToChunkRelativePos(null); } + /** Returns a new {@link DhBlockPos} limited to a value between 0 and 15 (inclusive) */ + public DhBlockPos createChunkRelativePos() { return this.mutateOrCreateChunkRelativePos(null); } + /** Limits the input {@link DhBlockPos} to a value between 0 and 15 (inclusive) */ + public void mutateToChunkRelativePos(DhBlockPos mutableBlockPos) { this.mutateOrCreateChunkRelativePos(mutableBlockPos); } /** * Limits the block position to a value between 0 and 15 (inclusive) * If not null, mutates "mutableBlockPos" + * + * @return the mutated or created {@link DhBlockPos} */ - public DhBlockPos mutateToChunkRelativePos(@Nullable DhBlockPos mutableBlockPos) + private DhBlockPos mutateOrCreateChunkRelativePos(@Nullable DhBlockPos mutableBlockPos) { // move the position into the range -15 and +15 int relX = (this.x % LodUtil.CHUNK_WIDTH); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java index 312ee0a60..4805e1f96 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java @@ -351,7 +351,6 @@ public class LodQuadTree extends QuadTree implements IDebugRen // )) { // prepare this section for rendering - // TODO this should fire for the lowest detail level first to improve loading speed if (!renderSection.gpuUploadInProgress() && renderSection.renderBuffer == null) { nodesNeedingLoading.add(renderSection); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java index 9268751bd..fc6f8bc39 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/wrapperInterfaces/chunk/IChunkWrapper.java @@ -90,7 +90,8 @@ public interface IChunkWrapper extends IBindable int getSkyLight(int relX, int relY, int relZ); - ArrayList getBlockLightPosList(); + /** Note: don't modify this array, it will only be generated once and then shared between uses */ + ArrayList getWorldBlockLightPosList(); default boolean blockPosInsideChunk(DhBlockPos blockPos) { return this.blockPosInsideChunk(blockPos.x, blockPos.y, blockPos.z); } @@ -321,14 +322,15 @@ public interface IChunkWrapper extends IBindable } // light emitting blocks (if the light changes then the LOD definitely needs to be updated) - ArrayList lightPosList = this.getBlockLightPosList(); + final DhBlockPos relPos = new DhBlockPos(); + ArrayList lightPosList = this.getWorldBlockLightPosList(); for (int i = 0; i < lightPosList.size(); i++) { DhBlockPos pos = lightPosList.get(i); - pos = pos.mutateToChunkRelativePos(pos); + pos.mutateToChunkRelativePos(relPos); - hash = (hash * primeBlockMultiplier) + this.getBlockState(pos.x, pos.y, pos.z).hashCode(); - hash = (hash * primeHeightMultiplier) + pos.y; + hash = (hash * primeBlockMultiplier) + this.getBlockState(relPos.x, relPos.y, relPos.z).hashCode(); + hash = (hash * primeHeightMultiplier) + relPos.y; } @@ -342,11 +344,12 @@ public interface IChunkWrapper extends IBindable AdjacentChunkHolder adjacentChunkHolder = new AdjacentChunkHolder(this, neighbourChunkList); // since beacons emit light we can check only the positions that are emitting light - ArrayList blockPosList = this.getBlockLightPosList(); + final DhBlockPos relPos = new DhBlockPos(); + ArrayList blockPosList = this.getWorldBlockLightPosList(); for (int i = 0; i < blockPosList.size(); i++) { DhBlockPos pos = blockPosList.get(i); - DhBlockPos relPos = pos.convertToChunkRelativePos(); + pos.mutateToChunkRelativePos(relPos); IBlockStateWrapper block = this.getBlockState(relPos); @@ -367,7 +370,7 @@ public interface IChunkWrapper extends IBindable @Nullable static Color getBeaconColor(DhBlockPos beaconPos, AdjacentChunkHolder chunkHolder) { - DhBlockPos beaconRelPos = beaconPos.convertToChunkRelativePos(); + DhBlockPos beaconRelPos = beaconPos.createChunkRelativePos(); DhBlockPos baseRelPos = new DhBlockPos(0, beaconRelPos.y-1, 0); diff --git a/core/src/test/java/testItems/lightingEngine/LightingTestChunkWrapper.java b/core/src/test/java/testItems/lightingEngine/LightingTestChunkWrapper.java index 142113859..6de322497 100644 --- a/core/src/test/java/testItems/lightingEngine/LightingTestChunkWrapper.java +++ b/core/src/test/java/testItems/lightingEngine/LightingTestChunkWrapper.java @@ -399,7 +399,7 @@ public class LightingTestChunkWrapper implements IChunkWrapper } @Override - public ArrayList getBlockLightPosList() { return this.blockLightPosList; } + public ArrayList getWorldBlockLightPosList() { return this.blockLightPosList; } @Override public boolean doNearbyChunksExist() { return false; }