From 10ffa3818e10fbbce8dbe2c7dcb448535926d357 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 5 Jun 2023 00:40:26 +0200 Subject: [PATCH] wip face culling --- .../models/block/state/baked/BakedFace.kt | 1 + .../models/block/state/baked/BakedModel.kt | 9 +++- .../block/state/baked/cull/FaceCulling.kt | 31 +++++++++++++ .../block/state/baked/cull/FaceCullingTest.kt | 46 +++++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCulling.kt create mode 100644 src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt index b20da0866..7a8fcd5ea 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt @@ -31,6 +31,7 @@ class BakedFace( val tintIndex: Int, val cull: Directions?, val texture: AbstractTexture, + val size: SideSize.FaceSize?, ) { private var cullIndex = cull?.ordinal ?: SELF_LIGHT_INDEX 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 6bf1d40a3..77cab20a8 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 @@ -16,6 +16,7 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.baked import de.bixilon.kotlinglm.vec3.Vec3i import de.bixilon.minosoft.data.registries.blocks.state.BlockState import de.bixilon.minosoft.data.world.positions.BlockPosition +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull.FaceCulling import de.bixilon.minosoft.gui.rendering.models.block.state.render.BlockRender import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh @@ -33,9 +34,13 @@ class BakedModel( var rendered = false - for ((index, faces) in faces.withIndex()) { - if (neighbours[index] != null) continue // TODO + for ((direction, faces) in faces.withIndex()) { + val neighbour = neighbours[direction] + for (face in faces) { + if (FaceCulling.canCull(face, neighbour)) { + continue + } face.render(offset, mesh, light, tints) rendered = true 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 new file mode 100644 index 000000000..801feb180 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCulling.kt @@ -0,0 +1,31 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull + +import de.bixilon.minosoft.data.registries.blocks.state.BlockState +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace + +object FaceCulling { + + fun canCull(face: BakedFace, neighbour: BlockState?): Boolean { + if (neighbour == null) return false + if (!face.touchingSide) return false + + + return true // TODO + } + + + private inline val BakedFace.touchingSide: Boolean get() = size != null +} diff --git a/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt b/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt new file mode 100644 index 000000000..dc9e56b2e --- /dev/null +++ b/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/cull/FaceCullingTest.kt @@ -0,0 +1,46 @@ +package de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull + +import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec2.Vec2i +import de.bixilon.minosoft.data.registries.blocks.state.BlockState +import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.SideSize +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies +import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.MemoryTexture +import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.EMPTY +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Test + +class FaceCullingTest { + + private fun createFace(size: SideSize.FaceSize? = SideSize.FaceSize(Vec2(0), Vec2(1)), transparency: TextureTransparencies = TextureTransparencies.OPAQUE): BakedFace { + return BakedFace(floatArrayOf(), floatArrayOf(), 1.0f, -1, null, MemoryTexture(minosoft("test"), Vec2i.EMPTY), size) + } + + private fun createNeighbour(size: SideSize? = SideSize(arrayOf(SideSize.FaceSize(Vec2(0), Vec2(1)))), transparency: TextureTransparencies = TextureTransparencies.OPAQUE): BlockState { + TODO() + } + + @Test + fun noNeighbour() { + val face = createFace() + assertFalse(FaceCulling.canCull(face, null)) + } + + @Test + fun selfNotTouching() { + val face = createFace(null) + val neighbour = createNeighbour() + assertFalse(FaceCulling.canCull(face, neighbour)) + } + + @Test + fun neighbourNotTouching() { + val face = createFace() + val neighbour = createNeighbour(null) + assertFalse(FaceCulling.canCull(face, neighbour)) + } + + // TODO: force no cull (e.g. leaves), mix of transparency, mix of side sizes +}