mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
chunk storage: store blocks as flat array (improve memory usage A LOT)
This commit is contained in:
parent
a32c6c6074
commit
71a75b7b53
@ -93,7 +93,11 @@ object VersionTweaker {
|
||||
return
|
||||
}
|
||||
for ((sectionHeight, section) in sections) {
|
||||
for ((location, blockInfo) in section.blocks) {
|
||||
for ((index, blockInfo) in section.blocks.withIndex()) {
|
||||
if (blockInfo == null) {
|
||||
continue
|
||||
}
|
||||
val location = ChunkSection.getPosition(index)
|
||||
val newBlock = transformBlock(blockInfo.block, sections, location, sectionHeight)
|
||||
if (newBlock === blockInfo.block) {
|
||||
continue
|
||||
|
@ -56,7 +56,7 @@ class Chunk(
|
||||
}
|
||||
// replace all chunk sections
|
||||
for ((sectionHeight, chunkSection) in it) {
|
||||
getSectionOrCreate(sectionHeight).setData(chunkSection, merge)
|
||||
getSectionOrCreate(sectionHeight).setData(chunkSection)
|
||||
}
|
||||
}
|
||||
data.biomeAccessor?.let {
|
||||
@ -82,7 +82,7 @@ class Chunk(
|
||||
getSectionOrCreate(position.getSectionHeight()).let {
|
||||
val inChunkSectionLocation = position.getInChunkSectionLocation()
|
||||
if (block == null) {
|
||||
it.blocks.remove(inChunkSectionLocation)
|
||||
it.blocks[ChunkSection.getIndex(inChunkSectionLocation)] = null
|
||||
return
|
||||
}
|
||||
it.setBlockInfo(inChunkSectionLocation, BlockInfo(block))
|
||||
|
@ -13,24 +13,21 @@
|
||||
package de.bixilon.minosoft.data.world
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
/**
|
||||
* Collection of 16x16x16 blocks
|
||||
*/
|
||||
class ChunkSection constructor(
|
||||
val blocks: MutableMap<InChunkSectionPosition, BlockInfo> = mutableMapOf(),
|
||||
class ChunkSection(
|
||||
val blocks: Array<BlockInfo?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
|
||||
) {
|
||||
|
||||
fun getBlockInfo(position: InChunkSectionPosition): BlockInfo? {
|
||||
return blocks[position]
|
||||
return blocks[getIndex(position)]
|
||||
}
|
||||
|
||||
fun setBlockInfo(position: InChunkSectionPosition, blockInfo: BlockInfo?) {
|
||||
if (blockInfo == null) {
|
||||
blocks.remove(position)
|
||||
return
|
||||
}
|
||||
blocks[position] = blockInfo
|
||||
blocks[getIndex(position)] = blockInfo
|
||||
}
|
||||
|
||||
fun getBlockInfo(x: Int, y: Int, z: Int): BlockInfo? {
|
||||
@ -45,10 +42,23 @@ class ChunkSection constructor(
|
||||
setBlockInfo(position, BlockInfo(block))
|
||||
}
|
||||
|
||||
fun setData(chunkSection: ChunkSection, merge: Boolean = false) {
|
||||
if (!merge) {
|
||||
this.blocks.clear()
|
||||
fun setData(chunkSection: ChunkSection) {
|
||||
for ((index, blockInfo) in chunkSection.blocks.withIndex()) {
|
||||
blocks[index] = blockInfo
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getIndex(position: InChunkSectionPosition): Int {
|
||||
return getIndex(position.x, position.y, position.z)
|
||||
}
|
||||
|
||||
fun getIndex(x: Int, y: Int, z: Int): Int {
|
||||
return y shl 8 or (z shl 4) or x
|
||||
}
|
||||
|
||||
fun getPosition(index: Int): InChunkSectionPosition {
|
||||
return InChunkSectionPosition(index and 0x0F, (index shr 8) and 0x0F, (index shr 4) and 0x0F)
|
||||
}
|
||||
this.blocks.putAll(chunkSection.blocks)
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,11 @@ class WorldRenderer(
|
||||
|
||||
val mesh = ChunkMesh()
|
||||
|
||||
for ((position, blockInfo) in section.blocks) {
|
||||
val blockPosition = BlockPosition(chunkPosition, sectionHeight, position)
|
||||
for ((index, blockInfo) in section.blocks.withIndex()) {
|
||||
if (blockInfo == null) {
|
||||
continue
|
||||
}
|
||||
val blockPosition = BlockPosition(chunkPosition, sectionHeight, ChunkSection.getPosition(index))
|
||||
|
||||
val neighborBlocks: Array<BlockInfo?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
||||
for (direction in Directions.DIRECTIONS) {
|
||||
|
@ -19,7 +19,6 @@ import de.bixilon.minosoft.data.mappings.blocks.BlockState;
|
||||
import de.bixilon.minosoft.data.world.BlockInfo;
|
||||
import de.bixilon.minosoft.data.world.ChunkData;
|
||||
import de.bixilon.minosoft.data.world.ChunkSection;
|
||||
import de.bixilon.minosoft.data.world.InChunkSectionPosition;
|
||||
import de.bixilon.minosoft.data.world.biome.DummyBiomeAccessor;
|
||||
import de.bixilon.minosoft.data.world.biome.XZBiomeAccessor;
|
||||
import de.bixilon.minosoft.data.world.light.DummyLightAccessor;
|
||||
@ -62,7 +61,7 @@ public final class ChunkUtil {
|
||||
HashMap<Integer, ChunkSection> sectionMap = new HashMap<>();
|
||||
for (int sectionHeight = dimension.getLowestSection(); sectionHeight < dimension.getHighestSection(); sectionHeight++) { // max sections per chunks in chunk column
|
||||
if (BitByte.isBitSet(sectionBitMasks[0], sectionHeight)) {
|
||||
HashMap<InChunkSectionPosition, BlockInfo> blockMap = new HashMap<>();
|
||||
BlockInfo[] blocks = new BlockInfo[ProtocolDefinition.BLOCKS_PER_SECTION];
|
||||
|
||||
for (int nibbleY = 0; nibbleY < ProtocolDefinition.SECTION_HEIGHT_Y; nibbleY++) {
|
||||
for (int nibbleZ = 0; nibbleZ < ProtocolDefinition.SECTION_WIDTH_Z; nibbleZ++) {
|
||||
@ -90,12 +89,15 @@ public final class ChunkUtil {
|
||||
continue;
|
||||
}
|
||||
BlockState block = buffer.getConnection().getMapping().getBlockState(fullBlockId);
|
||||
blockMap.put(new InChunkSectionPosition(nibbleX, nibbleY, nibbleZ), new BlockInfo(block));
|
||||
if (block == null) {
|
||||
continue;
|
||||
}
|
||||
blocks[ChunkSection.Companion.getIndex(nibbleX, nibbleY, nibbleZ)] = new BlockInfo(block);
|
||||
arrayPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blockMap)); // ToDo
|
||||
sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blocks)); // ToDo
|
||||
}
|
||||
}
|
||||
return new ChunkData(sectionMap, new DummyBiomeAccessor(buffer.getConnection().getMapping().getBiomeRegistry().get(0)), DummyLightAccessor.INSTANCE);
|
||||
@ -126,7 +128,7 @@ public final class ChunkUtil {
|
||||
if (!BitByte.isBitSet(sectionBitMasks[0], sectionHeight)) {
|
||||
continue;
|
||||
}
|
||||
HashMap<InChunkSectionPosition, BlockInfo> blockMap = new HashMap<>();
|
||||
BlockInfo[] blocks = new BlockInfo[ProtocolDefinition.BLOCKS_PER_SECTION];
|
||||
|
||||
for (int nibbleY = 0; nibbleY < ProtocolDefinition.SECTION_HEIGHT_Y; nibbleY++) {
|
||||
for (int nibbleZ = 0; nibbleZ < ProtocolDefinition.SECTION_WIDTH_Z; nibbleZ++) {
|
||||
@ -137,12 +139,12 @@ public final class ChunkUtil {
|
||||
arrayPos++;
|
||||
continue;
|
||||
}
|
||||
blockMap.put(new InChunkSectionPosition(nibbleX, nibbleY, nibbleZ), new BlockInfo(block));
|
||||
blocks[ChunkSection.Companion.getIndex(nibbleX, nibbleY, nibbleZ)] = new BlockInfo(block);
|
||||
arrayPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blockMap));
|
||||
sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blocks));
|
||||
}
|
||||
return new ChunkData(sectionMap, new DummyBiomeAccessor(buffer.getConnection().getMapping().getBiomeRegistry().get(0)), DummyLightAccessor.INSTANCE); // ToDo
|
||||
}
|
||||
@ -162,7 +164,7 @@ public final class ChunkUtil {
|
||||
|
||||
long[] data = buffer.readLongArray();
|
||||
|
||||
HashMap<InChunkSectionPosition, BlockInfo> blockMap = new HashMap<>();
|
||||
BlockInfo[] blocks = new BlockInfo[ProtocolDefinition.BLOCKS_PER_SECTION];
|
||||
for (int nibbleY = 0; nibbleY < ProtocolDefinition.SECTION_HEIGHT_Y; nibbleY++) {
|
||||
for (int nibbleZ = 0; nibbleZ < ProtocolDefinition.SECTION_WIDTH_Z; nibbleZ++) {
|
||||
for (int nibbleX = 0; nibbleX < ProtocolDefinition.SECTION_WIDTH_X; nibbleX++) {
|
||||
@ -193,7 +195,7 @@ public final class ChunkUtil {
|
||||
if (block == null) {
|
||||
continue;
|
||||
}
|
||||
blockMap.put(new InChunkSectionPosition(nibbleX, nibbleY, nibbleZ), new BlockInfo(block));
|
||||
blocks[ChunkSection.Companion.getIndex(nibbleX, nibbleY, nibbleZ)] = new BlockInfo(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,7 +208,7 @@ public final class ChunkUtil {
|
||||
// ToDo
|
||||
}
|
||||
|
||||
sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blockMap));
|
||||
sectionMap.put(dimension.getLowestSection() + sectionHeight, new ChunkSection(blocks));
|
||||
}
|
||||
ChunkData chunkData = new ChunkData();
|
||||
chunkData.setBlocks(sectionMap);
|
||||
|
Loading…
x
Reference in New Issue
Block a user