mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
optimize sky light (down) tracing
This commit is contained in:
parent
61228a9c05
commit
a7b10aaa49
@ -87,6 +87,10 @@ class SkyLightPlaceIT {
|
||||
fun filteredBelowBlock5() {
|
||||
val world = createConnection(3, light = true).world
|
||||
world.fill(6, 10, 6, 10, 10, 10, SlimeTest0.state, false)
|
||||
world.chunks[0, 0]!!.light.reset()
|
||||
world.chunks[0, 0]!!.light.sky.calculate()
|
||||
world.assertLight(8, 11, 8, 0xF0)
|
||||
world.assertLight(8, 10, 8, 0xE0)
|
||||
world.assertLight(8, 9, 8, 0xD0)
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ class ChunkSkyLight(val light: ChunkLight) {
|
||||
val baseY = sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y
|
||||
|
||||
for (y in topY downTo bottomY) {
|
||||
section.light.traceSkyLightIncrease(x, y, z, NEIGHBOUR_TRACE_LEVEL, target, baseY + y, false)
|
||||
section.light.traceSkyLightIncrease(x, y, z, NEIGHBOUR_TRACE_LEVEL, target, baseY + y)
|
||||
}
|
||||
section.light.update = true
|
||||
}
|
||||
@ -80,7 +80,8 @@ class ChunkSkyLight(val light: ChunkLight) {
|
||||
return
|
||||
}
|
||||
val section = chunk[y.sectionHeight] ?: return
|
||||
section.light.traceSkyLightIncrease(x, y.inSectionHeight, z, ProtocolDefinition.MAX_LIGHT_LEVEL_I, null, y, true)
|
||||
|
||||
section.light.traceSkyLightDown(x, y.inSectionHeight, z, Directions.DOWN, y)
|
||||
}
|
||||
|
||||
private fun floodFill(neighbours: Array<Chunk>, x: Int, z: Int) {
|
||||
@ -170,7 +171,7 @@ class ChunkSkyLight(val light: ChunkLight) {
|
||||
}
|
||||
|
||||
|
||||
private companion object {
|
||||
companion object {
|
||||
const val NEIGHBOUR_TRACE_LEVEL = ProtocolDefinition.MAX_LIGHT_LEVEL_I - 1
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import de.bixilon.minosoft.data.registries.blocks.state.BlockState
|
||||
import de.bixilon.minosoft.data.world.chunk.ChunkSection
|
||||
import de.bixilon.minosoft.data.world.chunk.ChunkSection.Companion.getIndex
|
||||
import de.bixilon.minosoft.data.world.chunk.chunk.Chunk
|
||||
import de.bixilon.minosoft.data.world.chunk.light.ChunkSkyLight.Companion.NEIGHBOUR_TRACE_LEVEL
|
||||
import de.bixilon.minosoft.data.world.chunk.neighbours.ChunkNeighbours
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
@ -316,21 +317,17 @@ class SectionLight(
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun traceSkyLightIncrease(x: Int, y: Int, z: Int, nextLevel: Int, direction: Directions?, totalY: Int) {
|
||||
return traceSkyLightIncrease(x, y, z, nextLevel, direction, totalY, false)
|
||||
}
|
||||
|
||||
fun traceSkyLightIncrease(x: Int, y: Int, z: Int, nextLevel: Int, target: Directions?, totalY: Int, force: Boolean) {
|
||||
fun traceSkyLightIncrease(x: Int, y: Int, z: Int, nextLevel: Int, target: Directions?, totalY: Int) {
|
||||
val chunk = section.chunk
|
||||
val heightmapIndex = (z shl 4) or x
|
||||
if (!force && totalY >= chunk.light.heightmap[heightmapIndex]) {
|
||||
if (totalY >= chunk.light.heightmap[heightmapIndex]) {
|
||||
// this light level will be 15, don't care
|
||||
return
|
||||
}
|
||||
val chunkNeighbours = chunk.neighbours.get() ?: return
|
||||
val index = heightmapIndex or (y shl 8)
|
||||
val currentLight = this[index].toInt()
|
||||
if (!force && ((currentLight and SKY_LIGHT_MASK) shr 4) >= nextLevel) {
|
||||
if (((currentLight and SKY_LIGHT_MASK) shr 4) >= nextLevel) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -409,6 +406,37 @@ class SectionLight(
|
||||
}
|
||||
}
|
||||
|
||||
fun traceSkyLightDown(x: Int, y: Int, z: Int, target: Directions?, totalY: Int) { // TODO: remove code duplicates
|
||||
val chunk = section.chunk
|
||||
val index = (y shl 8) or (z shl 4) or x
|
||||
|
||||
val state = section.blocks[index]
|
||||
var lightProperties = state?.block?.getLightProperties(state)
|
||||
|
||||
if (lightProperties == null) {
|
||||
lightProperties = TransparentProperty
|
||||
} else if (!lightProperties.propagatesLight || (target != null && !lightProperties.propagatesLight(target.inverted))) {
|
||||
return
|
||||
}
|
||||
|
||||
val neighbours = this.section.neighbours ?: return
|
||||
|
||||
this.light[index] = ((this[index].toInt() and BLOCK_LIGHT_MASK) or (ProtocolDefinition.MAX_LIGHT_LEVEL_I shl 4)).toByte()
|
||||
|
||||
if (!update) {
|
||||
update = true
|
||||
}
|
||||
|
||||
|
||||
if (lightProperties.propagatesLight(Directions.DOWN)) {
|
||||
if (y > 0) {
|
||||
traceSkyLightIncrease(x, y - 1, z, NEIGHBOUR_TRACE_LEVEL, Directions.DOWN, totalY - 1)
|
||||
} else {
|
||||
(neighbours[Directions.O_DOWN] ?: chunk.getOrPut(section.sectionHeight - 1, false))?.light?.traceSkyLightIncrease(x, ProtocolDefinition.SECTION_MAX_Y, z, NEIGHBOUR_TRACE_LEVEL, Directions.DOWN, totalY - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline operator fun Array<ChunkSection?>.get(direction: Int, neighbour: Int, neighbours: Array<Chunk>): ChunkSection? {
|
||||
return this[direction] ?: neighbours[neighbour].getOrPut(section.sectionHeight, false)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user