From a896eb0c7cbcaa53f15116796f58c21d0acd4f7a Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 15 Nov 2021 09:24:57 +0100 Subject: [PATCH] calculate max position in SectionDataProvider --- .../minosoft/data/world/ChunkSection.kt | 2 +- .../container/RegistrySectionDataProvider.kt | 3 +- .../world/container/SectionDataProvider.kt | 68 +++++++++++++++++-- .../bixilon/minosoft/util/chunk/ChunkUtil.kt | 6 +- .../bixilon/minosoft/util/chunk/LightUtil.kt | 1 - 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt b/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt index 3f382c673..924af2577 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/ChunkSection.kt @@ -36,7 +36,7 @@ class ChunkSection( var light: IntArray, // packed (skyLight: 0xF0, blockLight: 0x0F) ) { - constructor(registries: Registries) : this(RegistrySectionDataProvider(registries.blockStateRegistry.unsafeCast()), RegistrySectionDataProvider(registries.biomeRegistry), SectionDataProvider(), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION)) + constructor(registries: Registries) : this(RegistrySectionDataProvider(registries.blockStateRegistry.unsafeCast(), checkSize = true), RegistrySectionDataProvider(registries.biomeRegistry, checkSize = false), SectionDataProvider(checkSize = true), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION)) fun tick(connection: PlayConnection, chunkPosition: Vec2i, sectionHeight: Int) { if (blockEntities.isEmpty) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt b/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt index 4241b8077..3f42fe6ed 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/container/RegistrySectionDataProvider.kt @@ -19,7 +19,8 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition class RegistrySectionDataProvider( val registry: AbstractRegistry, data: Array = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION), -) : SectionDataProvider(data) { + checkSize: Boolean = false, +) : SectionDataProvider(data, checkSize = checkSize) { @Suppress("UNCHECKED_CAST") fun setIdData(ids: Array) { diff --git a/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt b/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt index 8c2bd00cf..6fbfd23cb 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/container/SectionDataProvider.kt @@ -15,9 +15,11 @@ package de.bixilon.minosoft.data.world.container import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.SemaphoreLock +import glm_.vec3.Vec3i open class SectionDataProvider( data: Array = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION), + val checkSize: Boolean = false, ) : Iterable { protected var data = data private set @@ -26,9 +28,13 @@ open class SectionDataProvider( private set val isEmpty: Boolean get() = count == 0 + lateinit var minPosition: Vec3i + private set + lateinit var maxPosition: Vec3i + private set init { - recalculateCount() + recalculate() } @Suppress("UNCHECKED_CAST") @@ -49,14 +55,54 @@ open class SectionDataProvider( return data[y shl 8 or (z shl 4) or x] as T } - private fun recalculateCount() { + private fun recalculate() { var count = 0 - for (value in data) { - if (value == null) { + var value: Any? + + var minX = 16 + var minY = 16 + var minZ = 16 + + var maxX = 0 + var maxY = 0 + var maxZ = 0 + + var x: Int + var y: Int + var z: Int + for (index in 0 until ProtocolDefinition.BLOCKS_PER_SECTION) { + data[index] ?: continue + count++ + if (!checkSize) { continue } - count++ + x = index and 0x0F + z = (index shr 4) and 0x0F + y = index shr 8 + + if (x < minX) { + minX = x + } + if (y < minY) { + minY = y + } + if (z < minZ) { + minZ = z + } + + if (x < maxX) { + maxX = x + } + if (y > maxY) { + maxY = y + } + if (z > maxZ) { + maxZ = z + } + } + this.minPosition = Vec3i(minX, minY, minZ) + this.maxPosition = Vec3i(maxX, maxY, maxZ) this.count = count } @@ -81,6 +127,16 @@ open class SectionDataProvider( count++ } data[index] = value + + if (checkSize) { + val x = index and 0x0F + val z = (index shr 4) and 0x0F + val y = index shr 8 + + if ((minPosition.x == x && minPosition.y == y && minPosition.z == z) || (maxPosition.x == x && maxPosition.y == y && maxPosition.z == z)) { + recalculate() + } + } unlock() } @@ -107,7 +163,7 @@ open class SectionDataProvider( lock() check(data.size == ProtocolDefinition.BLOCKS_PER_SECTION) { "Size does not match!" } this.data = data as Array - recalculateCount() + recalculate() unlock() } diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt index a2ab15ead..3a22e14af 100644 --- a/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/chunk/ChunkUtil.kt @@ -93,7 +93,7 @@ object ChunkUtil { blocks[blockNumber] = buffer.connection.registries.blockStateRegistry[blockId] ?: continue } - sectionBlocks[sectionHeight] = RegistrySectionDataProvider(buffer.connection.registries.blockStateRegistry.unsafeCast(), blocks.unsafeCast()) + sectionBlocks[sectionHeight] = RegistrySectionDataProvider(buffer.connection.registries.blockStateRegistry.unsafeCast(), blocks.unsafeCast(), true) } chunkData.blocks = sectionBlocks return chunkData @@ -138,7 +138,7 @@ object ChunkUtil { val block = buffer.connection.registries.blockStateRegistry[blockId] ?: continue blocks[blockNumber] = block } - sectionBlocks[sectionHeight] = RegistrySectionDataProvider(buffer.connection.registries.blockStateRegistry.unsafeCast(), blocks.unsafeCast()) + sectionBlocks[sectionHeight] = RegistrySectionDataProvider(buffer.connection.registries.blockStateRegistry.unsafeCast(), blocks.unsafeCast(), true) } chunkData.blocks = sectionBlocks return chunkData @@ -198,7 +198,7 @@ object ChunkUtil { light[sectionHeight - dimension.lowestSection] = LightUtil.mergeLight(blockLight, skyLight) lightReceived++ } - sectionBlocks[sectionHeight - dimension.lowestSection] = RegistrySectionDataProvider(buffer.connection.registries.blockStateRegistry.unsafeCast(), blocks.unsafeCast()) + sectionBlocks[sectionHeight - dimension.lowestSection] = RegistrySectionDataProvider(buffer.connection.registries.blockStateRegistry.unsafeCast(), blocks.unsafeCast(), true) } chunkData.blocks = sectionBlocks diff --git a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt index 098e2d031..8932839ff 100644 --- a/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/chunk/LightUtil.kt @@ -24,7 +24,6 @@ import java.util.* object LightUtil { fun readLightPacket(buffer: PlayInByteBuffer, skyLightMask: BitSet, blockLightMask: BitSet, dimension: DimensionProperties): ChunkData { - // ToDo val skyLight = if (dimension.hasSkyLight || buffer.versionId > V_1_16) { // ToDo: find out version readLightArray(buffer, skyLightMask, dimension) } else {