Change FullDataPointUtil to get/set sky and block lighting separately

The binary format is identical the only difference is the getter/setter methods
This commit is contained in:
James Seibel
2024-03-02 21:31:21 -06:00
parent 47391028d8
commit 3d999a1749
6 changed files with 40 additions and 36 deletions
@@ -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;
@@ -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);
}
@@ -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++;
}
@@ -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)
);
}
@@ -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)
@@ -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!");