mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 10:25:06 -04:00
wip face culling
This commit is contained in:
parent
097e72906c
commit
110bf94706
@ -15,9 +15,14 @@ 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.kutil.exception.Broken
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.settings.BlockSettings
|
||||
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||
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.BakedModel
|
||||
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
|
||||
@ -33,26 +38,34 @@ class FaceCullingTest {
|
||||
}
|
||||
|
||||
private fun createNeighbour(size: SideSize? = SideSize(arrayOf(SideSize.FaceSize(Vec2(0), Vec2(1)))), transparency: TextureTransparencies = TextureTransparencies.OPAQUE): BlockState {
|
||||
TODO()
|
||||
val block = object : Block(minosoft("dummy"), BlockSettings()) {
|
||||
override val hardness: Float get() = Broken()
|
||||
}
|
||||
|
||||
val state = BlockState(block, 0)
|
||||
|
||||
state.model = BakedModel(emptyArray(), arrayOf(size, size, size, size, size, size), null)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
fun noNeighbour() {
|
||||
val face = createFace()
|
||||
assertFalse(FaceCulling.canCull(face, null))
|
||||
assertFalse(FaceCulling.canCull(face, Directions.DOWN, null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun selfNotTouching() {
|
||||
val face = createFace(null)
|
||||
val neighbour = createNeighbour()
|
||||
assertFalse(FaceCulling.canCull(face, neighbour))
|
||||
assertFalse(FaceCulling.canCull(face, Directions.DOWN, neighbour))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun neighbourNotTouching() {
|
||||
val face = createFace()
|
||||
val neighbour = createNeighbour(null)
|
||||
assertFalse(FaceCulling.canCull(face, neighbour))
|
||||
assertFalse(FaceCulling.canCull(face, Directions.DOWN, neighbour))
|
||||
}
|
||||
|
||||
// TODO: force no cull (e.g. leaves), mix of transparency, mix of side sizes
|
||||
|
@ -14,6 +14,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering.models.block.state.baked
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
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
|
||||
@ -24,21 +25,24 @@ import java.util.*
|
||||
|
||||
class BakedModel(
|
||||
val faces: Array<Array<BakedFace>>,
|
||||
val sizes: Array<SideSize>,
|
||||
val sizes: Array<SideSize?>,
|
||||
val particle: AbstractTexture?,
|
||||
) : BlockRender {
|
||||
|
||||
override fun getSize(direction: Directions) = sizes[direction.ordinal]
|
||||
|
||||
override fun getParticleTexture(random: Random?, position: Vec3i) = particle
|
||||
|
||||
override fun render(position: BlockPosition, offset: FloatArray, mesh: WorldMesh, random: Random?, state: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean {
|
||||
|
||||
var rendered = false
|
||||
|
||||
for ((direction, faces) in faces.withIndex()) {
|
||||
val neighbour = neighbours[direction]
|
||||
for ((directionIndex, faces) in faces.withIndex()) {
|
||||
val neighbour = neighbours[directionIndex]
|
||||
val direction = Directions.VALUES[directionIndex].inverted
|
||||
|
||||
for (face in faces) {
|
||||
if (FaceCulling.canCull(face, neighbour)) {
|
||||
if (FaceCulling.canCull(face, direction, neighbour)) {
|
||||
continue
|
||||
}
|
||||
face.render(offset, mesh, light, tints)
|
||||
|
@ -19,6 +19,10 @@ class SideSize(
|
||||
val sizes: Array<FaceSize>,
|
||||
) {
|
||||
|
||||
init {
|
||||
if (sizes.isEmpty()) throw IllegalCallerException("sizes is empty!")
|
||||
}
|
||||
|
||||
|
||||
class FaceSize(
|
||||
val start: Vec2,
|
||||
|
@ -13,15 +13,19 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull
|
||||
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
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 {
|
||||
fun canCull(face: BakedFace, direction: Directions, neighbour: BlockState?): Boolean {
|
||||
if (neighbour == null) return false
|
||||
if (!face.touchingSide) return false
|
||||
|
||||
val model = neighbour.model ?: return false
|
||||
val size = model.getSize(direction) ?: return false
|
||||
|
||||
|
||||
return true // TODO
|
||||
}
|
||||
|
@ -37,4 +37,6 @@ class BuiltModel(
|
||||
|
||||
return rendered
|
||||
}
|
||||
|
||||
// TODO: getSize/culling support
|
||||
}
|
||||
|
@ -14,8 +14,10 @@
|
||||
package de.bixilon.minosoft.gui.rendering.models.block.state.render
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
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.SideSize
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import java.util.*
|
||||
@ -24,4 +26,6 @@ interface BlockRender {
|
||||
fun getParticleTexture(random: Random?, position: Vec3i): AbstractTexture? = null
|
||||
|
||||
fun render(position: BlockPosition, offset: FloatArray, mesh: WorldMesh, random: Random?, state: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean
|
||||
|
||||
fun getSize(direction: Directions): SideSize? = null
|
||||
}
|
||||
|
@ -15,10 +15,12 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.render
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
||||
import de.bixilon.kutil.exception.Broken
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
|
||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
||||
import de.bixilon.minosoft.data.world.positions.BlockPositionUtil.positionHash
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.SideSize
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||
import java.util.*
|
||||
@ -28,7 +30,11 @@ class WeightedBlockRender(
|
||||
val models: Array<WeightedEntry>,
|
||||
val totalWeight: Int,
|
||||
) : BlockRender {
|
||||
private val size = models.getSize()
|
||||
|
||||
override fun getSize(direction: Directions): SideSize? {
|
||||
return size[direction.ordinal] // TODO: get random block model
|
||||
}
|
||||
|
||||
private fun getModel(random: Random?, position: BlockPosition): BlockRender {
|
||||
if (random == null) return models.first().model
|
||||
@ -59,4 +65,33 @@ class WeightedBlockRender(
|
||||
val weight: Int,
|
||||
val model: BakedModel,
|
||||
)
|
||||
|
||||
private fun Array<WeightedEntry>.getSize(): Array<SideSize?> {
|
||||
val sizes: Array<SideSize?> = arrayOfNulls(Directions.SIZE)
|
||||
val skip = BooleanArray(Directions.SIZE)
|
||||
|
||||
for ((_, model) in this) {
|
||||
for (direction in Directions) {
|
||||
if (skip[direction.ordinal]) continue
|
||||
|
||||
val current = sizes[direction.ordinal]
|
||||
val size = model.getSize(direction)
|
||||
if (current == null) {
|
||||
sizes[direction.ordinal] = size
|
||||
continue
|
||||
}
|
||||
if (current != size) {
|
||||
skip[direction.ordinal] = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ((index, skip) in skip.withIndex()) {
|
||||
if (!skip) continue
|
||||
sizes[index] = null
|
||||
}
|
||||
|
||||
return sizes
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user