From b164576156b16a5db10e70294016a446a7643a63 Mon Sep 17 00:00:00 2001 From: Moritz Zwerger Date: Thu, 31 Aug 2023 22:57:25 +0200 Subject: [PATCH] optimize occlusion culling flood filling Now all negative blocks are not checked initially anymore. This is really not needed, because they must all have been checked before. There is still room for optimizations, it does not need to trace back. --- .../world/container/block/SectionOcclusion.kt | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/data/world/container/block/SectionOcclusion.kt b/src/main/java/de/bixilon/minosoft/data/world/container/block/SectionOcclusion.kt index dd7259571..70648ad8b 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/container/block/SectionOcclusion.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/container/block/SectionOcclusion.kt @@ -46,16 +46,31 @@ class SectionOcclusion( update(calculateOcclusion(floodFill()), notify) } - private fun trace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) { + private inline fun ShortArray.updateRegion(x: Int, y: Int, z: Int, id: Short): Boolean { val index = y shl 8 or (z shl 4) or x - if (regions[index] > 0) { - return + if (this[index] > 0) { + return true } val state = provider[index] if (state.isFullyOpaque()) { - return + return true } - regions[index] = nextId + this[index] = id + return false + } + + private fun startTrace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) { + if (regions.updateRegion(x, y, z, nextId)) return + + // no need to trace negative coordinates initially + if (x < ProtocolDefinition.SECTION_MAX_X) trace(regions, x + 1, y, z, nextId) + if (y < ProtocolDefinition.SECTION_MAX_Y) trace(regions, x, y + 1, z, nextId) + if (z < ProtocolDefinition.SECTION_MAX_Z) trace(regions, x, y, z + 1, nextId) + } + + private fun trace(regions: ShortArray, x: Int, y: Int, z: Int, nextId: Short) { + if (regions.updateRegion(x, y, z, nextId)) return + if (x > 0) trace(regions, x - 1, y, z, nextId) if (x < ProtocolDefinition.SECTION_MAX_X) trace(regions, x + 1, y, z, nextId) if (y > 0) trace(regions, x, y - 1, z, nextId) @@ -73,7 +88,7 @@ class SectionOcclusion( for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) { for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) { for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) { - trace(regions, x, y, z, ++next) + startTrace(regions, x, y, z, ++next) } } }