Fix DH beacon detection logic mutating input block pos
alternate title: Fix DH beacon detection logic breaking the lighting engine
This commit is contained in:
+20
-12
@@ -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<DhBlockPos> blockLightPosList = chunk.getBlockLightPosList();
|
||||
ArrayList<DhBlockPos> 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -351,7 +351,6 @@ public class LodQuadTree extends QuadTree<LodRenderSection> 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);
|
||||
|
||||
+11
-8
@@ -90,7 +90,8 @@ public interface IChunkWrapper extends IBindable
|
||||
int getSkyLight(int relX, int relY, int relZ);
|
||||
|
||||
|
||||
ArrayList<DhBlockPos> getBlockLightPosList();
|
||||
/** Note: don't modify this array, it will only be generated once and then shared between uses */
|
||||
ArrayList<DhBlockPos> 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<DhBlockPos> lightPosList = this.getBlockLightPosList();
|
||||
final DhBlockPos relPos = new DhBlockPos();
|
||||
ArrayList<DhBlockPos> 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<DhBlockPos> blockPosList = this.getBlockLightPosList();
|
||||
final DhBlockPos relPos = new DhBlockPos();
|
||||
ArrayList<DhBlockPos> 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);
|
||||
|
||||
|
||||
|
||||
@@ -399,7 +399,7 @@ public class LightingTestChunkWrapper implements IChunkWrapper
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<DhBlockPos> getBlockLightPosList() { return this.blockLightPosList; }
|
||||
public ArrayList<DhBlockPos> getWorldBlockLightPosList() { return this.blockLightPosList; }
|
||||
|
||||
@Override
|
||||
public boolean doNearbyChunksExist() { return false; }
|
||||
|
||||
Reference in New Issue
Block a user