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 ce0f8567f8b3d52b806c2c0ef600852ee192c05b..8733e11bdfdb355928a332c20ed94bb57c57045f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1216,6 +1216,95 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S } // 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) { + // NOTE: if there are any blocks in the future that rely on fall distance make sure this is correct. + // The only block I am aware of is powdered snow that has a special case for falling blocks. + if (this.fallDistance != 0.0F && d0 >= 1.0D && !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.setOnGroundWithKnownMovement(this.verticalCollisionBelow, vec3d1); + BlockPos blockposition = this.getOnPosLegacy(); + 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"); @@ -1593,6 +1682,95 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S 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 java.util.ArrayList<>(8); + final List potentialCollisionsVoxel = new java.util.ArrayList<>(2); + final AABB currBoundingBox = getBoundingBox(); + + if (scan) { + return scanAndCollide(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); + } else { + final AABB bb = currBoundingBox.expandTowards(movement.x, movement.y, movement.z); + collectCollisions(bb, potentialCollisionsVoxel, potentialCollisionsBB); + return io.papermc.paper.util.CollisionUtil.performCollisions(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); + } + } + + private Vec3 scanAndCollide(Vec3 movement, AABB currBoundingBox, List voxelList, 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 = scanY(currBoundingBox, y, voxelList, bbList); + + if (y != 0.0) { + currBoundingBox = io.papermc.paper.util.CollisionUtil.offsetY(currBoundingBox, y); + } + } + + if (xSmaller && z != 0.0) { + z = scanZ(currBoundingBox, z, voxelList, bbList); + + if (z != 0.0) { + currBoundingBox = io.papermc.paper.util.CollisionUtil.offsetZ(currBoundingBox, z); + } + } + + if (x != 0.0) { + x = scanX(currBoundingBox, x, voxelList, bbList); + + if (x != 0.0) { + currBoundingBox = io.papermc.paper.util.CollisionUtil.offsetX(currBoundingBox, x); + } + } + + if (!xSmaller && z != 0.0) { + z = scanZ(currBoundingBox, z, voxelList, bbList); + } + + return new Vec3(x, y, z); + } + + private void collectCollisions(AABB collisionBox, List voxelList, List bbList) { + // Copied from the collide method below + io.papermc.paper.util.CollisionUtil.getCollisions( + level, this, collisionBox, voxelList, bbList, + io.papermc.paper.util.CollisionUtil.COLLISION_FLAG_CHECK_BORDER | this.getExtraCollisionFlags(), // Sakura + null, null + ); + } + + private double scanX(AABB currBoundingBox, double x, List voxelList, List bbList) { + AABB scanBox = currBoundingBox.expandTowards(x, 0.0, 0.0); + collectCollisions(scanBox, voxelList, bbList); + x = io.papermc.paper.util.CollisionUtil.performAABBCollisionsX(currBoundingBox, x, bbList); + return io.papermc.paper.util.CollisionUtil.performVoxelCollisionsX(currBoundingBox, x, voxelList); + } + + private double scanY(AABB currBoundingBox, double y, List voxelList, List bbList) { + AABB scanBox = currBoundingBox.expandTowards(0.0, y, 0.0); + collectCollisions(scanBox, voxelList, bbList); + y = io.papermc.paper.util.CollisionUtil.performAABBCollisionsY(currBoundingBox, y, bbList); + return io.papermc.paper.util.CollisionUtil.performVoxelCollisionsY(currBoundingBox, y, voxelList); + } + + private double scanZ(AABB currBoundingBox, double z, List voxelList, List bbList) { + AABB scanBox = currBoundingBox.expandTowards(0.0, 0.0, z); + collectCollisions(scanBox, voxelList, bbList); + z = io.papermc.paper.util.CollisionUtil.performAABBCollisionsZ(currBoundingBox, z, bbList); + return io.papermc.paper.util.CollisionUtil.performVoxelCollisionsZ(currBoundingBox, z, voxelList); + } + // Sakura end + private Vec3 collide(Vec3 movement) { // Paper start - optimise collisions final boolean xZero = movement.x == 0.0; 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 3a0d82cd7a0d7ec20138effd6d84eee60ffab788..b7f9c8a6de4c07f230f99b6bfa1332166e696b49 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -201,7 +201,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 // 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 1b8d43cf54999c9a005459bc59d7b5a50bb9c1ee..ebfd24f9fb90071288f0c872c0e3fbd58bb3f2b9 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -118,7 +118,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { 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 // Paper start - Configurable TNT entity height nerf if (this.level().paperConfig().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) { this.discard();