9
0
mirror of https://github.com/Samsuik/Sakura.git synced 2025-12-21 15:59:26 +00:00
Files
SakuraMC/patches/server/0079-Optimise-check-inside-blocks-and-traverse-blocks.patch
2024-11-25 19:10:40 +00:00

153 lines
6.7 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Samsuik <kfian294ma4@gmail.com>
Date: Fri, 8 Nov 2024 19:35:49 +0000
Subject: [PATCH] Optimise check inside blocks and traverse blocks
diff --git a/src/main/java/me/samsuik/sakura/utils/BlockPosIterator.java b/src/main/java/me/samsuik/sakura/utils/BlockPosIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..e00c07c614e007c007076e3dbe8bd8ccf6c6572d
--- /dev/null
+++ b/src/main/java/me/samsuik/sakura/utils/BlockPosIterator.java
@@ -0,0 +1,60 @@
+package me.samsuik.sakura.utils;
+
+import com.google.common.collect.AbstractIterator;
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.BlockPos.MutableBlockPos;
+import net.minecraft.util.Mth;
+import net.minecraft.world.phys.AABB;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+@NullMarked
+public final class BlockPosIterator extends AbstractIterator<BlockPos> {
+ private final int startX;
+ private final int startY;
+ private final int startZ;
+ private final int endX;
+ private final int endY;
+ private final int endZ;
+ private @Nullable MutableBlockPos pos = null;
+
+ public static Iterable<BlockPos> iterable(AABB bb) {
+ return () -> new BlockPosIterator(bb);
+ }
+
+ public BlockPosIterator(AABB bb) {
+ this.startX = Mth.floor(bb.minX);
+ this.startY = Mth.floor(bb.minY);
+ this.startZ = Mth.floor(bb.minZ);
+ this.endX = Mth.floor(bb.maxX);
+ this.endY = Mth.floor(bb.maxY);
+ this.endZ = Mth.floor(bb.maxZ);
+ }
+
+ @Override
+ protected BlockPos computeNext() {
+ MutableBlockPos pos = this.pos;
+ if (pos == null) {
+ return this.pos = new MutableBlockPos(this.startX, this.startY, this.startZ);
+ } else {
+ int x = pos.getX();
+ int y = pos.getY();
+ int z = pos.getZ();
+
+ if (y < this.endY) {
+ y += 1;
+ } else if (x < this.endX) {
+ x += 1;
+ y = this.startY;
+ } else if (z < this.endZ) {
+ z += 1;
+ x = this.startX;
+ } else {
+ return this.endOfData();
+ }
+
+ pos.set(x, y, z);
+ return pos;
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 5067db32a3e024a27c1da8f76a0abade6f20096d..3e6733b3195019f0090ae67136bbcf8467b8333a 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2094,6 +2094,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
final Iterator iterator1 = positions.iterator();
// Sakura end - physics version api
+ // Sakura start - optimise check inside blocks
+ int lastChunkX = Integer.MIN_VALUE;
+ int lastChunkZ = Integer.MIN_VALUE;
+ net.minecraft.world.level.chunk.ChunkAccess chunk = null;
+ // Sakura end - optimise check inside blocks
while (iterator1.hasNext()) {
BlockPos blockposition = (BlockPos) iterator1.next();
@@ -2102,7 +2107,19 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return;
}
- BlockState iblockdata = this.level().getBlockState(blockposition);
+ // Sakura start - optimise check inside blocks
+ int chunkX = blockposition.getX() >> 4;
+ int chunkZ = blockposition.getZ() >> 4;
+ if (chunk == null || chunkX != lastChunkX || chunkZ != lastChunkZ) {
+ chunk = this.level.getChunkIfLoadedImmediately(chunkX, chunkZ);
+ if (chunk == null) {
+ continue;
+ }
+ lastChunkX = chunkX;
+ lastChunkZ = chunkZ;
+ }
+ BlockState iblockdata = chunk.getBlockState(blockposition);
+ // Sakura end - optimise check inside blocks
if (!iblockdata.isAir() && longset.add(blockposition.asLong())) {
try {
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
index 93738c7dea1ea3d19013a47380391274612a719b..bbf79df2636ea96a288cd614e5b90968e5754937 100644
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
@@ -215,11 +215,18 @@ public interface BlockGetter extends LevelHeightAccessor {
static Iterable<BlockPos> boxTraverseBlocks(Vec3 oldPos, Vec3 newPos, AABB boundingBox) {
Vec3 vec3d2 = newPos.subtract(oldPos);
- Iterable<BlockPos> iterable = BlockPos.betweenClosed(boundingBox);
-
+ // Sakura start - optimise check inside blocks
if (vec3d2.lengthSqr() < (double) Mth.square(0.99999F)) {
- return iterable;
+ return me.samsuik.sakura.utils.BlockPosIterator.iterable(boundingBox);
} else {
+ boolean xZero = vec3d2.x() == 0.0;
+ boolean yZero = vec3d2.y() == 0.0;
+ boolean zZero = vec3d2.z() == 0.0;
+ if (xZero && yZero || yZero && zZero || xZero && zZero) {
+ return traverseAreaFast(vec3d2, boundingBox);
+ }
+ Iterable<BlockPos> iterable = BlockPos.betweenClosed(boundingBox);
+ // Sakura end - optimise check inside blocks
Set<BlockPos> set = new ObjectLinkedOpenHashSet();
Vec3 vec3d3 = vec3d2.normalize().scale(1.0E-7D);
Vec3 vec3d4 = boundingBox.getMinPosition().add(vec3d3);
@@ -238,6 +245,16 @@ public interface BlockGetter extends LevelHeightAccessor {
}
}
+ // Sakura start - optimise check inside blocks
+ private static Iterable<BlockPos> traverseAreaFast(Vec3 vec, AABB boundingBox) {
+ double toTravel = Math.min(16.0 / vec.length(), 1.0);
+ Vec3 movement = vec.scale(toTravel);
+ AABB fromBB = boundingBox.move(-vec.x, -vec.y, -vec.z);
+ AABB searchArea = fromBB.expandTowards(movement);
+ return me.samsuik.sakura.utils.BlockPosIterator.iterable(searchArea);
+ }
+ // Sakura end - optimise check inside blocks
+
private static void addCollisionsAlongTravel(Set<BlockPos> result, Vec3 oldPos, Vec3 newPos, AABB boundingBox) {
Vec3 vec3d2 = newPos.subtract(oldPos);
int i = Mth.floor(oldPos.x);