diff --git a/api/src/main/java/com/seibel/distanthorizons/api/objects/data/DhApiTerrainDataPoint.java b/api/src/main/java/com/seibel/distanthorizons/api/objects/data/DhApiTerrainDataPoint.java index d78ca58e2..0c70dfbfb 100644 --- a/api/src/main/java/com/seibel/distanthorizons/api/objects/data/DhApiTerrainDataPoint.java +++ b/api/src/main/java/com/seibel/distanthorizons/api/objects/data/DhApiTerrainDataPoint.java @@ -40,7 +40,8 @@ public class DhApiTerrainDataPoint */ public final byte detailLevel; - public final int lightLevel; + public final int blockLightLevel; + public final int skyLightLevel; public final int topYBlockPos; public final int bottomYBlockPos; @@ -49,11 +50,12 @@ public class DhApiTerrainDataPoint - public DhApiTerrainDataPoint(byte detailLevel, int lightLevel, int topYBlockPos, int bottomYBlockPos, IDhApiBlockStateWrapper blockStateWrapper, IDhApiBiomeWrapper biomeWrapper) + public DhApiTerrainDataPoint(byte detailLevel, int blockLightLevel, int skyLightLevel, int topYBlockPos, int bottomYBlockPos, IDhApiBlockStateWrapper blockStateWrapper, IDhApiBiomeWrapper biomeWrapper) { this.detailLevel = detailLevel; - this.lightLevel = lightLevel; + this.blockLightLevel = blockLightLevel; + this.skyLightLevel = skyLightLevel; this.topYBlockPos = topYBlockPos; this.bottomYBlockPos = bottomYBlockPos; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java index 0cc87f208..c67342fac 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/external/methods/data/DhApiTerrainDataRepo.java @@ -290,7 +290,8 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo int topY = bottomY + height; return new DhApiTerrainDataPoint(detailLevel, - FullDataPointUtil.getLight(dataPoint), topY, bottomY, + FullDataPointUtil.getBlockLight(dataPoint), FullDataPointUtil.getSkyLight(dataPoint), + topY, bottomY, blockState, biomeWrapper); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/FullDataToRenderDataTransformer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/FullDataToRenderDataTransformer.java index 6c6451ecb..7ac3a5e9d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/FullDataToRenderDataTransformer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/FullDataToRenderDataTransformer.java @@ -178,7 +178,8 @@ public class FullDataToRenderDataTransformer int bottomY = FullDataPointUtil.getBottomY(fullData); int blockHeight = FullDataPointUtil.getHeight(fullData); int id = FullDataPointUtil.getId(fullData); - int light = FullDataPointUtil.getLight(fullData); + int blockLight = FullDataPointUtil.getBlockLight(fullData); + int skyLight = FullDataPointUtil.getSkyLight(fullData); // TODO how should corrupted data be handled? // TODO why is the full data corrupted in the first place? FullDataPointUtil hasn't been changed in a long time, could one of the full data point objects be corrupted? @@ -257,7 +258,7 @@ public class FullDataToRenderDataTransformer // add the block isVoid = false; - long columnData = RenderDataPointUtil.createDataPoint(bottomY + blockHeight, bottomY, color, light, block.getIrisBlockMaterialId()); + long columnData = RenderDataPointUtil.createDataPoint(bottomY + blockHeight, bottomY, color, skyLight, blockLight, block.getIrisBlockMaterialId()); column.set(columnOffset, columnData); columnOffset++; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java index 65c043fda..7b560e3d5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/transformers/LodDataBuilder.java @@ -137,7 +137,8 @@ public class LodDataBuilder IBlockStateWrapper blockState = AIR; int mappedId = dataSource.getMapping().addIfNotPresentAndGetId(biome, blockState); // FIXME: The lastY +1 offset is to reproduce the old behavior. Remove this when we get per-face lighting - byte light = (byte) ((chunkWrapper.getBlockLight(chunkX, lastY + 1, chunkZ) << 4) + chunkWrapper.getSkyLight(chunkX, lastY + 1, chunkZ)); + byte blockLight = (byte) chunkWrapper.getBlockLight(chunkX, lastY + 1, chunkZ); + byte skyLight = (byte) chunkWrapper.getSkyLight(chunkX, lastY + 1, chunkZ); // determine the starting Y Pos @@ -171,19 +172,21 @@ public class LodDataBuilder { IBiomeWrapper newBiome = chunkWrapper.getBiome(chunkX, y, chunkZ); IBlockStateWrapper newBlockState = chunkWrapper.getBlockState(chunkX, y, chunkZ); - byte newLight = (byte) ((chunkWrapper.getBlockLight(chunkX, y + 1, chunkZ) << 4) + chunkWrapper.getSkyLight(chunkX, y + 1, chunkZ)); + byte newBlockLight = (byte) chunkWrapper.getBlockLight(chunkX, y + 1, chunkZ); + byte newSkyLight = (byte) chunkWrapper.getSkyLight(chunkX, y + 1, chunkZ); if (!newBiome.equals(biome) || !newBlockState.equals(blockState)) { - longs.add(FullDataPointUtil.encode(mappedId, lastY - y, y + 1 - chunkWrapper.getMinBuildHeight(), light)); + longs.add(FullDataPointUtil.encode(mappedId, lastY - y, y + 1 - chunkWrapper.getMinBuildHeight(), blockLight, skyLight)); biome = newBiome; blockState = newBlockState; mappedId = dataSource.getMapping().addIfNotPresentAndGetId(biome, blockState); - light = newLight; + blockLight = newBlockLight; + skyLight = newSkyLight; lastY = y; } } - longs.add(FullDataPointUtil.encode(mappedId, lastY - y, y + 1 - chunkWrapper.getMinBuildHeight(), light)); + longs.add(FullDataPointUtil.encode(mappedId, lastY - y, y + 1 - chunkWrapper.getMinBuildHeight(), blockLight, skyLight)); dataSource.setSingleColumn(longs.toLongArray(), chunkX + chunkOffsetX, @@ -228,7 +231,8 @@ public class LodDataBuilder id, dataPoint.topYBlockPos - dataPoint.bottomYBlockPos, dataPoint.bottomYBlockPos - dataPoints.topYBlockPos, - (byte) (dataPoint.lightLevel) + (byte) (dataPoint.blockLightLevel), + (byte) (dataPoint.skyLightLevel) ); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtil.java index 9360c3ac5..04d65bb4f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtil.java @@ -60,23 +60,26 @@ public class FullDataPointUtil public static final int ID_WIDTH = 32; public static final int DP_WIDTH = 12; public static final int Y_WIDTH = 12; - public static final int LIGHT_WIDTH = 8; + public static final int BLOCK_LIGHT_WIDTH = 4; + public static final int SKY_LIGHT_WIDTH = 4; public static final int ID_OFFSET = 0; public static final int DP_OFFSET = ID_OFFSET + ID_WIDTH; /** indicates the Y position where the LOD starts relative to the level's minimum height */ public static final int Y_OFFSET = DP_OFFSET + DP_WIDTH; - public static final int LIGHT_OFFSET = Y_OFFSET + Y_WIDTH; + public static final int BLOCK_LIGHT_OFFSET = Y_OFFSET + Y_WIDTH; + public static final int SKY_LIGHT_OFFSET = BLOCK_LIGHT_OFFSET + BLOCK_LIGHT_WIDTH; public static final long ID_MASK = Integer.MAX_VALUE; public static final long INVERSE_ID_MASK = ~ID_MASK; public static final int DP_MASK = (int) Math.pow(2, DP_WIDTH) - 1; public static final int Y_MASK = (int) Math.pow(2, Y_WIDTH) - 1; - public static final int LIGHT_MASK = (int) Math.pow(2, LIGHT_WIDTH) - 1; + public static final int BLOCK_LIGHT_MASK = (int) Math.pow(2, BLOCK_LIGHT_WIDTH) - 1; + public static final int SKY_LIGHT_MASK = (int) Math.pow(2, SKY_LIGHT_WIDTH) - 1; /** creates a new datapoint with the given values */ - public static long encode(int id, int depth, int y, byte lightPair) + public static long encode(int id, int depth, int y, byte blockLight, byte skyLight) { LodUtil.assertTrue(y >= 0 && y < RenderDataPointUtil.MAX_WORLD_Y_SIZE, "Trying to create datapoint with y[{}] out of range!", y); LodUtil.assertTrue(depth > 0 && depth < RenderDataPointUtil.MAX_WORLD_Y_SIZE, "Trying to create datapoint with depth[{}] out of range!", depth); @@ -86,10 +89,16 @@ public class FullDataPointUtil data |= id & ID_MASK; data |= (long) (depth & DP_MASK) << DP_OFFSET; data |= (long) (y & Y_MASK) << Y_OFFSET; - data |= (long) lightPair << LIGHT_OFFSET; - LodUtil.assertTrue(getId(data) == id && getHeight(data) == depth && getBottomY(data) == y && getLight(data) == Byte.toUnsignedInt(lightPair), - "Trying to create datapoint with id[{}], depth[{}], y[{}], lightPair[{}] but got id[{}], depth[{}], y[{}], lightPair[{}]!", - id, depth, y, Byte.toUnsignedInt(lightPair), getId(data), getHeight(data), getBottomY(data), getLight(data)); + data |= (long) blockLight << BLOCK_LIGHT_OFFSET; + data |= (long) skyLight << SKY_LIGHT_OFFSET; + + // confirm the written data can still be retrieved + LodUtil.assertTrue( + getId(data) == id && getHeight(data) == depth && getBottomY(data) == y && getBlockLight(data) == Byte.toUnsignedInt(blockLight) && getSkyLight(data) == Byte.toUnsignedInt(skyLight), + "Trying to create datapoint with " + + "id[" + id + "], height[" + depth + "], minY[" + y + "], blockLight[" + blockLight + "], skyLight[" + skyLight + "] " + + "but got " + + "id[" + getId(data) + "], height[" + getHeight(data) + "], minY[" + getBottomY(data) + "], blockLight[" + getBlockLight(data) + "], skyLight[" + getSkyLight(data) + "]!"); return data; } @@ -100,9 +109,10 @@ public class FullDataPointUtil public static int getHeight(long data) { return (int) ((data >> DP_OFFSET) & DP_MASK); } /** Returns the block position of the bottom vertices for this LOD relative to the level's minimum height. */ public static int getBottomY(long data) { return (int) ((data >> Y_OFFSET) & Y_MASK); } - public static int getLight(long data) { return (int) ((data >> LIGHT_OFFSET) & LIGHT_MASK); } + public static int getBlockLight(long data) { return (int) ((data >> BLOCK_LIGHT_OFFSET) & BLOCK_LIGHT_MASK); } + public static int getSkyLight(long data) { return (int) ((data >> SKY_LIGHT_OFFSET) & SKY_LIGHT_MASK); } - public static String toString(long data) { return "[ID:" + getId(data) + ",Y:" + getBottomY(data) + ",Height:" + getHeight(data) + ",Light:" + getLight(data) + "]"; } + public static String toString(long data) { return "[ID:" + getId(data) + ",Y:" + getBottomY(data) + ",Height:" + getHeight(data) + ",BlockLight:" + getBlockLight(data) + ",SkyLight:" + getSkyLight(data) + "]"; } /** Remaps the biome/blockState ID of the given datapoint */ @Contract(pure = true) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java index 1a110fc2a..240a0b4aa 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/RenderDataPointUtil.java @@ -121,20 +121,6 @@ public class RenderDataPointUtil height, depth, lightSky, lightBlock, irisBlockMaterialId); } - public static long createDataPoint(int height, int depth, int color, int light, int irisBlockMaterialId) - { - LodUtil.assertTrue(light >= 0 && light < 256, "Raw Light value must be between 0 and 255!"); - - return createDataPoint( - ColorUtil.getAlpha(color), - ColorUtil.getRed(color), - ColorUtil.getGreen(color), - ColorUtil.getBlue(color), - height, depth, - light % 16, light / 16, - irisBlockMaterialId); - } - public static long createDataPoint(int alpha, int red, int green, int blue, int height, int depth, int lightSky, int lightBlock, int irisBlockMaterialId) { LodUtil.assertTrue(height >= 0 && height < MAX_WORLD_Y_SIZE, "Trying to create datapoint with height[" + height + "] out of range!");