Optimise Level#isOutsideBuildHeight

We can cache the min/max build height to avoid the indirection
required to compute them.
This commit is contained in:
Spottedleaf
2024-09-19 11:37:44 -07:00
parent 07dce0ffe6
commit 2acd5cc213
11 changed files with 109 additions and 65 deletions

View File

@@ -1,13 +1,11 @@
package ca.spottedleaf.moonrise.mixin.collisions;
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection;
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
import ca.spottedleaf.moonrise.patches.collisions.CollisionUtil;
import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState;
import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape;
import ca.spottedleaf.moonrise.patches.collisions.util.NoneMatchStream;
import ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel;
import ca.spottedleaf.moonrise.patches.getblock.GetBlockLevel;
import it.unimi.dsi.fastutil.floats.FloatArraySet;
import it.unimi.dsi.fastutil.floats.FloatArrays;
import net.minecraft.core.BlockPos;
@@ -15,13 +13,11 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.status.ChunkStatus;
@@ -226,7 +222,7 @@ abstract class EntityMixin {
final int maxChunkY = maxBlockY >> 4;
final int maxChunkZ = maxBlockZ >> 4;
final int minSection = ((CollisionLevel)world).moonrise$getMinSection();
final int minSection = ((GetBlockLevel)world).moonrise$getMinSection();
final ChunkSource chunkSource = world.getChunkSource();
final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
@@ -338,7 +334,7 @@ abstract class EntityMixin {
return new NoneMatchStream<>(true);
}
final int minSection = ((CollisionLevel)world).moonrise$getMinSection();
final int minSection = ((GetBlockLevel)world).moonrise$getMinSection();
final ChunkSource chunkSource = world.getChunkSource();
final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
@@ -424,7 +420,7 @@ abstract class EntityMixin {
return;
}
final int minSection = ((CollisionLevel)world).moonrise$getMinSection();
final int minSection = ((GetBlockLevel)world).moonrise$getMinSection();
final ChunkSource chunkSource = world.getChunkSource();
final BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();

View File

@@ -2,7 +2,7 @@ package ca.spottedleaf.moonrise.mixin.collisions;
import ca.spottedleaf.moonrise.common.PlatformHooks;
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
import ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk;
import ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk;
import ca.spottedleaf.moonrise.patches.collisions.CollisionUtil;
import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState;
import ca.spottedleaf.moonrise.patches.collisions.ExplosionBlockCache;

View File

@@ -5,7 +5,7 @@ import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection;
import ca.spottedleaf.moonrise.patches.collisions.CollisionUtil;
import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState;
import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape;
import ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel;
import ca.spottedleaf.moonrise.patches.getblock.GetBlockLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
@@ -43,7 +43,7 @@ import java.util.Optional;
// Higher priority to apply after Lithium mixin.world.inline_height.WorldMixin
@Mixin(value = Level.class, priority = 1100)
abstract class LevelMixin implements CollisionLevel, LevelAccessor, AutoCloseable {
abstract class LevelMixin implements LevelAccessor, AutoCloseable {
@Shadow
public abstract LevelChunk getChunk(int x, int z);
@@ -51,38 +51,6 @@ abstract class LevelMixin implements CollisionLevel, LevelAccessor, AutoCloseabl
@Shadow
public abstract WorldBorder getWorldBorder();
@Unique
private int minSection;
@Unique
private int maxSection;
@Override
public final int moonrise$getMinSection() {
return this.minSection;
}
@Override
public final int moonrise$getMaxSection() {
return this.maxSection;
}
/**
* @reason Init min/max section
* @author Spottedleaf
*/
@Inject(
method = "<init>",
at = @At(
value = "RETURN"
)
)
private void init(final CallbackInfo ci) {
this.minSection = WorldUtil.getMinSection(this);
this.maxSection = WorldUtil.getMaxSection(this);
}
/**
* Route to faster lookup.
* See {@link EntityGetterMixin#isUnobstructed(Entity, VoxelShape)} for expected behavior
@@ -176,7 +144,7 @@ abstract class LevelMixin implements CollisionLevel, LevelAccessor, AutoCloseabl
int lastChunkY = Integer.MIN_VALUE;
int lastChunkZ = Integer.MIN_VALUE;
final int minSection = ((CollisionLevel)level).moonrise$getMinSection();
final int minSection = ((GetBlockLevel)level).moonrise$getMinSection();
for (;;) {
currPos.set(currX, currY, currZ);
@@ -371,13 +339,13 @@ abstract class LevelMixin implements CollisionLevel, LevelAccessor, AutoCloseabl
*/
@Override
public Optional<BlockPos> findSupportingBlock(final Entity entity, final AABB aabb) {
final int minSection = this.moonrise$getMinSection();
final int minSection = ((GetBlockLevel)(Level)(Object)this).moonrise$getMinSection();
final int minBlockX = Mth.floor(aabb.minX - CollisionUtil.COLLISION_EPSILON) - 1;
final int maxBlockX = Mth.floor(aabb.maxX + CollisionUtil.COLLISION_EPSILON) + 1;
final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - CollisionUtil.COLLISION_EPSILON) - 1);
final int maxBlockY = Math.min((this.moonrise$getMaxSection() << 4) + 16, Mth.floor(aabb.maxY + CollisionUtil.COLLISION_EPSILON) + 1);
final int maxBlockY = Math.min((((GetBlockLevel)(Level)(Object)this).moonrise$getMaxSection() << 4) + 16, Mth.floor(aabb.maxY + CollisionUtil.COLLISION_EPSILON) + 1);
final int minBlockZ = Mth.floor(aabb.minZ - CollisionUtil.COLLISION_EPSILON) - 1;
final int maxBlockZ = Mth.floor(aabb.maxZ + CollisionUtil.COLLISION_EPSILON) + 1;

View File

@@ -1,4 +1,4 @@
package ca.spottedleaf.moonrise.mixin.chunk_getblock;
package ca.spottedleaf.moonrise.mixin.getblock;
import ca.spottedleaf.moonrise.common.util.WorldUtil;
import net.minecraft.core.Holder;

View File

@@ -1,7 +1,7 @@
package ca.spottedleaf.moonrise.mixin.chunk_getblock;
package ca.spottedleaf.moonrise.mixin.getblock;
import ca.spottedleaf.moonrise.common.util.WorldUtil;
import ca.spottedleaf.moonrise.patches.chunk_getblock.GetBlockChunk;
import ca.spottedleaf.moonrise.patches.getblock.GetBlockChunk;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.world.level.ChunkPos;

View File

@@ -0,0 +1,75 @@
package ca.spottedleaf.moonrise.mixin.getblock;
import ca.spottedleaf.moonrise.common.util.WorldUtil;
import ca.spottedleaf.moonrise.patches.getblock.GetBlockLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Level.class)
abstract class LevelMixin implements GetBlockLevel, LevelAccessor, AutoCloseable {
@Unique
private int minSection;
@Unique
private int maxSection;
@Unique
private int minBuildHeight;
@Unique
private int maxBuildHeight;
@Override
public final int moonrise$getMinSection() {
return this.minSection;
}
@Override
public final int moonrise$getMaxSection() {
return this.maxSection;
}
@Override
public final int moonrise$getMinBuildHeight() {
return this.minBuildHeight;
}
@Override
public final int moonrise$getMaxBuildHeight() {
return this.maxBuildHeight;
}
/**
* @reason Init min/max section
* @author Spottedleaf
*/
@Inject(
method = "<init>",
at = @At(
value = "RETURN"
)
)
private void init(final CallbackInfo ci) {
this.minSection = WorldUtil.getMinSection(this);
this.maxSection = WorldUtil.getMaxSection(this);
this.minBuildHeight = this.getMinBuildHeight();
this.maxBuildHeight = this.getMaxBuildHeight();
}
@Override
public boolean isOutsideBuildHeight(final int y) {
return y < this.minBuildHeight || y >= this.maxBuildHeight;
}
@Override
public boolean isOutsideBuildHeight(final BlockPos blockPos) {
return this.isOutsideBuildHeight(blockPos.getY());
}
}

View File

@@ -6,7 +6,7 @@ import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity;
import ca.spottedleaf.moonrise.patches.collisions.shape.CachedShapeData;
import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionDiscreteVoxelShape;
import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape;
import ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel;
import ca.spottedleaf.moonrise.patches.getblock.GetBlockLevel;
import ca.spottedleaf.moonrise.patches.block_counting.BlockCountingChunkSection;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import it.unimi.dsi.fastutil.doubles.DoubleList;
@@ -1934,13 +1934,13 @@ public final class CollisionUtil {
}
}
final int minSection = ((CollisionLevel)world).moonrise$getMinSection();
final int minSection = ((GetBlockLevel)world).moonrise$getMinSection();
final int minBlockX = Mth.floor(aabb.minX - COLLISION_EPSILON) - 1;
final int maxBlockX = Mth.floor(aabb.maxX + COLLISION_EPSILON) + 1;
final int minBlockY = Math.max((minSection << 4) - 1, Mth.floor(aabb.minY - COLLISION_EPSILON) - 1);
final int maxBlockY = Math.min((((CollisionLevel)world).moonrise$getMaxSection() << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1);
final int maxBlockY = Math.min((((GetBlockLevel)world).moonrise$getMaxSection() << 4) + 16, Mth.floor(aabb.maxY + COLLISION_EPSILON) + 1);
final int minBlockZ = Mth.floor(aabb.minZ - COLLISION_EPSILON) - 1;
final int maxBlockZ = Mth.floor(aabb.maxZ + COLLISION_EPSILON) + 1;

View File

@@ -1,9 +0,0 @@
package ca.spottedleaf.moonrise.patches.collisions.world;
public interface CollisionLevel {
public int moonrise$getMinSection();
public int moonrise$getMaxSection();
}

View File

@@ -1,4 +1,4 @@
package ca.spottedleaf.moonrise.patches.chunk_getblock;
package ca.spottedleaf.moonrise.patches.getblock;
import net.minecraft.world.level.block.state.BlockState;

View File

@@ -0,0 +1,13 @@
package ca.spottedleaf.moonrise.patches.getblock;
public interface GetBlockLevel {
public int moonrise$getMinSection();
public int moonrise$getMaxSection();
public int moonrise$getMinBuildHeight();
public int moonrise$getMaxBuildHeight();
}

View File

@@ -16,8 +16,9 @@
"blockstate_propertyaccess.IntegerPropertyMixin",
"blockstate_propertyaccess.PropertyMixin",
"blockstate_propertyaccess.StateHolderMixin",
"chunk_getblock.ChunkAccessMixin",
"chunk_getblock.LevelChunkMixin",
"getblock.ChunkAccessMixin",
"getblock.LevelChunkMixin",
"getblock.LevelMixin",
"chunk_system.ChunkBufferMixin",
"chunk_system.ChunkGeneratorMixin",
"chunk_system.ChunkHolderMixin",
@@ -138,5 +139,5 @@
},
"overwrites": {
"conformVisibility": true
}
}
}