From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Thu, 2 Apr 2020 02:37:57 -0400 Subject: [PATCH] Optimize Collision to not load chunks The collision code takes an AABB and generates a cuboid of checks rather than a cylinder, so at high velocity this can generate a lot of chunk checks. Treat an unloaded chunk as a collision for entities, and also for players if the "prevent moving into unloaded chunks" setting is enabled. If that serting is not enabled, collisions will be ignored for players, since movement will load only the chunk the player enters anyways and avoids loading massive amounts of surrounding chunks due to large AABB lookups. diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java index f851ed11df14fd9aa8017f44d82fb6cfc3bde345..d9aeb27a3d6cc2fef2030eafd01d92ef7758111c 100644 --- a/src/main/java/net/minecraft/server/ICollisionAccess.java +++ b/src/main/java/net/minecraft/server/ICollisionAccess.java @@ -83,19 +83,28 @@ public interface ICollisionAccess extends IBlockAccess { } while (cursorposition.a()) { - int k1 = cursorposition.b(); - int l1 = cursorposition.c(); - int i2 = cursorposition.d(); + int k1 = cursorposition.b();int x = k1; // Paper + int l1 = cursorposition.c();int y = l1; // Paper + int i2 = cursorposition.d();int z = i2; // Paper int j2 = cursorposition.e(); if (j2 != 3) { - int k2 = k1 >> 4; - int l2 = i2 >> 4; - IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2); - - if (iblockaccess != null) { - blockposition_mutableblockposition.d(k1, l1, i2); - IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); + // Paper start - ensure we don't load chunks + //int k2 = k1 >> 4; + //int l2 = i2 >> 4; + //boolean far = entity != null && MCUtil.distance(entity.locX(), entity.locY(), entity.locZ(), x, y, z) > 8; + blockposition_mutableblockposition.setValues(x, y, z); // Paper - moved up + IBlockData iblockdata = ICollisionAccess.this.getTypeIfLoaded(blockposition_mutableblockposition); + if (iblockdata == null) { + if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) { + VoxelShape voxelshape3 = VoxelShapes.a(new AxisAlignedBB(new BlockPosition(x, y, z))); + consumer.accept(voxelshape3); + return true; + } + } else { + //blockposition_mutableblockposition.d(k1, l1, i2); // moved up + //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up + // Paper end if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision); diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java index 08c83c62dfe875600162a46a0ca4b835b0bfe199..240aa3ea19ca30cf3a21f47611e8a5d2be0683c8 100644 --- a/src/main/java/net/minecraft/server/VoxelShapes.java +++ b/src/main/java/net/minecraft/server/VoxelShapes.java @@ -237,7 +237,8 @@ public final class VoxelShapes { if (k2 < 3) { blockposition_mutableblockposition.a(enumaxiscycle1, i2, j2, l1); - IBlockData iblockdata = iworldreader.getType(blockposition_mutableblockposition); + IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper + if (iblockdata == null) return 0.0D; // Paper if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0);