diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtilTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtilTest.kt
new file mode 100644
index 000000000..3e9895b2f
--- /dev/null
+++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtilTest.kt
@@ -0,0 +1,51 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020-2023 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.gui.rendering.models.util
+
+import de.bixilon.kotlinglm.vec2.Vec2i
+import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.minosoft.data.direction.Directions
+import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV
+import org.testng.Assert.assertEquals
+import org.testng.annotations.Test
+
+@Test(groups = ["rendering", "models"])
+class CuboidUtilTest {
+
+ fun `simple uv`() {
+ val from = Vec3(-7, 0, -7)
+ val to = Vec3(7, 10, 7)
+ val offset = Vec2i(0, 19)
+
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.DOWN), FaceUV(floatArrayOf(14f, 19f, 28f, 33f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.UP), FaceUV(floatArrayOf(28f, 33f, 42f, 19f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.NORTH), FaceUV(floatArrayOf(42f, 33f, 56f, 43f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.SOUTH), FaceUV(floatArrayOf(14f, 33f, 28f, 43f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.WEST), FaceUV(floatArrayOf(28f, 33f, 42f, 43f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.EAST), FaceUV(floatArrayOf(0f, 33f, 14f, 43f)))
+ }
+
+ fun `not same size uv`() {
+ val from = Vec3(-1, 0, 0)
+ val to = Vec3(1, 4, 1)
+ val offset = Vec2i(0, 0)
+
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.DOWN), FaceUV(floatArrayOf(1f, 0f, 3f, 1f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.UP), FaceUV(floatArrayOf(3f, 1f, 5f, 0f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.NORTH), FaceUV(floatArrayOf(4f, 1f, 6f, 5f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.SOUTH), FaceUV(floatArrayOf(1f, 1f, 3f, 5f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.WEST), FaceUV(floatArrayOf(3f, 1f, 4f, 5f)))
+ assertEquals(CuboidUtil.cubeUV(offset, from, to, Directions.EAST), FaceUV(floatArrayOf(0f, 1f, 1f, 5f)))
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtil.kt
index 6a3d8e12d..6d83b94a9 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtil.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/util/CuboidUtil.kt
@@ -13,9 +13,14 @@
package de.bixilon.minosoft.gui.rendering.models.util
+import de.bixilon.kotlinglm.vec2.Vec2
+import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kotlinglm.vec3.Vec3
+import de.bixilon.kotlinglm.vec3.Vec3i
+import de.bixilon.minosoft.data.Axes
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.gui.rendering.models.block.element.FaceVertexData
+import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV
object CuboidUtil {
@@ -31,4 +36,50 @@ object CuboidUtil {
// @formatter:on
}
}
+
+ fun cubeUV(offset: Vec2i, from: Vec3, to: Vec3, direction: Directions): FaceUV {
+ val cube = Vec3i(to - from)
+
+ val uv = Vec2i(offset)
+ val size = when (direction.axis) {
+ Axes.Y -> Vec2i(cube.x, cube.z)
+ Axes.Z -> Vec2i(cube.x, cube.y)
+ Axes.X -> Vec2i(cube.z, cube.y)
+ }
+
+ when (direction) {
+ Directions.DOWN -> {
+ uv.x += cube.z
+ }
+
+ Directions.UP -> {
+ uv.x += cube.z + cube.x
+ // flip y coordinate
+ uv.y += cube.z
+ size.y = -cube.z
+ }
+
+ Directions.NORTH -> {
+ uv.x += cube.z + cube.x + cube.z
+ uv.y += cube.z
+ }
+
+ Directions.SOUTH -> {
+ uv.x += cube.z
+ uv.y += cube.z
+ }
+
+ Directions.WEST -> {
+ uv.x += cube.z + cube.x
+ uv.y += cube.z
+ }
+
+ Directions.EAST -> {
+ uv.y += cube.z
+ }
+ }
+
+
+ return FaceUV(Vec2(uv.x, uv.y), Vec2(uv.x + size.x, uv.y + size.y))
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt
index b3028d04b..f38082858 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalElement.kt
@@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.rendering.skeletal.model.elements
+import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
@@ -30,6 +31,7 @@ data class SkeletalElement(
val inflate: Float = 0.0f,
val enabled: Boolean = true,
val texture: ResourceLocation? = null,
+ val uv: Vec2i? = null,
val transform: String? = null,
val faces: Map,
val children: Map = emptyMap(),
diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt
index f7f9b1160..697139418 100644
--- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt
+++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/elements/SkeletalFace.kt
@@ -26,10 +26,11 @@ import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalBakeContext
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
data class SkeletalFace(
- val uv: FaceUV,
+ val uv: FaceUV? = null,
val texture: ResourceLocation? = null,
) {
+
fun bake(context: SkeletalBakeContext, direction: Directions, element: SkeletalElement, transform: Int) {
val from = context.offset + (element.from - context.inflate) / BLOCK_SIZE
val to = context.offset + (element.to + context.inflate) / BLOCK_SIZE
@@ -38,7 +39,9 @@ data class SkeletalFace(
val texture = context.textures[texture ?: context.texture ?: throw IllegalStateException("Element has no texture set!")] ?: throw IllegalStateException("Texture not found!")
// TODO: why flip on x?
- val uv = FaceUV(
+ val uv = this.uv ?: CuboidUtil.cubeUV(element.uv!!, element.from, element.to, direction)
+
+ val uvData = FaceUV(
texture.texture.transformUV(Vec2(uv.end.x, uv.start.y) / texture.properties.resolution),
texture.texture.transformUV(Vec2(uv.start.x, uv.end.y) / texture.properties.resolution),
).toArray(direction, 0)
@@ -57,6 +60,6 @@ data class SkeletalFace(
}
}
- context.consumer.addQuad(positions, uv, transform, texture.texture)
+ context.consumer.addQuad(positions, uvData, transform, texture.texture)
}
}