From e83f7bd62ee39ceddbadf2c6013d39c7e604eb60 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Tue, 12 Mar 2024 21:00:50 -0500 Subject: [PATCH] Add FullDataPointUtilV1 for use with CompleteFullDataSource --- .../fullData/sources/NewFullDataSource.java | 14 +-- .../core/util/FullDataPointUtil.java | 8 +- .../core/util/FullDataPointUtilV1.java | 108 ++++++++++++++++++ 3 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtilV1.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/NewFullDataSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/NewFullDataSource.java index 43b83cbf3..53091e49c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/NewFullDataSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/NewFullDataSource.java @@ -25,11 +25,11 @@ import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.SingleColum import com.seibel.distanthorizons.core.dataObjects.transformers.LodDataBuilder; import com.seibel.distanthorizons.core.file.IDataSource; import com.seibel.distanthorizons.core.file.fullDatafile.NewFullDataFileHandler; -import com.seibel.distanthorizons.core.generation.DhLightingEngine; import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.util.FullDataPointUtil; +import com.seibel.distanthorizons.core.util.FullDataPointUtilV1; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.RenderDataPointUtil; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataOutputStream; @@ -171,13 +171,13 @@ public class NewFullDataSource implements IDataSource { long dataPoint = dataColumn[i]; - int id = FullDataPointUtil.getId(dataPoint); - int height = FullDataPointUtil.getHeight(dataPoint); - int bottomY = FullDataPointUtil.getBottomY(dataPoint); - byte blockLight = (byte) FullDataPointUtil.getBlockLight(dataPoint); - byte skyLight = (byte) FullDataPointUtil.getSkyLight(dataPoint); + int id = FullDataPointUtilV1.getId(dataPoint); + int height = FullDataPointUtilV1.getHeight(dataPoint); + int bottomY = FullDataPointUtilV1.getBottomY(dataPoint); + byte blockLight = (byte) FullDataPointUtilV1.getBlockLight(dataPoint); + byte skyLight = (byte) FullDataPointUtilV1.getSkyLight(dataPoint); - long newDataPoint = FullDataPointUtil.encode(id, height, bottomY, skyLight, blockLight); + long newDataPoint = FullDataPointUtil.encode(id, height, bottomY, blockLight, skyLight); dataColumn[i] = newDataPoint; 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 9862120e6..1e1ebfc49 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 @@ -25,9 +25,7 @@ import org.jetbrains.annotations.Contract; * A helper class that is used to access the data from a long * formatted as a full data point.
* A full data point contains the most information and is the - * base truth used when creating render data.

- * - * To access data from a long formatted as a render data point see: {@link RenderDataPointUtil}

+ * source of truth used when creating render data.

* * DataPoint Format:
* @@ -47,10 +45,10 @@ import org.jetbrains.annotations.Contract; * ID ID ID ID ID ID ID ID
* ID ID ID ID ID ID ID ID <-- Bottom bits
*
- * + * * @see RenderDataPointUtil + * @see FullDataPointUtilV1 */ -// TODO make a legacy version of this specifically for CompleteFullDataSource just in case things change in the future public class FullDataPointUtil { /** Represents the data held by an empty data point */ diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtilV1.java b/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtilV1.java new file mode 100644 index 000000000..aa40ee8a3 --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/FullDataPointUtilV1.java @@ -0,0 +1,108 @@ +package com.seibel.distanthorizons.core.util; + +import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource; + +/** + * Only for Legacy support
+ * Used by DH versions 2.0.0 and 2.0.1.

+ * + * Specifically used by the data sources:
+ * - {@link CompleteFullDataSource} aka CompleteFullDataSource
+ * - (Deleted) HighDetailIncompleteFullDataSource
+ * - (Deleted) LowDetailIncompleteFullDataSource

+ * + * DataPoint Format:
+ * + * ID: blockState id
+ * MY: Min Y Height (unsigned, relative to the minimum level height)
+ * HI: Height (how tall this data point is in blocks)
+ * BL: Block light
+ * SL: Sky light

+ * + * =======Bit layout=======
+ * SL SL SL SL BL BL BL BL <-- Top bits
+ * MY MY MY MY MY MY MY MY
+ * MY MY MY MY HI HI HI HI
+ * HI HI HI HI HI HI HI HI
+ * ID ID ID ID ID ID ID ID
+ * ID ID ID ID ID ID ID ID
+ * ID ID ID ID ID ID ID ID
+ * ID ID ID ID ID ID ID ID <-- Bottom bits
+ *
+ * + * @see CompleteFullDataSource + * @see FullDataPointUtil + */ +public class FullDataPointUtilV1 +{ + /** Represents the data held by an empty data point */ + public static final int EMPTY_DATA_POINT = 0; + + public static final int ID_WIDTH = 32; + public static final int HEIGHT_WIDTH = 12; + public static final int MIN_Y_WIDTH = 12; + public static final int SKY_LIGHT_WIDTH = 4; + public static final int BLOCK_LIGHT_WIDTH = 4; + + public static final int ID_OFFSET = 0; + public static final int HEIGHT_OFFSET = ID_OFFSET + ID_WIDTH; + /** indicates the Y position where the LOD starts relative to the level's minimum height */ + public static final int MIN_Y_OFFSET = HEIGHT_OFFSET + HEIGHT_WIDTH; + public static final int SKY_LIGHT_OFFSET = MIN_Y_OFFSET + MIN_Y_WIDTH; + public static final int BLOCK_LIGHT_OFFSET = SKY_LIGHT_OFFSET + SKY_LIGHT_WIDTH; + + + public static final long ID_MASK = Integer.MAX_VALUE; + public static final long INVERSE_ID_MASK = ~ID_MASK; + public static final int HEIGHT_MASK = (int) Math.pow(2, HEIGHT_WIDTH) - 1; + public static final int MIN_Y_MASK = (int) Math.pow(2, MIN_Y_WIDTH) - 1; + public static final int SKY_LIGHT_MASK = (int) Math.pow(2, SKY_LIGHT_WIDTH) - 1; + public static final int BLOCK_LIGHT_MASK = (int) Math.pow(2, BLOCK_LIGHT_WIDTH) - 1; + + + /** + * creates a new datapoint with the given values + * @param relMinY relative to the minimum level Y value + * + * @deprecated Should not be used anymore, just here as a reference for how the data points were constructed. + */ + @Deprecated + public static long encode(int id, int height, int relMinY, byte blockLight, byte skyLight) + { + LodUtil.assertTrue(relMinY >= 0 && relMinY < RenderDataPointUtil.MAX_WORLD_Y_SIZE, "Trying to create datapoint with y["+relMinY+"] out of range!"); + LodUtil.assertTrue(height > 0 && height < RenderDataPointUtil.MAX_WORLD_Y_SIZE, "Trying to create datapoint with height["+height+"] out of range!"); + LodUtil.assertTrue(relMinY + height <= RenderDataPointUtil.MAX_WORLD_Y_SIZE, "Trying to create datapoint with y+depth["+(relMinY+height)+"] out of range!"); + + long data = 0; + data |= id & ID_MASK; + data |= (long) (height & HEIGHT_MASK) << HEIGHT_OFFSET; + data |= (long) (relMinY & MIN_Y_MASK) << MIN_Y_OFFSET; + data |= (long) blockLight << BLOCK_LIGHT_OFFSET; + data |= (long) skyLight << SKY_LIGHT_OFFSET; + + LodUtil.assertTrue(getId(data) == id && getHeight(data) == height && getBottomY(data) == relMinY && getBlockLight(data) == Byte.toUnsignedInt(blockLight) && getSkyLight(data) == Byte.toUnsignedInt(skyLight), + "Trying to create datapoint with " + + "id[" + id + "], height[" + height + "], minY[" + relMinY + "], blockLight[" + blockLight + "], skyLight[" + skyLight + "] " + + "but got " + + "id[" + getId(data) + "], height[" + getHeight(data) + "], minY[" + getBottomY(data) + "], blockLight[" + getBlockLight(data) + "], skyLight[" + getSkyLight(data) + "]!"); + + return data; + } + + + /** Returns the BlockState/Biome pair ID used to identify this LOD's color */ + public static int getId(long data) { return (int) (data & ID_MASK); } + /** Returns how many blocks tall this LOD is. */ + public static int getHeight(long data) { return (int) ((data >> HEIGHT_OFFSET) & HEIGHT_MASK); } + /** + * Returns the unsigned block position of the bottom vertices for this LOD relative to the level's minimum height. + * Should be between 0 and {@link RenderDataPointUtil#MAX_WORLD_Y_SIZE} + */ + public static int getBottomY(long data) { return (int) ((data >> MIN_Y_OFFSET) & MIN_Y_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) + ",BlockLight:" + getBlockLight(data) + ",SkyLight:" + getSkyLight(data) + "]"; } + +}