Skip to content

Commit

Permalink
Fix mangrove roots culling
Browse files Browse the repository at this point in the history
  • Loading branch information
1foxy2 committed Mar 10, 2025
1 parent bf0884a commit e9be604
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ca.fxco.moreculling.api.block;

/**
* implement this if your block should cull like leaves but doesn't extend leaves block
*/
public interface LeavesCulling {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ca.fxco.moreculling.mixin.blocks;

import ca.fxco.moreculling.MoreCulling;
import ca.fxco.moreculling.api.block.LeavesCulling;
import ca.fxco.moreculling.api.block.MoreBlockCulling;
import ca.fxco.moreculling.config.option.LeavesCullingMode;
import ca.fxco.moreculling.utils.CullingUtils;
Expand All @@ -22,7 +23,7 @@
import static ca.fxco.moreculling.config.option.LeavesCullingMode.VERTICAL;

@Mixin(value = LeavesBlock.class, priority = 1220)
public class LeavesBlock_typesMixin extends Block implements MoreBlockCulling {
public class LeavesBlock_typesMixin extends Block implements MoreBlockCulling, LeavesCulling {

@Shadow
@Final
Expand All @@ -36,7 +37,7 @@ public LeavesBlock_typesMixin(Properties settings) {
public boolean skipRendering(BlockState state, BlockState stateFrom, Direction direction) {
if (MoreCulling.CONFIG.leavesCullingMode == FAST || CullingUtils.areLeavesOpaque() ||
(MoreCulling.CONFIG.leavesCullingMode == VERTICAL && direction.getAxis() == Direction.Axis.Y)) {
return stateFrom.getBlock() instanceof LeavesBlock || super.skipRendering(state, stateFrom, direction);
return stateFrom.getBlock() instanceof LeavesCulling || super.skipRendering(state, stateFrom, direction);
}
return super.skipRendering(state, stateFrom, direction);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
package ca.fxco.moreculling.mixin.blocks;

import ca.fxco.moreculling.MoreCulling;
import ca.fxco.moreculling.api.block.LeavesCulling;
import ca.fxco.moreculling.api.block.MoreBlockCulling;
import ca.fxco.moreculling.config.option.LeavesCullingMode;
import ca.fxco.moreculling.utils.CullingUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.MangroveRootsBlock;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Optional;

@Mixin(value = MangroveRootsBlock.class, priority = 1220)
public class MangroveRootsBlock_typesMixin extends Block implements MoreBlockCulling {
public class MangroveRootsBlock_typesMixin extends Block implements MoreBlockCulling, LeavesCulling {

public MangroveRootsBlock_typesMixin(Properties settings) {
super(settings);
}

@Override
public boolean skipRendering(BlockState state, BlockState stateFrom, Direction direction) {
@Inject(
method = "skipRendering",
at = @At(value = "HEAD"),
cancellable = true
)
private void moreculling$skipRendering(BlockState thisState, BlockState sideState,
Direction face, CallbackInfoReturnable<Boolean> cir) {
if (!MoreCulling.CONFIG.includeMangroveRoots) {
return super.skipRendering(state, stateFrom, direction);
return;
}
if (MoreCulling.CONFIG.leavesCullingMode == LeavesCullingMode.FAST || CullingUtils.areLeavesOpaque()) {
return stateFrom.getBlock() instanceof LeavesBlock || super.skipRendering(state, stateFrom, direction);
cir.setReturnValue(sideState.getBlock() instanceof LeavesCulling ||
super.skipRendering(thisState, sideState, face));
}
return super.skipRendering(state, stateFrom, direction);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public abstract class SimpleBakedModel_cacheMixin implements BakedOpacity {
@Unique
private final DirectionBits moreculling$solidFaces = new DirectionBits();
@Unique
private boolean moreculling$allStatesCanOcclude = true;
@Unique
private @Nullable VoxelShape moreculling$cullVoxelShape;
@Unique
private @Nullable boolean moreculling$isItem = false;
Expand All @@ -45,6 +47,15 @@ public abstract class SimpleBakedModel_cacheMixin implements BakedOpacity {
@Override
public void moreculling$resetTranslucencyCache(BlockState state) {
moreculling$solidFaces.clear();

if (state.canOcclude()) {
if (moreculling$allStatesCanOcclude) {
moreculling$solidFaces.fill();
}
} else {
moreculling$allStatesCanOcclude = false;
}

for (Map.Entry<Direction, List<BakedQuad>> entry : culledFaces.entrySet()) {
Direction direction = entry.getKey();
List<BakedQuad> layeredQuads = new ArrayList<>(entry.getValue());
Expand Down
14 changes: 7 additions & 7 deletions common/src/main/java/ca/fxco/moreculling/utils/CullingUtils.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ca.fxco.moreculling.utils;

import ca.fxco.moreculling.MoreCulling;
import ca.fxco.moreculling.api.block.LeavesCulling;
import ca.fxco.moreculling.api.blockstate.MoreStateCulling;
import ca.fxco.moreculling.api.blockstate.StateCullingShapeCache;
import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap;
Expand All @@ -13,7 +14,6 @@
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
Expand Down Expand Up @@ -99,15 +99,15 @@ public static boolean areLeavesOpaque() {

public static Optional<Boolean> shouldDrawFaceCheck(BlockGetter view, BlockState sideState,
BlockPos thisPos, BlockPos sidePos, Direction side) {
if (sideState.getBlock() instanceof LeavesBlock ||
if (sideState.getBlock() instanceof LeavesCulling ||
(sideState.canOcclude() && ((StateCullingShapeCache) sideState)
.moreculling$getFaceCullingShape(side.getOpposite()) == Shapes.block())) {
boolean isSurrounded = true;
for (Direction dir : DirectionUtils.DIRECTIONS) {
if (dir != side) {
BlockPos pos = thisPos.relative(dir);
BlockState state = view.getBlockState(pos);
isSurrounded &= state.getBlock() instanceof LeavesBlock ||
isSurrounded &= state.getBlock() instanceof LeavesCulling ||
(state.canOcclude() && ((StateCullingShapeCache) state)
.moreculling$getFaceCullingShape(dir.getOpposite()) == Shapes.block());
}
Expand All @@ -120,13 +120,13 @@ public static Optional<Boolean> shouldDrawFaceCheck(BlockGetter view, BlockState
public static Optional<Boolean> shouldDrawFaceGap(BlockGetter view, BlockState sideState,
BlockPos sidePos, Direction side) {
Direction oppositeSide = side.getOpposite();
if (sideState.getBlock() instanceof LeavesBlock ||
if (sideState.getBlock() instanceof LeavesCulling ||
(sideState.canOcclude() && ((StateCullingShapeCache) sideState)
.moreculling$getFaceCullingShape(oppositeSide) == Shapes.block())) {
for (int i = 1; i < (5 - MoreCulling.CONFIG.leavesCullingAmount); i++) {
BlockPos pos = sidePos.relative(side, i);
BlockState state = view.getBlockState(pos);
if (state == null || !(state.getBlock() instanceof LeavesBlock ||
if (state == null || !(state.getBlock() instanceof LeavesCulling ||
(state.canOcclude() && ((StateCullingShapeCache) state)
.moreculling$getFaceCullingShape(oppositeSide) == Shapes.block()))) {
return Optional.of(false);
Expand All @@ -138,7 +138,7 @@ public static Optional<Boolean> shouldDrawFaceGap(BlockGetter view, BlockState s

public static Optional<Boolean> shouldDrawFaceDepth(BlockGetter view, BlockState sideState,
BlockPos sidePos, Direction side) {
if (sideState.getBlock() instanceof LeavesBlock ||
if (sideState.getBlock() instanceof LeavesCulling ||
(sideState.canOcclude() && ((StateCullingShapeCache) sideState)
.moreculling$getFaceCullingShape(side.getOpposite()) == Shapes.block())) {
for (int i = 1; i < MoreCulling.CONFIG.leavesCullingAmount + 1; i++) {
Expand All @@ -154,7 +154,7 @@ public static Optional<Boolean> shouldDrawFaceDepth(BlockGetter view, BlockState

public static Optional<Boolean> shouldDrawFaceRandom(BlockGetter view, BlockState sideState,
BlockPos sidePos, Direction side) {
if (sideState.getBlock() instanceof LeavesBlock ||
if (sideState.getBlock() instanceof LeavesCulling ||
(sideState.canOcclude() && ((StateCullingShapeCache) sideState)
.moreculling$getFaceCullingShape(side.getOpposite()) == Shapes.block())) {
if (RANDOM.nextIntBetweenInclusive(1, MoreCulling.CONFIG.leavesCullingAmount + 1) == 1) {
Expand Down

0 comments on commit e9be604

Please sign in to comment.