mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-08 01:17:47 +01:00
Improve block indexing
This commit is contained in:
parent
f183c76afa
commit
3b6b1e9859
@ -18,10 +18,7 @@ import net.minestom.server.network.player.PlayerConnection;
|
|||||||
import net.minestom.server.utils.ArrayUtils;
|
import net.minestom.server.utils.ArrayUtils;
|
||||||
import net.minestom.server.utils.PacketUtils;
|
import net.minestom.server.utils.PacketUtils;
|
||||||
import net.minestom.server.utils.Position;
|
import net.minestom.server.utils.Position;
|
||||||
import net.minestom.server.utils.binary.BinaryReader;
|
|
||||||
import net.minestom.server.utils.chunk.ChunkCallback;
|
|
||||||
import net.minestom.server.utils.chunk.ChunkSupplier;
|
import net.minestom.server.utils.chunk.ChunkSupplier;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
|
||||||
import net.minestom.server.utils.player.PlayerUtils;
|
import net.minestom.server.utils.player.PlayerUtils;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.world.biomes.Biome;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -37,9 +34,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* Should contains all the blocks located at those positions and manage their tick updates.
|
* Should contains all the blocks located at those positions and manage their tick updates.
|
||||||
* Be aware that implementations do not need to be thread-safe, all chunks are guarded by their own instance ('this').
|
* Be aware that implementations do not need to be thread-safe, all chunks are guarded by their own instance ('this').
|
||||||
* <p>
|
* <p>
|
||||||
* Chunks can be serialized using {@link #getSerializedData()} and deserialized back with {@link #readChunk(BinaryReader, ChunkCallback)},
|
|
||||||
* allowing you to implement your own storage solution if needed.
|
|
||||||
* <p>
|
|
||||||
* You can create your own implementation of this class by extending it
|
* You can create your own implementation of this class by extending it
|
||||||
* and create the objects in {@link InstanceContainer#setChunkSupplier(ChunkSupplier)}.
|
* and create the objects in {@link InstanceContainer#setChunkSupplier(ChunkSupplier)}.
|
||||||
* <p>
|
* <p>
|
||||||
@ -472,16 +466,4 @@ public abstract class Chunk implements BlockGetter, BlockSetter, Viewable, Ticka
|
|||||||
ChunkDataPacket.CACHE.invalidate(getIdentifier());
|
ChunkDataPacket.CACHE.invalidate(getIdentifier());
|
||||||
UpdateLightPacket.CACHE.invalidate(getIdentifier());
|
UpdateLightPacket.CACHE.invalidate(getIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the index of a position, used to store blocks.
|
|
||||||
*
|
|
||||||
* @param x the block X
|
|
||||||
* @param y the block Y
|
|
||||||
* @param z the block Z
|
|
||||||
* @return the block index
|
|
||||||
*/
|
|
||||||
protected int getBlockIndex(int x, int y, int z) {
|
|
||||||
return ChunkUtils.getBlockIndex(x, y, z);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -53,7 +53,7 @@ public class DynamicChunk extends Chunk {
|
|||||||
Section section = retrieveSection(y);
|
Section section = retrieveSection(y);
|
||||||
section.setBlockAt(x, y, z, block.stateId());
|
section.setBlockAt(x, y, z, block.stateId());
|
||||||
|
|
||||||
final int index = getBlockIndex(x, y, z);
|
final int index = ChunkUtils.getBlockIndex(x, y, z);
|
||||||
// Handler
|
// Handler
|
||||||
final BlockHandler handler = block.handler();
|
final BlockHandler handler = block.handler();
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
@ -93,9 +93,9 @@ public class DynamicChunk extends Chunk {
|
|||||||
for (var entry : tickableMap.int2ObjectEntrySet()) {
|
for (var entry : tickableMap.int2ObjectEntrySet()) {
|
||||||
final int index = entry.getIntKey();
|
final int index = entry.getIntKey();
|
||||||
|
|
||||||
final byte x = ChunkUtils.blockIndexToChunkPositionX(index);
|
final int x = ChunkUtils.blockIndexToChunkPositionX(index);
|
||||||
final short y = ChunkUtils.blockIndexToChunkPositionY(index);
|
final int y = ChunkUtils.blockIndexToChunkPositionY(index);
|
||||||
final byte z = ChunkUtils.blockIndexToChunkPositionZ(index);
|
final int z = ChunkUtils.blockIndexToChunkPositionZ(index);
|
||||||
final BlockPosition blockPosition = new BlockPosition(x, y, z);
|
final BlockPosition blockPosition = new BlockPosition(x, y, z);
|
||||||
|
|
||||||
final Block block = getBlock(blockPosition);
|
final Block block = getBlock(blockPosition);
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package net.minestom.server.utils.chunk;
|
package net.minestom.server.utils.chunk;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongList;
|
|
||||||
import net.minestom.server.instance.Chunk;
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.utils.BlockPosition;
|
import net.minestom.server.utils.BlockPosition;
|
||||||
@ -32,7 +30,7 @@ public final class ChunkUtils {
|
|||||||
* @param eachCallback the optional callback when a chunk get loaded
|
* @param eachCallback the optional callback when a chunk get loaded
|
||||||
* @param endCallback the optional callback when all the chunks have been loaded
|
* @param endCallback the optional callback when all the chunks have been loaded
|
||||||
*/
|
*/
|
||||||
public static void optionalLoadAll(@NotNull Instance instance, @NotNull long[] chunks,
|
public static void optionalLoadAll(@NotNull Instance instance, long @NotNull [] chunks,
|
||||||
@Nullable ChunkCallback eachCallback, @Nullable ChunkCallback endCallback) {
|
@Nullable ChunkCallback eachCallback, @Nullable ChunkCallback endCallback) {
|
||||||
final int length = chunks.length;
|
final int length = chunks.length;
|
||||||
AtomicInteger counter = new AtomicInteger(0);
|
AtomicInteger counter = new AtomicInteger(0);
|
||||||
@ -176,7 +174,7 @@ public final class ChunkUtils {
|
|||||||
* @param range how far should it retrieves chunk
|
* @param range how far should it retrieves chunk
|
||||||
* @return an array containing chunks index
|
* @return an array containing chunks index
|
||||||
*/
|
*/
|
||||||
public static @NotNull long[] getChunksInRange(@NotNull Position position, int range) {
|
public static long @NotNull [] getChunksInRange(@NotNull Position position, int range) {
|
||||||
long[] visibleChunks = new long[MathUtils.square(range * 2 + 1)];
|
long[] visibleChunks = new long[MathUtils.square(range * 2 + 1)];
|
||||||
int xDistance = 0;
|
int xDistance = 0;
|
||||||
int xDirection = 1;
|
int xDirection = 1;
|
||||||
@ -217,46 +215,8 @@ public final class ChunkUtils {
|
|||||||
return visibleChunks;
|
return visibleChunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all the loaded neighbours of a chunk and itself, no diagonals.
|
|
||||||
*
|
|
||||||
* @param instance the instance of the chunks
|
|
||||||
* @param chunkX the chunk X
|
|
||||||
* @param chunkZ the chunk Z
|
|
||||||
* @return an array containing all the loaded neighbours chunk index
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
public static long[] getNeighbours(@NotNull Instance instance, int chunkX, int chunkZ) {
|
|
||||||
LongList chunks = new LongArrayList();
|
|
||||||
// Constants used to loop through the neighbors
|
|
||||||
final int[] posX = {1, 0, -1};
|
|
||||||
final int[] posZ = {1, 0, -1};
|
|
||||||
|
|
||||||
for (int x : posX) {
|
|
||||||
for (int z : posZ) {
|
|
||||||
|
|
||||||
// No diagonal check
|
|
||||||
if ((Math.abs(x) + Math.abs(z)) == 2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
final int targetX = chunkX + x;
|
|
||||||
final int targetZ = chunkZ + z;
|
|
||||||
final Chunk chunk = instance.getChunk(targetX, targetZ);
|
|
||||||
if (ChunkUtils.isLoaded(chunk)) {
|
|
||||||
// Chunk is loaded, add it
|
|
||||||
final long index = getChunkIndex(targetX, targetZ);
|
|
||||||
chunks.add(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chunks.toArray(new long[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the block index of a position.
|
* Gets the block index of a position.
|
||||||
* <p>
|
|
||||||
* This can be cast as a short as long as you don't mind receiving a negative value (not array-friendly).
|
|
||||||
*
|
*
|
||||||
* @param x the block X
|
* @param x the block X
|
||||||
* @param y the block Y
|
* @param y the block Y
|
||||||
@ -267,10 +227,10 @@ public final class ChunkUtils {
|
|||||||
x = x % Chunk.CHUNK_SIZE_X;
|
x = x % Chunk.CHUNK_SIZE_X;
|
||||||
z = z % Chunk.CHUNK_SIZE_Z;
|
z = z % Chunk.CHUNK_SIZE_Z;
|
||||||
|
|
||||||
short index = (short) (x & 0x000F);
|
int index = x & 0xF; // 4 bits
|
||||||
index |= (y << 4) & 0x0FF0;
|
index |= (y << 24) & 0x0FFFFFF0; // 24 bits
|
||||||
index |= (z << 12) & 0xF000;
|
index |= (z << 28) & 0xF0000000; // 4 bits
|
||||||
return index & 0xffff;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -295,7 +255,7 @@ public final class ChunkUtils {
|
|||||||
* @return the X coordinate of the block index
|
* @return the X coordinate of the block index
|
||||||
*/
|
*/
|
||||||
public static int blockIndexToPositionX(int index, int chunkX) {
|
public static int blockIndexToPositionX(int index, int chunkX) {
|
||||||
return (int) blockIndexToChunkPositionX(index) + Chunk.CHUNK_SIZE_X * chunkX;
|
return blockIndexToChunkPositionX(index) + Chunk.CHUNK_SIZE_X * chunkX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,7 +276,7 @@ public final class ChunkUtils {
|
|||||||
* @return the Z coordinate of the block index
|
* @return the Z coordinate of the block index
|
||||||
*/
|
*/
|
||||||
public static int blockIndexToPositionZ(int index, int chunkZ) {
|
public static int blockIndexToPositionZ(int index, int chunkZ) {
|
||||||
return (int) blockIndexToChunkPositionZ(index) + Chunk.CHUNK_SIZE_Z * chunkZ;
|
return blockIndexToChunkPositionZ(index) + Chunk.CHUNK_SIZE_Z * chunkZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -325,18 +285,18 @@ public final class ChunkUtils {
|
|||||||
* @param index an index computed from {@link #getBlockIndex(int, int, int)}
|
* @param index an index computed from {@link #getBlockIndex(int, int, int)}
|
||||||
* @return the chunk position X (O-15) of the specified index
|
* @return the chunk position X (O-15) of the specified index
|
||||||
*/
|
*/
|
||||||
public static byte blockIndexToChunkPositionX(int index) {
|
public static int blockIndexToChunkPositionX(int index) {
|
||||||
return (byte) (index & 0xF);
|
return index & 0xF; // 0-4 bits
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a block index to a chunk position Y.
|
* Converts a block index to a chunk position Y.
|
||||||
*
|
*
|
||||||
* @param index an index computed from {@link #getBlockIndex(int, int, int)}
|
* @param index an index computed from {@link #getBlockIndex(int, int, int)}
|
||||||
* @return the chunk position Y (O-255) of the specified index
|
* @return the chunk position Y of the specified index
|
||||||
*/
|
*/
|
||||||
public static short blockIndexToChunkPositionY(int index) {
|
public static int blockIndexToChunkPositionY(int index) {
|
||||||
return (short) (index >>> 4 & 0xFF);
|
return (index >> 4) & 0x0FFFFFF; // 4-28 bits
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -345,8 +305,8 @@ public final class ChunkUtils {
|
|||||||
* @param index an index computed from {@link #getBlockIndex(int, int, int)}
|
* @param index an index computed from {@link #getBlockIndex(int, int, int)}
|
||||||
* @return the chunk position Z (O-15) of the specified index
|
* @return the chunk position Z (O-15) of the specified index
|
||||||
*/
|
*/
|
||||||
public static byte blockIndexToChunkPositionZ(int index) {
|
public static int blockIndexToChunkPositionZ(int index) {
|
||||||
return (byte) (index >> 12 & 0xF);
|
return (index >> 28) & 0xF; // 28-32 bits
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user