From 3fc0cf6751c64dd7841ecd5949d4417b0369dd52 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Fri, 24 Mar 2023 01:38:39 +0100 Subject: [PATCH] baking util tests, model rotation tests --- build.gradle.kts | 3 +- doc/rendering/Meshes.md | 4 + .../rendering/models/baked/BakedModelTest.kt | 60 ------------ .../models/baked/BakedModelTestUtil.kt | 68 +++++++++++++ .../rendering/models/baked/CuboidBakeTest.kt | 53 ++++++++++ .../models/baked/FullCubeBakeTest.kt | 97 +++++++++++++++++++ .../models/block/element/face/ModelFace.kt | 20 ++++ .../block/state/apply/BlockStateApply.kt | 2 +- .../state/apply/SingleBlockStateApply.kt | 23 ++++- .../models/block/state/baked/BakedFace.kt | 2 +- .../models/block/state/baked/BakedModel.kt | 5 +- .../models/block/state/baked/BakingUtil.kt | 34 +++++++ .../models/block/state/baked/SideSize.kt | 27 ++++++ .../block/state/baked/BakingUtilTest.kt | 73 ++++++++++++++ 14 files changed, 404 insertions(+), 67 deletions(-) create mode 100644 doc/rendering/Meshes.md delete mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTest.kt create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/CuboidBakeTest.kt create mode 100644 src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/FullCubeBakeTest.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtil.kt create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SideSize.kt create mode 100644 src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtilTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index cef1e9a02..21c096c80 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -220,8 +220,7 @@ testing { options { val options = this as TestNGOptions options.preserveOrder = true - options.includeGroups("models") - // options.excludeGroups("pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "world_renderer", "rendering") + options.excludeGroups("version", "fluid", "world", "raycasting", "pixlyzer", "item", "block", "physics", "light", "packet", "container", "item_stack", "signature", "private_key", "interaction", "item_digging", "world_renderer", "rendering") } } } diff --git a/doc/rendering/Meshes.md b/doc/rendering/Meshes.md new file mode 100644 index 000000000..78226263e --- /dev/null +++ b/doc/rendering/Meshes.md @@ -0,0 +1,4 @@ +# Mesh + +OpenGL generally draws **counter-clockwise**. Minosoft internally uses **clockwise** rendering and maps then to quads or +triangles. diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTest.kt deleted file mode 100644 index 7cf37da4f..000000000 --- a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTest.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.baked - -import de.bixilon.kotlinglm.vec2.Vec2 -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.block.BlockModel -import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement -import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV -import de.bixilon.minosoft.gui.rendering.models.block.element.face.ModelFace -import de.bixilon.minosoft.gui.rendering.models.block.state.apply.SingleBlockStateApply -import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedModel -import de.bixilon.minosoft.gui.rendering.system.dummy.texture.DummyTextureManager -import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture -import org.testng.annotations.Test - -@Test(groups = ["models"]) -class BakedModelTest { - - private fun createTextureManager(vararg names: String): DummyTextureManager = TODO() - - private fun createFaces(texture: String): Map { - val map: MutableMap = mutableMapOf() - - for (direction in Directions) { - map[direction] = ModelFace(texture, FaceUV(Vec2(0), Vec2(1)), cull = direction, rotation = 0) - } - - return map - } - - private fun BakedModel.assertFace(directions: Directions, start: Vec3, end: Vec3, uvStart: Vec2, uvEnd: Vec2, shade: Float, texture: String? = null): Unit = TODO() - - fun simpleBlock() { - val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(Vec3(0), Vec3(1), faces = createFaces("#test"))), textures = mapOf("test" to minecraft("block/test").texture()))) - - val baked = model.bake(createTextureManager("block/test")) - - - baked.assertFace(Directions.UP, Vec3(0, 1, 0), Vec3(1, 1, 1), Vec2(0, 0), Vec2(1, 1), 1.0f) - baked.assertFace(Directions.DOWN, Vec3(0, 0, 0), Vec3(1, 0, 1), Vec2(0, 1), Vec2(1, 0), 0.5f) - baked.assertFace(Directions.NORTH, Vec3(1, 0, 0), Vec3(0, 1, 0), Vec2(0, 1), Vec2(1, 0), 0.8f) - baked.assertFace(Directions.SOUTH, Vec3(0, 0, 0), Vec3(1, 1, 0), Vec2(0, 1), Vec2(1, 0), 0.8f) - baked.assertFace(Directions.WEST, Vec3(0, 0, 0), Vec3(0, 1, 1), Vec2(0, 1), Vec2(1, 0), 0.5f) - baked.assertFace(Directions.EAST, Vec3(1, 0, 1), Vec3(1, 1, 0), Vec2(0, 1), Vec2(1, 0), 0.5f) - } -} diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt new file mode 100644 index 000000000..6096ca4c9 --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/BakedModelTestUtil.kt @@ -0,0 +1,68 @@ +/* + * 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.baked + +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.kutil.reflection.ReflectionUtil.forceSet +import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.assets.MemoryAssetsManager +import de.bixilon.minosoft.data.direction.Directions +import de.bixilon.minosoft.gui.rendering.Rendering +import de.bixilon.minosoft.gui.rendering.models.block.element.face.ModelFace +import de.bixilon.minosoft.gui.rendering.models.block.element.face.ModelFace.Companion.fallbackUV +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedModel +import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager +import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture +import de.bixilon.minosoft.protocol.network.connection.play.ConnectionTestUtil +import de.bixilon.minosoft.util.KUtil.toResourceLocation +import org.testng.Assert + +object BakedModelTestUtil { + private val texture = Minosoft::class.java.getResourceAsStream("/assets/minosoft/textures/debug.png")!!.readAllBytes() + + fun createTextureManager(vararg names: String): TextureManager { + val connection = ConnectionTestUtil.createConnection() + val assets = MemoryAssetsManager() + for (name in names) { + assets.push(name.toResourceLocation().texture(), texture) + } + connection::assetsManager.forceSet(assets) + val rendering = Rendering(connection) + + return rendering.context.textureManager + } + + fun createFaces(from: Vec3 = Vec3(0.0f), to: Vec3 = Vec3(1.0f), texture: String = "#test"): Map { + val map: MutableMap = mutableMapOf() + + for (direction in Directions) { + map[direction] = ModelFace(texture, fallbackUV(direction, from, to), cull = direction, rotation = 0) + } + + return map + } + + fun BakedModel.assertFace(direction: Directions, positions: FloatArray, uv: FloatArray, shade: Float, texture: String? = null) { + val faces = this.face[direction.ordinal] + if (faces.size != 1) throw IllegalArgumentException("Model has more/less than once face!") + val face = faces.first() + + Assert.assertEquals(face.positions, positions) + Assert.assertEquals(face.uv, uv) + Assert.assertEquals(face.shade, shade) + if (texture != null) { + Assert.assertEquals(face.texture.resourceLocation, texture.toResourceLocation().texture()) + } + } +} diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/CuboidBakeTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/CuboidBakeTest.kt new file mode 100644 index 000000000..c9964af16 --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/CuboidBakeTest.kt @@ -0,0 +1,53 @@ +/* + * 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.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.element.ModelElement.Companion.BLOCK_SIZE +import de.bixilon.minosoft.gui.rendering.models.block.state.apply.SingleBlockStateApply +import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture +import org.testng.annotations.Test + +@Test(groups = ["models"]) +class CuboidBakeTest { + + private fun block(vararg elements: Int): FloatArray { + val result = FloatArray(elements.size) + + for ((index, value) in elements.withIndex()) { + result[index] = value / BLOCK_SIZE + } + + return result + } + + fun cuboidY90() { + val from = Vec3(1, 2, 3) / BLOCK_SIZE + val to = Vec3(16, 15, 14) / BLOCK_SIZE + val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces(from, to))), textures = mapOf("test" to minecraft("block/test").texture())), y = 90) + + val baked = model.bake(createTextureManager("block/test"))!! + + + baked.assertFace(Directions.DOWN, block(2, 2, 1, 2, 2, 16, 13, 2, 16, 13, 2, 1), block(1, 14, 16, 14, 16, 3, 1, 3), 0.5f) + baked.assertFace(Directions.UP, block(2, 15, 1, 13, 15, 1, 13, 15, 16, 2, 15, 16), block(1, 2, 1, 13, 16, 13, 16, 2), 1.0f) + } +} diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/FullCubeBakeTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/FullCubeBakeTest.kt new file mode 100644 index 000000000..c9928eab9 --- /dev/null +++ b/src/integration-test/kotlin/de/bixilon/minosoft/gui/rendering/models/baked/FullCubeBakeTest.kt @@ -0,0 +1,97 @@ +/* + * 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.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 FullCubeBakeTest { + + fun fullCube() { + 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()))) + + 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, 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(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 fullCubeY90() { + 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 = 90) + + val baked = model.bake(createTextureManager("block/test"))!! + + + // rotating 90° -> only top/bottom texture rotated, rest is the same + 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, 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) + val model = SingleBlockStateApply(BlockModel(elements = listOf(ModelElement(from, to, faces = createFaces())), textures = mapOf("test" to minecraft("block/test").texture())), x = 90) + + 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(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(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, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.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 fullCubeX90Y90() { + 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 = 90, y = 90) + + val baked = model.bake(createTextureManager("block/test"))!! + + + 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(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.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(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) + } +} 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 5c8dc44cb..febc2baa7 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 @@ -18,8 +18,16 @@ 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 +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.system.base.texture.TextureManager +import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture import de.bixilon.minosoft.gui.rendering.tint.TintManager +import de.bixilon.minosoft.util.KUtil.toResourceLocation +import de.bixilon.minosoft.util.logging.Log +import de.bixilon.minosoft.util.logging.LogLevels +import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast import java.util.* @@ -31,6 +39,18 @@ data class ModelFace( val tintIndex: Int = -1, ) { + fun createTexture(model: BlockModel, manager: TextureManager): AbstractTexture { + if (!this.texture.startsWith("#")) { + return manager.staticTextures.createTexture(texture.toResourceLocation()) + } + val name = model.textures?.get(this.texture.substring(1)) + if (name == null || name !is ResourceLocation) { + Log.log(LogMessageType.VERSION_LOADING, LogLevels.WARN) { "Can not find mapped texture ${this.texture}, please check for broken resource packs!" } + return manager.debugTexture + } + return manager.staticTextures.createTexture(name) + } + companion object { fun fallbackUV(direction: Directions, from: Vec3, to: Vec3): FaceUV { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/BlockStateApply.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/BlockStateApply.kt index e1576340f..50d3305ec 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/BlockStateApply.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/BlockStateApply.kt @@ -21,7 +21,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager interface BlockStateApply { - fun bake(textures: TextureManager): BakedModel + fun bake(textures: TextureManager): BakedModel? companion object { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt index 7473b5f8a..4f1e180fc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/apply/SingleBlockStateApply.kt @@ -16,11 +16,16 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.apply import de.bixilon.kutil.json.JsonObject import de.bixilon.kutil.primitive.BooleanUtil.toBoolean import de.bixilon.kutil.primitive.IntUtil.toInt +import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.gui.rendering.models.block.BlockModel +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedFace import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakedModel +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.BakingUtil.positions +import de.bixilon.minosoft.gui.rendering.models.block.state.baked.SideSize import de.bixilon.minosoft.gui.rendering.models.loader.BlockLoader import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager import de.bixilon.minosoft.util.KUtil.toResourceLocation +import java.util.* data class SingleBlockStateApply( val model: BlockModel, @@ -30,8 +35,22 @@ data class SingleBlockStateApply( val y: Int = 0, ) : BlockStateApply { - override fun bake(textures: TextureManager): BakedModel { - TODO("Not yet implemented") + + override fun bake(textures: TextureManager): BakedModel? { + if (model.elements == null) return null + + val bakedFaces: MutableMap> = EnumMap(Directions::class.java) // TODO: use array + val sizes: MutableMap> = EnumMap(Directions::class.java) + + for (element in model.elements) { + for ((direction, face) in element.faces) { + val texture = face.createTexture(model, textures) + + + val positions = positions(direction, element.from, element.to) + } + } + TODO() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt index e30cecc75..093a858a1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedFace.kt @@ -21,6 +21,6 @@ class BakedFace( val uv: FloatArray, val shade: Float, val tintIndex: Int, - val cullface: Directions?, + val cull: Directions?, val texture: AbstractTexture, ) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt index 40fe1cf82..880dccacd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakedModel.kt @@ -13,4 +13,7 @@ package de.bixilon.minosoft.gui.rendering.models.block.state.baked -class BakedModel +class BakedModel( + val face: Array>, + val sizes: Array, +) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtil.kt new file mode 100644 index 000000000..5a433ff58 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtil.kt @@ -0,0 +1,34 @@ +/* + * 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.block.state.baked + +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.minosoft.data.direction.Directions + +object BakingUtil { + + fun positions(direction: Directions, from: Vec3, to: Vec3): FloatArray { + return when (direction) { + // @formatter:off + Directions.DOWN -> floatArrayOf(from.x, from.y, from.z, /**/ to.x, from.y, from.z, /**/ to.x, from.y, to.z, /**/ from.x, from.y, to.z ) + Directions.UP -> floatArrayOf(from.x, to.y, from.z, /**/ from.x, to.y, to.z, /**/ to.x, to.y, to.z, /**/ to.x, to.y, from.z ) + Directions.NORTH -> floatArrayOf(from.x, from.y, from.z, /**/ to.x, from.y, from.z, /**/ to.x, to.y, from.z, /**/ from.x, to.y, from.z ) + Directions.SOUTH -> floatArrayOf(from.x, from.y, to.z, /**/ from.x, to.y, to.z, /**/ to.x, to.y, to.z, /**/ to.x, from.y, to.z ) + Directions.WEST -> floatArrayOf(from.x, from.y, from.z, /**/ from.x, to.y, from.z, /**/ from.x, to.y, to.z, /**/ from.x, from.y, to.z ) + Directions.EAST -> floatArrayOf(to.x, from.y, from.z, /**/ to.x, from.y, to.z, /**/ to.x, to.y, to.z, /**/ to.x, to.y, from.z ) + // @formatter:on + } + } + +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SideSize.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SideSize.kt new file mode 100644 index 000000000..72e2e2d5c --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/SideSize.kt @@ -0,0 +1,27 @@ +/* + * 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.block.state.baked + +import de.bixilon.kotlinglm.vec2.Vec2 + +class SideSize( + val sizes: Array, +) { + + + class FaceSize( + val start: Vec2, + val end: Vec2, + ) +} diff --git a/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtilTest.kt b/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtilTest.kt new file mode 100644 index 000000000..1a2167b54 --- /dev/null +++ b/src/test/java/de/bixilon/minosoft/gui/rendering/models/block/state/baked/BakingUtilTest.kt @@ -0,0 +1,73 @@ +/* + * 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.block.state.baked + +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.minosoft.data.direction.Directions +import kotlin.test.Test +import kotlin.test.assertContentEquals + +class BakingUtilTest { + val from = Vec3(1, 2, 3) + val to = Vec3(6, 5, 4) + + + @Test + fun positionsDown() { + assertContentEquals( + BakingUtil.positions(Directions.DOWN, from, to), + floatArrayOf(1.0f, 2.0f, 3.0f, 6.0f, 2.0f, 3.0f, 6.0f, 2.0f, 4.0f, 1.0f, 2.0f, 4.0f) + ) + } + + @Test + fun positionsUp() { + assertContentEquals( + BakingUtil.positions(Directions.UP, from, to), + floatArrayOf(1.0f, 5.0f, 3.0f, 1.0f, 5.0f, 4.0f, 6.0f, 5.0f, 4.0f, 6.0f, 5.0f, 3.0f) + ) + } + + @Test + fun positionsNorth() { + assertContentEquals( + BakingUtil.positions(Directions.NORTH, from, to), + floatArrayOf(1.0f, 2.0f, 3.0f, 6.0f, 2.0f, 3.0f, 6.0f, 5.0f, 3.0f, 1.0f, 5.0f, 3.0f) + ) + } + + @Test + fun positionsSouth() { + assertContentEquals( + BakingUtil.positions(Directions.SOUTH, from, to), + floatArrayOf(1.0f, 2.0f, 4.0f, 1.0f, 5.0f, 4.0f, 6.0f, 5.0f, 4.0f, 6.0f, 2.0f, 4.0f) + ) + } + + @Test + fun positionsWest() { + assertContentEquals( + BakingUtil.positions(Directions.WEST, from, to), + floatArrayOf(1.0f, 2.0f, 3.0f, 1.0f, 5.0f, 3.0f, 1.0f, 5.0f, 4.0f, 1.0f, 2.0f, 4.0f) + ) + } + + @Test + fun positionsEast() { + assertContentEquals( + BakingUtil.positions(Directions.EAST, from, to), + floatArrayOf(6.0f, 2.0f, 3.0f, 6.0f, 2.0f, 4.0f, 6.0f, 5.0f, 4.0f, 6.0f, 5.0f, 3.0f) + ) + } +}