Added palette

This commit is contained in:
themode 2020-11-11 17:13:36 +01:00
parent 00656d96e0
commit 55cddf6b78
6 changed files with 62 additions and 13 deletions

View File

@ -42,8 +42,8 @@ public class DynamicChunk extends Chunk {
private static final int DATA_FORMAT_VERSION = 1;
// WARNING: not thread-safe
protected PaletteStorage blockPalette = new PaletteStorage(15);
protected PaletteStorage customBlockPalette = new PaletteStorage(15);
protected PaletteStorage blockPalette = new PaletteStorage(4);
protected PaletteStorage customBlockPalette = new PaletteStorage(4);
// Used to get all blocks with data (no null)
// Key is still chunk coordinates (see #getBlockIndex)

View File

@ -1,5 +1,7 @@
package net.minestom.server.instance.palette;
import it.unimi.dsi.fastutil.shorts.Short2ShortLinkedOpenHashMap;
import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
import net.minestom.server.utils.chunk.ChunkUtils;
import static net.minestom.server.instance.Chunk.*;
@ -7,15 +9,38 @@ import static net.minestom.server.instance.Chunk.*;
public class PaletteStorage {
private int bitsPerEntry;
private int valuesPerLong;
private long[][] sectionBlocks = new long[CHUNK_SECTION_COUNT][0];
// palette index = block id
private Short2ShortLinkedOpenHashMap paletteBlockMap = new Short2ShortLinkedOpenHashMap(CHUNK_SECTION_SIZE, 2);
// block id = palette index
private Short2ShortOpenHashMap blockPaletteMap = new Short2ShortOpenHashMap(CHUNK_SECTION_SIZE, 2);
{
// Default value
this.paletteBlockMap.put((short) 0, (short) 0);
this.blockPaletteMap.put((short) 0, (short) 0);
}
public PaletteStorage(int bitsPerEntry) {
this.bitsPerEntry = bitsPerEntry;
this.valuesPerLong = Long.SIZE / bitsPerEntry;
}
private short getPaletteIndex(short blockId) {
if (!blockPaletteMap.containsKey(blockId)) {
final short paletteIndex = (short) (paletteBlockMap.lastShortKey() + 1);
this.paletteBlockMap.put(paletteIndex, blockId);
this.blockPaletteMap.put(blockId, paletteIndex);
return paletteIndex;
}
return blockPaletteMap.get(blockId);
}
public void setBlockAt(int x, int y, int z, short blockId) {
x %= 16;
if (x < 0) {
@ -41,6 +66,9 @@ public class PaletteStorage {
sectionBlocks[section] = new long[getSize()];
}
// Change to palette value
blockId = getPaletteIndex(blockId);
long[] sectionBlock = sectionBlocks[section];
long block = sectionBlock[index];
@ -107,6 +135,9 @@ public class PaletteStorage {
finalValue = value & mask >> bitIndex;
}
// Change to palette value
final short blockId = paletteBlockMap.get((short) finalValue);
//System.out.println("final " + binary(finalValue));
@ -115,13 +146,12 @@ public class PaletteStorage {
System.out.println("mask " + binary(mask));
System.out.println("bin " + binary(blocks[index]));
System.out.println("result " + ((blocks[index] >> bitIndex) & mask));*/
return (short) finalValue;
return blockId;
}
private int getSize() {
final int blockCount = 16 * 16 * 16; // A whole chunk section
final int arraySize = (blockCount + valuesPerLong - 1) / valuesPerLong;
//System.out.println("size " + arraySize);
return arraySize;
}
@ -129,6 +159,10 @@ public class PaletteStorage {
return bitsPerEntry;
}
public short[] getPalette() {
return paletteBlockMap.keySet().toShortArray();
}
public long[][] getSectionBlocks() {
return sectionBlocks;
}
@ -136,6 +170,8 @@ public class PaletteStorage {
public PaletteStorage copy() {
PaletteStorage paletteStorage = new PaletteStorage(bitsPerEntry);
paletteStorage.sectionBlocks = sectionBlocks.clone();
paletteStorage.paletteBlockMap.putAll(paletteBlockMap);
paletteStorage.blockPaletteMap.putAll(blockPaletteMap);
return paletteStorage;
}

View File

@ -52,9 +52,8 @@ public class ChunkDataPacket implements ServerPacket {
if (fullChunk || (sections.length == CHUNK_SECTION_COUNT && sections[i] != 0)) {
final long[] section = paletteStorage.getSectionBlocks()[i];
if (section.length > 0) { // section contains at least one block
//if (true) {
mask |= 1 << i;
Utils.writeBlocks(blocks, section, paletteStorage.getBitsPerEntry());
Utils.writeBlocks(blocks, paletteStorage.getPalette(), section, paletteStorage.getBitsPerEntry());
} else {
mask |= 0;
}

View File

@ -116,17 +116,25 @@ public final class Utils {
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
0, 5};
public static void writeBlocks(ByteBuf buffer, long[] blocksId, int bitsPerEntry) {
public static void writeBlocks(ByteBuf buffer, short[] palette, long[] blocksId, int bitsPerEntry) {
/*short count = 0;
for (short id : blocksId)
if (id != 0)
count++;*/
//buffer.writeShort(count);
buffer.writeShort(200);
buffer.writeByte((byte) bitsPerEntry);
// Palette
if (bitsPerEntry < 9) {
// Palette has to exist
writeVarIntBuf(buffer, palette.length);
for (short paletteValue : palette) {
writeVarIntBuf(buffer, paletteValue);
}
}
final long[] data = blocksId;//encodeBlocksTEST(bitsPerEntry);
writeVarIntBuf(buffer, data.length);
for (long datum : data) {
@ -143,8 +151,12 @@ public final class Utils {
final int arraySize = blockCount / valuesPerLong;
long[] data = new long[arraySize];
//data[0] = 0b000000000000001_000000000000001_000000000000001_000000000000001L;
//data[1] = 0b000000000000001_000000000000001_000000000000001_000000000000010L;
data[0] = 0b000000010001L;
data[1] = 0b000000010001L;
if (true) {
return data;
}
for (int y = 0; y < Chunk.CHUNK_SECTION_SIZE; y++) {
for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) {

View File

@ -47,7 +47,7 @@ public final class ChunkUtils {
* @return the chunk X or Z based on the argument
*/
public static int getChunkCoordinate(int xz) {
// Assume Chunk.CHUNK_SIZE_X == Chunk.CHUNK_SIZE_Z
assert Chunk.CHUNK_SIZE_X == Chunk.CHUNK_SIZE_Z;
return Math.floorDiv(xz, Chunk.CHUNK_SIZE_X);
}

View File

@ -17,6 +17,7 @@ import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.inventory.Inventory;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
@ -124,8 +125,9 @@ public class PlayerInit {
return;
final short blockStateId = player.getInstance().getBlockStateId(event.getBlockPosition());
final CustomBlock customBlock = player.getInstance().getCustomBlock(event.getBlockPosition());
final Block block = Block.fromStateId(blockStateId);
player.sendMessage("You clicked at the block " + block);
player.sendMessage("You clicked at the block " + block + " " + customBlock);
});
player.addEventCallback(PickupItemEvent.class, event -> {
@ -165,7 +167,7 @@ public class PlayerInit {
});
player.addEventCallback(PlayerSpawnEvent.class, event -> {
player.setGameMode(GameMode.SURVIVAL);
player.setGameMode(GameMode.CREATIVE);
if (event.isFirstSpawn()) {
player.teleport(new Position(0, 64f, 0));
}