/* * Decompiled with CFR 0.152. * * Could not load the following classes: * it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue */ package net.minecraft.client.renderer.chunk; import it.unimi.dsi.fastutil.ints.IntArrayFIFOQueue; import java.util.BitSet; import java.util.EnumSet; import java.util.Set; import net.minecraft.client.renderer.chunk.VisibilitySet; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.util.Util; public class VisGraph { private static final int SIZE_IN_BITS = 4; private static final int LEN = 16; private static final int MASK = 15; private static final int SIZE = 4096; private static final int X_SHIFT = 0; private static final int Z_SHIFT = 4; private static final int Y_SHIFT = 8; private static final int DX = (int)Math.pow(16.0, 0.0); private static final int DZ = (int)Math.pow(16.0, 1.0); private static final int DY = (int)Math.pow(16.0, 2.0); private static final int INVALID_INDEX = -1; private static final Direction[] DIRECTIONS = Direction.values(); private final BitSet bitSet = new BitSet(4096); private static final int[] INDEX_OF_EDGES = Util.make(new int[1352], map -> { boolean min = false; int max = 15; int index = 0; for (int x = 0; x < 16; ++x) { for (int y = 0; y < 16; ++y) { for (int z = 0; z < 16; ++z) { if (x != 0 && x != 15 && y != 0 && y != 15 && z != 0 && z != 15) continue; map[index++] = VisGraph.getIndex(x, y, z); } } } }); private int empty = 4096; public void setOpaque(BlockPos pos) { this.bitSet.set(VisGraph.getIndex(pos), true); --this.empty; } private static int getIndex(BlockPos pos) { return VisGraph.getIndex(pos.getX() & 0xF, pos.getY() & 0xF, pos.getZ() & 0xF); } private static int getIndex(int x, int y, int z) { return x << 0 | y << 8 | z << 4; } public VisibilitySet resolve() { VisibilitySet visibilitySet = new VisibilitySet(); if (4096 - this.empty < 256) { visibilitySet.setAll(true); } else if (this.empty == 0) { visibilitySet.setAll(false); } else { for (int i : INDEX_OF_EDGES) { if (this.bitSet.get(i)) continue; visibilitySet.add(this.floodFill(i)); } } return visibilitySet; } private Set floodFill(int startIndex) { EnumSet edges = EnumSet.noneOf(Direction.class); IntArrayFIFOQueue queue = new IntArrayFIFOQueue(); queue.enqueue(startIndex); this.bitSet.set(startIndex, true); while (!queue.isEmpty()) { int index = queue.dequeueInt(); this.addEdges(index, edges); for (Direction direction : DIRECTIONS) { int neighborIndex = this.getNeighborIndexAtFace(index, direction); if (neighborIndex < 0 || this.bitSet.get(neighborIndex)) continue; this.bitSet.set(neighborIndex, true); queue.enqueue(neighborIndex); } } return edges; } private void addEdges(int index, Set edges) { int x = index >> 0 & 0xF; if (x == 0) { edges.add(Direction.WEST); } else if (x == 15) { edges.add(Direction.EAST); } int y = index >> 8 & 0xF; if (y == 0) { edges.add(Direction.DOWN); } else if (y == 15) { edges.add(Direction.UP); } int z = index >> 4 & 0xF; if (z == 0) { edges.add(Direction.NORTH); } else if (z == 15) { edges.add(Direction.SOUTH); } } private int getNeighborIndexAtFace(int index, Direction direction) { switch (direction) { case DOWN: { if ((index >> 8 & 0xF) == 0) { return -1; } return index - DY; } case UP: { if ((index >> 8 & 0xF) == 15) { return -1; } return index + DY; } case NORTH: { if ((index >> 4 & 0xF) == 0) { return -1; } return index - DZ; } case SOUTH: { if ((index >> 4 & 0xF) == 15) { return -1; } return index + DZ; } case WEST: { if ((index >> 0 & 0xF) == 0) { return -1; } return index - DX; } case EAST: { if ((index >> 0 & 0xF) == 15) { return -1; } return index + DX; } } return -1; } }