From 6e0202c33b5578bf0a778913ce40fae0f8f87ad0 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 11 Apr 2021 03:21:38 +0200 Subject: [PATCH] Fix math, improve physics performance --- .../server/collision/CollisionUtils.java | 32 ++++++++++++------- .../server/utils/chunk/ChunkUtils.java | 16 +++++----- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/minestom/server/collision/CollisionUtils.java b/src/main/java/net/minestom/server/collision/CollisionUtils.java index a55d0f172..fb947341f 100644 --- a/src/main/java/net/minestom/server/collision/CollisionUtils.java +++ b/src/main/java/net/minestom/server/collision/CollisionUtils.java @@ -32,21 +32,22 @@ public class CollisionUtils { @NotNull Vector velocityOut) { // TODO handle collisions with nearby entities (should it be done here?) final Instance instance = entity.getInstance(); + final Chunk originChunk = entity.getChunk(); final Position currentPosition = entity.getPosition(); final BoundingBox boundingBox = entity.getBoundingBox(); Vector intermediaryPosition = new Vector(); - final boolean yCollision = stepAxis(instance, currentPosition.toVector(), Y_AXIS, deltaPosition.getY(), + final boolean yCollision = stepAxis(instance, originChunk, currentPosition.toVector(), Y_AXIS, deltaPosition.getY(), intermediaryPosition, deltaPosition.getY() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace() ); - final boolean xCollision = stepAxis(instance, intermediaryPosition, X_AXIS, deltaPosition.getX(), + final boolean xCollision = stepAxis(instance, originChunk, intermediaryPosition, X_AXIS, deltaPosition.getX(), intermediaryPosition, deltaPosition.getX() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace() ); - final boolean zCollision = stepAxis(instance, intermediaryPosition, Z_AXIS, deltaPosition.getZ(), + final boolean zCollision = stepAxis(instance, originChunk, intermediaryPosition, Z_AXIS, deltaPosition.getZ(), intermediaryPosition, deltaPosition.getZ() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace() ); @@ -80,7 +81,11 @@ public class CollisionUtils { * @param corners the corners to check against * @return true if a collision has been found */ - private static boolean stepAxis(Instance instance, Vector startPosition, Vector axis, double stepAmount, Vector positionOut, Vector... corners) { + private static boolean stepAxis(Instance instance, + Chunk originChunk, + Vector startPosition, Vector axis, + double stepAmount, Vector positionOut, + Vector... corners) { positionOut.copy(startPosition); if (corners.length == 0) return false; // avoid degeneracy in following computations @@ -99,7 +104,7 @@ public class CollisionUtils { // used to determine if 'remainingLength' should be used boolean collisionFound = false; for (int i = 0; i < Math.abs(blockLength); i++) { - if (!stepOnce(instance, axis, sign, cornersCopy, cornerPositions)) { + if (!stepOnce(instance, originChunk, axis, sign, cornersCopy, cornerPositions)) { collisionFound = true; } if (collisionFound) { @@ -111,7 +116,7 @@ public class CollisionUtils { if (!collisionFound) { Vector direction = new Vector(); direction.copy(axis); - collisionFound = !stepOnce(instance, direction, remainingLength, cornersCopy, cornerPositions); + collisionFound = !stepOnce(instance, originChunk, direction, remainingLength, cornersCopy, cornerPositions); } // find the corner which moved the least @@ -138,7 +143,9 @@ public class CollisionUtils { * @param cornerPositions the corners, converted to BlockPosition (mutable) * @return false if this method encountered a collision */ - private static boolean stepOnce(Instance instance, Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) { + private static boolean stepOnce(Instance instance, + Chunk originChunk, + Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) { final double sign = Math.signum(amount); for (int cornerIndex = 0; cornerIndex < cornersCopy.length; cornerIndex++) { Vector corner = cornersCopy[cornerIndex]; @@ -148,10 +155,13 @@ public class CollisionUtils { blockPos.setY((int) Math.floor(corner.getY())); blockPos.setZ((int) Math.floor(corner.getZ())); - final Chunk chunk = instance.getChunkAt(blockPos); - if (!ChunkUtils.isLoaded(chunk)) { - // Collision at chunk border - return false; + Chunk chunk = originChunk; + if (!ChunkUtils.same(originChunk, blockPos.getX(), blockPos.getZ())) { + chunk = instance.getChunkAt(blockPos); + if (!ChunkUtils.isLoaded(chunk)) { + // Collision at chunk border + return false; + } } final short blockStateId = chunk.getBlockStateId(blockPos.getX(), blockPos.getY(), blockPos.getZ()); diff --git a/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java b/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java index f3388a0eb..eeefd3b64 100644 --- a/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java +++ b/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java @@ -85,17 +85,17 @@ public final class ChunkUtils { } public static boolean same(@NotNull Chunk chunk, double x, double z) { - final int chunkX = ChunkUtils.getChunkCoordinate(x); - final int chunkZ = ChunkUtils.getChunkCoordinate(z); - return chunk.getChunkX() != chunkX || chunk.getChunkZ() != chunkZ; + final int chunkX = getChunkCoordinate(x); + final int chunkZ = getChunkCoordinate(z); + return chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ; } public static boolean same(@NotNull Position pos1, @NotNull Position pos2) { - final int x1 = ChunkUtils.getChunkCoordinate(pos1.getX()); - final int z1 = ChunkUtils.getChunkCoordinate(pos1.getZ()); - final int x2 = ChunkUtils.getChunkCoordinate(pos2.getX()); - final int z2 = ChunkUtils.getChunkCoordinate(pos2.getZ()); - return x1 != x2 || z1 != z2; + final int x1 = getChunkCoordinate(pos1.getX()); + final int z1 = getChunkCoordinate(pos1.getZ()); + final int x2 = getChunkCoordinate(pos2.getX()); + final int z2 = getChunkCoordinate(pos2.getZ()); + return x1 == x2 && z1 == z2; } /**