PaperMC/Spigot-Server-Patches/Remove-some-Streams-usage-in-Entity-Collision.patch
Aikar a26aabf9d0 Fix teleporting onto a chunk line
Obscure detail in that if you teleport right on a chunk line, it
adds +1 to your collision check and will check the unloaded neighbor.

but the call to load the chunk then returned null if it was pending unload, such
as the load we did in Player List

However we want gen=true for players here anyways, so use getType
2020-05-10 05:36:35 -04:00

177 lines
9.8 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sat, 9 May 2020 18:36:27 -0400
Subject: [PATCH] Remove some Streams usage in Entity Collision
While there is more down the collision system, remove some of the wrapping
Spliterator stuff as even this wrapper stream has shown up in profiling.
With other collision optimizations, we might also even avoid inner streams too.
diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/GeneratorAccess.java
+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java
@@ -0,0 +0,0 @@ public interface GeneratorAccess extends IEntityAccess, IWorldReader, VirtualLev
this.a((EntityHuman) null, i, blockposition, j);
}
+ @Override default java.util.List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {return IEntityAccess.super.getEntityCollisions(entity, axisalignedbb, set, returnFast); } // Paper
@Override
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
return IEntityAccess.super.b(entity, axisalignedbb, set);
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 {
}
default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
- return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty);
+ // Paper start - reduce stream usage
+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, true);
+ for (int i = 0; i < blockCollisions.size(); i++) {
+ VoxelShape blockCollision = blockCollisions.get(i);
+ if (!blockCollision.isEmpty()) {
+ return false;
+ }
+ }
+ return getEntityCollisions(entity, axisalignedbb, set, true).isEmpty();
+ // Paper end
}
+ default java.util.List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) { return java.util.Collections.emptyList(); } // Paper
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
return Stream.empty();
}
default Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
- return Streams.concat(new Stream[]{this.b(entity, axisalignedbb), this.b(entity, axisalignedbb, set)});
+ // Paper start - reduce stream usage
+ java.util.List<VoxelShape> blockCollisions = getBlockCollision(entity, axisalignedbb, false);
+ java.util.List<VoxelShape> entityCollisions = getEntityCollisions(entity, axisalignedbb, set, false);
+ return Stream.concat(blockCollisions.stream(), entityCollisions.stream());
+ // Paper end
}
default Stream<VoxelShape> b(@Nullable final Entity entity, AxisAlignedBB axisalignedbb) {
+ // Paper start - reduce stream usage
+ java.util.List<VoxelShape> collision = getBlockCollision(entity, axisalignedbb, false);
+ return !collision.isEmpty() ? collision.stream() : Stream.empty();
+ }
+
+ default java.util.List<VoxelShape> getBlockCollision(@Nullable final Entity entity, AxisAlignedBB axisalignedbb, boolean returnFast) {
+ // Paper end
int i = MathHelper.floor(axisalignedbb.minX - 1.0E-7D) - 1;
int j = MathHelper.floor(axisalignedbb.maxX + 1.0E-7D) + 1;
int k = MathHelper.floor(axisalignedbb.minY - 1.0E-7D) - 1;
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
final BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
final VoxelShape voxelshape = VoxelShapes.a(axisalignedbb);
- return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
- boolean a = entity == null;
-
- public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {
- if (!this.a) {
- this.a = true;
+ // Paper start - reduce stream usage (this part done by Aikar)
+ java.util.List<VoxelShape> collisions = new java.util.ArrayList<>();
+ if (true) {//return StreamSupport.stream(new AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
+ if (true) { //public boolean tryAdvance(Consumer<? super VoxelShape> consumer) {*/ // Paper
+ if (entity != null) {
+ // Paper end
VoxelShape voxelshape1 = ICollisionAccess.this.getWorldBorder().a();
boolean flag = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().shrink(1.0E-7D)), OperatorBoolean.AND);
boolean flag1 = VoxelShapes.c(voxelshape1, VoxelShapes.a(entity.getBoundingBox().g(1.0E-7D)), OperatorBoolean.AND);
if (!flag && flag1) {
- consumer.accept(voxelshape1);
- return true;
+ collisions.add(voxelshape1);// Paper
+ if (returnFast) return collisions;
}
}
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
);
if (iblockdata == null) {
if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
- VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
- consumer.accept(voxelshape3);
- return true;
+ collisions.add(VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z))));
+ if (returnFast) return collisions;
}
} else {
//blockposition_mutableblockposition.d(k1, l1, i2); // moved up
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
if (voxelshape2 == VoxelShapes.fullCube()) {
if (axisalignedbb.intersects(x, y, z, x + 1.0D, y + 1.0D, z + 1.0D)) {
- consumer.accept(voxelshape2.offset(x, y, z));
- return true;
+ collisions.add(voxelshape2.offset(x, y, z));
+ if (returnFast) return collisions;
}
} else {
VoxelShape shape = voxelshape2.offset(x, y, z);
if (VoxelShapes.applyOperation(shape, voxelshape, OperatorBoolean.AND)) {
- consumer.accept(shape);
- return true;
+ collisions.add(shape);
+ if (returnFast) return collisions;
}
// Paper end
}
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
}
}
- return false;
+ //return false; // Paper
}
- }, false);
+ } //}, false);
+ return collisions; // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
@@ -0,0 +0,0 @@ public interface IEntityAccess {
// Paper start - remove streams from entity collision
if (axisalignedbb.getAverageSideLength() < 1.0E-7D) {
return Stream.empty();
-
}
+ return getEntityCollisions(entity, axisalignedbb, set, false).stream();
+ }
+ default List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set, boolean returnFast) {
AxisAlignedBB selection = axisalignedbb.grow(1.0E-7D);
List<Entity> entities = entity != null && entity.hardCollides() ? getEntities(entity, selection) : getHardCollidingEntities(entity, selection);
List<VoxelShape> shapes = new java.util.ArrayList<>();
@@ -0,0 +0,0 @@ public interface IEntityAccess {
if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
shapes.add(VoxelShapes.of(otherEntityBox));
+ if (returnFast) return shapes;
}
if (entity != null) {
@@ -0,0 +0,0 @@ public interface IEntityAccess {
if (otherEntityHardBox != null && selection.intersects(otherEntityHardBox)) {
shapes.add(VoxelShapes.of(otherEntityHardBox));
+ if (returnFast) return shapes;
}
}
}
- return shapes.stream();
+ return shapes;
// Paper end
}