3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-09-17 01:23:43 +02:00

Fix biome palette writing

Co-authored-by: Gerrygames <gecam59@gmail.com>
Dieser Commit ist enthalten in:
Nassim Jahnke 2021-10-08 12:52:53 +02:00
Ursprung 3feff8e751
Commit e744214ad6
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
7 geänderte Dateien mit 56 neuen und 46 gelöschten Zeilen

Datei anzeigen

@ -31,6 +31,11 @@ public interface ChunkSection {
*/ */
int SIZE = 16 * 16 * 16; // width * depth * height int SIZE = 16 * 16 * 16; // width * depth * height
/**
* Size (dimensions) of biomes in a chunks section.
*/
int BIOME_SIZE = 4 * 4 * 4;
static int index(int x, int y, int z) { static int index(int x, int y, int z) {
return y << 8 | z << 4 | x; return y << 8 | z << 4 | x;
} }

Datei anzeigen

@ -36,14 +36,14 @@ public class ChunkSectionImpl implements ChunkSection {
} }
public ChunkSectionImpl(final boolean holdsLight) { public ChunkSectionImpl(final boolean holdsLight) {
addPalette(PaletteType.BLOCKS, new DataPaletteImpl()); addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE));
if (holdsLight) { if (holdsLight) {
this.light = new ChunkSectionLightImpl(); this.light = new ChunkSectionLightImpl();
} }
} }
public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) { public ChunkSectionImpl(final boolean holdsLight, final int expectedPaletteLength) {
addPalette(PaletteType.BLOCKS, new DataPaletteImpl(expectedPaletteLength)); addPalette(PaletteType.BLOCKS, new DataPaletteImpl(ChunkSection.SIZE, expectedPaletteLength));
if (holdsLight) { if (holdsLight) {
this.light = new ChunkSectionLightImpl(); this.light = new ChunkSectionLightImpl();
} }

Datei anzeigen

@ -24,11 +24,21 @@ package com.viaversion.viaversion.api.minecraft.chunks;
public interface DataPalette { public interface DataPalette {
/**
* Returns the packet section index of the given coordinates.
*
* @param x x
* @param y y
* @param z z
* @return packed section index of the given coordinates
*/
int index(final int x, final int y, final int z);
/** /**
* Returns the value of the given chunk coordinate. * Returns the value of the given chunk coordinate.
* *
* @param sectionCoordinate block index within the section * @param sectionCoordinate section index within the section
* @return block state of the given index * @return section state of the given index
*/ */
int idAt(int sectionCoordinate); int idAt(int sectionCoordinate);
@ -38,17 +48,17 @@ public interface DataPalette {
* @param sectionX section x * @param sectionX section x
* @param sectionY section y * @param sectionY section y
* @param sectionZ section z * @param sectionZ section z
* @return block state of the given section coordinate * @return id of the given section coordinate
*/ */
default int idAt(final int sectionX, final int sectionY, final int sectionZ) { default int idAt(final int sectionX, final int sectionY, final int sectionZ) {
return idAt(ChunkSection.index(sectionX, sectionY, sectionZ)); return idAt(index(sectionX, sectionY, sectionZ));
} }
/** /**
* Set a value in the chunk section. * Set a value in the chunk section.
* This method does not update non-air blocks count. * This method does not update non-air blocks count.
* *
* @param sectionCoordinate block index within the section * @param sectionCoordinate section index within the section
* @param id id value * @param id id value
*/ */
void setIdAt(int sectionCoordinate, int id); void setIdAt(int sectionCoordinate, int id);
@ -63,7 +73,7 @@ public interface DataPalette {
* @param id id value * @param id id value
*/ */
default void setIdAt(final int sectionX, final int sectionY, final int sectionZ, final int id) { default void setIdAt(final int sectionX, final int sectionY, final int sectionZ, final int id) {
setIdAt(ChunkSection.index(sectionX, sectionY, sectionZ), id); setIdAt(index(sectionX, sectionY, sectionZ), id);
} }
/** /**
@ -83,17 +93,17 @@ public interface DataPalette {
void setIdByIndex(int index, int id); void setIdByIndex(int index, int id);
/** /**
* Returns the palette index of the given block index. * Returns the palette index of the given section index.
* *
* @param packedCoordinate block index * @param packedCoordinate section index
* @return palette index of the given block index * @return palette index of the given section index
*/ */
int paletteIndexAt(int packedCoordinate); int paletteIndexAt(int packedCoordinate);
/** /**
* Sets the index of the given section coordinate. * Sets the index of the given section coordinate.
* *
* @param sectionCoordinate block index * @param sectionCoordinate section index
* @param index palette index * @param index palette index
*/ */
void setPaletteIndexAt(int sectionCoordinate, int index); void setPaletteIndexAt(int sectionCoordinate, int index);

Datei anzeigen

@ -32,22 +32,26 @@ public final class DataPaletteImpl implements DataPalette {
private final IntList palette; private final IntList palette;
private final Int2IntMap inversePalette; private final Int2IntMap inversePalette;
private final int[] values; private final int[] values;
private final int sizeBits;
public DataPaletteImpl() { public DataPaletteImpl(final int valuesLength) {
this.values = new int[ChunkSection.SIZE]; this(valuesLength, 8);
palette = new IntArrayList();
inversePalette = new Int2IntOpenHashMap();
inversePalette.defaultReturnValue(-1);
} }
public DataPaletteImpl(final int expectedPaletteLength) { public DataPaletteImpl(final int valuesLength, final int expectedPaletteLength) {
this.values = new int[ChunkSection.SIZE]; this.values = new int[valuesLength];
sizeBits = Integer.numberOfTrailingZeros(valuesLength) / 3;
// Pre-size the palette array/map // Pre-size the palette array/map
palette = new IntArrayList(expectedPaletteLength); palette = new IntArrayList(expectedPaletteLength);
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength); inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
inversePalette.defaultReturnValue(-1); inversePalette.defaultReturnValue(-1);
} }
@Override
public int index(final int x, final int y, final int z) {
return (y << this.sizeBits | z) << this.sizeBits | x;
}
@Override @Override
public int idAt(final int sectionCoordinate) { public int idAt(final int sectionCoordinate) {
final int index = values[sectionCoordinate]; final int index = values[sectionCoordinate];

Datei anzeigen

@ -24,18 +24,18 @@ package com.viaversion.viaversion.api.minecraft.chunks;
public enum PaletteType { public enum PaletteType {
BLOCKS(ChunkSection.SIZE, 8), BLOCKS(ChunkSection.SIZE, 8),
BIOMES(4 * 4 * 4, 2); BIOMES(ChunkSection.BIOME_SIZE, 2);
private final int maxSize; private final int size;
private final int highestBitsPerValue; private final int highestBitsPerValue;
PaletteType(final int maxSize, final int highestBitsPerValue) { PaletteType(final int size, final int highestBitsPerValue) {
this.maxSize = maxSize; this.size = size;
this.highestBitsPerValue = highestBitsPerValue; this.highestBitsPerValue = highestBitsPerValue;
} }
public int maxSize() { public int size() {
return maxSize; return size;
} }
public int highestBitsPerValue() { public int highestBitsPerValue() {

Datei anzeigen

@ -52,7 +52,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
final DataPaletteImpl palette; final DataPaletteImpl palette;
if (bitsPerValue == 0) { if (bitsPerValue == 0) {
//TODO Create proper singleton palette Object //TODO Create proper singleton palette Object
palette = new DataPaletteImpl(1); palette = new DataPaletteImpl(type.size(), 1);
palette.addId(Type.VAR_INT.readPrimitive(buffer)); palette.addId(Type.VAR_INT.readPrimitive(buffer));
Type.VAR_INT.readPrimitive(buffer); // 0 values length Type.VAR_INT.readPrimitive(buffer); // 0 values length
return palette; return palette;
@ -60,19 +60,19 @@ public final class PaletteType1_18 extends Type<DataPalette> {
if (bitsPerValue != globalPaletteBits) { if (bitsPerValue != globalPaletteBits) {
final int paletteLength = Type.VAR_INT.readPrimitive(buffer); final int paletteLength = Type.VAR_INT.readPrimitive(buffer);
palette = new DataPaletteImpl(paletteLength); palette = new DataPaletteImpl(type.size(), paletteLength);
for (int i = 0; i < paletteLength; i++) { for (int i = 0; i < paletteLength; i++) {
palette.addId(Type.VAR_INT.readPrimitive(buffer)); palette.addId(Type.VAR_INT.readPrimitive(buffer));
} }
} else { } else {
palette = new DataPaletteImpl(); palette = new DataPaletteImpl(type.size());
} }
// Read values // Read values
final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)]; final long[] values = new long[Type.VAR_INT.readPrimitive(buffer)];
if (values.length > 0) { if (values.length > 0) {
final char valuesPerLong = (char) (64 / bitsPerValue); final char valuesPerLong = (char) (64 / bitsPerValue);
final int expectedLength = (type.maxSize() + valuesPerLong - 1) / valuesPerLong; final int expectedLength = (type.size() + valuesPerLong - 1) / valuesPerLong;
if (values.length != expectedLength) { if (values.length != expectedLength) {
throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue); throw new IllegalStateException("Palette data length (" + values.length + ") does not match expected length (" + expectedLength + ")! bitsPerValue=" + bitsPerValue + ", originalBitsPerValue=" + originalBitsPerValue);
} }
@ -80,7 +80,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
for (int i = 0; i < values.length; i++) { for (int i = 0; i < values.length; i++) {
values[i] = buffer.readLong(); values[i] = buffer.readLong();
} }
CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.maxSize(), values, CompactArrayUtil.iterateCompactArrayWithPadding(bitsPerValue, type.size(), values,
bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt); bitsPerValue == globalPaletteBits ? palette::setIdAt : palette::setPaletteIndexAt);
} }
return palette; return palette;
@ -120,7 +120,7 @@ public final class PaletteType1_18 extends Type<DataPalette> {
} }
} }
final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.maxSize(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt); final long[] data = CompactArrayUtil.createCompactArrayWithPadding(bitsPerValue, type.size(), bitsPerValue == globalPaletteBits ? palette::idAt : palette::paletteIndexAt);
Type.VAR_INT.writePrimitive(buffer, data.length); Type.VAR_INT.writePrimitive(buffer, data.length);
for (final long l : data) { for (final long l : data) {
buffer.writeLong(l); buffer.writeLong(l);

Datei anzeigen

@ -47,7 +47,6 @@ public final class WorldPackets {
private static final int WIDTH_BITS = 2; private static final int WIDTH_BITS = 2;
private static final int HORIZONTAL_MASK = 3; private static final int HORIZONTAL_MASK = 3;
private static final int BIOMES_PER_CHUNK = 4 * 4 * 4;
public static void register(final Protocol1_18To1_17_1 protocol) { public static void register(final Protocol1_18To1_17_1 protocol) {
protocol.registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() { protocol.registerClientbound(ClientboundPackets1_17_1.BLOCK_ENTITY_DATA, new PacketRemapper() {
@ -137,7 +136,7 @@ public final class WorldPackets {
sections[i] = section; sections[i] = section;
section.setNonAirBlocksCount(0); section.setNonAirBlocksCount(0);
final DataPaletteImpl blockPalette = new DataPaletteImpl(); final DataPaletteImpl blockPalette = new DataPaletteImpl(ChunkSection.SIZE);
blockPalette.addId(0); blockPalette.addId(0);
section.addPalette(PaletteType.BLOCKS, blockPalette); section.addPalette(PaletteType.BLOCKS, blockPalette);
} else { } else {
@ -149,20 +148,12 @@ public final class WorldPackets {
} }
// Fill biome palette // Fill biome palette
final DataPaletteImpl biomePalette = new DataPaletteImpl(); final DataPaletteImpl biomePalette = new DataPaletteImpl(ChunkSection.BIOME_SIZE);
section.addPalette(PaletteType.BIOMES, biomePalette); section.addPalette(PaletteType.BIOMES, biomePalette);
for (int biomeIndex = i * BIOMES_PER_CHUNK; biomeIndex < (i * BIOMES_PER_CHUNK) + BIOMES_PER_CHUNK; biomeIndex++) {
final int biome = biomeData[biomeIndex]; final int offset = i * ChunkSection.BIOME_SIZE;
final int minX = (biomeIndex & HORIZONTAL_MASK) << 2; for (int biomeIndex = 0; biomeIndex < ChunkSection.BIOME_SIZE; biomeIndex++) {
final int minY = ((biomeIndex >> WIDTH_BITS + WIDTH_BITS) << 2) & 15; biomePalette.setIdAt(biomeIndex, biomeData[offset + biomeIndex]);
final int minZ = (biomeIndex >> WIDTH_BITS & HORIZONTAL_MASK) << 2;
for (int x = minX; x < minX + 4; x++) {
for (int y = minY; y < minY + 4; y++) {
for (int z = minZ; z < minZ + 4; z++) {
biomePalette.setIdAt(x, y, z, biome);
}
}
}
} }
} }