From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik <40902469+Samsuik@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:36:19 +0100 Subject: [PATCH] Optimise Fast Movement diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index ff25112e1a270f32faf8b0a885166dc57848b5cf..09c2513a49fde78e3376f3c62e743fb2b29c82e8 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1075,6 +1075,92 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { } // Paper end - detailed watchdog information + // Sakura start - stripped back movement method for basic entities + public void moveBasic(MoverType movementType, Vec3 movement) { + io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main"); + if (this.noPhysics) { + this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); + } else { + if (movementType == MoverType.PISTON) { // Paper + movement = this.limitPistonMovement(movement); + if (movement.equals(Vec3.ZERO)) { + return; + } + } + + this.level.getProfiler().push("move"); + if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) { + movement = movement.multiply(this.stuckSpeedMultiplier); + this.stuckSpeedMultiplier = Vec3.ZERO; + this.setDeltaMovement(Vec3.ZERO); + } + + // collideScan for optimised large movements + Vec3 vec3d1 = this.collideScan(movement); + double d0 = vec3d1.lengthSqr(); + + if (d0 > 1.0E-7D) { + if (this.fallDistance != 0.0F && d0 >= 1.0D && !this.isFallingBlock) { + BlockHitResult movingobjectpositionblock = this.level.clip(new ClipContext(this.position(), this.position().add(vec3d1), ClipContext.Block.FALLDAMAGE_RESETTING, ClipContext.Fluid.WATER, this)); + + if (movingobjectpositionblock.getType() != HitResult.Type.MISS) { + this.resetFallDistance(); + } + } + + this.setPos(this.getX() + vec3d1.x, this.getY() + vec3d1.y, this.getZ() + vec3d1.z); + } + + this.level.getProfiler().pop(); + this.level.getProfiler().push("rest"); + boolean flag = !Mth.equal(movement.x, vec3d1.x); + boolean flag1 = !Mth.equal(movement.z, vec3d1.z); + + this.horizontalCollision = flag || flag1; + this.verticalCollision = movement.y != vec3d1.y; + this.verticalCollisionBelow = this.verticalCollision && movement.y < 0.0D; + if (this.horizontalCollision) { + this.minorHorizontalCollision = this.isHorizontalCollisionMinor(vec3d1); + } else { + this.minorHorizontalCollision = false; + } + + this.onGround = this.verticalCollision && movement.y < 0.0D; + BlockPos blockposition = this.getOnPos(); + BlockState iblockdata = this.level.getBlockState(blockposition); + + this.checkFallDamage(vec3d1.y, this.onGround, iblockdata, blockposition); + if (this.isRemoved()) { + this.level.getProfiler().pop(); + } else { + if (this.horizontalCollision) { + Vec3 vec3d2 = this.getDeltaMovement(); + + this.setDeltaMovement(flag ? 0.0D : vec3d2.x, vec3d2.y, flag1 ? 0.0D : vec3d2.z); + } + + Block block = iblockdata.getBlock(); + + if (movement.y != vec3d1.y) { + block.updateEntityAfterFallOn(this.level, this); + } + + if (this.onGround) { + // used for slowing down entities on top of slime + block.stepOn(this.level, blockposition, iblockdata, this); + } + + this.tryCheckInsideBlocks(); + + float f = this.getBlockSpeedFactor(); + + this.multiplyDeltaMovement((double) f, 1.0D, (double) f); // Sakura - reduce movement allocations + this.level.getProfiler().pop(); + } + } + } + // Sakura end + public void move(MoverType movementType, Vec3 movement) { // Paper start - detailed watchdog information io.papermc.paper.util.TickThread.ensureTickThread("Cannot move an entity off-main"); @@ -1407,6 +1493,88 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { return offsetFactor; } + // Sakura start + private Vec3 collideScan(Vec3 movement) { + if (movement.x == 0.0 && movement.y == 0.0 && movement.z == 0.0) { + return movement; + } + + final boolean scan = movement.lengthSqr() >= 12.0; + final List potentialCollisionsBB = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(4); + final AABB currBoundingBox = getBoundingBox(); + + if (scan) { + return scanAndCollide(movement, currBoundingBox, potentialCollisionsBB); + } else { + final AABB bb = currBoundingBox.expandTowards(movement.x, movement.y, movement.z); + this.collectCollisions(bb, potentialCollisionsBB); + return io.papermc.paper.util.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsBB); + } + } + + private Vec3 scanAndCollide(Vec3 movement, AABB currBoundingBox, List bbList) { + double x = movement.x; + double y = movement.y; + double z = movement.z; + + final boolean xSmaller = Math.abs(x) < Math.abs(z); + + if (y != 0.0) { + y = this.scanY(currBoundingBox, y, bbList); + if (y != 0.0) { + currBoundingBox = io.papermc.paper.util.CollisionUtil.offsetY(currBoundingBox, y); + } + } + + if (xSmaller && z != 0.0) { + z = this.scanZ(currBoundingBox, z, bbList); + if (z != 0.0) { + currBoundingBox = io.papermc.paper.util.CollisionUtil.offsetZ(currBoundingBox, z); + } + } + + if (x != 0.0) { + x = this.scanX(currBoundingBox, x, bbList); + if (x != 0.0) { + currBoundingBox = io.papermc.paper.util.CollisionUtil.offsetX(currBoundingBox, x); + } + } + + if (!xSmaller && z != 0.0) { + z = this.scanZ(currBoundingBox, z, bbList); + } + + return new Vec3(x, y, z); + } + + private void collectCollisions(AABB collisionBox, List bbList) { + // Copied from the collide method below + io.papermc.paper.util.CollisionUtil.getCollisions( + this.level, this, collisionBox, bbList, + this.loadChunks, this.level.paperConfig.preventMovingIntoUnloadedChunks, // Sakura - load chunks on movement + false, this.loadChunks, false, null, null // Sakura - load chunks on movement + ); + } + + private double scanX(AABB currBoundingBox, double x, List bbList) { + AABB scanBox = currBoundingBox.expandTowards(x, 0.0, 0.0); + this.collectCollisions(scanBox, bbList); + return io.papermc.paper.util.CollisionUtil.performCollisionsX(currBoundingBox, x, bbList); + } + + private double scanY(AABB currBoundingBox, double y, List bbList) { + AABB scanBox = currBoundingBox.expandTowards(0.0, y, 0.0); + this.collectCollisions(scanBox, bbList); + return io.papermc.paper.util.CollisionUtil.performCollisionsY(currBoundingBox, y, bbList); + } + + private double scanZ(AABB currBoundingBox, double z, List bbList) { + AABB scanBox = currBoundingBox.expandTowards(0.0, 0.0, z); + this.collectCollisions(scanBox, bbList); + return io.papermc.paper.util.CollisionUtil.performCollisionsZ(currBoundingBox, z, bbList); + } + // Sakura end + private Vec3 collide(Vec3 movement) { // Paper start - optimise collisions // This is a copy of vanilla's except that it uses strictly AABB math diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java index 229477058eb28798edf684dffe3640aab87bc189..8f02b04cb3193c3ed164193868d216f7320962f5 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -198,7 +198,7 @@ public class FallingBlockEntity extends Entity { this.addDeltaMovement(0.0D, -0.04D, 0.0D); // Sakura - reduce movement allocations } - this.move(MoverType.SELF, this.getDeltaMovement()); + this.moveBasic(MoverType.SELF, this.getDeltaMovement()); // Sakura - optimise simple entity movement // Paper start - fix sand duping if (this.isRemoved()) { diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java index 88f83ef060b818e31bbb636a45048b2cdb1d4fec..0a130c840a20d357c7375f94d36e83a8ea8a59ee 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -88,7 +88,7 @@ public class PrimedTnt extends Entity { this.addDeltaMovement(0.0D, -0.04D, 0.0D); // Sakura - reduce movement allocations } - this.move(MoverType.SELF, this.getDeltaMovement()); + this.moveBasic(MoverType.SELF, this.getDeltaMovement()); // Sakura - optimise simple entity movement // Paper start - Configurable TNT entity height nerf if (this.level.paperConfig.entityTNTHeightNerf != 0 && this.getY() > this.level.paperConfig.entityTNTHeightNerf) { this.discard();