From 037e890d0d67ad9d62f8ea9a9613940a6d5c4a34 Mon Sep 17 00:00:00 2001 From: TomTheFurry Date: Fri, 6 May 2022 15:02:45 +0800 Subject: [PATCH] Make some more change, (and also lost my changes... rip) --- .../lod/core/objects/a7/LodDataSource.java | 9 +- .../lod/core/objects/a7/LodQuadTree.java | 12 +- .../lod/core/objects/a7/LodSection.java | 385 ++---------------- .../lod/core/objects/a7/LodSubRegion.java | 37 -- .../core/objects/a7/RenderDataContaioner.java | 371 +++++++++++++++++ .../seibel/lod/core/objects/a7/data/Data.java | 49 +++ .../objects/a7/data/LodDataContainer.java | 23 ++ 7 files changed, 475 insertions(+), 411 deletions(-) delete mode 100644 src/main/java/com/seibel/lod/core/objects/a7/LodSubRegion.java create mode 100644 src/main/java/com/seibel/lod/core/objects/a7/RenderDataContaioner.java create mode 100644 src/main/java/com/seibel/lod/core/objects/a7/data/Data.java create mode 100644 src/main/java/com/seibel/lod/core/objects/a7/data/LodDataContainer.java diff --git a/src/main/java/com/seibel/lod/core/objects/a7/LodDataSource.java b/src/main/java/com/seibel/lod/core/objects/a7/LodDataSource.java index 13f4e7623..099f46667 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/LodDataSource.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/LodDataSource.java @@ -1,9 +1,8 @@ package com.seibel.lod.core.objects.a7; -import com.seibel.lod.core.objects.lod.LevelContainer; - public interface LodDataSource { - LevelContainer readLodData(byte detailLevel, int x, int z); - boolean canSave(); - boolean saveLodData(LevelContainer levelContainer, byte detailLevel, int x, int z); + RenderDataContaioner createRenderData(byte detailLevel, int x, int z); + + + boolean saveLodData(RenderDataContaioner levelContainer, byte detailLevel, int x, int z); } diff --git a/src/main/java/com/seibel/lod/core/objects/a7/LodQuadTree.java b/src/main/java/com/seibel/lod/core/objects/a7/LodQuadTree.java index 94435935b..8beac3f03 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/LodQuadTree.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/LodQuadTree.java @@ -7,7 +7,7 @@ import com.seibel.lod.core.util.gridList.MovableGridRingList; public class LodQuadTree { public final int maxPossibleDetailLevel; - private final MovableGridRingList[] ringLists; + private final MovableGridRingList[] ringLists; public LodQuadTree(int viewDistance, int initialPlayerX, int initialPlayerZ) { maxPossibleDetailLevel = DetailDistanceUtil.getDetailLevelFromDistance(viewDistance*Math.sqrt(2)); @@ -16,17 +16,9 @@ public class LodQuadTree { for (int detailLevel = 0; detailLevel < maxPossibleDetailLevel; detailLevel++) { double distance = DetailDistanceUtil.getDrawDistanceFromDetail(detailLevel); int blockCount = ((int)Math.ceil(distance / (1 << detailLevel))); - ringLists[detailLevel] = new MovableGridRingList(blockCount, initialPlayerX >> detailLevel, initialPlayerZ >> detailLevel); + ringLists[detailLevel] = new MovableGridRingList(blockCount, initialPlayerX >> detailLevel, initialPlayerZ >> detailLevel); size = ringLists[detailLevel].getSize(); - for(int sectionIndexX = 0; sectionIndexX < size; sectionIndexX++) - { - for(int sectionIndexZ = 0; sectionIndexZ < size; sectionIndexZ++) - { - ringLists[detailLevel].set(sectionIndexX, sectionIndexZ, new LodSection(sectionIndexX)) - } - } } - } diff --git a/src/main/java/com/seibel/lod/core/objects/a7/LodSection.java b/src/main/java/com/seibel/lod/core/objects/a7/LodSection.java index ed3b3b927..3437d8622 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/LodSection.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/LodSection.java @@ -1,371 +1,38 @@ package com.seibel.lod.core.objects.a7; -import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.objects.LodDataView; -import com.seibel.lod.core.objects.lod.LevelContainer; import com.seibel.lod.core.objects.lod.VerticalLevelContainer; -import com.seibel.lod.core.util.DataPointUtil; -import com.seibel.lod.core.util.DetailDistanceUtil; -import com.seibel.lod.core.util.LodUtil; -import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Arrays; +public class LodSection { + public static final int SUB_REGION_DATA_WIDTH = 16*16; -public class LodSection -{ - public static final boolean DO_SAFETY_CHECKS = true; - - private final short minHeight; public final byte detailLevel; - public final int SECTION_SIZE = 128; - public final int verticalSize; - - public final long[] dataContainer; - - public LodSection(byte detailLevel) - { + public final int x; + public final int z; + private RenderDataContaioner levelContainer; + private RenderContainer renderContainer = null; + + // Create sub region + public LodSection(byte detailLevel, int x, int z) { this.detailLevel = detailLevel; - verticalSize = DetailDistanceUtil.getMaxVerticalData(detailLevel); - dataContainer = new long[SECTION_SIZE * SECTION_SIZE * DetailDistanceUtil.getMaxVerticalData(detailLevel)]; - minHeight = SingletonHandler.get(IMinecraftClientWrapper.class).getWrappedClientWorld().getMinHeight(); + this.x = x; + this.z = z; + levelContainer = null; } - - public byte getDetailLevel() - { - return detailLevel; + LodSection(byte detailLevel, int x, int z, RenderDataContaioner levelContainer) { + this.detailLevel = detailLevel; + this.x = x; + this.z = z; + this.levelContainer = levelContainer; } - - public void clear(int posX, int posZ) - { - for (int verticalIndex = 0; verticalIndex < verticalSize; verticalIndex++) - dataContainer[posX * SECTION_SIZE * verticalSize + posZ * verticalSize + verticalIndex] = DataPointUtil.EMPTY_DATA; - } - - public boolean addData(long data, int posX, int posZ, int verticalIndex) - { - dataContainer[posX * SECTION_SIZE * verticalSize + posZ * verticalSize + verticalIndex] = data; - return true; - } - - private void forceWriteVerticalData(long[] data, int posX, int posZ) - { - int index = posX * SECTION_SIZE * verticalSize + posZ * verticalSize; - if (verticalSize >= 0) System.arraycopy(data, 0, dataContainer, index + 0, verticalSize); - } - - public boolean addVerticalData(long[] data, int posX, int posZ, boolean override) - { - int index = posX * SECTION_SIZE * verticalSize + posZ * verticalSize; - int compare = DataPointUtil.compareDatapointPriority(data[0], dataContainer[index]); - if (override) { - if (compare<0) return false; - } else { - if (compare<=0) return false; + + // Return null if data does not exist + public static LodSection loadSection(byte detailLevel, int x, int z, LodDataSource lodDataSource) { + RenderDataContaioner data = lodDataSource.createRenderData(detailLevel, x, z); + if (data == null) { + return null; } - forceWriteVerticalData(data, posX, posZ); - return true; + return new LodSection(detailLevel, x, z, data); } - - public boolean copyVerticalData(LodDataView data, int posX, int posZ, boolean override) { - if (DO_SAFETY_CHECKS) { - if (data.size() != verticalSize) - throw new IllegalArgumentException("data size not the same as vertical size"); - if (posX < 0 || posX >= SECTION_SIZE) - throw new IllegalArgumentException("X position is out of bounds"); - if (posZ < 0 || posZ >= SECTION_SIZE) - throw new IllegalArgumentException("Z position is out of bounds"); - } - int index = posX * SECTION_SIZE * verticalSize + posZ * verticalSize; - int compare = DataPointUtil.compareDatapointPriority(data.get(0), dataContainer[index]); - if (override) { - if (compare<0) return false; - } else { - if (compare<=0) return false; - } - data.copyTo(dataContainer, index); - return true; - } - - public boolean addChunkOfData(long[] data, int posX, int posZ, int widthX, int widthZ, boolean override) - { - boolean anyChange = false; - if (posX+widthX > SECTION_SIZE || posZ+widthZ > SECTION_SIZE) - throw new IndexOutOfBoundsException("addChunkOfData param not inside valid range"); - if (widthX*widthZ*verticalSize != data.length) - throw new IndexOutOfBoundsException("addChunkOfData data array not sized correctly to contain the data to be copied"); - if (posX<0 || posZ<0 || widthX<0 || widthZ<0) - throw new IndexOutOfBoundsException("addChunkOfData param is negative"); - - for (int ox=0; ox SECTION_SIZE || posZ+widthZ > SECTION_SIZE) - throw new IndexOutOfBoundsException("addChunkOfData param not inside valid range"); - if (widthX*widthZ*verticalSize != data.size()) - throw new IndexOutOfBoundsException("addChunkOfData data array not sized correctly to contain the data to be copied"); - if (posX<0 || posZ<0 || widthX<0 || widthZ<0) - throw new IndexOutOfBoundsException("addChunkOfData param is negative"); - - for (int ox=0; ox tLocalVerticalUpdateArrays = ThreadLocal.withInitial(() -> - { - return new long[LodUtil.DETAIL_OPTIONS - 1][]; - }); - - public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ) - { - //We reset the array - long[][] verticalUpdateArrays = tLocalVerticalUpdateArrays.get(); - long[] dataToMerge = verticalUpdateArrays[detailLevel-1]; - int arrayLength = DetailDistanceUtil.getMaxVerticalData(detailLevel-1) * 4; - if (dataToMerge == null || dataToMerge.length != arrayLength) { - dataToMerge = new long[arrayLength]; - verticalUpdateArrays[detailLevel-1] = dataToMerge; - } else Arrays.fill(dataToMerge, 0); - - int lowerMaxVertical = dataToMerge.length / 4; - int childPosX; - int childPosZ; - long[] data; - boolean anyDataExist = false; - for (int x = 0; x <= 1; x++) - { - for (int z = 0; z <= 1; z++) - { - childPosX = 2 * posX + x; - childPosZ = 2 * posZ + z; - if (lowerLevelContainer.doesItExist(childPosX, childPosZ)) anyDataExist = true; - for (int verticalIndex = 0; verticalIndex < lowerMaxVertical; verticalIndex++) - dataToMerge[(z * 2 + x) * lowerMaxVertical + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex); - } - } - data = DataPointUtil.mergeMultiData(dataToMerge, lowerMaxVertical, getVerticalSize()); - if (!anyDataExist) - throw new RuntimeException("Update data called but no child datapoint exist!"); - - if ((!DataPointUtil.doesItExist(data[0])) && anyDataExist) - throw new RuntimeException("Update data called but higher level datapoint doesn't exist even though child data does exist!"); - - //FIXME: Disabled check if genMode for old data is already invalid due to having genMode 0. - if (DataPointUtil.getGenerationMode(data[0]) != DataPointUtil.getGenerationMode(lowerLevelContainer.getSingleData(posX*2, posZ*2))) - throw new RuntimeException("Update data called but higher level datapoint does not have the same GenerationMode as the top left corner child datapoint!"); - - forceWriteVerticalData(data, posX, posZ); - } - - public boolean writeData(DataOutputStream output) throws IOException { - output.writeByte(detailLevel); - output.writeByte((byte) verticalSize); - output.writeByte((byte) (minHeight & 0xFF)); - output.writeByte((byte) ((minHeight >> 8) & 0xFF)); - boolean allGenerated = true; - int x = SECTION_SIZE * SECTION_SIZE; - for (int i = 0; i < x; i++) - { - for (int j = 0; j < verticalSize; j++) - { - long current = dataContainer[i * verticalSize + j]; - output.writeLong(Long.reverseBytes(current)); - } - if (!DataPointUtil.doesItExist(dataContainer[i])) - allGenerated = false; - } - return allGenerated; - } - - public String toString() - { - String LINE_DELIMITER = "\n"; - String DATA_DELIMITER = " "; - String SUBDATA_DELIMITER = ","; - StringBuilder stringBuilder = new StringBuilder(); - int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel); - stringBuilder.append(detailLevel); - stringBuilder.append(LINE_DELIMITER); - for (int z = 0; z < size; z++) - { - for (int x = 0; x < size; x++) - { - for (int y = 0; y < verticalSize; y++) { - //Converting the dataToHex - stringBuilder.append(Long.toHexString(getData(x,z,y))); - if (y != verticalSize) stringBuilder.append(SUBDATA_DELIMITER); - } - if (x != size) stringBuilder.append(DATA_DELIMITER); - } - if (z != size) stringBuilder.append(LINE_DELIMITER); - } - return stringBuilder.toString(); - } - - public int getMaxNumberOfLods() - { - return SECTION_SIZE * SECTION_SIZE * getVerticalSize(); - } - - public long getRoughRamUsage() - { - return dataContainer.length * Long.BYTES; - } - - + + } diff --git a/src/main/java/com/seibel/lod/core/objects/a7/LodSubRegion.java b/src/main/java/com/seibel/lod/core/objects/a7/LodSubRegion.java deleted file mode 100644 index 94bc21e17..000000000 --- a/src/main/java/com/seibel/lod/core/objects/a7/LodSubRegion.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.seibel.lod.core.objects.a7; - -import com.seibel.lod.core.objects.lod.LevelContainer; -import com.seibel.lod.core.objects.lod.VerticalLevelContainer; - -public class LodSubRegion { - public static final int SUB_REGION_DATA_WIDTH = 16*16; - - public final byte detailLevel; - public final int x; - public final int z; - private LevelContainer levelContainer; - private RenderContainer renderContainer = null; - - // Create sub region - public LodSubRegion(byte detailLevel, int x, int z) { - this.detailLevel = detailLevel; - this.x = x; - this.z = z; - levelContainer = new VerticalLevelContainer(detailLevel); - } - LodSubRegion(byte detailLevel, int x, int z, LevelContainer levelContainer) { - this.detailLevel = detailLevel; - this.x = x; - this.z = z; - this.levelContainer = levelContainer; - } - - // Return null if data does not exist - public static LodSubRegion loadSubRegion(byte detailLevel, int x, int z, LodDataSource lodDataSource) { - LevelContainer data = lodDataSource.readLodData(detailLevel, x, z); - if (data == null) { - return null; - } - return new LodSubRegion(detailLevel, x, z, data); - } -} diff --git a/src/main/java/com/seibel/lod/core/objects/a7/RenderDataContaioner.java b/src/main/java/com/seibel/lod/core/objects/a7/RenderDataContaioner.java new file mode 100644 index 000000000..0d6ebbf70 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/a7/RenderDataContaioner.java @@ -0,0 +1,371 @@ +package com.seibel.lod.core.objects.a7; + +import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; +import com.seibel.lod.core.objects.LodDataView; +import com.seibel.lod.core.objects.lod.LevelContainer; +import com.seibel.lod.core.objects.lod.VerticalLevelContainer; +import com.seibel.lod.core.util.DataPointUtil; +import com.seibel.lod.core.util.DetailDistanceUtil; +import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; + +public class RenderDataContaioner +{ + public static final boolean DO_SAFETY_CHECKS = true; + + private final short minHeight; + public final byte detailLevel; + public final int SECTION_SIZE = 128; + public final int verticalSize; + + public final long[] dataContainer; + + public RenderDataContaioner(byte detailLevel) + { + this.detailLevel = detailLevel; + verticalSize = DetailDistanceUtil.getMaxVerticalData(detailLevel); + dataContainer = new long[SECTION_SIZE * SECTION_SIZE * DetailDistanceUtil.getMaxVerticalData(detailLevel)]; + minHeight = SingletonHandler.get(IMinecraftClientWrapper.class).getWrappedClientWorld().getMinHeight(); + } + + public byte getDetailLevel() + { + return detailLevel; + } + + public void clear(int posX, int posZ) + { + for (int verticalIndex = 0; verticalIndex < verticalSize; verticalIndex++) + dataContainer[posX * SECTION_SIZE * verticalSize + posZ * verticalSize + verticalIndex] = DataPointUtil.EMPTY_DATA; + } + + public boolean addData(long data, int posX, int posZ, int verticalIndex) + { + dataContainer[posX * SECTION_SIZE * verticalSize + posZ * verticalSize + verticalIndex] = data; + return true; + } + + private void forceWriteVerticalData(long[] data, int posX, int posZ) + { + int index = posX * SECTION_SIZE * verticalSize + posZ * verticalSize; + if (verticalSize >= 0) System.arraycopy(data, 0, dataContainer, index + 0, verticalSize); + } + + public boolean addVerticalData(long[] data, int posX, int posZ, boolean override) + { + int index = posX * SECTION_SIZE * verticalSize + posZ * verticalSize; + int compare = DataPointUtil.compareDatapointPriority(data[0], dataContainer[index]); + if (override) { + if (compare<0) return false; + } else { + if (compare<=0) return false; + } + forceWriteVerticalData(data, posX, posZ); + return true; + } + + public boolean copyVerticalData(LodDataView data, int posX, int posZ, boolean override) { + if (DO_SAFETY_CHECKS) { + if (data.size() != verticalSize) + throw new IllegalArgumentException("data size not the same as vertical size"); + if (posX < 0 || posX >= SECTION_SIZE) + throw new IllegalArgumentException("X position is out of bounds"); + if (posZ < 0 || posZ >= SECTION_SIZE) + throw new IllegalArgumentException("Z position is out of bounds"); + } + int index = posX * SECTION_SIZE * verticalSize + posZ * verticalSize; + int compare = DataPointUtil.compareDatapointPriority(data.get(0), dataContainer[index]); + if (override) { + if (compare<0) return false; + } else { + if (compare<=0) return false; + } + data.copyTo(dataContainer, index); + return true; + } + + public boolean addChunkOfData(long[] data, int posX, int posZ, int widthX, int widthZ, boolean override) + { + boolean anyChange = false; + if (posX+widthX > SECTION_SIZE || posZ+widthZ > SECTION_SIZE) + throw new IndexOutOfBoundsException("addChunkOfData param not inside valid range"); + if (widthX*widthZ*verticalSize != data.length) + throw new IndexOutOfBoundsException("addChunkOfData data array not sized correctly to contain the data to be copied"); + if (posX<0 || posZ<0 || widthX<0 || widthZ<0) + throw new IndexOutOfBoundsException("addChunkOfData param is negative"); + + for (int ox=0; ox SECTION_SIZE || posZ+widthZ > SECTION_SIZE) + throw new IndexOutOfBoundsException("addChunkOfData param not inside valid range"); + if (widthX*widthZ*verticalSize != data.size()) + throw new IndexOutOfBoundsException("addChunkOfData data array not sized correctly to contain the data to be copied"); + if (posX<0 || posZ<0 || widthX<0 || widthZ<0) + throw new IndexOutOfBoundsException("addChunkOfData param is negative"); + + for (int ox=0; ox tLocalVerticalUpdateArrays = ThreadLocal.withInitial(() -> + { + return new long[LodUtil.DETAIL_OPTIONS - 1][]; + }); + + public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ) + { + //We reset the array + long[][] verticalUpdateArrays = tLocalVerticalUpdateArrays.get(); + long[] dataToMerge = verticalUpdateArrays[detailLevel-1]; + int arrayLength = DetailDistanceUtil.getMaxVerticalData(detailLevel-1) * 4; + if (dataToMerge == null || dataToMerge.length != arrayLength) { + dataToMerge = new long[arrayLength]; + verticalUpdateArrays[detailLevel-1] = dataToMerge; + } else Arrays.fill(dataToMerge, 0); + + int lowerMaxVertical = dataToMerge.length / 4; + int childPosX; + int childPosZ; + long[] data; + boolean anyDataExist = false; + for (int x = 0; x <= 1; x++) + { + for (int z = 0; z <= 1; z++) + { + childPosX = 2 * posX + x; + childPosZ = 2 * posZ + z; + if (lowerLevelContainer.doesItExist(childPosX, childPosZ)) anyDataExist = true; + for (int verticalIndex = 0; verticalIndex < lowerMaxVertical; verticalIndex++) + dataToMerge[(z * 2 + x) * lowerMaxVertical + verticalIndex] = lowerLevelContainer.getData(childPosX, childPosZ, verticalIndex); + } + } + data = DataPointUtil.mergeMultiData(dataToMerge, lowerMaxVertical, getVerticalSize()); + if (!anyDataExist) + throw new RuntimeException("Update data called but no child datapoint exist!"); + + if ((!DataPointUtil.doesItExist(data[0])) && anyDataExist) + throw new RuntimeException("Update data called but higher level datapoint doesn't exist even though child data does exist!"); + + //FIXME: Disabled check if genMode for old data is already invalid due to having genMode 0. + if (DataPointUtil.getGenerationMode(data[0]) != DataPointUtil.getGenerationMode(lowerLevelContainer.getSingleData(posX*2, posZ*2))) + throw new RuntimeException("Update data called but higher level datapoint does not have the same GenerationMode as the top left corner child datapoint!"); + + forceWriteVerticalData(data, posX, posZ); + } + + public boolean writeData(DataOutputStream output) throws IOException { + output.writeByte(detailLevel); + output.writeByte((byte) verticalSize); + output.writeByte((byte) (minHeight & 0xFF)); + output.writeByte((byte) ((minHeight >> 8) & 0xFF)); + boolean allGenerated = true; + int x = SECTION_SIZE * SECTION_SIZE; + for (int i = 0; i < x; i++) + { + for (int j = 0; j < verticalSize; j++) + { + long current = dataContainer[i * verticalSize + j]; + output.writeLong(Long.reverseBytes(current)); + } + if (!DataPointUtil.doesItExist(dataContainer[i])) + allGenerated = false; + } + return allGenerated; + } + + public String toString() + { + String LINE_DELIMITER = "\n"; + String DATA_DELIMITER = " "; + String SUBDATA_DELIMITER = ","; + StringBuilder stringBuilder = new StringBuilder(); + int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel); + stringBuilder.append(detailLevel); + stringBuilder.append(LINE_DELIMITER); + for (int z = 0; z < size; z++) + { + for (int x = 0; x < size; x++) + { + for (int y = 0; y < verticalSize; y++) { + //Converting the dataToHex + stringBuilder.append(Long.toHexString(getData(x,z,y))); + if (y != verticalSize) stringBuilder.append(SUBDATA_DELIMITER); + } + if (x != size) stringBuilder.append(DATA_DELIMITER); + } + if (z != size) stringBuilder.append(LINE_DELIMITER); + } + return stringBuilder.toString(); + } + + public int getMaxNumberOfLods() + { + return SECTION_SIZE * SECTION_SIZE * getVerticalSize(); + } + + public long getRoughRamUsage() + { + return dataContainer.length * Long.BYTES; + } + + +} diff --git a/src/main/java/com/seibel/lod/core/objects/a7/data/Data.java b/src/main/java/com/seibel/lod/core/objects/a7/data/Data.java new file mode 100644 index 000000000..19710c01a --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/a7/data/Data.java @@ -0,0 +1,49 @@ +package com.seibel.lod.core.objects.a7.data; + +// Static class for the data format: +// ID: blockState id Y: Height(signed) DP: Depth(signed?) +// =======Bit layout======= +// __ __ __ __ __ __ __ __ <-- 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 +// 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 + + +public class Data { + + 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 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 ID_MASK = (int)Math.pow(2, ID_WIDTH) - 1; + 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) { + long data = 0; + data |= id & ID_MASK; + data |= (long) (depth & DP_MASK) << DP_OFFSET; + data |= (long) (y & Y_MASK) << Y_OFFSET; + return data; + } + + public static int getId(long data) { + return (int) (data & ID_MASK); + } + + public static int getDepth(long data) { + return (int) (data << (64 - DP_OFFSET - DP_WIDTH) >> DP_OFFSET); + } + + public static int getY(long data) { + return (int) (data << (64 - Y_OFFSET - Y_WIDTH) >> Y_OFFSET); + } + +} diff --git a/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataContainer.java b/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataContainer.java new file mode 100644 index 000000000..a56f02074 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataContainer.java @@ -0,0 +1,23 @@ +package com.seibel.lod.core.objects.a7.data; + +import java.util.ArrayList; + +public class LodDataContainer { + ArrayList idMap; + int minX; + int minY; + int minZ; + int maxX; + int maxY; + int maxZ; + + public LodDataContainer() { + idMap = new ArrayList(); + } + + + + + + +}