From 0df4011a9a7ad3d3b7a988dc8b5717626c0bf086 Mon Sep 17 00:00:00 2001 From: TomTheFurry Date: Thu, 23 Jun 2022 18:30:33 +0800 Subject: [PATCH] Full Data Source half done! --- .../lod/core/a7/datatype/LodDataSource.java | 1 + .../core/a7/datatype/full/ChunkSizedData.java | 8 ++- .../core/a7/datatype/full/FullDataSource.java | 39 +++++-------- .../lod/core/a7/datatype/full/FullFormat.java | 27 +++++++-- .../datatype/full/IdBiomeBlockStateMap.java | 57 +++++++++++++++++++ .../datatype/full/accessor/FullArrayView.java | 49 ++++++++++++---- .../datatype/full/accessor/IFullDataView.java | 4 ++ .../full/accessor/SingleFullArrayView.java | 27 ++++++++- .../a7/datatype/transform/LodDataBuilder.java | 44 ++++++++++++++ .../core/builders/lodBuilding/LodBuilder.java | 1 - .../block/IBlockStateWrapper.java | 5 ++ .../chunk/IChunkWrapper.java | 3 + 12 files changed, 219 insertions(+), 46 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java create mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockStateWrapper.java diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java b/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java index abd1dc8c0..262302fdc 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java @@ -16,6 +16,7 @@ public interface LodDataSource { byte getDataVersion(); + // Saving related void saveData(ILevel level, DataMetaFile file, OutputStream dataStream) throws IOException; default File generateFilePathAndName(File levelFolderPath, ILevel level, DhSectionPos sectionPos) { diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/full/ChunkSizedData.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/ChunkSizedData.java index 50be6e77d..277203622 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/full/ChunkSizedData.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/ChunkSizedData.java @@ -3,9 +3,11 @@ package com.seibel.lod.core.a7.datatype.full; import com.seibel.lod.core.a7.datatype.full.accessor.FullArrayView; public class ChunkSizedData extends FullArrayView { - private final long[][] chunkDataArray = new long[16*16][]; + public ChunkSizedData() { + super(new IdBiomeBlockStateMap(), new long[16*16][0], 16); + } - public ChunkSizedData(long[][] dataArrays) { - super(dataArrays, 16); + public void setSingleColumn(long[] data, int x, int z) { + dataArrays[x*16+z] = data; } } \ No newline at end of file diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java index 5c501d314..509831024 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java @@ -1,5 +1,7 @@ package com.seibel.lod.core.a7.datatype.full; +import com.seibel.lod.core.a7.datatype.column.ColumnRenderSource; +import com.seibel.lod.core.a7.datatype.full.accessor.FullArrayView; import com.seibel.lod.core.a7.level.ILevel; import com.seibel.lod.core.a7.save.io.file.DataMetaFile; import com.seibel.lod.core.a7.datatype.LodDataSource; @@ -12,11 +14,15 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; -public class FullDataSource implements LodDataSource { // 1 chunk - private DhSectionPos sectionPos; - ArrayList idMap; - protected FullDataSource() { - idMap = new ArrayList(); +public class FullDataSource extends FullArrayView implements LodDataSource { // 1 chunk + public static final byte SECTION_SIZE_OFFSET = ColumnRenderSource.SECTION_SIZE_OFFSET; + public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET; + public static final byte LATEST_VERSION = 0; + private final DhSectionPos sectionPos; + private int localVersion = 0; + protected FullDataSource(DhSectionPos sectionPos) { + super(new IdBiomeBlockStateMap(), new long[SECTION_SIZE*SECTION_SIZE][0], SECTION_SIZE); + this.sectionPos = sectionPos; } @Override @@ -26,36 +32,21 @@ public class FullDataSource implements LodDataSource { // 1 chunk @Override public byte getDataDetail() { - return 0; + return (byte) (sectionPos.sectionDetail-SECTION_SIZE_OFFSET); } @Override public void setLocalVersion(int localVer) { - + localVersion = localVer; } @Override public byte getDataVersion() { - return 0; + return LATEST_VERSION; } @Override public void saveData(ILevel level, DataMetaFile file, OutputStream dataStream) throws IOException { - - } - - public static FullDataSource createNewFromChunk(IChunkWrapper chunk) { - FullDataSource dataContainer = new FullDataSource(); - HashMap idMap = new HashMap(); - - idMap.put(IdMappingUtil.BLOCKSTATE_ID_AIR, 0); - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - int y = chunk.getMaxY(x, z); - String currentBlockState = IdMappingUtil.BLOCKSTATE_ID_AIR; - // FIXME: Move LodBuilder code to here - } - } - return dataContainer; + //TODO } } diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java index 84f8f3d43..3d0d5b129 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java @@ -2,35 +2,42 @@ package com.seibel.lod.core.a7.datatype.full; // Static class for the data format: // ID: blockState id Y: Height(signed) DP: Depth(signed?) +// BL: Block light SL: Sky light // =======Bit layout======= -// __ __ __ __ __ __ __ __ <-- Top bits +// BL BL BL BL SL SL SL SL <-- Top bits // YY YY YY YY YY YY YY YY -// YY YY YY YY DP DP -// DP DP DP DP DP DP DP DP DP DP +// YY YY YY YY DP DP DP DP +// DP DP DP DP DP DP DP DP // ID ID ID ID ID ID IO ID // ID ID ID ID ID ID IO ID // ID ID ID ID ID ID IO ID // ID ID ID ID ID ID IO ID <-- Bottom bits -// + +import org.jetbrains.annotations.Contract; public class FullFormat { 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 ID_OFFSET = 0; public static final int DP_OFFSET = ID_OFFSET + ID_WIDTH; public static final int Y_OFFSET = DP_OFFSET + DP_WIDTH; + public static final int LIGHT_OFFSET = Y_OFFSET + Y_WIDTH; - public static final int ID_MASK = (int)Math.pow(2, ID_WIDTH) - 1; + + 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 long encode(int id, int depth, int y) { + public static long encode(int id, int depth, int y, byte lightPair) { long data = 0; data |= id & ID_MASK; data |= (long) (depth & DP_MASK) << DP_OFFSET; data |= (long) (y & Y_MASK) << Y_OFFSET; + data |= (long) lightPair << LIGHT_OFFSET; return data; } @@ -46,4 +53,12 @@ public class FullFormat { return (int) (data << (64 - Y_OFFSET - Y_WIDTH) >> Y_OFFSET); } + public static byte getLight(long data) { + return (byte) (data << (64 - LIGHT_OFFSET - LIGHT_WIDTH) >> LIGHT_OFFSET); + } + + @Contract(pure = true) + public static long remap(int[] mapping, long data) { + return (data & INVERSE_ID_MASK) | mapping[(int)data]; + } } diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java new file mode 100644 index 000000000..2d963971f --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java @@ -0,0 +1,57 @@ +package com.seibel.lod.core.a7.datatype.full; + +import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Objects; + +// WARNING: This is not THREAD-SAFE! +public class IdBiomeBlockStateMap { + public static final class Entry { + public final IBiomeWrapper biome; + public final IBlockStateWrapper blockState; + public Entry(IBiomeWrapper biome, IBlockStateWrapper blockState) { + this.biome = biome; + this.blockState = blockState; + } + @Override + public int hashCode() { + return Objects.hash(biome, blockState); + } + } + + + final ArrayList entries = new ArrayList<>(); + final HashMap idMap = new HashMap<>(); + + public Entry get(int id) { + return entries.get(id); + } + + public int setAndGetId(IBiomeWrapper biome, IBlockStateWrapper blockState) { + return idMap.computeIfAbsent(new Entry(biome, blockState), (e) -> { + int id = entries.size(); + entries.add(e); + return id; + }); + } + public int setAndGetId(Entry biomeBlockStateEntry) { + return idMap.computeIfAbsent(biomeBlockStateEntry, (e) -> { + int id = entries.size(); + entries.add(e); + return id; + }); + } + + public int[] computeAndMergeMapFrom(IdBiomeBlockStateMap target) { + ArrayList mergeEntry = target.entries; + int[] mapper = new int[mergeEntry.size()]; + for (int i=0; i=chunk.getMinBuildHeight(); y--) { + IBiomeWrapper newBiome = chunk.getBiome(x, y, z); + IBlockStateWrapper newBlockState = chunk.getBlockState(x, y, z); + byte newLight = (byte) (chunk.getBlockLight(x,y,z) << 4 + chunk.getSkyLight(x,y,z)); + if (!newBiome.equals(biome) || !newBlockState.equals(blockState)) { + longs.add(FullFormat.encode(mappedId, lastY-y+1, y+1, light)); + biome = newBiome; + blockState = newBlockState; + mappedId = chunkData.getMapping().setAndGetId(biome, blockState); + light = newLight; + lastY = y; + } else if (newLight != light) { + longs.add(FullFormat.encode(mappedId, lastY-y+1, y+1, light)); + light = newLight; + lastY = y; + } + } + longs.add(FullFormat.encode(mappedId, lastY-y+1, y+1, light)); + chunkData.setSingleColumn(longs.toArray((long[]) null), x, z); + } + } + + return chunkData; + } + + public static boolean canGenerateLodFromChunk(IChunkWrapper chunk) + { + return chunk != null && + chunk.isLightCorrect(); } } diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index 80a777b56..777fd5312 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -215,7 +215,6 @@ public class LodBuilder return chunk != null && chunk.isLightCorrect() && chunk.doesNearbyChunksExist(); } - private boolean writeAllLodNodeData(LodDimension lodDim, LodRegion region, int chunkX, int chunkZ, long[] data, LodBuilderConfig config, boolean override) { diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockStateWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockStateWrapper.java new file mode 100644 index 000000000..9ae724794 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/block/IBlockStateWrapper.java @@ -0,0 +1,5 @@ +package com.seibel.lod.core.wrapperInterfaces.block; + +public interface IBlockStateWrapper { + IBlockStateWrapper AIR = null; +} diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java index 14827bd91..286563420 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/chunk/IChunkWrapper.java @@ -23,6 +23,7 @@ import com.seibel.lod.core.enums.ELodDirection; import com.seibel.lod.core.handlers.dependencyInjection.IBindable; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; +import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; /** @@ -99,4 +100,6 @@ public interface IChunkWrapper extends IBindable return hash; } + + IBlockStateWrapper getBlockState(int x, int y, int z); }