Add BuilderB0y's getBlockState optimization
This commit is contained in:
+7
-3
@@ -40,6 +40,7 @@ import com.seibel.distanthorizons.core.util.RenderDataPointUtil;
|
||||
import com.seibel.distanthorizons.core.util.objects.DataCorruptedException;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
@@ -132,6 +133,9 @@ public class LodDataBuilder
|
||||
|
||||
try
|
||||
{
|
||||
IMutableBlockPosWrapper mcBlockPos = chunkWrapper.getMutableBlockPosWrapper();
|
||||
IBlockStateWrapper previousBlockState = null;
|
||||
|
||||
int minBuildHeight = chunkWrapper.getMinNonEmptyHeight();
|
||||
for (int relBlockX = 0; relBlockX < LodUtil.CHUNK_WIDTH; relBlockX++)
|
||||
{
|
||||
@@ -163,7 +167,7 @@ public class LodDataBuilder
|
||||
// determine the starting Y Pos
|
||||
int y = chunkWrapper.getLightBlockingHeightMapValue(relBlockX, relBlockZ);
|
||||
// go up until we reach open air or the world limit
|
||||
IBlockStateWrapper topBlockState = chunkWrapper.getBlockState(relBlockX, y, relBlockZ);
|
||||
IBlockStateWrapper topBlockState = previousBlockState = chunkWrapper.getBlockState(relBlockX, y, relBlockZ, mcBlockPos, previousBlockState);
|
||||
while (!topBlockState.isAir() && y < chunkWrapper.getMaxBuildHeight())
|
||||
{
|
||||
try
|
||||
@@ -171,7 +175,7 @@ public class LodDataBuilder
|
||||
// This is necessary in some edge cases with snow layers and some other blocks that may not appear in the height map but do block light.
|
||||
// Interestingly this doesn't appear to be the case in the DhLightingEngine, if this same logic is added there the lighting breaks for the affected blocks.
|
||||
y++;
|
||||
topBlockState = chunkWrapper.getBlockState(relBlockX, y, relBlockZ);
|
||||
topBlockState = previousBlockState = chunkWrapper.getBlockState(relBlockX, y, relBlockZ, mcBlockPos, previousBlockState);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -190,7 +194,7 @@ public class LodDataBuilder
|
||||
for (; y >= minBuildHeight; y--)
|
||||
{
|
||||
IBiomeWrapper newBiome = chunkWrapper.getBiome(relBlockX, y, relBlockZ);
|
||||
IBlockStateWrapper newBlockState = chunkWrapper.getBlockState(relBlockX, y, relBlockZ);
|
||||
IBlockStateWrapper newBlockState = previousBlockState = chunkWrapper.getBlockState(relBlockX, y, relBlockZ, mcBlockPos, previousBlockState);
|
||||
byte newBlockLight = (byte) chunkWrapper.getBlockLight(relBlockX, y + 1, relBlockZ);
|
||||
byte newSkyLight = (byte) chunkWrapper.getSkyLight(relBlockX, y + 1, relBlockZ);
|
||||
|
||||
|
||||
+16
-2
@@ -29,6 +29,7 @@ import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -163,6 +164,9 @@ public class DhLightingEngine
|
||||
// if the dimension has skylights
|
||||
if (maxSkyLight > 0)
|
||||
{
|
||||
IMutableBlockPosWrapper mcBlockPos = chunk.getMutableBlockPosWrapper();
|
||||
IBlockStateWrapper previousBlockState = null;
|
||||
|
||||
int maxY = chunk.getMaxNonEmptyHeight();
|
||||
int minY = chunk.getMinBuildHeight();
|
||||
|
||||
@@ -174,7 +178,7 @@ public class DhLightingEngine
|
||||
// set each pos' sky light all the way down until an opaque block is hit
|
||||
for (int y = maxY; y >= minY; y--)
|
||||
{
|
||||
IBlockStateWrapper block = chunk.getBlockState(relX, y, relZ);
|
||||
IBlockStateWrapper block = previousBlockState = chunk.getBlockState(relX, y, relZ, mcBlockPos, previousBlockState);
|
||||
if (block != null && block.getOpacity() != LodUtil.BLOCK_FULLY_TRANSPARENT)
|
||||
{
|
||||
// keep moving down until we find a non-transparent block
|
||||
@@ -247,6 +251,8 @@ public class DhLightingEngine
|
||||
final DhBlockPosMutable neighbourBlockPos = PRIMARY_BLOCK_POS_REF.get();
|
||||
final DhBlockPosMutable relNeighbourBlockPos = SECONDARY_BLOCK_POS_REF.get();
|
||||
|
||||
IMutableBlockPosWrapper mcBlockPos = null;
|
||||
IBlockStateWrapper previousBlockState = null;
|
||||
|
||||
// update each light position
|
||||
while (!lightPosQueue.isEmpty())
|
||||
@@ -290,7 +296,15 @@ public class DhLightingEngine
|
||||
}
|
||||
|
||||
|
||||
IBlockStateWrapper neighbourBlockState = neighbourChunk.getBlockState(relNeighbourBlockPos);
|
||||
if (mcBlockPos == null)
|
||||
{
|
||||
// it doesn't matter what chunk we get the position object from
|
||||
// TODO move this getter logic out of ChunkWrapper
|
||||
mcBlockPos = neighbourChunk.getMutableBlockPosWrapper();
|
||||
}
|
||||
|
||||
|
||||
IBlockStateWrapper neighbourBlockState = previousBlockState = neighbourChunk.getBlockState(relNeighbourBlockPos, mcBlockPos, previousBlockState);
|
||||
// Math.max(1, ...) is used so that the propagated light level always drops by at least 1, preventing infinite cycles.
|
||||
int targetLevel = lightValue - Math.max(1, neighbourBlockState.getOpacity());
|
||||
if (targetLevel > currentBlockLight)
|
||||
|
||||
+22
-6
@@ -20,15 +20,13 @@
|
||||
package com.seibel.distanthorizons.core.wrapperInterfaces.chunk;
|
||||
|
||||
import com.seibel.distanthorizons.core.generation.AdjacentChunkHolder;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPosMutable;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.sql.dto.BeaconBeamDTO;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IMutableBlockPosWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import com.seibel.distanthorizons.coreapi.interfaces.dependencyInjection.IBindable;
|
||||
@@ -117,6 +115,15 @@ public interface IChunkWrapper extends IBindable
|
||||
|
||||
default IBlockStateWrapper getBlockState(DhBlockPos pos) { return this.getBlockState(pos.getX(), pos.getY(), pos.getZ()); }
|
||||
IBlockStateWrapper getBlockState(int relX, int relY, int relZ);
|
||||
/** @see IChunkWrapper#getBlockState(int, int, int, IMutableBlockPosWrapper, IBlockStateWrapper) */
|
||||
default IBlockStateWrapper getBlockState(DhBlockPos pos, IMutableBlockPosWrapper mcBlockPos, IBlockStateWrapper guess) { return this.getBlockState(pos.getX(), pos.getY(), pos.getZ(), mcBlockPos, guess); }
|
||||
/**
|
||||
* Can be faster than {@link IChunkWrapper#getBlockState} in some cases
|
||||
* due to directly passing in several shared objects.
|
||||
*/
|
||||
IBlockStateWrapper getBlockState(int relX, int relY, int relZ, IMutableBlockPosWrapper mcBlockPos, IBlockStateWrapper guess);
|
||||
|
||||
IMutableBlockPosWrapper getMutableBlockPosWrapper();
|
||||
|
||||
IBiomeWrapper getBiome(int relX, int relY, int relZ);
|
||||
|
||||
@@ -290,6 +297,9 @@ public interface IChunkWrapper extends IBindable
|
||||
int minBuildHeight = this.getMinNonEmptyHeight();
|
||||
int maxBuildHeight = this.getMaxNonEmptyHeight();
|
||||
|
||||
IMutableBlockPosWrapper mcBlockPos = this.getMutableBlockPosWrapper();
|
||||
IBlockStateWrapper previousBlockState = null;
|
||||
|
||||
|
||||
// most blocks (only some blocks are sampled since checking every block is a very slow operation)
|
||||
for (int x = 0; x < LodUtil.CHUNK_WIDTH; x+=2)
|
||||
@@ -298,7 +308,9 @@ public interface IChunkWrapper extends IBindable
|
||||
{
|
||||
for (int y = minBuildHeight; y < maxBuildHeight; y+=2)
|
||||
{
|
||||
hash = (hash * primeBlockMultiplier) + this.getBlockState(x, y, z).hashCode();
|
||||
previousBlockState = this.getBlockState(x, y, z, mcBlockPos, previousBlockState);
|
||||
|
||||
hash = (hash * primeBlockMultiplier) + previousBlockState.hashCode();
|
||||
hash = (hash * primeBiomeMultiplier) + this.getBiome(x, y, z).hashCode();
|
||||
hash = (hash * primeHeightMultiplier) + y;
|
||||
}
|
||||
@@ -311,14 +323,18 @@ public interface IChunkWrapper extends IBindable
|
||||
for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++)
|
||||
{
|
||||
int lightBlockingY = this.getLightBlockingHeightMapValue(x, z);
|
||||
hash = (hash * primeBlockMultiplier) + this.getBlockState(x, lightBlockingY, z).hashCode();
|
||||
previousBlockState = this.getBlockState(x, lightBlockingY, z, mcBlockPos, previousBlockState);
|
||||
|
||||
hash = (hash * primeBlockMultiplier) + previousBlockState.hashCode();
|
||||
hash = (hash * primeBiomeMultiplier) + this.getBiome(x, lightBlockingY, z).hashCode();
|
||||
hash = (hash * primeHeightMultiplier) + lightBlockingY;
|
||||
|
||||
int solidY = this.getSolidHeightMapValue(x, z);
|
||||
if (solidY != lightBlockingY)
|
||||
{
|
||||
hash = (hash * primeBlockMultiplier) + this.getBlockState(x, solidY, z).hashCode();
|
||||
previousBlockState = this.getBlockState(x, lightBlockingY, z, mcBlockPos, previousBlockState);
|
||||
|
||||
hash = (hash * primeBlockMultiplier) + previousBlockState.hashCode();
|
||||
hash = (hash * primeBiomeMultiplier) + this.getBiome(x, solidY, z).hashCode();
|
||||
hash = (hash * primeHeightMultiplier) + solidY;
|
||||
}
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.seibel.distanthorizons.core.wrapperInterfaces.misc;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.IDhApiUnsafeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
|
||||
/**
|
||||
* Currently this wrapper is just used to prevent
|
||||
* accidentally passing in the wrong object to
|
||||
* {@link IChunkWrapper#getBlockState(int, int, int, IMutableBlockPosWrapper, IBlockStateWrapper)}
|
||||
*/
|
||||
public interface IMutableBlockPosWrapper extends IDhApiUnsafeWrapper
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user