mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 19:05:02 -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.Vec2
|
||||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
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.state.BlockState
|
||||||
|
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||||
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
|
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.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.models.block.state.baked.SideSize
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparencies
|
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.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 {
|
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() {
|
fun noNeighbour() {
|
||||||
val face = createFace()
|
val face = createFace()
|
||||||
assertFalse(FaceCulling.canCull(face, null))
|
assertFalse(FaceCulling.canCull(face, Directions.DOWN, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun selfNotTouching() {
|
fun selfNotTouching() {
|
||||||
val face = createFace(null)
|
val face = createFace(null)
|
||||||
val neighbour = createNeighbour()
|
val neighbour = createNeighbour()
|
||||||
assertFalse(FaceCulling.canCull(face, neighbour))
|
assertFalse(FaceCulling.canCull(face, Directions.DOWN, neighbour))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun neighbourNotTouching() {
|
fun neighbourNotTouching() {
|
||||||
val face = createFace()
|
val face = createFace()
|
||||||
val neighbour = createNeighbour(null)
|
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
|
// 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
|
package de.bixilon.minosoft.gui.rendering.models.block.state.baked
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
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.registries.blocks.state.BlockState
|
||||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
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.baked.cull.FaceCulling
|
||||||
@ -24,21 +25,24 @@ import java.util.*
|
|||||||
|
|
||||||
class BakedModel(
|
class BakedModel(
|
||||||
val faces: Array<Array<BakedFace>>,
|
val faces: Array<Array<BakedFace>>,
|
||||||
val sizes: Array<SideSize>,
|
val sizes: Array<SideSize?>,
|
||||||
val particle: AbstractTexture?,
|
val particle: AbstractTexture?,
|
||||||
) : BlockRender {
|
) : BlockRender {
|
||||||
|
|
||||||
|
override fun getSize(direction: Directions) = sizes[direction.ordinal]
|
||||||
|
|
||||||
override fun getParticleTexture(random: Random?, position: Vec3i) = particle
|
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 {
|
override fun render(position: BlockPosition, offset: FloatArray, mesh: WorldMesh, random: Random?, state: BlockState, neighbours: Array<BlockState?>, light: ByteArray, tints: IntArray?): Boolean {
|
||||||
|
|
||||||
var rendered = false
|
var rendered = false
|
||||||
|
|
||||||
for ((direction, faces) in faces.withIndex()) {
|
for ((directionIndex, faces) in faces.withIndex()) {
|
||||||
val neighbour = neighbours[direction]
|
val neighbour = neighbours[directionIndex]
|
||||||
|
val direction = Directions.VALUES[directionIndex].inverted
|
||||||
|
|
||||||
for (face in faces) {
|
for (face in faces) {
|
||||||
if (FaceCulling.canCull(face, neighbour)) {
|
if (FaceCulling.canCull(face, direction, neighbour)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
face.render(offset, mesh, light, tints)
|
face.render(offset, mesh, light, tints)
|
||||||
|
@ -19,6 +19,10 @@ class SideSize(
|
|||||||
val sizes: Array<FaceSize>,
|
val sizes: Array<FaceSize>,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (sizes.isEmpty()) throw IllegalCallerException("sizes is empty!")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class FaceSize(
|
class FaceSize(
|
||||||
val start: Vec2,
|
val start: Vec2,
|
||||||
|
@ -13,15 +13,19 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.models.block.state.baked.cull
|
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.data.registries.blocks.state.BlockState
|
||||||
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace
|
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace
|
||||||
|
|
||||||
object FaceCulling {
|
object FaceCulling {
|
||||||
|
|
||||||
fun canCull(face: BakedFace, neighbour: BlockState?): Boolean {
|
fun canCull(face: BakedFace, direction: Directions, neighbour: BlockState?): Boolean {
|
||||||
if (neighbour == null) return false
|
if (neighbour == null) return false
|
||||||
if (!face.touchingSide) return false
|
if (!face.touchingSide) return false
|
||||||
|
|
||||||
|
val model = neighbour.model ?: return false
|
||||||
|
val size = model.getSize(direction) ?: return false
|
||||||
|
|
||||||
|
|
||||||
return true // TODO
|
return true // TODO
|
||||||
}
|
}
|
||||||
|
@ -37,4 +37,6 @@ class BuiltModel(
|
|||||||
|
|
||||||
return rendered
|
return rendered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: getSize/culling support
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,10 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering.models.block.state.render
|
package de.bixilon.minosoft.gui.rendering.models.block.state.render
|
||||||
|
|
||||||
import de.bixilon.kotlinglm.vec3.Vec3i
|
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.registries.blocks.state.BlockState
|
||||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
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.system.base.texture.texture.AbstractTexture
|
||||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -24,4 +26,6 @@ interface BlockRender {
|
|||||||
fun getParticleTexture(random: Random?, position: Vec3i): AbstractTexture? = null
|
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 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.kotlinglm.vec3.Vec3i
|
||||||
import de.bixilon.kutil.exception.Broken
|
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.registries.blocks.state.BlockState
|
||||||
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
import de.bixilon.minosoft.data.world.positions.BlockPosition
|
||||||
import de.bixilon.minosoft.data.world.positions.BlockPositionUtil.positionHash
|
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.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.system.base.texture.texture.AbstractTexture
|
||||||
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
import de.bixilon.minosoft.gui.rendering.world.mesh.WorldMesh
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -28,7 +30,11 @@ class WeightedBlockRender(
|
|||||||
val models: Array<WeightedEntry>,
|
val models: Array<WeightedEntry>,
|
||||||
val totalWeight: Int,
|
val totalWeight: Int,
|
||||||
) : BlockRender {
|
) : 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 {
|
private fun getModel(random: Random?, position: BlockPosition): BlockRender {
|
||||||
if (random == null) return models.first().model
|
if (random == null) return models.first().model
|
||||||
@ -59,4 +65,33 @@ class WeightedBlockRender(
|
|||||||
val weight: Int,
|
val weight: Int,
|
||||||
val model: BakedModel,
|
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