mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 23:38:25 +01:00
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 setting 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. Fixes #3321
This commit is contained in:
parent
7c9097159c
commit
f0b502d564
2 changed files with 72 additions and 39 deletions
|
@ -1,39 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 2 Apr 2020 02:37:57 -0400
|
||||
Subject: [PATCH] Optimize Collision Chunk lookup and avoid loading far chunks
|
||||
|
||||
Try to use a faster chunk lookup for collision detection, and only
|
||||
fall back to the original for nearby 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.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
+ // Paper start - ensure we don't load chunks
|
||||
+ boolean far = entity != null && MCUtil.distance(entity.locX(), entity.locY(), entity.locZ(), x, y, z) > 32;
|
||||
+ IBlockAccess iblockaccess = ICollisionAccess.this instanceof WorldServer ? ((WorldServer) ICollisionAccess.this).getChunkProvider().getChunkAtIfLoadedMainThread(k2, l2) : null;
|
||||
+ if (!far && iblockaccess == null) iblockaccess = ICollisionAccess.this.c(k2, l2);
|
||||
+ // Paper end
|
||||
|
||||
if (iblockaccess != null) {
|
||||
blockposition_mutableblockposition.d(k1, l1, i2);
|
|
@ -0,0 +1,72 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/VoxelShapes.java
|
||||
+++ b/src/main/java/net/minecraft/server/VoxelShapes.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
Loading…
Reference in a new issue