proper fallback uv

This commit is contained in:
Bixilon 2023-03-23 16:25:07 +01:00
parent 3604e81178
commit 96ba612fc9
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
4 changed files with 20 additions and 13 deletions

View File

@ -93,7 +93,7 @@ class BlockModelTest {
val model = loadModel("""{"textures":{"a":"a:b"},"elements":[{"from":[5,3,1],"to":[15,13,11],"faces":{"down": {"texture":"#a"},"up":{"texture":"#a"},"north":{"texture":"#a"},"south":{"texture":"#a"},"west": {"texture":"#a"},"east": {"texture":"#a"}}}]}""")
val faces = model.elements?.firstOrNull()?.faces ?: throw NullPointerException("no models?")
assertEquals(faces[Directions.DOWN]?.uv, FaceUV(5, 5, 14, 14))
assertEquals(faces[Directions.DOWN]?.uv, FaceUV(5, 5, 15, 15))
assertEquals(faces[Directions.UP]?.uv, FaceUV(5, 1, 15, 11))
assertEquals(faces[Directions.NORTH]?.uv, FaceUV(1, 3, 11, 13))
assertEquals(faces[Directions.SOUTH]?.uv, FaceUV(5, 3, 15, 13))

View File

@ -40,7 +40,7 @@ data class ModelElement(
val shade = data["shade"]?.toBoolean() ?: true
val rotation = data["rotation"]?.toJsonObject()?.let { ElementRotation.deserialize(it) }
val faces = ModelFace.deserialize(data["faces"].unsafeCast()) ?: return null
val faces = ModelFace.deserialize(from, to, data["faces"].unsafeCast()) ?: return null
return ModelElement(from, to, faces, shade, rotation)

View File

@ -20,6 +20,6 @@ data class FaceUV(
val start: Vec2,
val end: Vec2,
) {
constructor(u1: Float, v1: Float, u2: Float, v2: Float) : this(Vec2(u1 / BLOCK_SIZE, v1 / BLOCK_SIZE), Vec2(u2 / BLOCK_SIZE, v2 / BLOCK_SIZE))
constructor(u1: Int, v1: Int, u2: Int, v2: Int) : this(u1.toFloat(), v1.toFloat(), u2.toFloat(), v2.toFloat())
constructor(u1: Float, v1: Float, u2: Float, v2: Float) : this(Vec2(u1, v1), Vec2(u2, v2))
constructor(u1: Int, v1: Int, u2: Int, v2: Int) : this(u1 / BLOCK_SIZE, v1 / BLOCK_SIZE, u2 / BLOCK_SIZE, v2 / BLOCK_SIZE)
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.models.block.element.face
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kutil.json.JsonObject
import de.bixilon.kutil.primitive.IntUtil.toInt
import de.bixilon.minosoft.data.direction.Directions
@ -32,15 +33,21 @@ data class ModelFace(
companion object {
fun deserialize(data: JsonObject): ModelFace {
fun fallbackUV(direction: Directions, from: Vec3, to: Vec3): FaceUV {
return when (direction) {
Directions.DOWN -> FaceUV(from.x, 1.0f - to.z, to.x, 1.0f - from.z)
Directions.UP -> FaceUV(from.x, from.z, to.x, to.z)
Directions.NORTH -> FaceUV(1.0f - to.x, 1.0f - to.y, 1.0f - from.x, 1.0f - from.y)
Directions.SOUTH -> FaceUV(from.x, 1.0f - to.y, to.x, 1.0f - from.y)
Directions.WEST -> FaceUV(from.z, 1.0f - to.y, to.z, 1.0f - from.y)
Directions.EAST -> FaceUV(1.0f - to.z, 1.0f - to.y, 1.0f - from.z, 1.0f - from.y)
}
}
fun deserialize(direction: Directions, from: Vec3, to: Vec3, data: JsonObject): ModelFace {
val texture = data["texture"].toString()
val rawUV = data["uv"]?.listCast<Number>()
// TODO: that is wrong, fallback is element start/end
val uv = FaceUV(
start = rawUV?.let { Vec2(rawUV[0], rawUV[1]) / BLOCK_SIZE } ?: Vec2(0.0f),
end = rawUV?.let { Vec2(rawUV[0], rawUV[1]) / BLOCK_SIZE } ?: Vec2(1.0f),
)
val uv = data["uv"]?.listCast<Number>()?.let { FaceUV(start = Vec2(it[0], it[1]) / BLOCK_SIZE, end = Vec2(it[2], it[3]) / BLOCK_SIZE) } ?: fallbackUV(direction, from, to)
val rotation = data["rotation"]?.toInt() ?: 0
val cullface = data["cullface"]?.toString()?.let { if (it == "none") null else Directions[it] }
@ -49,12 +56,12 @@ data class ModelFace(
return ModelFace(texture, uv, rotation, cullface, tintIndex)
}
fun deserialize(data: Map<String, JsonObject>): Map<Directions, ModelFace>? {
fun deserialize(from: Vec3, to: Vec3, data: Map<String, JsonObject>): Map<Directions, ModelFace>? {
val map: MutableMap<Directions, ModelFace> = EnumMap(Directions::class.java)
for ((key, value) in data) {
val direction = Directions[key]
val face = deserialize(value)
val face = deserialize(direction, from, to, value)
map[direction] = face
}