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 c34e4077ba1c8768d3ed8f32a14df46a32009ab8..d7216d8e4c2a60d94b6c8ca2580c8aa9a7b58c67 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -1137,6 +1137,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.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"); @@ -1489,6 +1575,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, + false, this.level.paperConfig().chunks.preventMovingIntoUnloadedChunks, + 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 2965d963ca7eaf7bfd010094c08aa8b80af79a13..33a247ac617c17e7c0cf1614ca485398c60ea579 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -200,7 +200,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 f3330d5219edfac9fd23b10e3f97e999fc3b5b0e..ab4bcf2383e060a348eb172d1b36310cbbe17f72 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -85,7 +85,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().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) { this.discard();