calculate max position in SectionDataProvider

This commit is contained in:
Bixilon 2021-11-15 09:24:57 +01:00
parent 465e9c4bf0
commit a896eb0c7c
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 68 additions and 12 deletions

View File

@ -36,7 +36,7 @@ class ChunkSection(
var light: IntArray, // packed (skyLight: 0xF0, blockLight: 0x0F)
) {
constructor(registries: Registries) : this(RegistrySectionDataProvider<BlockState?>(registries.blockStateRegistry.unsafeCast()), RegistrySectionDataProvider(registries.biomeRegistry), SectionDataProvider(), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION))
constructor(registries: Registries) : this(RegistrySectionDataProvider<BlockState?>(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) {

View File

@ -19,7 +19,8 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
class RegistrySectionDataProvider<T>(
val registry: AbstractRegistry<T>,
data: Array<Any?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
) : SectionDataProvider<T>(data) {
checkSize: Boolean = false,
) : SectionDataProvider<T>(data, checkSize = checkSize) {
@Suppress("UNCHECKED_CAST")
fun setIdData(ids: Array<Int>) {

View File

@ -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<T>(
data: Array<Any?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
val checkSize: Boolean = false,
) : Iterable<T> {
protected var data = data
private set
@ -26,9 +28,13 @@ open class SectionDataProvider<T>(
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<T>(
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<T>(
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<T>(
lock()
check(data.size == ProtocolDefinition.BLOCKS_PER_SECTION) { "Size does not match!" }
this.data = data as Array<Any?>
recalculateCount()
recalculate()
unlock()
}

View File

@ -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

View File

@ -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 {