From 96ba612fc91ddef7cfb80152cf782a501e9b475a Mon Sep 17 00:00:00 2001 From: Bixilon Date: Thu, 23 Mar 2023 16:25:07 +0100 Subject: [PATCH] proper fallback uv --- .../gui/rendering/models/BlockModelTest.kt | 2 +- .../models/block/element/ModelElement.kt | 2 +- .../models/block/element/face/FaceUV.kt | 4 +-- .../models/block/element/face/ModelFace.kt | 25 ++++++++++++------- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/BlockModelTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/BlockModelTest.kt index 2392bd02a..66e5a05f9 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/BlockModelTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/BlockModelTest.kt @@ -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)) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/ModelElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/ModelElement.kt index 4bedd0742..30002837f 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/ModelElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/ModelElement.kt @@ -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) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/FaceUV.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/FaceUV.kt index b88fdabc8..1396b48e1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/FaceUV.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/FaceUV.kt @@ -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) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/ModelFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/ModelFace.kt index eb4daa3af..eb1d32e9b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/ModelFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/element/face/ModelFace.kt @@ -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() - // 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()?.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): Map? { + fun deserialize(from: Vec3, to: Vec3, data: Map): Map? { val map: MutableMap = 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 }