mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-19 04:15:14 -04:00
rendering: improve cullfacing (2)
This commit is contained in:
parent
6cc781a724
commit
bdfe1345fa
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.data
|
package de.bixilon.minosoft.data
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceBorderSize
|
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceSize
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
@ -27,8 +27,6 @@ enum class Directions(val directionVector: Vec3i) {
|
|||||||
EAST(Vec3i(1, 0, 0));
|
EAST(Vec3i(1, 0, 0));
|
||||||
|
|
||||||
val floatDirectionVector = Vec3(directionVector)
|
val floatDirectionVector = Vec3(directionVector)
|
||||||
val blockResolutionVector = directionVector * BlockModelElement.BLOCK_RESOLUTION
|
|
||||||
val blockResolutionVectorFloat = Vec3(blockResolutionVector)
|
|
||||||
|
|
||||||
lateinit var inverse: Directions
|
lateinit var inverse: Directions
|
||||||
private set
|
private set
|
||||||
@ -53,54 +51,43 @@ enum class Directions(val directionVector: Vec3i) {
|
|||||||
/**
|
/**
|
||||||
* @return the size of the face in this direction. null if the face is not touching the border (determinated by the block resolution)
|
* @return the size of the face in this direction. null if the face is not touching the border (determinated by the block resolution)
|
||||||
*/
|
*/
|
||||||
fun getFaceBorderSizes(start: Vec3, end: Vec3): FaceBorderSize? {
|
fun getFaceBorderSizes(start: Vec3, end: Vec3): FaceSize? {
|
||||||
// check if face is touching the border of a block
|
// check if face is touching the border of a block
|
||||||
|
|
||||||
|
if (!isBlockResolutionBorder(start, end)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return getFaceSize(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFaceSize(start: Vec3, end: Vec3): FaceSize {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
DOWN -> {
|
DOWN, UP -> {
|
||||||
if (start.y != 0.0f && end.y != 0.0f) {
|
FaceSize(Vec2i(start.x, start.z), Vec2i(end.x, end.z))
|
||||||
null
|
|
||||||
} else {
|
|
||||||
FaceBorderSize(Vec2i(start.x, start.z), Vec2i(end.x, end.z))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
UP -> {
|
NORTH, SOUTH -> {
|
||||||
if (start.y != BlockModelElement.BLOCK_RESOLUTION_FLOAT && end.y != BlockModelElement.BLOCK_RESOLUTION_FLOAT) {
|
FaceSize(Vec2i(start.x, start.y), Vec2i(end.x, end.y))
|
||||||
null
|
|
||||||
} else {
|
|
||||||
FaceBorderSize(Vec2i(start.x, start.z), Vec2i(end.x, end.z))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
NORTH -> {
|
EAST, WEST -> {
|
||||||
if (start.z != 0.0f && end.z != 0.0f) {
|
FaceSize(Vec2i(start.y, start.z), Vec2i(end.y, end.z))
|
||||||
null
|
|
||||||
} else {
|
|
||||||
FaceBorderSize(Vec2i(start.x, start.y), Vec2i(end.x, end.y))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SOUTH -> {
|
|
||||||
if (start.z != BlockModelElement.BLOCK_RESOLUTION_FLOAT && end.z != BlockModelElement.BLOCK_RESOLUTION_FLOAT) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
FaceBorderSize(Vec2i(start.x, start.y), Vec2i(end.x, end.y))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WEST -> {
|
|
||||||
if (start.x != 0.0f && end.x != 0.0f) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
FaceBorderSize(Vec2i(start.y, start.z), Vec2i(end.y, end.z))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EAST -> {
|
|
||||||
if (start.x != BlockModelElement.BLOCK_RESOLUTION_FLOAT && end.x != BlockModelElement.BLOCK_RESOLUTION_FLOAT) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
FaceBorderSize(Vec2i(start.y, start.z), Vec2i(end.y, end.z))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isBlockResolutionBorder(start: Vec3, end: Vec3): Boolean {
|
||||||
|
return isCoordinateBorder(directionVector.x, start.x, end.x) || isCoordinateBorder(directionVector.y, start.y, end.y) || isCoordinateBorder(directionVector.z, start.z, end.z)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isCoordinateBorder(directionValue: Int, start: Float, end: Float): Boolean {
|
||||||
|
if (directionValue == 1) {
|
||||||
|
return start == BlockModelElement.BLOCK_RESOLUTION_FLOAT || end == BlockModelElement.BLOCK_RESOLUTION_FLOAT
|
||||||
|
}
|
||||||
|
if (directionValue == -1) {
|
||||||
|
return start == 0.0f || end == 0.0f
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DIRECTIONS = values()
|
val DIRECTIONS = values()
|
||||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.gui.rendering.chunk.models
|
|||||||
|
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
data class FaceBorderSize(
|
data class FaceSize(
|
||||||
val start: Vec2i = Vec2i(0, 0),
|
val start: Vec2i = Vec2i(0, 0),
|
||||||
val end: Vec2i = Vec2i(16, 16),
|
val end: Vec2i = Vec2i(16, 16),
|
||||||
)
|
)
|
@ -13,10 +13,10 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.chunk.models.loading
|
package de.bixilon.minosoft.gui.rendering.chunk.models.loading
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import de.bixilon.minosoft.data.Directions
|
import de.bixilon.minosoft.data.Directions
|
||||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.VecUtil.readUV
|
||||||
import glm_.Java.Companion.glm
|
import glm_.Java.Companion.glm
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
@ -44,9 +44,7 @@ class BlockModelFace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateTexturePositions(data: JsonObject?, from: Vec3, to: Vec3, direction: Directions): MutableList<Vec2> {
|
private fun calculateTexturePositions(data: JsonObject?, from: Vec3, to: Vec3, direction: Directions): MutableList<Vec2> {
|
||||||
val (textureTopLeft: Vec2, textureBottomRight: Vec2) = data?.get("uv")?.asJsonArray?.let {
|
val (textureTopLeft: Vec2, textureBottomRight: Vec2) = data?.get("uv")?.asJsonArray?.readUV() ?: getTexturePositionsFromRegion(from, to, direction)
|
||||||
readUV(it)
|
|
||||||
} ?: getTexturePositionsFromRegion(from, to, direction)
|
|
||||||
return mutableListOf(
|
return mutableListOf(
|
||||||
uvToFloat(Vec2(textureTopLeft.x, textureTopLeft.y)),
|
uvToFloat(Vec2(textureTopLeft.x, textureTopLeft.y)),
|
||||||
uvToFloat(Vec2(textureTopLeft.x, textureBottomRight.y)),
|
uvToFloat(Vec2(textureTopLeft.x, textureBottomRight.y)),
|
||||||
@ -55,15 +53,12 @@ class BlockModelFace {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readUV(data: JsonArray): Pair<Vec2, Vec2> {
|
|
||||||
return Pair(Vec2(data[0].asFloat, data[3].asFloat), Vec2(data[2].asFloat, data[1].asFloat))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getTexturePositionsFromRegion(from: Vec3, to: Vec3, direction: Directions): Pair<Vec2, Vec2> {
|
private fun getTexturePositionsFromRegion(from: Vec3, to: Vec3, direction: Directions): Pair<Vec2, Vec2> {
|
||||||
|
// ToDo: Remove the duplicated code in Directions
|
||||||
return when (direction) {
|
return when (direction) {
|
||||||
Directions.EAST, Directions.WEST -> Pair(Vec2(from.z.toInt(), to.y.toInt()), Vec2(to.z.toInt(), from.y.toInt()))
|
|
||||||
Directions.UP, Directions.DOWN -> Pair(Vec2(from.x.toInt(), to.z.toInt()), Vec2(to.x.toInt(), from.z.toInt()))
|
Directions.UP, Directions.DOWN -> Pair(Vec2(from.x.toInt(), to.z.toInt()), Vec2(to.x.toInt(), from.z.toInt()))
|
||||||
Directions.NORTH, Directions.SOUTH -> Pair(Vec2(from.x.toInt(), to.y.toInt()), Vec2(to.x.toInt(), from.y.toInt()))
|
Directions.NORTH, Directions.SOUTH -> Pair(Vec2(from.x.toInt(), to.y.toInt()), Vec2(to.x.toInt(), from.y.toInt()))
|
||||||
|
Directions.EAST, Directions.WEST -> Pair(Vec2(from.z.toInt(), to.y.toInt()), Vec2(to.z.toInt(), from.y.toInt()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@ import de.bixilon.minosoft.data.world.BlockPosition
|
|||||||
import de.bixilon.minosoft.data.world.World
|
import de.bixilon.minosoft.data.world.World
|
||||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceBorderSize
|
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceSize
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
|
|
||||||
interface BlockRenderInterface {
|
interface BlockRenderInterface {
|
||||||
val faceBorderSizes: Array<Array<FaceBorderSize>?> // direction indexed
|
val faceBorderSizes: Array<Array<FaceSize>?> // direction indexed
|
||||||
val transparentFaces: BooleanArray
|
val transparentFaces: BooleanArray
|
||||||
|
|
||||||
fun render(blockState: BlockState, lightAccessor: LightAccessor, tintColor: RGBColor?, position: BlockPosition, meshCollection: ChunkMeshCollection, neighbourBlocks: Array<BlockState?>, world: World)
|
fun render(blockState: BlockState, lightAccessor: LightAccessor, tintColor: RGBColor?, position: BlockPosition, meshCollection: ChunkMeshCollection, neighbourBlocks: Array<BlockState?>, world: World)
|
||||||
|
@ -23,7 +23,7 @@ import de.bixilon.minosoft.data.world.World
|
|||||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceBorderSize
|
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceSize
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.TextureTransparencies
|
import de.bixilon.minosoft.gui.rendering.textures.TextureTransparencies
|
||||||
@ -33,7 +33,7 @@ class BlockRenderer : BlockRenderInterface {
|
|||||||
val textures: MutableMap<String, String> = mutableMapOf()
|
val textures: MutableMap<String, String> = mutableMapOf()
|
||||||
private val elements: MutableSet<ElementRenderer> = mutableSetOf()
|
private val elements: MutableSet<ElementRenderer> = mutableSetOf()
|
||||||
private val textureMapping: MutableMap<String, Texture> = mutableMapOf()
|
private val textureMapping: MutableMap<String, Texture> = mutableMapOf()
|
||||||
override val faceBorderSizes: Array<Array<FaceBorderSize>?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
override val faceBorderSizes: Array<Array<FaceSize>?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
||||||
override val transparentFaces: BooleanArray = BooleanArray(Directions.DIRECTIONS.size)
|
override val transparentFaces: BooleanArray = BooleanArray(Directions.DIRECTIONS.size)
|
||||||
|
|
||||||
constructor(data: JsonObject, parent: BlockModel) {
|
constructor(data: JsonObject, parent: BlockModel) {
|
||||||
@ -64,7 +64,7 @@ class BlockRenderer : BlockRenderInterface {
|
|||||||
for (direction in Directions.DIRECTIONS) {
|
for (direction in Directions.DIRECTIONS) {
|
||||||
var directionIsCullFace: Boolean? = null
|
var directionIsCullFace: Boolean? = null
|
||||||
var directionIsNotTransparent: Boolean? = null
|
var directionIsNotTransparent: Boolean? = null
|
||||||
var faceBorderSites: MutableList<FaceBorderSize> = mutableListOf()
|
var faceBorderSites: MutableList<FaceSize> = mutableListOf()
|
||||||
for (element in elements) {
|
for (element in elements) {
|
||||||
if (element.isCullFace(direction)) {
|
if (element.isCullFace(direction)) {
|
||||||
directionIsCullFace = true
|
directionIsCullFace = true
|
||||||
@ -98,11 +98,9 @@ class BlockRenderer : BlockRenderInterface {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for (direction in Directions.DIRECTIONS) {
|
for (direction in Directions.DIRECTIONS) {
|
||||||
val cullFace = cullFaces[direction.ordinal] != null
|
|
||||||
|
|
||||||
val invertedDirection = direction.inverse
|
val invertedDirection = direction.inverse
|
||||||
var isNeighbourTransparent = false
|
var isNeighbourTransparent = false
|
||||||
var neighbourFaceSize: Array<FaceBorderSize>? = null
|
var neighbourFaceSize: Array<FaceSize>? = null
|
||||||
neighbourBlocks[direction.ordinal]?.getBlockRenderer(position + direction)?.let {
|
neighbourBlocks[direction.ordinal]?.getBlockRenderer(position + direction)?.let {
|
||||||
if (it.transparentFaces[invertedDirection.ordinal]) {
|
if (it.transparentFaces[invertedDirection.ordinal]) {
|
||||||
isNeighbourTransparent = true
|
isNeighbourTransparent = true
|
||||||
@ -110,6 +108,8 @@ class BlockRenderer : BlockRenderInterface {
|
|||||||
neighbourFaceSize = it.faceBorderSizes[invertedDirection.ordinal]
|
neighbourFaceSize = it.faceBorderSizes[invertedDirection.ordinal]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToDo: Should we preserve the cullface attribute? It seems to has no point here.
|
||||||
|
|
||||||
for (element in elements) {
|
for (element in elements) {
|
||||||
var drawElementFace = true
|
var drawElementFace = true
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.world.BlockPosition
|
|||||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.SectionArrayMesh
|
import de.bixilon.minosoft.gui.rendering.chunk.SectionArrayMesh
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceBorderSize
|
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceSize
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelFace
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelFace
|
||||||
@ -35,7 +35,7 @@ import glm_.vec2.Vec2
|
|||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
class ElementRenderer(parent: BlockModelElement, val rotation: Vec3, uvLock: Boolean, rescale: Boolean) {
|
class ElementRenderer(parent: BlockModelElement, val rotation: Vec3, uvLock: Boolean, rescale: Boolean) {
|
||||||
val faceBorderSize: Array<FaceBorderSize?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
val faceBorderSize: Array<FaceSize?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
||||||
private val faces: MutableMap<Directions, BlockModelFace> = mutableMapOf()
|
private val faces: MutableMap<Directions, BlockModelFace> = mutableMapOf()
|
||||||
private var transformedPositions: Array<Vec3> = parent.transformedPositions.clone()
|
private var transformedPositions: Array<Vec3> = parent.transformedPositions.clone()
|
||||||
private val directionMapping: HashBiMap<Directions, Directions> = HashBiMap.create()
|
private val directionMapping: HashBiMap<Directions, Directions> = HashBiMap.create()
|
||||||
|
@ -9,7 +9,7 @@ import de.bixilon.minosoft.data.world.World
|
|||||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
import de.bixilon.minosoft.gui.rendering.chunk.ChunkMeshCollection
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceBorderSize
|
import de.bixilon.minosoft.gui.rendering.chunk.models.FaceSize
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement
|
||||||
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelFace
|
import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelFace
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||||
@ -25,7 +25,7 @@ class FluidRenderer(
|
|||||||
private val flowingTextureName: String,
|
private val flowingTextureName: String,
|
||||||
private val regex: String,
|
private val regex: String,
|
||||||
) : BlockRenderInterface {
|
) : BlockRenderInterface {
|
||||||
override val faceBorderSizes: Array<Array<FaceBorderSize>?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
override val faceBorderSizes: Array<Array<FaceSize>?> = arrayOfNulls(Directions.DIRECTIONS.size)
|
||||||
override val transparentFaces: BooleanArray = BooleanArray(Directions.DIRECTIONS.size)
|
override val transparentFaces: BooleanArray = BooleanArray(Directions.DIRECTIONS.size)
|
||||||
private lateinit var stillTexture: Texture
|
private lateinit var stillTexture: Texture
|
||||||
private lateinit var flowingTexture: Texture
|
private lateinit var flowingTexture: Texture
|
||||||
|
@ -75,4 +75,7 @@ object VecUtil {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun JsonArray.readUV(): Pair<Vec2, Vec2> {
|
||||||
|
return Pair(Vec2(this[0].asFloat, this[3].asFloat), Vec2(this[2].asFloat, this[1].asFloat))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user