From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: IPECTER Date: Wed, 10 May 2023 13:32:42 +0900 Subject: [PATCH] Implement FerriteCore Original: malte0811/FerriteCore Copyright (C) 2023 malte0811 diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java index 942ce713afe27ec75d849877a88721ef6334fafa..595771af13659fcb365fd3f088762dc01964842f 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -789,6 +789,12 @@ public abstract class BlockBehaviour implements FeatureElement { protected BlockBehaviour.BlockStateBase.Cache cache; private FluidState fluidState; private boolean isRandomlyTicking; + // Plazma start - FerriteCore + public static final java.util.Map CACHE_COLLIDE = new java.util.HashMap<>(); + public static final java.util.Map> CACHE_PROJECT = new java.util.HashMap<>(); + public static final java.util.Map CACHE_FACE_STURDY = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap<>(it.unimi.dsi.fastutil.booleans.BooleanArrays.HASH_STRATEGY); + private static final ThreadLocal LAST_CACHE = new ThreadLocal<>(); + // Plazma end protected BlockStateBase(Block block, ImmutableMap, Comparable> propertyMap, MapCodec codec) { super(block, propertyMap, codec); @@ -871,6 +877,7 @@ public abstract class BlockBehaviour implements FeatureElement { // Paper end public void initCache() { + LAST_CACHE.set(asState().cache); // Plazma - FerriteCore this.fluidState = ((Block) this.owner).getFluidState(this.asState()); this.isRandomlyTicking = ((Block) this.owner).isRandomlyTicking(this.asState()); if (!this.getBlock().hasDynamicShape()) { @@ -909,7 +916,61 @@ public abstract class BlockBehaviour implements FeatureElement { } } // Paper end + // Plazma start - FerriteCore + if (asState().cache != null) { + Cache newCache = asState().cache; + final Cache oldCache = LAST_CACHE.get(); + VoxelShape dedupedCollisionShape; + if (oldCache != null && oldCache.collisionShape.equals(newCache.collisionShape)) { + dedupedCollisionShape = oldCache.collisionShape; + } else { + dedupedCollisionShape = CACHE_COLLIDE.computeIfAbsent(newCache.collisionShape, Function.identity()); + } + if (dedupedCollisionShape instanceof net.minecraft.world.phys.shapes.ArrayVoxelShape keepArray && newCache.collisionShape instanceof net.minecraft.world.phys.shapes.ArrayVoxelShape replaceArray) { + replaceInternals(keepArray, replaceArray); + } + newCache.collisionShape = dedupedCollisionShape; + final VoxelShape newRenderShape = getRenderShape(newCache.occlusionShapes); + if (newRenderShape == null) return; + org.apache.commons.lang3.tuple.Pair dedupedRenderShapes = null; + if (oldCache != null) { + final VoxelShape oldRenderShape = getRenderShape(oldCache.occlusionShapes); + if (newRenderShape.equals(oldRenderShape)) dedupedRenderShapes = org.apache.commons.lang3.tuple.Pair.of(oldRenderShape, oldCache.occlusionShapes); + } + if (dedupedRenderShapes == null) { + org.apache.commons.lang3.tuple.Pair newPair = org.apache.commons.lang3.tuple.Pair.of(newRenderShape, newCache.occlusionShapes); + dedupedRenderShapes = CACHE_PROJECT.putIfAbsent(newRenderShape, newPair); + if (dedupedRenderShapes == null) dedupedRenderShapes = newPair; + } + if (dedupedRenderShapes.getLeft() instanceof net.minecraft.world.phys.shapes.ArrayVoxelShape keepArray && newRenderShape instanceof net.minecraft.world.phys.shapes.ArrayVoxelShape replaceArray) { + replaceInternals(keepArray, replaceArray); + } + newCache.occlusionShapes = dedupedRenderShapes.getRight(); + boolean equalCheck = oldCache != null && Arrays.equals(oldCache.faceSturdy, newCache.faceSturdy); + newCache.faceSturdy = equalCheck ? oldCache.faceSturdy : CACHE_FACE_STURDY.computeIfAbsent(newCache.faceSturdy, Function.identity()); + LAST_CACHE.set(null); + } + // Plazma end + } + + // Plazma start - FerriteCore + private void replaceInternals(net.minecraft.world.phys.shapes.ArrayVoxelShape toKeep, net.minecraft.world.phys.shapes.ArrayVoxelShape toReplace) { + if (toKeep == toReplace) return; + toReplace.xs = toKeep.xs; + toReplace.ys = toKeep.ys; + toReplace.zs = toKeep.zs; + toReplace.faces = toKeep.faces; + toReplace.shape = toKeep.shape; + } + + @Nullable + private static VoxelShape getRenderShape(@Nullable VoxelShape[] projected) { + if (projected != null) { + for (VoxelShape side : projected) if (side instanceof net.minecraft.world.phys.shapes.SliceShape slice) return slice.getDelegate(); + } + return null; } + // Plazma end public Block getBlock() { return (Block) this.owner; @@ -1305,10 +1366,10 @@ public abstract class BlockBehaviour implements FeatureElement { final boolean propagatesSkylightDown; final int lightBlock; @Nullable - final VoxelShape[] occlusionShapes; - protected final VoxelShape collisionShape; + public VoxelShape[] occlusionShapes; // Plazma - FerriteCore - final -> public + public VoxelShape collisionShape; // Plazma - FerriteCore - protected final -> public protected final boolean largeCollisionShape; - private final boolean[] faceSturdy; + public boolean[] faceSturdy; // Plazma - FerriteCore - private final -> public protected final boolean isCollisionShapeFullBlock; Cache(BlockState state) { diff --git a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java index ca5f01be5d5ccfcc56780ff93cca3824409ffc0d..767311b27219d830ef049df94314f0871ac9afff 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/ArrayVoxelShape.java @@ -10,9 +10,9 @@ import net.minecraft.core.Direction; import it.unimi.dsi.fastutil.doubles.AbstractDoubleList; // Paper end public class ArrayVoxelShape extends VoxelShape { - private final DoubleList xs; - private final DoubleList ys; - private final DoubleList zs; + public DoubleList xs; // Plazma - FerriteCore - private final -> public + public DoubleList ys; // Plazma - FerriteCore - private final -> public + public DoubleList zs; // Plazma - FerriteCore - private final -> public protected ArrayVoxelShape(DiscreteVoxelShape shape, double[] xPoints, double[] yPoints, double[] zPoints) { this(shape, (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(xPoints, shape.getXSize() + 1)), (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(yPoints, shape.getYSize() + 1)), (DoubleList)DoubleArrayList.wrap(Arrays.copyOf(zPoints, shape.getZSize() + 1))); diff --git a/src/main/java/net/minecraft/world/phys/shapes/SliceShape.java b/src/main/java/net/minecraft/world/phys/shapes/SliceShape.java index cf469f9daa81da8bc330c9cac7e813db87f9f9af..bcd094d6746d8102b04ce6547db6d4bc497463e8 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/SliceShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/SliceShape.java @@ -4,7 +4,7 @@ import it.unimi.dsi.fastutil.doubles.DoubleList; import net.minecraft.core.Direction; public class SliceShape extends VoxelShape { - private final VoxelShape delegate; + private final VoxelShape delegate; public VoxelShape getDelegate() { return this.delegate; } // Plazma - FerriteCore private final Direction.Axis axis; private static final DoubleList SLICE_COORDS = new CubePointRange(1); diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java index 2182afd1b95acf14c55bddfeec17dae0a63e1f00..5fc28a6a09b251ce7adbb93e30045869ea43718a 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java +++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java @@ -16,9 +16,9 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; public abstract class VoxelShape { - public final DiscreteVoxelShape shape; // Paper - public + public DiscreteVoxelShape shape; // Paper - public // Plazma - FerriteCore - public final -> public @Nullable - private VoxelShape[] faces; + public VoxelShape[] faces; // Plazma - FerriteCore - private -> public // Paper start public boolean intersects(AABB shape) {