optimize chunk packer with extended block storage
This commit is contained in:
@@ -28,7 +28,9 @@ import net.minecraft.block.state.IBlockState;
|
|||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.chunk.BlockStateContainer;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -40,17 +42,50 @@ public final class ChunkPacker implements Helper {
|
|||||||
|
|
||||||
private ChunkPacker() {}
|
private ChunkPacker() {}
|
||||||
|
|
||||||
|
private static BitSet originalPacker(Chunk chunk) {
|
||||||
|
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||||
|
for (int y = 0; y < 256; y++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
|
IBlockState state = chunk.getBlockState(x, y, z);
|
||||||
|
boolean[] bits = getPathingBlockType(state).getBits();
|
||||||
|
bitSet.set(index, bits[0]);
|
||||||
|
bitSet.set(index + 1, bits[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bitSet;
|
||||||
|
}
|
||||||
|
|
||||||
public static CachedChunk pack(Chunk chunk) {
|
public static CachedChunk pack(Chunk chunk) {
|
||||||
long start = System.nanoTime() / 1000000L;
|
long start = System.nanoTime() / 1000000L;
|
||||||
|
|
||||||
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
Map<String, List<BlockPos>> specialBlocks = new HashMap<>();
|
||||||
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
BitSet bitSet = new BitSet(CachedChunk.SIZE);
|
||||||
try {
|
try {
|
||||||
for (int y = 0; y < 256; y++) {
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int y0 = 0; y0 < 16; y0++) {
|
||||||
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
|
if (extendedblockstorage == null) {
|
||||||
|
// any 16x16x16 area that's all air will have null storage
|
||||||
|
// for example, in an ocean biome, with air from y=64 to y=256
|
||||||
|
// the first 4 extended blocks storages will be full
|
||||||
|
// and the remaining 12 will be null
|
||||||
|
|
||||||
|
// since the index into the bitset is calculated from the x y and z
|
||||||
|
// and doesn't function as an append, we can entirely skip the scanning
|
||||||
|
// since a bitset is initialized to all zero, and air is saved as zeros
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||||
|
int yReal = y0 << 4;
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int y1 = 0; y1 < 16; y1++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
int y = y1 | yReal;
|
||||||
int index = CachedChunk.getPositionIndex(x, y, z);
|
int index = CachedChunk.getPositionIndex(x, y, z);
|
||||||
IBlockState state = chunk.getBlockState(x, y, z);
|
IBlockState state = bsc.get(x, y1, z);
|
||||||
boolean[] bits = getPathingBlockType(state).getBits();
|
boolean[] bits = getPathingBlockType(state).getBits();
|
||||||
bitSet.set(index, bits[0]);
|
bitSet.set(index, bits[0]);
|
||||||
bitSet.set(index + 1, bits[1]);
|
bitSet.set(index + 1, bits[1]);
|
||||||
@@ -62,6 +97,10 @@ public final class ChunkPacker implements Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/*if (!bitSet.equals(originalPacker(chunk))) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}*/
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@@ -64,18 +64,21 @@ public enum WorldScanner implements Helper {
|
|||||||
}
|
}
|
||||||
allUnloaded = false;
|
allUnloaded = false;
|
||||||
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
|
||||||
|
chunkX = chunkX << 4;
|
||||||
|
chunkZ = chunkZ << 4;
|
||||||
for (int y0 = 0; y0 < 16; y0++) {
|
for (int y0 = 0; y0 < 16; y0++) {
|
||||||
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
|
||||||
if (extendedblockstorage == null) {
|
if (extendedblockstorage == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
int yReal = y0 << 4;
|
||||||
BlockStateContainer bsc = extendedblockstorage.getData();
|
BlockStateContainer bsc = extendedblockstorage.getData();
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
IBlockState state = bsc.get(x, y, z);
|
IBlockState state = bsc.get(x, y, z);
|
||||||
if (asBlocks.contains(state.getBlock())) {
|
if (asBlocks.contains(state.getBlock())) {
|
||||||
res.add(new BlockPos(chunkX * 16 + x, y0 * 16 + y, chunkZ * 16 + z));
|
res.add(new BlockPos(chunkX | x, yReal | y, chunkZ | z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user