2020-05-10 01:18:26 +02:00
|
|
|
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 e865a5694f78fb9273a0625ab2c30b87d0711a90..5648ba73c533f622c35c808decdb305f8a1cf6b0 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/GeneratorAccess.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java
|
|
|
|
@@ -52,6 +52,7 @@ 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
|
2020-06-20 11:22:09 +02:00
|
|
|
index 5e20dba0d011d20b714d784cb4a545a05bbf6f9c..5a21205a49606b294de4cd27b60438c6a5b3c526 100644
|
2020-05-10 01:18:26 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
2020-06-20 11:22:09 +02:00
|
|
|
@@ -44,19 +44,40 @@ public interface ICollisionAccess extends IBlockAccess {
|
2020-05-10 01:18:26 +02:00
|
|
|
|
|
|
|
default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
|
2020-06-20 11:22:09 +02:00
|
|
|
try { if (entity != null) entity.collisionLoadChunks = true; // Paper
|
2020-05-10 01:18:26 +02:00
|
|
|
- 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
|
2020-06-20 11:22:09 +02:00
|
|
|
} finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
|
2020-05-10 01:18:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
+ 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;
|
2020-06-20 11:22:09 +02:00
|
|
|
@@ -68,19 +89,19 @@ public interface ICollisionAccess extends IBlockAccess {
|
2020-05-10 01:18:26 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 11:22:09 +02:00
|
|
|
@@ -104,9 +125,8 @@ public interface ICollisionAccess extends IBlockAccess {
|
2020-05-10 11:36:35 +02:00
|
|
|
);
|
2020-05-10 01:18:26 +02:00
|
|
|
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
|
2020-06-20 11:22:09 +02:00
|
|
|
@@ -123,14 +143,14 @@ public interface ICollisionAccess extends IBlockAccess {
|
2020-05-10 01:18:26 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2020-06-20 11:22:09 +02:00
|
|
|
@@ -139,8 +159,9 @@ public interface ICollisionAccess extends IBlockAccess {
|
2020-05-10 01:18:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- 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 d434aaaaf0ab6a18ab0fe5ad0bf8ed4662f49120..3bc57ef91d557383178533b0cc87a71a521d6b3e 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
|
|
@@ -55,8 +55,10 @@ 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<>();
|
|
|
|
@@ -74,6 +76,7 @@ public interface IEntityAccess {
|
|
|
|
|
|
|
|
if (otherEntityBox != null && selection.intersects(otherEntityBox)) {
|
|
|
|
shapes.add(VoxelShapes.of(otherEntityBox));
|
|
|
|
+ if (returnFast) return shapes;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entity != null) {
|
|
|
|
@@ -81,11 +84,12 @@ 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
|
|
|
|
}
|
|
|
|
|