From 64bf7fa4d460ea54e697635311119ed4799e8a82 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Thu, 22 Jun 2023 23:31:41 +0200 Subject: [PATCH] more face culling tests --- .../block/state/baked/cull/FaceCullingTest.kt | 93 ++++++++++++++++++- .../data/registries/blocks/types/Block.kt | 4 - .../types/pixlyzer/leaves/LeavesBlock.kt | 8 -- .../models/block/state/baked/BakedModel.kt | 2 +- .../block/state/baked/cull/FaceCulling.kt | 2 +- 5 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt index 9acbf01c6..479ed4b12 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt @@ -28,6 +28,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparenci import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.MemoryTexture import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY import org.testng.Assert.assertFalse +import org.testng.Assert.assertTrue import org.testng.annotations.Test @Test(groups = ["models", "culling"]) @@ -49,24 +50,110 @@ class FaceCullingTest { return state } + private fun createState() = createNeighbour() + fun noNeighbour() { val face = createFace() - assertFalse(FaceCulling.canCull(face, Directions.DOWN, null)) + assertFalse(FaceCulling.canCull(createState(), face, Directions.DOWN, null)) } @Test fun selfNotTouching() { val face = createFace(null) val neighbour = createNeighbour() - assertFalse(FaceCulling.canCull(face, Directions.DOWN, neighbour)) + assertFalse(FaceCulling.canCull(createState(), face, Directions.DOWN, neighbour)) } @Test fun neighbourNotTouching() { val face = createFace() val neighbour = createNeighbour(null) - assertFalse(FaceCulling.canCull(face, Directions.DOWN, neighbour)) + assertFalse(FaceCulling.canCull(createState(), face, Directions.DOWN, neighbour)) + } + + @Test + fun fullNeighbour() { + val face = createFace() + val neighbour = createNeighbour() + assertTrue(FaceCulling.canCull(createState(), face, Directions.DOWN, neighbour)) + } + + @Test + fun sizeMatch() { + val face = createFace(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f))) + val neighbour = createNeighbour(side(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f)))) + assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun greaterNeighbour() { + val face = createFace(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f))) + val neighbour = createNeighbour(side(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.6f)))) + assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun smallerNeighbour() { + val face = createFace(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f))) + val neighbour = createNeighbour(side(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.4f)))) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun shiftedNeighbour1() { + val face = createFace(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f))) + val neighbour = createNeighbour(side(SideSize.FaceSize(Vec2(0.1f, 0.5f), Vec2(1.0f, 0.5f)))) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun shiftedNeighbour2() { + val face = createFace(SideSize.FaceSize(Vec2(0.0f, 0.5f), Vec2(1.0f, 0.5f))) + val neighbour = createNeighbour(side(SideSize.FaceSize(Vec2(0.1f, 0.5f), Vec2(1.0f, 0.6f)))) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun shiftedNeighbour3() { + val face = createFace(SideSize.FaceSize(Vec2(0.1f, 0.8f), Vec2(0.9f, 0.9f))) + val neighbour = createNeighbour(side(SideSize.FaceSize(Vec2(0.1f, 0.5f), Vec2(0.95f, 0.95f)))) + assertTrue(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun opaqueOnTransparent() { + val face = createFace(transparency = TextureTransparencies.OPAQUE) + val neighbour = createNeighbour(transparency = TextureTransparencies.TRANSPARENT) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun transparentOnOpaque() { + val face = createFace(transparency = TextureTransparencies.TRANSPARENT) + val neighbour = createNeighbour(transparency = TextureTransparencies.OPAQUE) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun opaqueOnTranslucent() { + val face = createFace(transparency = TextureTransparencies.OPAQUE) + val neighbour = createNeighbour(transparency = TextureTransparencies.TRANSLUCENT) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) + } + + @Test + fun translucentOnOpaque() { + val face = createFace(transparency = TextureTransparencies.TRANSLUCENT) + val neighbour = createNeighbour(transparency = TextureTransparencies.OPAQUE) + assertFalse(FaceCulling.canCull(createState(), face, Directions.EAST, neighbour)) } // TODO: force no cull (e.g. leaves), mix of transparency, mix of side sizes + + // TODO: same transparency when same block + + + private fun side(vararg size: SideSize.FaceSize): SideSize { + return SideSize(arrayOf(*size)) + } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/Block.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/Block.kt index 905682188..da43246b2 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/Block.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/Block.kt @@ -75,10 +75,6 @@ abstract class Block( @Deprecated("Interface") open fun randomTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, random: Random) = Unit - @Deprecated("Interface") - open fun canCull(blockState: BlockState, other: BlockState): Boolean = true - - fun updateStates(states: Set, default: BlockState, properties: Map>) { this::properties.forceSet(properties) this::states.forceSet(states) diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/pixlyzer/leaves/LeavesBlock.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/pixlyzer/leaves/LeavesBlock.kt index 87b518c79..77c6ed9ec 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/pixlyzer/leaves/LeavesBlock.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/types/pixlyzer/leaves/LeavesBlock.kt @@ -14,20 +14,12 @@ package de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.leaves import de.bixilon.minosoft.data.registries.blocks.factory.PixLyzerBlockFactory -import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.registries.blocks.types.pixlyzer.PixLyzerBlock import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.registries.Registries open class LeavesBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map) : PixLyzerBlock(resourceLocation, registries, data) { - override fun canCull(blockState: BlockState, other: BlockState): Boolean { - if (other.block is LeavesBlock) { - return false - } - return true - } - companion object : PixLyzerBlockFactory { override fun build(resourceLocation: ResourceLocation, registries: Registries, data: Map): LeavesBlock { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt index cfae52efd..a0bc6fd11 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt @@ -42,7 +42,7 @@ class BakedModel( val direction = Directions.VALUES[directionIndex].inverted for (face in faces) { - if (FaceCulling.canCull(face, direction, neighbour)) { + if (FaceCulling.canCull(state, face, direction, neighbour)) { continue } face.render(offset, mesh, light, tints) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCulling.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCulling.kt index 88795a40e..962f640d0 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCulling.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCulling.kt @@ -19,7 +19,7 @@ import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace object FaceCulling { - fun canCull(face: BakedFace, direction: Directions, neighbour: BlockState?): Boolean { + fun canCull(block: BlockState, face: BakedFace, direction: Directions, neighbour: BlockState?): Boolean { if (neighbour == null) return false if (!face.touchingSide) return false