From 7404f94d3a7e5ba2edb3dd01cbe95dbfb0ca6e70 Mon Sep 17 00:00:00 2001 From: "Lukas Rieger (Blue)" Date: Sat, 10 Jun 2023 14:30:23 +0200 Subject: [PATCH] Implement PackedIntArrayAccess --- .../bluemap/core/mca/ChunkAnvil118.java | 6 +- .../bluecolored/bluemap/core/mca/MCAMath.java | 4 + .../core/mca/PackedIntArrayAccess.java | 103 ++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/PackedIntArrayAccess.java diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil118.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil118.java index aaf9db56..a790f9de 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil118.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/ChunkAnvil118.java @@ -225,7 +225,7 @@ public Section(CompoundTag sectionData) { if (skyLight.length < 2048 && skyLight.length > 0) skyLight = Arrays.copyOf(skyLight, 2048); this.bitsPerBlock = this.blocks.length >> 6; // available longs * 64 (bits per long) / 4096 (blocks per section) (floored result) - this.bitsPerBiome = Integer.SIZE - Integer.numberOfLeadingZeros(this.biomePalette.length - 1); + this.bitsPerBiome = MCAMath.ceilLog2(this.biomePalette.length); } private BlockState readBlockStatePaletteEntry(CompoundTag paletteEntry) { @@ -298,4 +298,8 @@ public String getBiome(int x, int y, int z) { } } + private static PackedIntArrayAccess heightmap(int worldHeight, long[] data) { + return new PackedIntArrayAccess(MCAMath.ceilLog2(worldHeight + 1), data); + } + } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAMath.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAMath.java index b10cacdd..ed15d883 100644 --- a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAMath.java +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/MCAMath.java @@ -71,4 +71,8 @@ public static int getByteHalf(int value, boolean largeHalf) { return value; } + public static int ceilLog2(int n) { + return Integer.SIZE - Integer.numberOfLeadingZeros(n - 1); + } + } diff --git a/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/PackedIntArrayAccess.java b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/PackedIntArrayAccess.java new file mode 100644 index 00000000..879d01ce --- /dev/null +++ b/BlueMapCore/src/main/java/de/bluecolored/bluemap/core/mca/PackedIntArrayAccess.java @@ -0,0 +1,103 @@ +package de.bluecolored.bluemap.core.mca; + +public class PackedIntArrayAccess { + private static final int[] INDEX_PARAMETERS = new int[]{ + -1, -1, 0, + Integer.MIN_VALUE, 0, 0, + 1431655765, 1431655765, 0, + Integer.MIN_VALUE, 0, 1, + 858993459, 858993459, 0, + 715827882, 715827882, 0, + 613566756, 613566756, 0, + Integer.MIN_VALUE, 0, 2, + 477218588, 477218588, 0, + 429496729, 429496729, 0, + 390451572, 390451572, 0, + 357913941, 357913941, 0, + 330382099, 330382099, 0, + 306783378, 306783378, 0, + 286331153, 286331153, 0, + Integer.MIN_VALUE, 0, 3, + 252645135, 252645135, 0, + 238609294, 238609294, 0, + 226050910, 226050910, 0, + 214748364, 214748364, 0, + 204522252, 204522252, 0, + 195225786, 195225786, 0, + 186737708, 186737708, 0, + 178956970, 178956970, 0, + 171798691, 171798691, 0, + 165191049, 165191049, 0, + 159072862, 159072862, 0, + 153391689, 153391689, 0, + 148102320, 148102320, 0, + 143165576, 143165576, 0, + 138547332, 138547332, 0, + Integer.MIN_VALUE, 0, 4, + 130150524, 130150524, 0, + 126322567, 126322567, 0, + 122713351, 122713351, 0, + 119304647, 119304647, 0, + 116080197, 116080197, 0, + 113025455, 113025455, 0, + 110127366, 110127366, 0, + 107374182, 107374182, 0, + 104755299, 104755299, 0, + 102261126, 102261126, 0, + 99882960, 99882960, 0, + 97612893, 97612893, 0, + 95443717, 95443717, 0, + 93368854, 93368854, 0, + 91382282, 91382282, 0, + 89478485, 89478485, 0, + 87652393, 87652393, 0, + 85899345, 85899345, 0, + 84215045, 84215045, 0, + 82595524, 82595524, 0, + 81037118, 81037118, 0, + 79536431, 79536431, 0, + 78090314, 78090314, 0, + 76695844, 76695844, 0, + 75350303, 75350303, 0, + 74051160, 74051160, 0, + 72796055, 72796055, 0, + 71582788, 71582788, 0, + 70409299, 70409299, 0, + 69273666, 69273666, 0, + 68174084, 68174084, 0, + Integer.MIN_VALUE, 0, 5 + }; + + private final int bitsPerElement; + private final long[] data; + + private final long maxValue; + private final int elementsPerLong, indexScale, indexOffset, indexShift; + + public PackedIntArrayAccess(int bitsPerElement, long[] data) { + this.bitsPerElement = bitsPerElement; + this.data = data; + + this.maxValue = (1L << this.bitsPerElement) - 1L; + this.elementsPerLong = (char)(64 / this.bitsPerElement); + + int i = 3 * (this.elementsPerLong - 1); + this.indexScale = INDEX_PARAMETERS[i]; + this.indexOffset = INDEX_PARAMETERS[i + 1]; + this.indexShift = INDEX_PARAMETERS[i + 2]; + } + + public int get(int i) { + int j = this.storageIndex(i); + long l = this.data[j]; + int k = (i - j * this.elementsPerLong) * this.bitsPerElement; + return (int)(l >> k & this.maxValue); + } + + public int storageIndex(int i) { + long l = Integer.toUnsignedLong(this.indexScale); + long m = Integer.toUnsignedLong(this.indexOffset); + return (int) ((long) i * l + m >> 32 >> this.indexShift); + } + +}