mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-15 11:51:53 +01:00
Improve chunk block getter
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
5376b8af76
commit
dda90a6dfe
@ -1,11 +1,11 @@
|
||||
package net.minestom.server.instance.palette;
|
||||
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ShortLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.clone.PublicCloneable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static net.minestom.server.instance.Chunk.CHUNK_SECTION_SIZE;
|
||||
@ -15,6 +15,7 @@ import static net.minestom.server.instance.Chunk.CHUNK_SECTION_SIZE;
|
||||
* <p>
|
||||
* 0 is always interpreted as being air, reason being that the block array will be filled with it during initialization.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class Palette implements PublicCloneable<Palette> {
|
||||
|
||||
/**
|
||||
@ -44,11 +45,17 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
511, 1023, 2047, 4095,
|
||||
8191, 16383, 32767};
|
||||
|
||||
private static final Short2ShortOpenHashMap MAP_TEMPLATE = new Short2ShortOpenHashMap(CHUNK_SECTION_SIZE);
|
||||
|
||||
static {
|
||||
MAP_TEMPLATE.put((short) 0, (short) 0);
|
||||
}
|
||||
|
||||
private long[] blocks;
|
||||
|
||||
// chunk section - palette index = block id
|
||||
private Short2ShortLinkedOpenHashMap paletteBlockMap;
|
||||
// chunk section - block id = palette index
|
||||
// palette index = block id
|
||||
private short[] paletteBlockArray;
|
||||
// block id = palette index
|
||||
private Short2ShortOpenHashMap blockPaletteMap;
|
||||
|
||||
private int bitsPerEntry;
|
||||
@ -56,6 +63,7 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
|
||||
private int valuesPerLong;
|
||||
private boolean hasPalette;
|
||||
private int lastPaletteIndex;
|
||||
|
||||
private short blockCount = 0;
|
||||
|
||||
@ -77,7 +85,7 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
return;
|
||||
}
|
||||
// Initialize the section
|
||||
blocks = new long[getSize(valuesPerLong)];
|
||||
this.blocks = new long[(BLOCK_COUNT + valuesPerLong - 1) / valuesPerLong];
|
||||
}
|
||||
|
||||
// Change to palette value
|
||||
@ -121,10 +129,9 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
final int index = sectionIdentifier / valuesPerLong;
|
||||
final int bitIndex = sectionIdentifier % valuesPerLong * bitsPerEntry;
|
||||
|
||||
final long value = blocks[index] >> bitIndex & MAGIC_MASKS[bitsPerEntry];
|
||||
|
||||
final short value = (short) (blocks[index] >> bitIndex & MAGIC_MASKS[bitsPerEntry]);
|
||||
// Change to palette value and return
|
||||
return fromPalette((short) value);
|
||||
return hasPalette ? paletteBlockArray[value] : value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,18 +145,21 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
newBitsPerEntry = fixBitsPerEntry(newBitsPerEntry);
|
||||
|
||||
Palette palette = new Palette(newBitsPerEntry, bitsIncrement);
|
||||
palette.paletteBlockMap = paletteBlockMap;
|
||||
palette.paletteBlockArray = paletteBlockArray;
|
||||
palette.blockPaletteMap = blockPaletteMap;
|
||||
palette.lastPaletteIndex = lastPaletteIndex;
|
||||
|
||||
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
|
||||
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {
|
||||
for (int z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
final short blockId = getBlockAt(x, y, z);
|
||||
palette.setBlockAt(x, y, z, blockId);
|
||||
palette.setBlockAt(x, y, z, getBlockAt(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.paletteBlockArray = palette.paletteBlockArray;
|
||||
this.lastPaletteIndex = palette.lastPaletteIndex;
|
||||
|
||||
this.bitsPerEntry = palette.bitsPerEntry;
|
||||
|
||||
this.valuesPerLong = palette.valuesPerLong;
|
||||
@ -177,15 +187,15 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
if (canClear) {
|
||||
this.blocks = new long[0];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.blocks = new long[0];
|
||||
this.paletteBlockMap = createPaletteBlockMap();
|
||||
this.blockPaletteMap = createBlockPaletteMap();
|
||||
this.paletteBlockArray = new short[1 << bitsPerEntry];
|
||||
this.blockPaletteMap = MAP_TEMPLATE.clone();
|
||||
this.blockCount = 0;
|
||||
this.lastPaletteIndex = 1; // First index is air
|
||||
}
|
||||
|
||||
public long[] getBlocks() {
|
||||
@ -197,7 +207,7 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of non air blocks in this section.
|
||||
* Get the amount of non-air blocks in this section.
|
||||
*
|
||||
* @return The amount of blocks in this section.
|
||||
*/
|
||||
@ -209,8 +219,12 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
this.blockCount = blockCount;
|
||||
}
|
||||
|
||||
public Short2ShortLinkedOpenHashMap getPaletteBlockMap() {
|
||||
return paletteBlockMap;
|
||||
public short[] getPaletteBlockArray() {
|
||||
return paletteBlockArray;
|
||||
}
|
||||
|
||||
public int getLastPaletteIndex() {
|
||||
return lastPaletteIndex;
|
||||
}
|
||||
|
||||
public Short2ShortOpenHashMap getBlockPaletteMap() {
|
||||
@ -230,48 +244,18 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
* @return the palette index of {@code blockId}
|
||||
*/
|
||||
private short getPaletteIndex(short blockId) {
|
||||
if (!hasPalette) {
|
||||
return blockId;
|
||||
}
|
||||
if (!hasPalette) return blockId;
|
||||
final short value = blockPaletteMap.getOrDefault(blockId, (short) -1);
|
||||
if (value == -1) {
|
||||
// Resize the palette if full
|
||||
if (paletteBlockMap.size() >= getMaxPaletteSize()) {
|
||||
resize(bitsPerEntry + bitsIncrement);
|
||||
}
|
||||
final short paletteIndex = (short) (paletteBlockMap.lastShortKey() + 1);
|
||||
paletteBlockMap.put(paletteIndex, blockId);
|
||||
blockPaletteMap.put(blockId, paletteIndex);
|
||||
return paletteIndex;
|
||||
if (value != -1) return value;
|
||||
|
||||
if (lastPaletteIndex >= paletteBlockArray.length) {
|
||||
// Palette is full, must resize
|
||||
resize(bitsPerEntry + bitsIncrement);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum number of blocks that the current palette (could be the global one) can take.
|
||||
*
|
||||
* @return the number of blocks possible in the palette
|
||||
*/
|
||||
private int getMaxPaletteSize() {
|
||||
return 1 << bitsPerEntry;
|
||||
}
|
||||
|
||||
private short fromPalette(short value) {
|
||||
return hasPalette ? paletteBlockMap.get(value) : value;
|
||||
}
|
||||
|
||||
private static Short2ShortLinkedOpenHashMap createPaletteBlockMap() {
|
||||
Short2ShortLinkedOpenHashMap map = new Short2ShortLinkedOpenHashMap(CHUNK_SECTION_SIZE);
|
||||
map.put((short) 0, (short) 0);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Short2ShortOpenHashMap createBlockPaletteMap() {
|
||||
Short2ShortOpenHashMap map = new Short2ShortOpenHashMap(CHUNK_SECTION_SIZE);
|
||||
map.put((short) 0, (short) 0);
|
||||
|
||||
return map;
|
||||
final short paletteIndex = (short) lastPaletteIndex++;
|
||||
this.paletteBlockArray[paletteIndex] = blockId;
|
||||
this.blockPaletteMap.put(blockId, paletteIndex);
|
||||
return paletteIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,16 +271,6 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
return y << 8 | z << 4 | x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array length of one section based on the number of values which can be stored in one long.
|
||||
*
|
||||
* @param valuesPerLong the number of values per long
|
||||
* @return the array length based on {@code valuesPerLong}
|
||||
*/
|
||||
private static int getSize(int valuesPerLong) {
|
||||
return (BLOCK_COUNT + valuesPerLong - 1) / valuesPerLong;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes invalid bitsPerEntry values.
|
||||
* <p>
|
||||
@ -314,13 +288,12 @@ public final class Palette implements PublicCloneable<Palette> {
|
||||
return bitsPerEntry;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Palette clone() {
|
||||
public @NotNull Palette clone() {
|
||||
try {
|
||||
Palette palette = (Palette) super.clone();
|
||||
palette.blocks = blocks.clone();
|
||||
palette.paletteBlockMap = paletteBlockMap.clone();
|
||||
palette.paletteBlockArray = paletteBlockArray.clone();
|
||||
palette.blockPaletteMap = blockPaletteMap.clone();
|
||||
palette.blockCount = blockCount;
|
||||
return palette;
|
||||
|
@ -186,7 +186,7 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
int paletteSize = reader.readVarInt();
|
||||
for (int i = 0; i < paletteSize; i++) {
|
||||
final int paletteValue = reader.readVarInt();
|
||||
palette.getPaletteBlockMap().put((short) i, (short) paletteValue);
|
||||
palette.getPaletteBlockArray()[i] = (short) paletteValue;
|
||||
palette.getBlockPaletteMap().put((short) paletteValue, (short) i);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.minestom.server.utils;
|
||||
|
||||
import it.unimi.dsi.fastutil.shorts.Short2ShortLinkedOpenHashMap;
|
||||
import net.minestom.server.instance.palette.Palette;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -122,10 +121,11 @@ public final class Utils {
|
||||
// Palette
|
||||
if (bitsPerEntry < 9) {
|
||||
// Palette has to exist
|
||||
final Short2ShortLinkedOpenHashMap paletteBlockMap = palette.getPaletteBlockMap();
|
||||
writeVarInt(buffer, paletteBlockMap.size());
|
||||
for (short paletteValue : paletteBlockMap.values()) {
|
||||
writeVarInt(buffer, paletteValue);
|
||||
final short[] paletteBlockArray = palette.getPaletteBlockArray();
|
||||
final int paletteSize = palette.getLastPaletteIndex() + 1;
|
||||
writeVarInt(buffer, paletteSize);
|
||||
for (int i = 0; i < paletteSize; i++) {
|
||||
writeVarInt(buffer, paletteBlockArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user