diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/GeneralHeightmapTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/GeneralHeightmapTest.kt index dbea7aeba..b7987c825 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/GeneralHeightmapTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/GeneralHeightmapTest.kt @@ -43,5 +43,4 @@ class GeneralHeightmapTest { chunk[InChunkPosition(2, 255, 3)] = GlassTest0.state assertEquals(chunk.light.heightmap[2, 3], Int.MIN_VALUE) } - } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/place/BlockLightPlaceIT.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/place/BlockLightPlaceIT.kt index a1f6d1f10..e2d964d45 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/place/BlockLightPlaceIT.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/world/chunk/light/place/BlockLightPlaceIT.kt @@ -204,9 +204,8 @@ class BlockLightPlaceIT { chunk.assertLight(9, 256, 8, 0xFC) } - @Test(enabled = false) // TODO: update heightmap of neighbours on change fun bottomHeightmap() { - val world = SessionTestUtil.createSession(4).world + val world = SessionTestUtil.createSession(4, light = true).world world.fill(BlockPosition(-25, 0, -25), BlockPosition(40, 1, 40), IT.BLOCK_1) world.assertLight(8, -1, 8, 0x00) @@ -218,9 +217,8 @@ class BlockLightPlaceIT { world.assertLight(+8, -1, -4, 0x00) } - @Test(enabled = false) // TODO: update heightmap of neighbours on change fun bottomPropagation() { - val world = SessionTestUtil.createSession(4).world + val world = SessionTestUtil.createSession(4, light = true).world world.fill(BlockPosition(-25, 0, -25), BlockPosition(40, 1, 40), IT.BLOCK_1) world[BlockPosition(8, 0, 8)] = TorchTest0.state @@ -228,7 +226,7 @@ class BlockLightPlaceIT { world.assertLight(9, -1, 8, 0x0C) world.assertLight(+20, -1, +8, 0x01) - world.assertLight(+8, -1, +8, 0x01) + world.assertLight(+8, -1, +20, 0x01) world.assertLight(-4, -1, +8, 0x01) world.assertLight(+8, -1, -4, 0x01) } diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/SectionLight.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/SectionLight.kt index 2e5f23c19..ea4ac4328 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/SectionLight.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/SectionLight.kt @@ -153,7 +153,7 @@ class SectionLight( } val height = section.chunk.light.heightmap[position.xz] - if (position.y + section.height * SECTION_HEIGHT_Y >= height) { // TODO: > or >= + if (section.height * SECTION_HEIGHT_Y + position.y >= height) { level = level.with(sky = 0) // level is set with heightmap, no need to trace anything } @@ -180,7 +180,7 @@ class SectionLight( event = true } - fun calculate() { + private fun calculateBlocks() { if (section.blocks.isEmpty) return val min = section.blocks.minPosition val max = section.blocks.maxPosition @@ -197,11 +197,15 @@ class SectionLight( } } } - // TODO: Start skylight tracing from heightmap start max per xz + } + + fun calculate() { + calculateBlocks() + // TODO: Start skylight tracing from (top of the world (max neighbour heightmap) to heightmap start) per xz } protected fun getNeighbour(direction: Directions): SectionLight? { - return section.chunk.neighbours[direction]?.sections?.get(section.height)?.light + return section.chunk.neighbours[direction]?.get(section.height)?.light } private fun propagateVertical() { diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/BottomSectionLight.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/BottomSectionLight.kt index 219e66346..78dc9894d 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/BottomSectionLight.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/BottomSectionLight.kt @@ -39,14 +39,14 @@ class BottomSectionLight( val height = chunk.light.heightmap[position.xz] - if (position.y + chunk.minSection * SECTION_HEIGHT_Y >= height) { // TODO: > or >= + if ((chunk.minSection - 1) * SECTION_HEIGHT_Y + SECTION_MAX_Y >= height) { level = level.with(sky = 0) // level is set with heightmap, no need to trace anything } light[position.xz] = level.raw - if (level.block <= 1 && level.sky <= 1) return // can not increase further + if (level.block <= 1 && level.sky <= 1) return // can not decrease any further - val next = current.decrease() + val next = level.decrease() chunk.getOrPut(chunk.minSection)?.light?.trace(position.with(y = SECTION_MAX_Y), next, Directions.UP) traceVertical(position, next) @@ -59,7 +59,7 @@ class BottomSectionLight( override fun propagate() { super.propagateVertical() - val section = chunk.sections.first()?.light ?: return + val section = chunk[chunk.minSection]?.light ?: return for (xz in 0 until SECTION_WIDTH_X * SECTION_WIDTH_Z) { val position = InSectionPosition(xz).with(y = 0) section.traceFrom(position, Directions.DOWN) diff --git a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/TopSectionLight.kt b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/TopSectionLight.kt index c4f93cdd1..e8394f375 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/TopSectionLight.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/chunk/light/section/border/TopSectionLight.kt @@ -36,9 +36,9 @@ class TopSectionLight( if (current.block >= level.block) return light[position.xz] = level.raw - if (current.block <= 1) return // can not increase further + if (level.block <= 1) return // can not decrease any further - val next = LightLevel(block = current.block - 1, sky = 0) // remove sky light, its always max + val next = LightLevel(block = level.block - 1, sky = 0) // remove sky light, its always max chunk.getOrPut(chunk.maxSection)?.light?.trace(position.with(y = SECTION_MAX_Y), next, Directions.DOWN) traceVertical(position, next) @@ -48,11 +48,10 @@ class TopSectionLight( System.arraycopy(array.array, InSectionPosition(0, 0, 0).index, this.light, 0, SECTION_WIDTH_X * SECTION_WIDTH_Z) } - override fun propagate() { super.propagateVertical() - val section = chunk.sections.last()?.light ?: return + val section = chunk[chunk.maxSection]?.light ?: return for (xz in 0 until SECTION_WIDTH_X * SECTION_WIDTH_Z) { val position = InSectionPosition(xz).with(y = SECTION_MAX_Y) section.traceFrom(position, Directions.UP) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/light/RenderLight.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/light/RenderLight.kt index 5a9f2acac..05ab69c8c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/light/RenderLight.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/light/RenderLight.kt @@ -1,6 +1,6 @@ /* * Minosoft - * Copyright (C) 2020-2024 Moritz Zwerger + * Copyright (C) 2020-2025 Moritz Zwerger * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * @@ -40,7 +40,7 @@ class RenderLight(val context: RenderContext) { ) ) { DefaultThreadPool += { - session.world.recalculateLight() + session.world.recalculateLight(heightmap = true) session.util.sendDebugMessage("Light recalculated and chunk cache cleared!") } }