mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 09:26:11 -04:00
skeletal: automatic cube uv mapping
This commit is contained in:
parent
b364512075
commit
ee4720155d
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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)))
|
||||
}
|
||||
}
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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<Directions, SkeletalFace>,
|
||||
val children: Map<String, SkeletalElement> = emptyMap(),
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user