mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
290 lines
14 KiB
Diff
290 lines
14 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: hayanesuru <hayanesuru@outlook.jp>
|
|
Date: Sat, 9 Aug 2025 18:12:11 +0900
|
|
Subject: [PATCH] optimize checkInsideBlocks
|
|
|
|
|
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
|
index 4689764a580d7dca468cdfa2b0fef7e70c57687f..e4c2c0b4ea2b153266c2bb35574167364029bc7c 100644
|
|
--- a/net/minecraft/world/entity/Entity.java
|
|
+++ b/net/minecraft/world/entity/Entity.java
|
|
@@ -1723,72 +1723,57 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
private void checkInsideBlocks(Vec3 vec3, Vec3 vec31, InsideBlockEffectApplier.StepBasedCollector stepBasedCollector, LongSet set) {
|
|
final Level level = this.level();
|
|
AABB aabb = this.getBoundingBox().move(vec31.subtract(this.position())).deflate(1.0E-5F);
|
|
- final net.minecraft.world.level.chunk.ChunkAccess[] cachedChunk = { null };
|
|
- final long[] cachedChunkPos = { Long.MIN_VALUE };
|
|
|
|
- BlockGetter.forEachBlockIntersectedBetween(
|
|
+ BlockGetter.leaf$forEachBlockIntersectedBetween(
|
|
+ set,
|
|
vec3,
|
|
vec31,
|
|
aabb,
|
|
(pos, index) -> {
|
|
+ final int posX = pos.getX();
|
|
+ final int posY = pos.getY();
|
|
+ final int posZ = pos.getZ();
|
|
+ BlockState blockState = level.getBlockStateIfLoadedUnchecked(posX, posY, posZ);
|
|
+ if (blockState == null) {
|
|
+ blockState = level.getBlockState(pos);
|
|
+ }
|
|
+ if (blockState.isAir()) {
|
|
+ this.debugBlockIntersection(pos, false, false);
|
|
+ return true;
|
|
+ }
|
|
if (!this.isAlive()) {
|
|
return false;
|
|
- } else {
|
|
- final int chunkX = pos.getX() >> 4;
|
|
- final int chunkZ = pos.getZ() >> 4;
|
|
- final long currentChunkPos = ChunkPos.asLong(chunkX, chunkZ);
|
|
- BlockState blockState;
|
|
-
|
|
- if (cachedChunkPos[0] != currentChunkPos) {cachedChunk[0] = level.getChunkIfLoaded(chunkX, chunkZ);cachedChunkPos[0] = currentChunkPos;}
|
|
-
|
|
- if (cachedChunk[0] != null) {blockState = cachedChunk[0].getBlockState(pos);
|
|
- } else {
|
|
- blockState = level.getBlockStateIfLoaded(pos);
|
|
- if (blockState == null) {blockState = Blocks.AIR.defaultBlockState();}
|
|
+ }
|
|
+ VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(level, pos, this);
|
|
+ boolean flag = entityInsideCollisionShape == Shapes.block()
|
|
+ || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs());
|
|
+ if (flag) {
|
|
+ try {
|
|
+ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
+ blockState.entityInside(level, pos, this, stepBasedCollector);
|
|
+ this.onInsideBlock(blockState);
|
|
+ } catch (Throwable var14) {
|
|
+ CrashReport crashReport = CrashReport.forThrowable(var14, "Colliding entity with block");
|
|
+ CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with");
|
|
+ CrashReportCategory.populateBlockDetails(crashReportCategory, level, pos, blockState);
|
|
+ CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision");
|
|
+ this.fillCrashReportCategory(crashReportCategory1);
|
|
+ throw new ReportedException(crashReport);
|
|
}
|
|
+ }
|
|
|
|
- final long posLong = pos.asLong();
|
|
- if (blockState.isAir()) {
|
|
- this.debugBlockIntersection(pos, false, false);
|
|
- return true;
|
|
- } else if (!set.add(posLong)) {
|
|
- return true;
|
|
- } else {
|
|
- VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(level, pos, this);
|
|
- boolean flag = entityInsideCollisionShape == Shapes.block()
|
|
- || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs());
|
|
-
|
|
- if (flag) {
|
|
- try {
|
|
- stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
- blockState.entityInside(level, pos, this, stepBasedCollector);
|
|
- this.onInsideBlock(blockState);
|
|
- } catch (Throwable var14) {
|
|
- CrashReport crashReport = CrashReport.forThrowable(var14, "Colliding entity with block");
|
|
- CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with");
|
|
- CrashReportCategory.populateBlockDetails(crashReportCategory, level, pos, blockState);
|
|
- CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision");
|
|
- this.fillCrashReportCategory(crashReportCategory1);
|
|
- throw new ReportedException(crashReport);
|
|
- }
|
|
- }
|
|
-
|
|
- final FluidState fluidState = blockState.getFluidState();
|
|
- boolean flag1 = !fluidState.isEmpty() && this.collidedWithFluid(fluidState, pos, vec3, vec31);
|
|
-
|
|
- if (flag1) {
|
|
- stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
- fluidState.entityInside(level, pos, this, stepBasedCollector);
|
|
- }
|
|
-
|
|
- this.debugBlockIntersection(pos, flag, flag1);
|
|
- return true;
|
|
- }
|
|
+ boolean flag1 = (blockState.tagFlag & org.dreeam.leaf.util.BlockMasks.FLUID) != 0
|
|
+ && this.collidedWithFluid(blockState.getFluidState(), pos, vec3, vec31);
|
|
+ if (flag1) {
|
|
+ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on
|
|
+ blockState.getFluidState().entityInside(level, pos, this, stepBasedCollector);
|
|
}
|
|
+ this.debugBlockIntersection(pos, flag, flag1);
|
|
+ return true;
|
|
}
|
|
);
|
|
}
|
|
-// Leaf end - optimize checkInsideBlocks calls
|
|
+ // Leaf end - optimize checkInsideBlocks calls
|
|
|
|
private void debugBlockIntersection(BlockPos blockPos, boolean flag, boolean flag1) {
|
|
}
|
|
diff --git a/net/minecraft/world/entity/InsideBlockEffectApplier.java b/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
|
index 92b9c324cb6aab415abe2e77c5844b74c251a42f..eba3896b73c70f29732388373e89bf7ce3a07c92 100644
|
|
--- a/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
|
+++ b/net/minecraft/world/entity/InsideBlockEffectApplier.java
|
|
@@ -33,6 +33,7 @@ public interface InsideBlockEffectApplier {
|
|
// Leaf start - optimize checkInsideBlocks calls
|
|
private static final InsideBlockEffectType[] APPLY_ORDER = InsideBlockEffectType.values();
|
|
private static final int NO_STEP = -1;
|
|
+ private int flags = 0;
|
|
|
|
private final Consumer<Entity>[] effectsInStep = new Consumer[APPLY_ORDER.length];
|
|
private final List<Consumer<Entity>>[] beforeEffectsInStep = new List[APPLY_ORDER.length];
|
|
@@ -40,13 +41,13 @@ public interface InsideBlockEffectApplier {
|
|
|
|
private static final List<Consumer<Entity>> EMPTY_LIST = List.of();
|
|
|
|
- private final List<Consumer<Entity>> finalEffects = new ArrayList<>();
|
|
+ private final List<Consumer<Entity>> finalEffects = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>();
|
|
private int lastStep = -1;
|
|
|
|
public StepBasedCollector() {
|
|
for (int i = 0; i < APPLY_ORDER.length; i++) {
|
|
- beforeEffectsInStep[i] = new ArrayList<>(2);
|
|
- afterEffectsInStep[i] = new ArrayList<>(2);
|
|
+ beforeEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2);
|
|
+ afterEffectsInStep[i] = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(2);
|
|
}
|
|
}
|
|
|
|
@@ -100,6 +101,10 @@ public interface InsideBlockEffectApplier {
|
|
}
|
|
|
|
private void flushStep() {
|
|
+ final int flags = this.flags;
|
|
+ if (flags == 0) {
|
|
+ return;
|
|
+ }
|
|
final int len = APPLY_ORDER.length;
|
|
final List<Consumer<Entity>>[] beforeArr = this.beforeEffectsInStep;
|
|
final Consumer<Entity>[] effectArr = this.effectsInStep;
|
|
@@ -107,6 +112,9 @@ public interface InsideBlockEffectApplier {
|
|
final List<Consumer<Entity>> finalList = this.finalEffects;
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
+ if (((1 << i) & flags) == 0) {
|
|
+ continue;
|
|
+ }
|
|
// Process before effects
|
|
List<Consumer<Entity>> beforeList = beforeArr[i];
|
|
if (!beforeList.isEmpty()) {
|
|
@@ -128,21 +136,28 @@ public interface InsideBlockEffectApplier {
|
|
afterList.clear();
|
|
}
|
|
}
|
|
+ this.flags = 0;
|
|
}
|
|
|
|
@Override
|
|
public void apply(InsideBlockEffectType type) {
|
|
- effectsInStep[type.ordinal()] = recorded(type);
|
|
+ int i = type.ordinal();
|
|
+ effectsInStep[i] = recorded(type);
|
|
+ this.flags |= 1 << i;
|
|
}
|
|
|
|
@Override
|
|
public void runBefore(InsideBlockEffectType type, Consumer<Entity> effect) {
|
|
- beforeEffectsInStep[type.ordinal()].add(effect);
|
|
+ int i = type.ordinal();
|
|
+ beforeEffectsInStep[i].add(effect);
|
|
+ this.flags |= 1 << i;
|
|
}
|
|
|
|
@Override
|
|
public void runAfter(InsideBlockEffectType type, Consumer<Entity> effect) {
|
|
- afterEffectsInStep[type.ordinal()].add(effect);
|
|
+ int i = type.ordinal();
|
|
+ afterEffectsInStep[i].add(effect);
|
|
+ this.flags |= 1 << i;
|
|
}
|
|
|
|
// Paper start - track position inside effect was triggered on
|
|
diff --git a/net/minecraft/world/level/BlockGetter.java b/net/minecraft/world/level/BlockGetter.java
|
|
index eeddffbe6a47dc1a42c07f286bfec0cbde33fc17..b0da274c944fcef6aaae39b43f05a79110e4bb16 100644
|
|
--- a/net/minecraft/world/level/BlockGetter.java
|
|
+++ b/net/minecraft/world/level/BlockGetter.java
|
|
@@ -255,6 +255,81 @@ public interface BlockGetter extends LevelHeightAccessor {
|
|
}
|
|
}
|
|
|
|
+ // Leaf start
|
|
+ static boolean leaf$forEachBlockIntersectedBetween(it.unimi.dsi.fastutil.longs.LongSet set, Vec3 from, Vec3 to, AABB boundingBox, BlockGetter.BlockStepVisitor visitor) {
|
|
+ Vec3 vec3 = to.subtract(from);
|
|
+ BlockPos.MutableBlockPos cursor = new BlockPos.MutableBlockPos();
|
|
+ if (vec3.lengthSqr() < Mth.square(0.99999F)) {
|
|
+ int pos1x = Mth.floor(boundingBox.minX);
|
|
+ int pos1y = Mth.floor(boundingBox.minY);
|
|
+ int pos1z = Mth.floor(boundingBox.minZ);
|
|
+ int pos2x = Mth.floor(boundingBox.maxX);
|
|
+ int pos2y = Mth.floor(boundingBox.maxY);
|
|
+ int pos2z = Mth.floor(boundingBox.maxZ);
|
|
+ int x1 = Math.min(pos1x, pos2x);
|
|
+ int y1 = Math.min(pos1y, pos2y);
|
|
+ int z1 = Math.min(pos1z, pos2z);
|
|
+ int i = Math.max(pos1x, pos2x) - x1 + 1;
|
|
+ int i1 = Math.max(pos1y, pos2y) - y1 + 1;
|
|
+ int i2 = Math.max(pos1z, pos2z) - z1 + 1;
|
|
+ int i3 = i * i1 * i2;
|
|
+ int index = 0;
|
|
+ while (index != i3) {
|
|
+ int i4 = index % i;
|
|
+ int i5 = index / i;
|
|
+ int i6 = i5 % i1;
|
|
+ int i7 = i5 / i1;
|
|
+ index++;
|
|
+ int x0 = x1 + i4;
|
|
+ int y0 = y1 + i6;
|
|
+ int z0 = z1 + i7;
|
|
+ if (set.add(BlockPos.asLong(x0, y0, z0)) && !visitor.visit(cursor.set(x0, y0, z0), 0)) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ } else {
|
|
+ Vec3 minPosition = boundingBox.getMinPosition();
|
|
+ Vec3 vec31 = minPosition.subtract(vec3);
|
|
+ int i = addCollisionsAlongTravel(set, vec31, minPosition, boundingBox, visitor);
|
|
+ if (i < 0) {
|
|
+ return false;
|
|
+ } else {
|
|
+ int pos1x = Mth.floor(boundingBox.minX);
|
|
+ int pos1y = Mth.floor(boundingBox.minY);
|
|
+ int pos1z = Mth.floor(boundingBox.minZ);
|
|
+ int pos2x = Mth.floor(boundingBox.maxX);
|
|
+ int pos2y = Mth.floor(boundingBox.maxY);
|
|
+ int pos2z = Mth.floor(boundingBox.maxZ);
|
|
+ int x1 = Math.min(pos1x, pos2x);
|
|
+ int y1 = Math.min(pos1y, pos2y);
|
|
+ int z1 = Math.min(pos1z, pos2z);
|
|
+ int j = Math.max(pos1x, pos2x) - x1 + 1;
|
|
+ int i1 = Math.max(pos1y, pos2y) - y1 + 1;
|
|
+ int i2 = Math.max(pos1z, pos2z) - z1 + 1;
|
|
+ int i3 = j * i1 * i2;
|
|
+ int index = 0;
|
|
+ while (index != i3) {
|
|
+ int i4 = index % j;
|
|
+ int i5 = index / j;
|
|
+ int i6 = i5 % i1;
|
|
+ int i7 = i5 / i1;
|
|
+ index++;
|
|
+ int x0 = x1 + i4;
|
|
+ int y0 = y1 + i6;
|
|
+ int z0 = z1 + i7;
|
|
+ if (set.add(BlockPos.asLong(x0, y0, z0)) && !visitor.visit(cursor.set(x0, y0, z0), i + 1)) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Leaf end
|
|
+
|
|
private static int addCollisionsAlongTravel(LongSet output, Vec3 from, Vec3 to, AABB boundingBox, BlockGetter.BlockStepVisitor stepVisitor) {
|
|
Vec3 vec3 = to.subtract(from);
|
|
int floor = Mth.floor(from.x);
|