Update patches to handle vineflower decompiler (#10406)
* Update patches to handle vineflower decompiler * update patches again to handle inlined simple lambdas * update vf again and re-apply/rebuild patches * update patches after removal of verify-merges flag * fix compile issue * remove maven local * fix some issues * address more issues * fix collision patch * use paperweight release * more fixes * update fineflower and fix patches again * add missing comment descriptor --------- Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
This commit is contained in:
@@ -2470,14 +2470,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
--- a/src/main/java/net/minecraft/world/level/BlockCollisions.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BlockCollisions.java
|
||||
@@ -0,0 +0,0 @@ public class BlockCollisions<T> extends AbstractIterator<T> {
|
||||
|
||||
VoxelShape voxelShape = blockState.getCollisionShape(this.collisionGetter, this.pos, this.context);
|
||||
if (voxelShape == Shapes.block()) {
|
||||
- if (!this.box.intersects((double)i, (double)j, (double)k, (double)i + 1.0D, (double)j + 1.0D, (double)k + 1.0D)) {
|
||||
+ if (!io.papermc.paper.util.CollisionUtil.voxelShapeIntersect(this.box, (double)i, (double)j, (double)k, (double)i + 1.0D, (double)j + 1.0D, (double)k + 1.0D)) { // Paper - keep vanilla behavior for voxelshape intersection - See comment in CollisionUtil
|
||||
continue;
|
||||
}
|
||||
|
||||
// Paper end
|
||||
VoxelShape voxelShape = blockState.getCollisionShape(this.collisionGetter, this.pos, this.context);
|
||||
if (voxelShape == Shapes.block()) {
|
||||
- if (this.box.intersects(i, j, k, i + 1.0, j + 1.0, k + 1.0)) {
|
||||
+ if (io.papermc.paper.util.CollisionUtil.voxelShapeIntersect(this.box, i, j, k, i + 1.0, j + 1.0, k + 1.0)) { // Paper - keep vanilla behavior for voxelshape intersection - See comment in CollisionUtil
|
||||
return this.resultProvider.apply(this.pos, voxelShape.move(i, j, k));
|
||||
}
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/ClipContext.java b/src/main/java/net/minecraft/world/level/ClipContext.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/ClipContext.java
|
||||
@@ -2508,7 +2508,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ // Paper end - optimise collisions
|
||||
+
|
||||
default boolean noCollision(AABB box) {
|
||||
return this.noCollision((Entity)null, box);
|
||||
return this.noCollision(null, box);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
@@ -2522,8 +2522,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
if (shape.isEmpty()) {
|
||||
- return true;
|
||||
- } else {
|
||||
- for(Entity entity : this.getEntities(except, shape.bounds())) {
|
||||
- if (!entity.isRemoved() && entity.blocksBuilding && (except == null || !entity.isPassengerOfSameVehicle(except)) && Shapes.joinIsNotEmpty(shape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
|
||||
- for (Entity entity : this.getEntities(except, shape.bounds())) {
|
||||
- if (!entity.isRemoved()
|
||||
- && entity.blocksBuilding
|
||||
- && (except == null || !entity.isPassengerOfSameVehicle(except))
|
||||
- && Shapes.joinIsNotEmpty(shape, Shapes.create(entity.getBoundingBox()), BooleanOp.AND)) {
|
||||
- return false;
|
||||
+ return false;
|
||||
+ }
|
||||
@@ -2561,7 +2564,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
}
|
||||
|
||||
default List<VoxelShape> getEntityCollisions(@Nullable Entity entity, AABB box) {
|
||||
- if (box.getSize() < 1.0E-7D) {
|
||||
- if (box.getSize() < 1.0E-7) {
|
||||
- return List.of();
|
||||
+ // Paper start - optimise collisions
|
||||
+ // first behavior change is to correctly check for empty AABB
|
||||
@@ -2580,21 +2583,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ entities = this.getEntities(entity, box, null);
|
||||
} else {
|
||||
- Predicate<Entity> predicate = entity == null ? EntitySelector.CAN_BE_COLLIDED_WITH : EntitySelector.NO_SPECTATORS.and(entity::canCollideWith);
|
||||
- List<Entity> list = this.getEntities(entity, box.inflate(1.0E-7D), predicate);
|
||||
- List<Entity> list = this.getEntities(entity, box.inflate(1.0E-7), predicate);
|
||||
- if (list.isEmpty()) {
|
||||
- return List.of();
|
||||
- } else {
|
||||
- ImmutableList.Builder<VoxelShape> builder = ImmutableList.builderWithExpectedSize(list.size());
|
||||
- Builder<VoxelShape> builder = ImmutableList.builderWithExpectedSize(list.size());
|
||||
-
|
||||
- for(Entity entity2 : list) {
|
||||
- for (Entity entity2 : list) {
|
||||
- builder.add(Shapes.create(entity2.getBoundingBox()));
|
||||
- }
|
||||
+ entities = this.getHardCollidingEntities(entity, box, null);
|
||||
+ }
|
||||
+
|
||||
+ final List<VoxelShape> ret = new java.util.ArrayList<>(Math.min(25, entities.size()));
|
||||
|
||||
- return builder.build();
|
||||
+ final List<VoxelShape> ret = new java.util.ArrayList<>(Math.min(25, entities.size()));
|
||||
+
|
||||
+ for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
+ final Entity otherEntity = entities.get(i);
|
||||
+
|
||||
@@ -3234,23 +3237,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ // Paper end
|
||||
+
|
||||
public AABB(BlockPos pos) {
|
||||
this((double)pos.getX(), (double)pos.getY(), (double)pos.getZ(), (double)(pos.getX() + 1), (double)(pos.getY() + 1), (double)(pos.getZ() + 1));
|
||||
this(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class AABB {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- private static Direction getDirection(AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ) {
|
||||
+ public static Direction getDirection(AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ) { // Paper - optimise collisions - public
|
||||
if (deltaX > 1.0E-7D) {
|
||||
approachDirection = clipPoint(traceDistanceResult, approachDirection, deltaX, deltaY, deltaZ, box.minX, box.minY, box.maxY, box.minZ, box.maxZ, Direction.WEST, intersectingVector.x, intersectingVector.y, intersectingVector.z);
|
||||
} else if (deltaX < -1.0E-7D) {
|
||||
- private static Direction getDirection(
|
||||
+ public static Direction getDirection( // Paper - optimise collisions - public
|
||||
AABB box, Vec3 intersectingVector, double[] traceDistanceResult, @Nullable Direction approachDirection, double deltaX, double deltaY, double deltaZ
|
||||
) {
|
||||
if (deltaX > 1.0E-7) {
|
||||
diff --git a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java
|
||||
@@ -0,0 +0,0 @@ public class ArrayVoxelShape extends VoxelShape {
|
||||
this(shape, (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(xPoints, shape.getXSize() + 1)), (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(yPoints, shape.getYSize() + 1)), (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(zPoints, shape.getZSize() + 1)));
|
||||
);
|
||||
}
|
||||
|
||||
- ArrayVoxelShape(DiscreteVoxelShape shape, DoubleList xPoints, DoubleList yPoints, DoubleList zPoints) {
|
||||
@@ -3259,8 +3262,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
int i = shape.getXSize() + 1;
|
||||
int j = shape.getYSize() + 1;
|
||||
@@ -0,0 +0,0 @@ public class ArrayVoxelShape extends VoxelShape {
|
||||
} else {
|
||||
throw (IllegalArgumentException)Util.pauseInIde(new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape."));
|
||||
new IllegalArgumentException("Lengths of point arrays must be consistent with the size of the VoxelShape.")
|
||||
);
|
||||
}
|
||||
+ this.initCache(); // Paper - optimise collisions
|
||||
}
|
||||
@@ -3305,11 +3308,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ // Paper start - optimise collisions
|
||||
+ // called with the shape of a VoxelShape, so we can expect the cache to exist
|
||||
+ final io.papermc.paper.util.collisions.CachedShapeData cache = voxelSet.getOrCreateCachedShapeData();
|
||||
+
|
||||
|
||||
- for (int i = 0; i < bitSetDiscreteVoxelShape.ySize; i++) {
|
||||
- for (int j = 0; j < bitSetDiscreteVoxelShape.xSize; j++) {
|
||||
- int k = -1;
|
||||
+ final int sizeX = cache.sizeX();
|
||||
+ final int sizeY = cache.sizeY();
|
||||
+ final int sizeZ = cache.sizeZ();
|
||||
+
|
||||
|
||||
- for (int l = 0; l <= bitSetDiscreteVoxelShape.zSize; l++) {
|
||||
- if (bitSetDiscreteVoxelShape.isFullWide(j, i, l)) {
|
||||
- if (coalesce) {
|
||||
- if (k == -1) {
|
||||
- k = l;
|
||||
- }
|
||||
- } else {
|
||||
- callback.consume(j, i, l, j + 1, i + 1, l + 1);
|
||||
+ int indexX;
|
||||
+ int indexY = 0;
|
||||
+ int indexZ;
|
||||
@@ -3339,21 +3353,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ } else {
|
||||
+ // same notes about loop order as the above
|
||||
+ // this branch is actually important to optimise, as it affects uncached toAabbs() (which affects optimize())
|
||||
|
||||
- for(int i = 0; i < bitSetDiscreteVoxelShape.ySize; ++i) {
|
||||
- for(int j = 0; j < bitSetDiscreteVoxelShape.xSize; ++j) {
|
||||
- int k = -1;
|
||||
+
|
||||
+ // only clone when we may write to it
|
||||
+ bitset = bitset.clone();
|
||||
|
||||
- for(int l = 0; l <= bitSetDiscreteVoxelShape.zSize; ++l) {
|
||||
- if (bitSetDiscreteVoxelShape.isFullWide(j, i, l)) {
|
||||
- if (coalesce) {
|
||||
- if (k == -1) {
|
||||
- k = l;
|
||||
- }
|
||||
- } else {
|
||||
- callback.consume(j, i, l, j + 1, i + 1, l + 1);
|
||||
+
|
||||
+ for (int y = 0; y < sizeY; ++y, indexY += incY) {
|
||||
+ indexX = indexY;
|
||||
+ for (int x = 0; x < sizeX; ++x, indexX += incX) {
|
||||
@@ -3368,17 +3371,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- int n = i;
|
||||
- bitSetDiscreteVoxelShape.clearZStrip(k, l, j, i);
|
||||
-
|
||||
- while(bitSetDiscreteVoxelShape.isZStripFull(k, l, m + 1, i)) {
|
||||
- while (bitSetDiscreteVoxelShape.isZStripFull(k, l, m + 1, i)) {
|
||||
- bitSetDiscreteVoxelShape.clearZStrip(k, l, m + 1, i);
|
||||
- ++m;
|
||||
- m++;
|
||||
+
|
||||
+ int lastSetZ = io.papermc.paper.util.collisions.FlatBitsetUtil.firstClear(bitset, firstSetZ, endIndex);
|
||||
+ if (lastSetZ == -1) {
|
||||
+ lastSetZ = endIndex;
|
||||
}
|
||||
|
||||
- while(bitSetDiscreteVoxelShape.isXZRectangleFull(j, m + 1, k, l, n + 1)) {
|
||||
- for(int o = j; o <= m; ++o) {
|
||||
- while (bitSetDiscreteVoxelShape.isXZRectangleFull(j, m + 1, k, l, n + 1)) {
|
||||
- for (int o = j; o <= m; o++) {
|
||||
- bitSetDiscreteVoxelShape.clearZStrip(k, l, o, n + 1);
|
||||
+ io.papermc.paper.util.collisions.FlatBitsetUtil.clearRange(bitset, firstSetZ, lastSetZ);
|
||||
+
|
||||
@@ -3408,7 +3411,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ }
|
||||
}
|
||||
|
||||
- ++n;
|
||||
- n++;
|
||||
+ ++endY;
|
||||
+
|
||||
+ // passed, so we can clear it
|
||||
@@ -3426,7 +3429,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
+ // Paper end - optimise collisions
|
||||
}
|
||||
|
||||
@@ -3539,8 +3541,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
@@ -0,0 +0,0 @@ public final class Shapes {
|
||||
public static final double EPSILON = 1.0E-7D;
|
||||
public static final double BIG_EPSILON = 1.0E-6D;
|
||||
public static final double EPSILON = 1.0E-7;
|
||||
public static final double BIG_EPSILON = 1.0E-6;
|
||||
private static final VoxelShape BLOCK = Util.make(() -> {
|
||||
- DiscreteVoxelShape discreteVoxelShape = new BitSetDiscreteVoxelShape(1, 1, 1);
|
||||
- discreteVoxelShape.fill(0, 0, 0);
|
||||
@@ -3555,8 +3557,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ );
|
||||
+ // Paper end - optimise collisions - force arrayvoxelshape
|
||||
});
|
||||
public static final VoxelShape INFINITY = box(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
|
||||
private static final VoxelShape EMPTY = new ArrayVoxelShape(new BitSetDiscreteVoxelShape(0, 0, 0), (DoubleList)(new DoubleArrayList(new double[]{0.0D})), (DoubleList)(new DoubleArrayList(new double[]{0.0D})), (DoubleList)(new DoubleArrayList(new double[]{0.0D})));
|
||||
public static final VoxelShape INFINITY = box(
|
||||
Double.NEGATIVE_INFINITY,
|
||||
@@ -0,0 +0,0 @@ public final class Shapes {
|
||||
new DoubleArrayList(new double[]{0.0})
|
||||
);
|
||||
|
||||
+ // Paper start - optimise collisions - force arrayvoxelshape
|
||||
+ private static final DoubleArrayList[] PARTS_BY_BITS = new DoubleArrayList[] {
|
||||
@@ -3588,13 +3593,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
@@ -0,0 +0,0 @@ public final class Shapes {
|
||||
|
||||
public static VoxelShape create(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
|
||||
if (!(maxX - minX < 1.0E-7D) && !(maxY - minY < 1.0E-7D) && !(maxZ - minZ < 1.0E-7D)) {
|
||||
if (!(maxX - minX < 1.0E-7) && !(maxY - minY < 1.0E-7) && !(maxZ - minZ < 1.0E-7)) {
|
||||
- int i = findBits(minX, maxX);
|
||||
- int j = findBits(minY, maxY);
|
||||
- int k = findBits(minZ, maxZ);
|
||||
- if (i >= 0 && j >= 0 && k >= 0) {
|
||||
- if (i == 0 && j == 0 && k == 0) {
|
||||
- return block();
|
||||
- if (i < 0 || j < 0 || k < 0) {
|
||||
- return new ArrayVoxelShape(
|
||||
- BLOCK.shape,
|
||||
- DoubleArrayList.wrap(new double[]{minX, maxX}),
|
||||
- DoubleArrayList.wrap(new double[]{minY, maxY}),
|
||||
- DoubleArrayList.wrap(new double[]{minZ, maxZ})
|
||||
- );
|
||||
- } else if (i == 0 && j == 0 && k == 0) {
|
||||
- return block();
|
||||
+ // Paper start - optimise collisions
|
||||
+ // force ArrayVoxelShape in every case
|
||||
+ final int bitsX = findBits(minX, maxX);
|
||||
@@ -3603,12 +3614,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ if (bitsX >= 0 && bitsY >= 0 && bitsZ >= 0) {
|
||||
+ if (bitsX == 0 && bitsY == 0 && bitsZ == 0) {
|
||||
+ return BLOCK;
|
||||
} else {
|
||||
- int l = 1 << i;
|
||||
- int m = 1 << j;
|
||||
- int n = 1 << k;
|
||||
- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.withFilledBounds(l, m, n, (int)Math.round(minX * (double)l), (int)Math.round(minY * (double)m), (int)Math.round(minZ * (double)n), (int)Math.round(maxX * (double)l), (int)Math.round(maxY * (double)m), (int)Math.round(maxZ * (double)n));
|
||||
- return new CubeVoxelShape(bitSetDiscreteVoxelShape);
|
||||
+ } else {
|
||||
+ final int sizeX = 1 << bitsX;
|
||||
+ final int sizeY = 1 << bitsY;
|
||||
+ final int sizeZ = 1 << bitsZ;
|
||||
@@ -3623,15 +3629,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ PARTS_BY_BITS[bitsY],
|
||||
+ PARTS_BY_BITS[bitsZ]
|
||||
+ );
|
||||
}
|
||||
+ }
|
||||
} else {
|
||||
- return new ArrayVoxelShape(BLOCK.shape, (DoubleList)DoubleArrayList.wrap(new double[]{minX, maxX}), (DoubleList)DoubleArrayList.wrap(new double[]{minY, maxY}), (DoubleList)DoubleArrayList.wrap(new double[]{minZ, maxZ}));
|
||||
- int l = 1 << i;
|
||||
- int m = 1 << j;
|
||||
- int n = 1 << k;
|
||||
- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.withFilledBounds(
|
||||
- l,
|
||||
- m,
|
||||
- n,
|
||||
- (int)Math.round(minX * l),
|
||||
- (int)Math.round(minY * m),
|
||||
- (int)Math.round(minZ * n),
|
||||
- (int)Math.round(maxX * l),
|
||||
- (int)Math.round(maxY * m),
|
||||
- (int)Math.round(maxZ * n)
|
||||
+ return new ArrayVoxelShape(
|
||||
+ BLOCK.shape,
|
||||
+ minX == 0.0 && maxX == 1.0 ? io.papermc.paper.util.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minX, maxX }),
|
||||
+ minY == 0.0 && maxY == 1.0 ? io.papermc.paper.util.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minY, maxY }),
|
||||
+ minZ == 0.0 && maxZ == 1.0 ? io.papermc.paper.util.CollisionUtil.ZERO_ONE : DoubleArrayList.wrap(new double[] { minZ, maxZ })
|
||||
+ );
|
||||
);
|
||||
- return new CubeVoxelShape(bitSetDiscreteVoxelShape);
|
||||
}
|
||||
+ // Paper end - optimise collisions
|
||||
} else {
|
||||
@@ -3699,9 +3718,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- } else {
|
||||
- IndexMerger indexMerger = createIndexMerger(1, one.getCoords(Direction.Axis.X), two.getCoords(Direction.Axis.X), bl, bl2);
|
||||
- IndexMerger indexMerger2 = createIndexMerger(indexMerger.size() - 1, one.getCoords(Direction.Axis.Y), two.getCoords(Direction.Axis.Y), bl, bl2);
|
||||
- IndexMerger indexMerger3 = createIndexMerger((indexMerger.size() - 1) * (indexMerger2.size() - 1), one.getCoords(Direction.Axis.Z), two.getCoords(Direction.Axis.Z), bl, bl2);
|
||||
- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.join(one.shape, two.shape, indexMerger, indexMerger2, indexMerger3, function);
|
||||
- return (VoxelShape)(indexMerger instanceof DiscreteCubeMerger && indexMerger2 instanceof DiscreteCubeMerger && indexMerger3 instanceof DiscreteCubeMerger ? new CubeVoxelShape(bitSetDiscreteVoxelShape) : new ArrayVoxelShape(bitSetDiscreteVoxelShape, indexMerger.getList(), indexMerger2.getList(), indexMerger3.getList()));
|
||||
- IndexMerger indexMerger3 = createIndexMerger(
|
||||
- (indexMerger.size() - 1) * (indexMerger2.size() - 1), one.getCoords(Direction.Axis.Z), two.getCoords(Direction.Axis.Z), bl, bl2
|
||||
- );
|
||||
- BitSetDiscreteVoxelShape bitSetDiscreteVoxelShape = BitSetDiscreteVoxelShape.join(
|
||||
- one.shape, two.shape, indexMerger, indexMerger2, indexMerger3, function
|
||||
- );
|
||||
- return (VoxelShape)(indexMerger instanceof DiscreteCubeMerger
|
||||
- && indexMerger2 instanceof DiscreteCubeMerger
|
||||
- && indexMerger3 instanceof DiscreteCubeMerger
|
||||
- ? new CubeVoxelShape(bitSetDiscreteVoxelShape)
|
||||
- : new ArrayVoxelShape(bitSetDiscreteVoxelShape, indexMerger.getList(), indexMerger2.getList(), indexMerger3.getList()));
|
||||
- }
|
||||
- }
|
||||
+ return io.papermc.paper.util.CollisionUtil.joinUnoptimized(one, two, function); // Paper - optimise collisions
|
||||
@@ -3720,19 +3747,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- boolean bl3 = predicate.apply(true, false);
|
||||
- boolean bl4 = predicate.apply(false, true);
|
||||
-
|
||||
- for(Direction.Axis axis : AxisCycle.AXIS_VALUES) {
|
||||
- if (shape1.max(axis) < shape2.min(axis) - 1.0E-7D) {
|
||||
- for (Direction.Axis axis : AxisCycle.AXIS_VALUES) {
|
||||
- if (shape1.max(axis) < shape2.min(axis) - 1.0E-7) {
|
||||
- return bl3 || bl4;
|
||||
- }
|
||||
-
|
||||
- if (shape2.max(axis) < shape1.min(axis) - 1.0E-7D) {
|
||||
- if (shape2.max(axis) < shape1.min(axis) - 1.0E-7) {
|
||||
- return bl3 || bl4;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- IndexMerger indexMerger = createIndexMerger(1, shape1.getCoords(Direction.Axis.X), shape2.getCoords(Direction.Axis.X), bl3, bl4);
|
||||
- IndexMerger indexMerger2 = createIndexMerger(indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), bl3, bl4);
|
||||
- IndexMerger indexMerger3 = createIndexMerger((indexMerger.size() - 1) * (indexMerger2.size() - 1), shape1.getCoords(Direction.Axis.Z), shape2.getCoords(Direction.Axis.Z), bl3, bl4);
|
||||
- IndexMerger indexMerger2 = createIndexMerger(
|
||||
- indexMerger.size() - 1, shape1.getCoords(Direction.Axis.Y), shape2.getCoords(Direction.Axis.Y), bl3, bl4
|
||||
- );
|
||||
- IndexMerger indexMerger3 = createIndexMerger(
|
||||
- (indexMerger.size() - 1) * (indexMerger2.size() - 1), shape1.getCoords(Direction.Axis.Z), shape2.getCoords(Direction.Axis.Z), bl3, bl4
|
||||
- );
|
||||
- return joinIsNotEmpty(indexMerger, indexMerger2, indexMerger3, shape1.shape, shape2.shape, predicate);
|
||||
- }
|
||||
- } else {
|
||||
@@ -3742,7 +3773,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ return io.papermc.paper.util.CollisionUtil.isJoinNonEmpty(shape1, shape2, predicate); // Paper - optimise collisions
|
||||
}
|
||||
|
||||
private static boolean joinIsNotEmpty(IndexMerger mergedX, IndexMerger mergedY, IndexMerger mergedZ, DiscreteVoxelShape shape1, DiscreteVoxelShape shape2, BooleanOp predicate) {
|
||||
private static boolean joinIsNotEmpty(
|
||||
@@ -0,0 +0,0 @@ public final class Shapes {
|
||||
}
|
||||
|
||||
@@ -3758,6 +3789,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ }
|
||||
+
|
||||
+ if (shape.isEmpty() | neighbor.isEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // we optimise getOpposite, so we can use it
|
||||
+ // secondly, use our cache to retrieve sliced shape
|
||||
+ final VoxelShape newFirst = shape.getFaceShapeClamped(direction);
|
||||
+ if (newFirst.isEmpty()) {
|
||||
return false;
|
||||
- } else {
|
||||
- Direction.Axis axis = direction.getAxis();
|
||||
@@ -3765,15 +3803,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? shape : neighbor;
|
||||
- VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? neighbor : shape;
|
||||
- BooleanOp booleanOp = axisDirection == Direction.AxisDirection.POSITIVE ? BooleanOp.ONLY_FIRST : BooleanOp.ONLY_SECOND;
|
||||
- return DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0D, 1.0E-7D) && DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0D, 1.0E-7D) && !joinIsNotEmpty(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), booleanOp);
|
||||
- return DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)
|
||||
- && DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)
|
||||
- && !joinIsNotEmpty(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), booleanOp);
|
||||
}
|
||||
+
|
||||
+ // we optimise getOpposite, so we can use it
|
||||
+ // secondly, use our cache to retrieve sliced shape
|
||||
+ final VoxelShape newFirst = shape.getFaceShapeClamped(direction);
|
||||
+ if (newFirst.isEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ final VoxelShape newSecond = neighbor.getFaceShapeClamped(direction.getOpposite());
|
||||
+ if (newSecond.isEmpty()) {
|
||||
+ return false;
|
||||
@@ -3791,10 +3824,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- boolean bl;
|
||||
- int i;
|
||||
- if (direction.getAxisDirection() == Direction.AxisDirection.POSITIVE) {
|
||||
- bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0D, 1.0E-7D);
|
||||
- bl = DoubleMath.fuzzyEquals(shape.max(axis), 1.0, 1.0E-7);
|
||||
- i = shape.shape.getSize(axis) - 1;
|
||||
- } else {
|
||||
- bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0D, 1.0E-7D);
|
||||
- bl = DoubleMath.fuzzyEquals(shape.min(axis), 0.0, 1.0E-7);
|
||||
- i = 0;
|
||||
- }
|
||||
+ return shape.getFaceShapeClamped(direction); // Paper - optimise collisions
|
||||
@@ -3828,7 +3861,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- Direction.AxisDirection axisDirection = direction.getAxisDirection();
|
||||
- VoxelShape voxelShape = axisDirection == Direction.AxisDirection.POSITIVE ? one : two;
|
||||
- VoxelShape voxelShape2 = axisDirection == Direction.AxisDirection.POSITIVE ? two : one;
|
||||
- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0D, 1.0E-7D)) {
|
||||
- if (!DoubleMath.fuzzyEquals(voxelShape.max(axis), 1.0, 1.0E-7)) {
|
||||
- voxelShape = empty();
|
||||
- }
|
||||
+ // Paper start - optimise collisions
|
||||
@@ -3837,14 +3870,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ return true;
|
||||
+ }
|
||||
|
||||
- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0D, 1.0E-7D)) {
|
||||
- if (!DoubleMath.fuzzyEquals(voxelShape2.min(axis), 0.0, 1.0E-7)) {
|
||||
- voxelShape2 = empty();
|
||||
- }
|
||||
+ if (one.isEmpty() & two.isEmpty()) {
|
||||
+ return false;
|
||||
+ }
|
||||
|
||||
- return !joinIsNotEmpty(block(), joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR), BooleanOp.ONLY_FIRST);
|
||||
- return !joinIsNotEmpty(
|
||||
- block(),
|
||||
- joinUnoptimized(new SliceShape(voxelShape, axis, voxelShape.shape.getSize(axis) - 1), new SliceShape(voxelShape2, axis, 0), BooleanOp.OR),
|
||||
- BooleanOp.ONLY_FIRST
|
||||
- );
|
||||
- } else {
|
||||
+ // we optimise getOpposite, so we can use it
|
||||
+ // secondly, use our cache to retrieve sliced shape
|
||||
@@ -3876,17 +3913,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
}
|
||||
|
||||
public static boolean faceShapeOccludes(VoxelShape one, VoxelShape two) {
|
||||
- if (one != block() && two != block()) {
|
||||
- if (one.isEmpty() && two.isEmpty()) {
|
||||
- return false;
|
||||
- } else {
|
||||
- return !joinIsNotEmpty(block(), joinUnoptimized(one, two, BooleanOp.OR), BooleanOp.ONLY_FIRST);
|
||||
- }
|
||||
- } else {
|
||||
- return one == block()
|
||||
- || two == block()
|
||||
- || (!one.isEmpty() || !two.isEmpty()) && !joinIsNotEmpty(block(), joinUnoptimized(one, two, BooleanOp.OR), BooleanOp.ONLY_FIRST);
|
||||
+ // Paper start - optimise collisions
|
||||
+ if (one.occludesFullBlockIfCached() || two.occludesFullBlockIfCached()) {
|
||||
return true;
|
||||
}
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ final boolean s1Empty = one.isEmpty();
|
||||
+ final boolean s2Empty = two.isEmpty();
|
||||
@@ -3937,7 +3970,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ private double offsetX;
|
||||
+ private double offsetY;
|
||||
+ private double offsetZ;
|
||||
+ private AABB singleAABBRepresentation;
|
||||
+ @Nullable private AABB singleAABBRepresentation;
|
||||
+ private double[] rootCoordinatesX;
|
||||
+ private double[] rootCoordinatesY;
|
||||
+ private double[] rootCoordinatesZ;
|
||||
@@ -4335,15 +4368,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- if (this.isEmpty()) {
|
||||
- throw (UnsupportedOperationException)Util.pauseInIde(new UnsupportedOperationException("No bounds for empty shape."));
|
||||
- } else {
|
||||
- return new AABB(this.min(Direction.Axis.X), this.min(Direction.Axis.Y), this.min(Direction.Axis.Z), this.max(Direction.Axis.X), this.max(Direction.Axis.Y), this.max(Direction.Axis.Z));
|
||||
- return new AABB(
|
||||
- this.min(Direction.Axis.X),
|
||||
- this.min(Direction.Axis.Y),
|
||||
- this.min(Direction.Axis.Z),
|
||||
- this.max(Direction.Axis.X),
|
||||
- this.max(Direction.Axis.Y),
|
||||
- this.max(Direction.Axis.Z)
|
||||
- );
|
||||
+ // Paper start - optimise collisions
|
||||
+ if (this.isEmpty) {
|
||||
+ throw Util.pauseInIde(new UnsupportedOperationException("No bounds for empty shape."));
|
||||
}
|
||||
+ }
|
||||
+ AABB cached = this.cachedBounds;
|
||||
+ if (cached != null) {
|
||||
+ return cached;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ final io.papermc.paper.util.collisions.CachedShapeData shapeData = this.cachedShapeData;
|
||||
+
|
||||
@@ -4378,26 +4418,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
public boolean isEmpty() {
|
||||
- return this.shape.isEmpty();
|
||||
+ return this.isEmpty; // Paper - optimise collisions
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - optimise collisions
|
||||
+ private static DoubleList offsetList(final DoubleList src, final double by) {
|
||||
+ if (src instanceof OffsetDoubleList offsetDoubleList) {
|
||||
+ return new OffsetDoubleList(offsetDoubleList.delegate, by + offsetDoubleList.offset);
|
||||
+ }
|
||||
+ return new OffsetDoubleList(src, by);
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - optimise collisions
|
||||
+
|
||||
|
||||
public VoxelShape move(double x, double y, double z) {
|
||||
- return (VoxelShape)(this.isEmpty() ? Shapes.empty() : new ArrayVoxelShape(this.shape, (DoubleList)(new OffsetDoubleList(this.getCoords(Direction.Axis.X), x)), (DoubleList)(new OffsetDoubleList(this.getCoords(Direction.Axis.Y), y)), (DoubleList)(new OffsetDoubleList(this.getCoords(Direction.Axis.Z), z))));
|
||||
- return (VoxelShape)(this.isEmpty()
|
||||
- ? Shapes.empty()
|
||||
- : new ArrayVoxelShape(
|
||||
+ // Paper start - optimise collisions
|
||||
+ if (this.isEmpty) {
|
||||
+ return Shapes.empty();
|
||||
+ }
|
||||
+
|
||||
+ final ArrayVoxelShape ret = new ArrayVoxelShape(
|
||||
+ this.shape,
|
||||
this.shape,
|
||||
- new OffsetDoubleList(this.getCoords(Direction.Axis.X), x),
|
||||
- new OffsetDoubleList(this.getCoords(Direction.Axis.Y), y),
|
||||
- new OffsetDoubleList(this.getCoords(Direction.Axis.Z), z)
|
||||
- ));
|
||||
+ offsetList(this.getCoords(Direction.Axis.X), x),
|
||||
+ offsetList(this.getCoords(Direction.Axis.Y), y),
|
||||
+ offsetList(this.getCoords(Direction.Axis.Z), z)
|
||||
@@ -4414,9 +4460,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
|
||||
public VoxelShape optimize() {
|
||||
- VoxelShape[] voxelShapes = new VoxelShape[]{Shapes.empty()};
|
||||
- this.forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> {
|
||||
- voxelShapes[0] = Shapes.joinUnoptimized(voxelShapes[0], Shapes.box(minX, minY, minZ, maxX, maxY, maxZ), BooleanOp.OR);
|
||||
- });
|
||||
- this.forAllBoxes(
|
||||
- (minX, minY, minZ, maxX, maxY, maxZ) -> voxelShapes[0] = Shapes.joinUnoptimized(
|
||||
- voxelShapes[0], Shapes.box(minX, minY, minZ, maxX, maxY, maxZ), BooleanOp.OR
|
||||
- )
|
||||
- );
|
||||
- return voxelShapes[0];
|
||||
+ // Paper start - optimise collisions
|
||||
+ // Optimise merge strategy to increase the number of simple joins, and additionally forward the toAabbs cache
|
||||
@@ -4487,7 +4535,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
|
||||
public void forAllEdges(Shapes.DoubleLineConsumer consumer) {
|
||||
@@ -0,0 +0,0 @@ public abstract class VoxelShape {
|
||||
}, true);
|
||||
);
|
||||
}
|
||||
|
||||
+ // Paper start - optimise collisions
|
||||
@@ -4510,9 +4558,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
public List<AABB> toAabbs() {
|
||||
- List<AABB> list = Lists.newArrayList();
|
||||
- this.forAllBoxes((x1, y1, z1, x2, y2, z2) -> {
|
||||
- list.add(new AABB(x1, y1, z1, x2, y2, z2));
|
||||
- });
|
||||
- this.forAllBoxes((x1, y1, z1, x2, y2, z2) -> list.add(new AABB(x1, y1, z1, x2, y2, z2)));
|
||||
- return list;
|
||||
+ // Paper start - optimise collisions
|
||||
+ io.papermc.paper.util.collisions.CachedToAABBs cachedToAABBs = this.cachedToAABBs;
|
||||
@@ -4536,7 +4582,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
|
||||
public double min(Direction.Axis axis, double from, double to) {
|
||||
@@ -0,0 +0,0 @@ public abstract class VoxelShape {
|
||||
}) - 1;
|
||||
return Mth.binarySearch(0, this.shape.getSize(axis) + 1, i -> coord < this.get(axis, i)) - 1;
|
||||
}
|
||||
|
||||
+ // Paper start - optimise collisions
|
||||
@@ -4568,11 +4614,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
return null;
|
||||
- } else {
|
||||
- Vec3 vec3 = end.subtract(start);
|
||||
- if (vec3.lengthSqr() < 1.0E-7D) {
|
||||
- if (vec3.lengthSqr() < 1.0E-7) {
|
||||
- return null;
|
||||
- } else {
|
||||
- Vec3 vec32 = start.add(vec3.scale(0.001D));
|
||||
- return this.shape.isFullWide(this.findIndex(Direction.Axis.X, vec32.x - (double)pos.getX()), this.findIndex(Direction.Axis.Y, vec32.y - (double)pos.getY()), this.findIndex(Direction.Axis.Z, vec32.z - (double)pos.getZ())) ? new BlockHitResult(vec32, Direction.getNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true) : AABB.clip(this.toAabbs(), start, end, pos);
|
||||
- Vec3 vec32 = start.add(vec3.scale(0.001));
|
||||
- return this.shape
|
||||
- .isFullWide(
|
||||
- this.findIndex(Direction.Axis.X, vec32.x - pos.getX()),
|
||||
- this.findIndex(Direction.Axis.Y, vec32.y - pos.getY()),
|
||||
- this.findIndex(Direction.Axis.Z, vec32.z - pos.getZ())
|
||||
- )
|
||||
- ? new BlockHitResult(vec32, Direction.getNearest(vec3.x, vec3.y, vec3.z).getOpposite(), pos, true)
|
||||
- : AABB.clip(this.toAabbs(), start, end, pos);
|
||||
+ }
|
||||
+
|
||||
+ final Vec3 directionOpposite = end.subtract(start);
|
||||
@@ -4615,10 +4668,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
- if (vec3s[0] == null || target.distanceToSqr(d, e, f) < target.distanceToSqr(vec3s[0])) {
|
||||
- vec3s[0] = new Vec3(d, e, f);
|
||||
- }
|
||||
+ }
|
||||
|
||||
- });
|
||||
- return Optional.of(vec3s[0]);
|
||||
}
|
||||
+
|
||||
+ Vec3 ret = null;
|
||||
+ double retDistance = Double.MAX_VALUE;
|
||||
+
|
||||
@@ -4634,7 +4687,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ ret = new Vec3(x, y, z);
|
||||
+ retDistance = dist;
|
||||
+ }
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ return Optional.ofNullable(ret);
|
||||
+ // Paper end - optimise collisions
|
||||
|
||||
Reference in New Issue
Block a user