From 07654ca1ab14e47625262725da9da87ac41ec623 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 1 Mar 2021 21:53:34 +0100 Subject: [PATCH] rendering: bugfix and code quality improvements --- .../chunk/models/loading/BlockModelElement.kt | 48 ++----------------- .../chunk/models/loading/BlockModelFace.kt | 31 ++++++++---- .../models/renderable/ElementRenderer.kt | 37 ++++++++++---- .../minosoft/gui/rendering/util/VecUtil.kt | 27 +++++++++++ 4 files changed, 81 insertions(+), 62 deletions(-) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelElement.kt index 383a942ce..e0668ccc4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelElement.kt @@ -18,7 +18,6 @@ import de.bixilon.minosoft.data.Axes import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.gui.rendering.util.VecUtil import glm_.glm -import glm_.vec2.Vec2 import glm_.vec3.Vec3 open class BlockModelElement(data: JsonObject) { @@ -34,7 +33,6 @@ open class BlockModelElement(data: JsonObject) { VecUtil.jsonToVec3(it) } ?: Vec3(BLOCK_RESOLUTION) - positions = arrayOf( Vec3(from), Vec3(to.x, from.y, from.z), @@ -52,12 +50,14 @@ open class BlockModelElement(data: JsonObject) { val rescale = it["rescale"]?.asBoolean ?: false rotatePositions(positions, axis, angle, VecUtil.jsonToVec3(it["origin"].asJsonArray), rescale) } + data["faces"]?.asJsonObject?.let { for ((directionName, json) in it.entrySet()) { val direction = Directions.valueOf(directionName.toUpperCase()) faces[direction] = BlockModelFace(json.asJsonObject, from, to, direction) } } + for ((i, position) in positions.withIndex()) { positions[i] = transformPosition(position) } @@ -76,48 +76,6 @@ open class BlockModelElement(data: JsonObject) { intArrayOf(5, 1, 3, 7) ) - private val POSITION_1 = Vec3(-0.5f, -0.5f, -0.5f) // Vec3(0, 0, 0) - private val POSITION_2 = Vec3(+0.5f, -0.5f, -0.5f) // Vec3(BLOCK_RESOLUTION, 0, 0) - private val POSITION_3 = Vec3(-0.5f, -0.5f, +0.5f) // Vec3(0, 0, BLOCK_RESOLUTION) - private val POSITION_4 = Vec3(+0.5f, -0.5f, +0.5f) // Vec3(BLOCK_RESOLUTION, 0, BLOCK_RESOLUTION) - private val POSITION_5 = Vec3(-0.5f, +0.5f, -0.5f) // Vec3(0, BLOCK_RESOLUTION, 0) - private val POSITION_6 = Vec3(+0.5f, +0.5f, +0.5f) // Vec3(BLOCK_RESOLUTION, BLOCK_RESOLUTION, 0) - private val POSITION_7 = Vec3(-0.5f, +0.5f, +0.5f) // Vec3(0, BLOCK_RESOLUTION, BLOCK_RESOLUTION) - private val POSITION_8 = Vec3(+0.5f, +0.5f, +0.5f) // Vec3(BLOCK_RESOLUTION, BLOCK_RESOLUTION, BLOCK_RESOLUTION) - - val FULL_TEST_POSITIONS = arrayOf( - setOf(POSITION_1, POSITION_2, POSITION_3, POSITION_4), - setOf(POSITION_5, POSITION_6, POSITION_7, POSITION_8), - setOf(POSITION_3, POSITION_4, POSITION_7, POSITION_8), - setOf(POSITION_1, POSITION_2, POSITION_5, POSITION_6), - setOf(POSITION_2, POSITION_4, POSITION_6, POSITION_8), - setOf(POSITION_1, POSITION_3, POSITION_5, POSITION_7) - ) - - fun getRotatedValues(x: Float, y: Float, sin: Double, cos: Double): Vec2 { - return Vec2((x * cos - y * sin).toFloat(), (x * sin + y * cos).toFloat()) - } - - fun rotateVector(original: Vec3, angle: Double, axis: Axes): Vec3 { - if (angle == 0.0) { - return original - } - return when (axis) { - Axes.X -> { - val rotatedValues = getRotatedValues(original.y, original.z, glm.sin(angle), glm.cos(angle)) - Vec3(original.x, rotatedValues) - } - Axes.Y -> { - val rotatedValues = getRotatedValues(original.x, original.z, glm.sin(angle), glm.cos(angle)) - Vec3(rotatedValues.x, original.y, rotatedValues.y) - } - Axes.Z -> { - val rotatedValues = getRotatedValues(original.x, original.y, glm.sin(angle), glm.cos(angle)) - Vec3(rotatedValues.x, rotatedValues.y, original.z) - } - } - } - fun rotatePositions(positions: Array, axis: Axes, angle: Double, origin: Vec3, rescale: Boolean) { // TODO: optimize for 90deg, 180deg, 270deg rotations if (angle == 0.0) { @@ -125,7 +83,7 @@ open class BlockModelElement(data: JsonObject) { } for ((i, position) in positions.withIndex()) { var transformedPosition = position - origin - transformedPosition = rotateVector(transformedPosition, angle, axis) + transformedPosition = VecUtil.rotateVector(transformedPosition, angle, axis) if (rescale) { transformedPosition = transformedPosition / glm.cos(angle) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelFace.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelFace.kt index 173a3f84c..dd53ae57b 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelFace.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockModelFace.kt @@ -15,18 +15,21 @@ package de.bixilon.minosoft.gui.rendering.chunk.models.loading import com.google.gson.JsonObject import de.bixilon.minosoft.data.Directions +import de.bixilon.minosoft.gui.rendering.util.VecUtil import glm_.Java.Companion.glm import glm_.vec2.Vec2 import glm_.vec3.Vec3 import java.util.* -class BlockModelFace(data: JsonObject, from: Vec3, to: Vec3, direction: Directions) { - val textureName: String = data.get("texture").asString.removePrefix("#") +class BlockModelFace { + val textureName: String val cullFace: Directions? - val tint: Boolean = data.has("tintindex") - private var positions: MutableList + val tint: Boolean + private val positions: MutableList - init { + constructor(data: JsonObject, from: Vec3, to: Vec3, direction: Directions) { + tint = data.has("tintindex") + textureName = data.get("texture").asString.removePrefix("#") var textureStart = Vec2(0, 0) var textureEnd = Vec2(16, 16) when (direction) { @@ -64,6 +67,16 @@ class BlockModelFace(data: JsonObject, from: Vec3, to: Vec3, direction: Directio Collections.rotate(positions, rotation) } + constructor(parent: BlockModelFace) { + textureName = parent.textureName + cullFace = parent.cullFace + tint = parent.tint + positions = mutableListOf() + for (position in parent.positions) { + positions.add(Vec2(position)) + } + } + fun getTexturePositionArray(direction: Directions): Array { val template = textureTemplate[direction.ordinal] val result = arrayOfNulls(template.size) @@ -79,9 +92,9 @@ class BlockModelFace(data: JsonObject, from: Vec3, to: Vec3, direction: Directio } val sin = glm.sin(angle) val cos = glm.cos(angle) - for (i in positions.indices) { - val offset = positions[i] - Vec2(0.5f, 0.5f) - positions[i] = BlockModelElement.getRotatedValues(offset.x, offset.y, sin, cos) + Vec2(0.5f, 0.5f) + for ((i, position) in positions.withIndex()) { + val offset = position - TEXTURE_MIDDLE + positions[i] = VecUtil.getRotatedValues(offset.x, offset.y, sin, cos) + TEXTURE_MIDDLE } } @@ -102,5 +115,7 @@ class BlockModelFace(data: JsonObject, from: Vec3, to: Vec3, direction: Directio arrayOf(2, 3, 0, 1), arrayOf(1, 0, 3, 2), ) + + val TEXTURE_MIDDLE = Vec2(0.5, 0.5) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt index 4a1a15259..125af47fe 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/ElementRenderer.kt @@ -26,28 +26,29 @@ import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelElement import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModelFace import de.bixilon.minosoft.gui.rendering.textures.Texture import de.bixilon.minosoft.gui.rendering.textures.TextureArray +import de.bixilon.minosoft.gui.rendering.util.VecUtil import glm_.Java.Companion.glm import glm_.mat4x4.Mat4 import glm_.vec2.Vec2 import glm_.vec3.Vec3 import glm_.vec4.Vec4 -class ElementRenderer(element: BlockModelElement, val rotation: Vec3, uvLock: Boolean, rescale: Boolean) { +class ElementRenderer(parent: BlockModelElement, val rotation: Vec3, uvLock: Boolean, rescale: Boolean) { private val fullFaceDirections: MutableSet = mutableSetOf() - private val faces: MutableMap = element.faces.toMutableMap() - private var positions: Array = element.positions.clone() + private val faces: MutableMap = mutableMapOf() + private var positions: Array = parent.positions.clone() private val directionMapping: HashBiMap = HashBiMap.create() init { rotatePositionsAxes(positions, rotation, rescale) // TODO : uvLock for (direction in Directions.DIRECTIONS) { - if (positions.containsAllVectors(BlockModelElement.FULL_TEST_POSITIONS[direction.ordinal], 0.0001f)) { // TODO: check if texture is transparent ==> && ! texture.isTransparent + if (positions.containsAllVectors(FULL_TEST_POSITIONS[direction.ordinal], 0.0001f)) { // TODO: check if texture is transparent ==> && ! texture.isTransparent fullFaceDirections.add(direction) } directionMapping[direction] = getRotatedDirection(rotation, direction) - for (face in faces.values) { - face.rotate(rotation.y.toDouble()) + parent.faces[direction]?.let { + faces[direction] = BlockModelFace(it) } } } @@ -144,9 +145,9 @@ class ElementRenderer(element: BlockModelElement, val rotation: Vec3, uvLock: Bo if (rotation == EMPTY_VECTOR) { return direction } - var rotatedDirectionVector = BlockModelElement.rotateVector(direction.directionVector, rotation.z.toDouble(), Axes.Z) - rotatedDirectionVector = BlockModelElement.rotateVector(rotatedDirectionVector, rotation.y.toDouble(), Axes.Y) - return Directions.byDirection(BlockModelElement.rotateVector(rotatedDirectionVector, rotation.x.toDouble(), Axes.X)) + var rotatedDirectionVector = VecUtil.rotateVector(direction.directionVector, rotation.x.toDouble(), Axes.X) + rotatedDirectionVector = VecUtil.rotateVector(rotatedDirectionVector, rotation.y.toDouble(), Axes.Y) + return Directions.byDirection(VecUtil.rotateVector(rotatedDirectionVector, rotation.z.toDouble(), Axes.Z)) } fun rotatePositionsAxes(positions: Array, angles: Vec3, rescale: Boolean) { @@ -157,6 +158,24 @@ class ElementRenderer(element: BlockModelElement, val rotation: Vec3, uvLock: Bo BlockModelElement.rotatePositions(positions, Axes.Y, angles.y.toDouble(), EMPTY_VECTOR, rescale) BlockModelElement.rotatePositions(positions, Axes.Z, angles.z.toDouble(), EMPTY_VECTOR, rescale) } + + private val POSITION_1 = Vec3(-0.5f, -0.5f, -0.5f) + private val POSITION_2 = Vec3(+0.5f, -0.5f, -0.5f) + private val POSITION_3 = Vec3(-0.5f, -0.5f, +0.5f) + private val POSITION_4 = Vec3(+0.5f, -0.5f, +0.5f) + private val POSITION_5 = Vec3(-0.5f, +0.5f, -0.5f) + private val POSITION_6 = Vec3(+0.5f, +0.5f, +0.5f) + private val POSITION_7 = Vec3(-0.5f, +0.5f, +0.5f) + private val POSITION_8 = Vec3(+0.5f, +0.5f, +0.5f) + + val FULL_TEST_POSITIONS = arrayOf( + setOf(POSITION_1, POSITION_2, POSITION_3, POSITION_4), + setOf(POSITION_5, POSITION_6, POSITION_7, POSITION_8), + setOf(POSITION_3, POSITION_4, POSITION_7, POSITION_8), + setOf(POSITION_1, POSITION_2, POSITION_5, POSITION_6), + setOf(POSITION_2, POSITION_4, POSITION_6, POSITION_8), + setOf(POSITION_1, POSITION_3, POSITION_5, POSITION_7) + ) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt index 5dced1d15..7cf500fdd 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/util/VecUtil.kt @@ -16,6 +16,9 @@ package de.bixilon.minosoft.gui.rendering.util import com.google.gson.JsonArray import com.google.gson.JsonElement import com.google.gson.JsonObject +import de.bixilon.minosoft.data.Axes +import glm_.glm +import glm_.vec2.Vec2 import glm_.vec3.Vec3 object VecUtil { @@ -27,4 +30,28 @@ object VecUtil { else -> throw IllegalArgumentException("Not a Vec3!") } } + + fun getRotatedValues(x: Float, y: Float, sin: Double, cos: Double): Vec2 { + return Vec2((x * cos - y * sin).toFloat(), (x * sin + y * cos).toFloat()) + } + + fun rotateVector(original: Vec3, angle: Double, axis: Axes): Vec3 { + if (angle == 0.0) { + return original + } + return when (axis) { + Axes.X -> { + val rotatedValues = getRotatedValues(original.y, original.z, glm.sin(angle), glm.cos(angle)) + Vec3(original.x, rotatedValues) + } + Axes.Y -> { + val rotatedValues = getRotatedValues(original.x, original.z, glm.sin(angle), glm.cos(angle)) + Vec3(rotatedValues.x, original.y, rotatedValues.y) + } + Axes.Z -> { + val rotatedValues = getRotatedValues(original.x, original.y, glm.sin(angle), glm.cos(angle)) + Vec3(rotatedValues.x, rotatedValues.y, original.z) + } + } + } }