(LevelChunk chunk)
| 48 | private ChunkPacker() {} |
| 49 | |
| 50 | public static CachedChunk pack(LevelChunk chunk) { |
| 51 | //long start = System.nanoTime() / 1000000L; |
| 52 | |
| 53 | Map<String, List<BlockPos>> specialBlocks = new HashMap<>(); |
| 54 | final int height = chunk.getLevel().dimensionType().height(); |
| 55 | BitSet bitSet = new BitSet(CachedChunk.size(height)); |
| 56 | try { |
| 57 | LevelChunkSection[] chunkInternalStorageArray = chunk.getSections(); |
| 58 | for (int y0 = 0; y0 < height / 16; y0++) { |
| 59 | LevelChunkSection extendedblockstorage = chunkInternalStorageArray[y0]; |
| 60 | if (extendedblockstorage == null) { |
| 61 | // any 16x16x16 area that's all air will have null storage |
| 62 | // for example, in an ocean biome, with air from y=64 to y=256 |
| 63 | // the first 4 extended blocks storages will be full |
| 64 | // and the remaining 12 will be null |
| 65 | |
| 66 | // since the index into the bitset is calculated from the x y and z |
| 67 | // and doesn't function as an append, we can entirely skip the scanning |
| 68 | // since a bitset is initialized to all zero, and air is saved as zeros |
| 69 | continue; |
| 70 | } |
| 71 | PalettedContainer<BlockState> bsc = extendedblockstorage.getStates(); |
| 72 | int yReal = y0 << 4; |
| 73 | // the mapping of BlockStateContainer.getIndex from xyz to index is y << 8 | z << 4 | x; |
| 74 | // for better cache locality, iterate in that order |
| 75 | for (int y1 = 0; y1 < 16; y1++) { |
| 76 | int y = y1 | yReal; |
| 77 | for (int z = 0; z < 16; z++) { |
| 78 | for (int x = 0; x < 16; x++) { |
| 79 | int index = CachedChunk.getPositionIndex(x, y, z); |
| 80 | BlockState state = bsc.get(x, y1, z); |
| 81 | boolean[] bits = getPathingBlockType(state, chunk, x, y, z).getBits(); |
| 82 | bitSet.set(index, bits[0]); |
| 83 | bitSet.set(index + 1, bits[1]); |
| 84 | Block block = state.getBlock(); |
| 85 | if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) { |
| 86 | String name = BlockUtils.blockToString(block); |
| 87 | specialBlocks.computeIfAbsent(name, b -> new ArrayList<>()).add(new BlockPos(x, y+chunk.getMinY(), z)); |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | } catch (Exception e) { |
| 94 | e.printStackTrace(); |
| 95 | } |
| 96 | //long end = System.nanoTime() / 1000000L; |
| 97 | //System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z); |
| 98 | BlockState[] blocks = new BlockState[256]; |
| 99 | |
| 100 | // get top block in columns |
| 101 | // @formatter:off |
| 102 | for (int z = 0; z < 16; z++) { |
| 103 | https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html |
| 104 | for (int x = 0; x < 16; x++) { |
| 105 | for (int y = height - 1; y >= 0; y--) { |
| 106 | int index = CachedChunk.getPositionIndex(x, y, z); |
| 107 | if (bitSet.get(index) || bitSet.get(index + 1)) { |
no test coverage detected