Created
April 28, 2019 09:37
-
-
Save Runemoro/02bf2f7e273b415dd0bdb4aaec2a75c4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import it.unimi.dsi.fastutil.longs.Long2ByteLinkedOpenHashMap; | |
import net.fabricmc.api.EnvType; | |
import net.fabricmc.api.Environment; | |
import net.minecraft.block.Block; | |
import net.minecraft.block.BlockState; | |
import net.minecraft.util.BooleanBiFunction; | |
import net.minecraft.util.math.BlockPos; | |
import net.minecraft.util.math.Direction; | |
import net.minecraft.util.shape.VoxelShape; | |
import net.minecraft.util.shape.VoxelShapes; | |
import net.minecraft.world.BlockView; | |
import org.spongepowered.asm.mixin.Mixin; | |
import org.spongepowered.asm.mixin.Overwrite; | |
@Mixin(value = Block.class, priority = 500) | |
public class BlockMixin { | |
private static final ThreadLocal<Long2ByteLinkedOpenHashMap> FACE_CULL_MAP_ = ThreadLocal.withInitial(() -> { | |
Long2ByteLinkedOpenHashMap map = new Long2ByteLinkedOpenHashMap(1000) { | |
@Override | |
protected void rehash(int newN) {} | |
} | |
map.defaultReturnValue((byte) 127); | |
return map; | |
}); | |
/** | |
* Don't use NeighborGroups, calculating its hashCode is slow. Instead, calculate a long cache key based | |
* on the state, neighbor state and side. | |
*/ | |
@Overwrite | |
@Environment(EnvType.CLIENT) | |
public static boolean shouldDrawSide(BlockState state, BlockView world, BlockPos pos, Direction side) { | |
BlockPos neighbor = pos.offset(side); | |
BlockState neighborState = world.getBlockState(neighbor); | |
if (state.skipRenderingSide(neighborState, side)) { | |
return false; | |
} | |
if (!neighborState.isFullBoundsCubeForCulling()) { | |
return true; | |
} | |
Long2ByteLinkedOpenHashMap cullMap = FACE_CULL_MAP_.get(); | |
// hashCode is unique, see AbstractPropertyContainerMixin | |
long cacheKey = ((long) state.hashCode() << 32 + 3) + ((long) neighborState.hashCode() << 3) + side.ordinal(); | |
byte cached = cullMap.getAndMoveToFirst(cacheKey); | |
if (cached != 127) { | |
return cached != 0; | |
} | |
VoxelShape shape = state.getCullShape(world, pos, side); | |
VoxelShape neighborShape = neighborState.getCullShape(world, neighbor, side.getOpposite()); | |
boolean shouldDraw = VoxelShapes.matchesAnywhere(shape, neighborShape, BooleanBiFunction.ONLY_FIRST); | |
if (cullMap.size() == 1000) { | |
cullMap.removeLastByte(); | |
} | |
cullMap.putAndMoveToFirst(cacheKey, (byte) (shouldDraw ? 1 : 0)); | |
return shouldDraw; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment