wip: light filtering blocks, integration block testing

This commit is contained in:
Bixilon 2022-10-18 14:00:54 +02:00
parent 826263c480
commit 93780140b8
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
14 changed files with 259 additions and 14 deletions

View File

@ -0,0 +1,56 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.minosoft.IT
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.types.Block
import org.testng.Assert
import org.testng.Assert.assertEquals
abstract class BlockTest<T : Block> {
var block: T = unsafeNull()
var state: BlockState = unsafeNull()
fun retrieveBlock(name: ResourceLocation) {
val block = IT.V_1_18_2.registries!!.blockRegistry[name]
Assert.assertNotNull(block)
block!!
assertEquals(block.resourceLocation, name)
this.block = block.unsafeCast()
this.state = block.defaultState
}
fun testLightProperties(
luminance: Int,
propagatesLight: Boolean,
skylightEnters: Boolean,
filtersSkylight: Boolean,
propagates: BooleanArray,
) {
assertEquals(state.luminance, luminance)
val light = state.lightProperties
assertEquals(light.propagatesLight, propagatesLight)
assertEquals(light.skylightEnters, skylightEnters)
assertEquals(light.filtersSkylight, filtersSkylight)
for (direction in Directions.VALUES) {
assertEquals(light.propagatesLight(direction), propagates[direction.ordinal], "$direction failed")
}
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.Block
import org.testng.annotations.Test
internal object CobwebTest : BlockTest<Block>() {
@Test
private fun getOakLeaves() {
super.retrieveBlock(MinecraftBlocks.COBWEB)
}
@Test
fun testLightProperties() {
super.testLightProperties(0, true, true, false, booleanArrayOf(true, true, true, true, true, true))
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.Block
import org.testng.annotations.Test
internal object GlassTest : BlockTest<Block>() {
@Test
private fun getOakLeaves() {
super.retrieveBlock(MinecraftBlocks.GLASS)
}
@Test
fun testLightProperties() {
super.testLightProperties(0, true, true, false, booleanArrayOf(true, true, true, true, true, true))
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.leaves.LeavesBlock
import org.testng.annotations.Test
internal object LeavesTest : BlockTest<LeavesBlock>() {
@Test
private fun getOakLeaves() {
super.retrieveBlock(MinecraftBlocks.OAK_LEAVES)
}
@Test
fun testLightProperties() {
super.testLightProperties(0, true, false, true, booleanArrayOf(true, true, true, true, true, true))
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.Block
import org.testng.annotations.Test
internal object StairsTest : BlockTest<Block>() {
@Test
private fun getOakLeaves() {
super.retrieveBlock(MinecraftBlocks.OAK_STAIRS)
}
@Test
fun testLightProperties() {
super.testLightProperties(0, true, false, false, booleanArrayOf(false, true, true, true, true, true)) // ToDo: one side needs to be false
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.Block
import org.testng.annotations.Test
internal object StoneTest : BlockTest<Block>() {
@Test
private fun getOakLeaves() {
super.retrieveBlock(MinecraftBlocks.STONE)
}
@Test
fun testLightProperties() {
super.testLightProperties(0, false, false, true, booleanArrayOf(false, false, false, false, false, false))
}
}

View File

@ -0,0 +1,30 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.registries.blocks
import de.bixilon.minosoft.data.registries.blocks.types.Block
import org.testng.annotations.Test
internal object TorchTest : BlockTest<Block>() {
@Test
private fun getOakLeaves() {
super.retrieveBlock(MinecraftBlocks.TORCH)
}
@Test
fun testLightProperties() {
super.testLightProperties(14, true, true, false, booleanArrayOf(true, true, true, true, true, true))
}
}

View File

@ -130,11 +130,11 @@ data class BlockState(
} else if (outlineShape == VoxelShape.FULL) {
SolidProperty
} else {
DirectedProperty.of(outlineShape, false)
DirectedProperty.of(outlineShape, false, false)
}
if (lightProperties is SolidProperty && !opaque) {
lightProperties = CustomLightProperties(propagatesLight = true, propagatesSkylight = false)
lightProperties = CustomLightProperties(propagatesLight = true, skylightEnters = false, false)
}

View File

@ -15,5 +15,6 @@ package de.bixilon.minosoft.data.registries.blocks.light
class CustomLightProperties(
override val propagatesLight: Boolean,
override val propagatesSkylight: Boolean,
override val skylightEnters: Boolean,
override val filtersSkylight: Boolean,
) : SimpleLightProperties

View File

@ -21,10 +21,10 @@ import de.bixilon.minosoft.data.registries.shapes.side.VoxelSideSet
class DirectedProperty(
private val directions: BooleanArray,
propagatesSkylight: Boolean,
override val skylightEnters: Boolean,
override val filtersSkylight: Boolean,
) : LightProperties {
override val propagatesLight: Boolean = true
override val propagatesSkylight: Boolean = propagatesSkylight && propagatesLight(Directions.UP) && propagatesLight(Directions.DOWN)
override fun propagatesLight(direction: Directions): Boolean {
return directions[direction.ordinal]
@ -50,7 +50,7 @@ class DirectedProperty(
return value
}
fun of(shape: VoxelShape, propagatesSkylight: Boolean): LightProperties {
fun of(shape: VoxelShape, skylightEnters: Boolean, filtersLight: Boolean): LightProperties {
val directions = BooleanArray(Directions.SIZE)
for ((index, direction) in Directions.VALUES.withIndex()) {
@ -58,10 +58,10 @@ class DirectedProperty(
}
val simple = directions.isSimple ?: return DirectedProperty(directions, propagatesSkylight)
val simple = directions.isSimple ?: return DirectedProperty(directions, skylightEnters, filtersLight)
if (!propagatesSkylight) {
return DirectedProperty(if (simple) TRUE else FALSE, false)
if (!filtersLight) {
return DirectedProperty(if (simple) TRUE else FALSE, simple, !simple)
}
return if (simple) TransparentProperty else SolidProperty

View File

@ -17,7 +17,9 @@ import de.bixilon.minosoft.data.direction.Directions
interface LightProperties {
val propagatesLight: Boolean
val propagatesSkylight: Boolean
val skylightEnters: Boolean
val filtersSkylight: Boolean
fun propagatesLight(direction: Directions): Boolean

View File

@ -15,5 +15,6 @@ package de.bixilon.minosoft.data.registries.blocks.light
object SolidProperty : SimpleLightProperties {
override val propagatesLight: Boolean get() = false
override val propagatesSkylight: Boolean get() = false
override val skylightEnters: Boolean get() = false
override val filtersSkylight: Boolean get() = true
}

View File

@ -15,5 +15,6 @@ package de.bixilon.minosoft.data.registries.blocks.light
object TransparentProperty : SimpleLightProperties {
override val propagatesLight: Boolean get() = true
override val propagatesSkylight: Boolean get() = true
override val skylightEnters: Boolean get() = true
override val filtersSkylight: Boolean get() = false
}

View File

@ -206,11 +206,15 @@ class ChunkLight(private val chunk: Chunk) {
section.acquire()
for (sectionY in ProtocolDefinition.SECTION_MAX_Y downTo 0) {
val light = section.blocks.unsafeGet(x, sectionY, z)?.lightProperties ?: continue
if (light.propagatesSkylight) {
if (light.skylightEnters && !light.filtersSkylight) {
// can go through block
continue
}
y = (sectionIndex + chunk.lowestSection) * ProtocolDefinition.SECTION_HEIGHT_Y + sectionY + 1
y = (sectionIndex + chunk.lowestSection) * ProtocolDefinition.SECTION_HEIGHT_Y + sectionY
if (!light.skylightEnters) {
y++
}
section.release()
break@sectionLoop
}