Optimize block collision check

This commit is contained in:
TheMode 2021-07-11 20:44:37 +02:00
parent 9e8d0c9ce0
commit 8597d93e22
5 changed files with 38 additions and 18 deletions

View File

@ -29,6 +29,7 @@ import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceManager;
import net.minestom.server.instance.block.Block;
import net.minestom.server.instance.block.BlockGetter;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.player.PlayerConnection;
@ -573,8 +574,9 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
final Chunk chunk = ChunkUtils.retrieve(instance, currentChunk, x, z);
if (!ChunkUtils.isLoaded(chunk))
continue;
final Block block = chunk.getBlock(x, y, z);
final Block block = chunk.getBlock(x, y, z, BlockGetter.Condition.CACHED);
if (block == null)
continue;
final BlockHandler handler = block.handler();
if (handler != null) {
// checks that we are actually in the block, and not just here because of a rounding error

View File

@ -96,13 +96,16 @@ public class DynamicChunk extends Chunk {
}
@Override
public @NotNull Block getBlock(int x, int y, int z) {
public @Nullable Block getBlock(int x, int y, int z, @NotNull Condition condition) {
// Verify if the block object is present
final int index = ChunkUtils.getBlockIndex(x, y, z);
final var entry = entries.get(index);
final var entry = !entries.isEmpty() ?
entries.get(ChunkUtils.getBlockIndex(x, y, z)) : null;
if (entry != null) {
return entry;
}
if (condition != Condition.NONE) {
return null;
}
// Retrieve the block from state id
final Section section = retrieveSection(y);
final short blockStateId = section.getBlockAt(x, y, z);

View File

@ -520,11 +520,11 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta
}
@Override
public @NotNull Block getBlock(int x, int y, int z) {
public @Nullable Block getBlock(int x, int y, int z, @NotNull Condition condition) {
final Chunk chunk = getChunkAt(x, z);
Check.notNull(chunk, "The chunk at {0}:{1} is not loaded", x, z);
synchronized (chunk) {
return chunk.getBlock(x, y, z);
return chunk.getBlock(x, y, z, condition);
}
}

View File

@ -2,17 +2,33 @@ package net.minestom.server.instance.block;
import net.minestom.server.coordinate.Point;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public interface BlockGetter {
@NotNull Block getBlock(int x, int y, int z);
@Nullable Block getBlock(int x, int y, int z, @NotNull Condition condition);
default @Nullable Block getBlock(@NotNull Point point, @NotNull Condition condition) {
return getBlock(point.blockX(), point.blockY(), point.blockZ(), condition);
}
default @NotNull Block getBlock(int x, int y, int z) {
return Objects.requireNonNull(getBlock(x, y, z, Condition.NONE));
}
/**
* Gets block from given position.
*
* @param point position to get the block from
* @return Block at given position.
*/
default @NotNull Block getBlock(@NotNull Point point) {
return getBlock(point.blockX(), point.blockY(), point.blockZ());
return Objects.requireNonNull(getBlock(point, Condition.NONE));
}
enum Condition {
/**
* Returns a block no matter what.
*/
NONE,
/**
* Returns a block only if it has a handler or nbt.
*/
CACHED
}
}

View File

@ -85,9 +85,8 @@ public final class ChunkUtils {
}
public static boolean same(@NotNull Chunk chunk, double x, double z) {
final int chunkX = getChunkCoordinate(x);
final int chunkZ = getChunkCoordinate(z);
return chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ;
return chunk.getChunkX() == getChunkCoordinate(x) &&
chunk.getChunkZ() == getChunkCoordinate(z);
}
public static Chunk retrieve(Instance instance, Chunk originChunk, double x, double z) {