more rotation tests

This commit is contained in:
Bixilon 2023-03-24 13:35:37 +01:00
parent 45c5b6b9c9
commit 93218f5827
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
9 changed files with 134 additions and 17 deletions

View File

@ -43,11 +43,11 @@ object BakedModelTestUtil {
return rendering.context.textureManager
}
fun createFaces(from: Vec3 = Vec3(0.0f), to: Vec3 = Vec3(1.0f), texture: String = "#test"): Map<Directions, ModelFace> {
fun createFaces(from: Vec3 = Vec3(0.0f), to: Vec3 = Vec3(1.0f), rotation: Int = 0, texture: String = "#test"): Map<Directions, ModelFace> {
val map: MutableMap<Directions, ModelFace> = mutableMapOf()
for (direction in Directions) {
map[direction] = ModelFace(texture, fallbackUV(direction, from, to), cull = direction, rotation = 0)
map[direction] = ModelFace(texture, fallbackUV(direction, from, to), cull = direction, rotation = rotation)
}
return map

View File

@ -0,0 +1,65 @@
/*
* 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.baked
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModelTestUtil.assertFace
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModelTestUtil.createFaces
import de.bixilon.minosoft.gui.rendering.models.baked.BakedModelTestUtil.createTextureManager
import de.bixilon.minosoft.gui.rendering.models.block.BlockModel
import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement
import de.bixilon.minosoft.gui.rendering.models.block.state.apply.SingleBlockStateApply
import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakingUtil.positions
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import org.testng.annotations.Test
@Test(groups = ["models"])
class FaceRotationTest {
fun rotation1() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces(rotation = 1))), textures = mapOf("test" to minecraft("block/test").texture())))
val baked = model.bake(createTextureManager("block/test"))!!
// we can use positions() here, because it is not rotated and already unit tested
baked.assertFace(Directions.DOWN, positions(Directions.DOWN, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.5f)
baked.assertFace(Directions.UP, positions(Directions.UP, from, to), floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f), 1.0f)
baked.assertFace(Directions.NORTH, positions(Directions.NORTH, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.8f)
baked.assertFace(Directions.SOUTH, positions(Directions.SOUTH, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.8f)
baked.assertFace(Directions.WEST, positions(Directions.WEST, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.6f)
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.6f)
}
fun rotation3() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces(rotation = 3))), textures = mapOf("test" to minecraft("block/test").texture())))
val baked = model.bake(createTextureManager("block/test"))!!
// we can use positions() here, because it is not rotated and already unit tested
baked.assertFace(Directions.DOWN, positions(Directions.DOWN, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 0.5f)
baked.assertFace(Directions.UP, positions(Directions.UP, from, to), floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f), 1.0f)
baked.assertFace(Directions.NORTH, positions(Directions.NORTH, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.8f)
baked.assertFace(Directions.SOUTH, positions(Directions.SOUTH, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.8f)
baked.assertFace(Directions.WEST, positions(Directions.WEST, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.6f)
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.6f)
}
}

View File

@ -63,6 +63,23 @@ class FullCubeBakeTest {
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.6f)
}
fun fullCubeY180() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces())), textures = mapOf("test" to minecraft("block/test").texture())), y = 2)
val baked = model.bake(createTextureManager("block/test"))!!
// rotating 180° -> only top/bottom texture rotated, rest is the same
baked.assertFace(Directions.DOWN, positions(Directions.DOWN, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.5f)
baked.assertFace(Directions.UP, positions(Directions.UP, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 1.0f)
baked.assertFace(Directions.NORTH, positions(Directions.NORTH, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.8f)
baked.assertFace(Directions.SOUTH, positions(Directions.SOUTH, from, to), floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f), 0.8f)
baked.assertFace(Directions.WEST, positions(Directions.WEST, from, to), floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f), 0.6f)
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 0.6f)
}
fun fullCubeX90() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
@ -79,6 +96,22 @@ class FullCubeBakeTest {
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.6f)
}
fun fullCubeX180() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces())), textures = mapOf("test" to minecraft("block/test").texture())), x = 2)
val baked = model.bake(createTextureManager("block/test"))!!
baked.assertFace(Directions.DOWN, positions(Directions.DOWN, from, to), floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f), 0.5f)
baked.assertFace(Directions.UP, positions(Directions.UP, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 1.0f)
baked.assertFace(Directions.NORTH, positions(Directions.NORTH, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 0.8f)
baked.assertFace(Directions.SOUTH, positions(Directions.SOUTH, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.8f)
baked.assertFace(Directions.WEST, positions(Directions.WEST, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.6f)
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 0.6f)
}
fun fullCubeX90Y90() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
@ -94,4 +127,20 @@ class FullCubeBakeTest {
baked.assertFace(Directions.WEST, positions(Directions.WEST, from, to), floatArrayOf(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f), 0.6f)
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 0.6f)
}
fun fullCubeX180Y180() {
val from = Vec3(0.0f)
val to = Vec3(1.0f)
val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces())), textures = mapOf("test" to minecraft("block/test").texture())), x = 2, y = 2)
val baked = model.bake(createTextureManager("block/test"))!!
baked.assertFace(Directions.DOWN, positions(Directions.DOWN, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.5f)
baked.assertFace(Directions.UP, positions(Directions.UP, from, to), floatArrayOf(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f), 1.0f)
baked.assertFace(Directions.NORTH, positions(Directions.NORTH, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 0.8f)
baked.assertFace(Directions.SOUTH, positions(Directions.SOUTH, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.8f)
baked.assertFace(Directions.WEST, positions(Directions.WEST, from, to), floatArrayOf(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f), 0.6f)
baked.assertFace(Directions.EAST, positions(Directions.EAST, from, to), floatArrayOf(0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f), 0.6f)
}
}

View File

@ -27,7 +27,7 @@ object DirectionUtil {
var count = count % Directions.SIZE_SIDES
if (count < 0) count += Directions.SIZE_SIDES
return Directions.HORIZONTAL[ArrayUtil.modifyArrayIndex((horizontalId - Directions.SIDE_OFFSET) + count, Directions.SIZE_SIDES)]
return Directions.HORIZONTAL[ArrayUtil.modifyArrayIndex(horizontal + count, Directions.SIZE_SIDES)]
}
fun rotateMatrix(direction: Directions): Mat4 {

View File

@ -30,7 +30,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import kotlin.reflect.jvm.javaField
enum class Directions(
@Deprecated("remove") val horizontalId: Int,
@Deprecated("remove") val campfireId: Int,
val vector: Vec3i,
val horizontal: Int,
) {

View File

@ -73,7 +73,7 @@ class CampfireBlockEntity(connection: PlayConnection) : BlockEntity(connection)
}
}
val facing = blockState.getFacing().horizontalId
val facing = blockState.getFacing().campfireId
for ((index, item) in items.withIndex()) {
item ?: continue

View File

@ -30,10 +30,10 @@ data class FaceUV(
// @formatter:off
Directions.DOWN,
Directions.SOUTH,
Directions.WEST -> floatArrayOf(start.x, start.y, start.x, end.y, end.x, end.y, end.x, start.y)
Directions.UP -> floatArrayOf(start.x, end.y, end.x, end.y, end.x, start.y, start.x, start.y)
Directions.WEST -> floatArrayOf(start.x, start.y, start.x, end.y, end.x, end.y, end.x, start.y )
Directions.UP -> floatArrayOf(start.x, end.y, end.x, end.y, end.x, start.y, start.x, start.y )
Directions.NORTH,
Directions.EAST -> floatArrayOf(end.x, start.y, start.x, start.y, start.x, end.y, end.x, end.y)
Directions.EAST -> floatArrayOf(end.x, start.y, start.x, start.y, start.x, end.y, end.x, end.y )
// @formatter:on
}
}

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.models.block.BlockModel
import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement.Companion.BLOCK_SIZE
import de.bixilon.minosoft.gui.rendering.models.block.state.apply.SingleBlockStateApply.Companion.rotation
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
import de.bixilon.minosoft.gui.rendering.tint.TintManager
@ -69,7 +70,7 @@ data class ModelFace(
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 rotation = data["rotation"]?.toInt()?.rotation() ?: 0
val cull = data["cullface"]?.toString()?.let { if (it == "none") null else Directions[it] }
val tintIndex = data["tintindex"]?.toInt() ?: TintManager.DEFAULT_TINT_INDEX

View File

@ -73,17 +73,19 @@ data class SingleBlockStateApply(
companion object {
const val ROTATION_STEP = 90
fun Int.rotation(): Int {
var rotation = this
if (rotation % ROTATION_STEP != 0) throw IllegalArgumentException("Invalid rotation: $rotation")
rotation /= ROTATION_STEP
return rotation and 0x03
}
fun deserialize(model: BlockModel, data: JsonObject): SingleBlockStateApply {
val uvLock = data["uvlock"]?.toBoolean() ?: false
val weight = data["weight"]?.toInt() ?: 1
var x = data["x"]?.toInt() ?: 0
var y = data["y"]?.toInt() ?: 0
if (x % ROTATION_STEP != 0) throw IllegalArgumentException("Invalid x rotation: $x")
x /= ROTATION_STEP
if (y % ROTATION_STEP != 0) throw IllegalArgumentException("Invalid x rotation: $y")
y /= ROTATION_STEP
val x = data["x"]?.toInt()?.rotation() ?: 0
val y = data["y"]?.toInt()?.rotation() ?: 0
return SingleBlockStateApply(model, uvLock, weight, x, y)
}