rendering: fix textures not being rotated correctly

This commit is contained in:
Lukas 2021-02-22 22:47:59 +01:00
parent 4d987cb0d0
commit 5226a26aa5
3 changed files with 29 additions and 12 deletions

View File

@ -18,6 +18,7 @@ import com.google.gson.JsonObject
import de.bixilon.minosoft.data.Axes import de.bixilon.minosoft.data.Axes
import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.Directions
import glm_.glm import glm_.glm
import glm_.vec2.Vec2
import glm_.vec3.Vec3 import glm_.vec3.Vec3
open class BlockModelElement(data: JsonObject) { open class BlockModelElement(data: JsonObject) {
@ -96,22 +97,23 @@ open class BlockModelElement(data: JsonObject) {
Directions.NORTH to setOf(POSITION_3, POSITION_4, POSITION_7, POSITION_8), Directions.NORTH to setOf(POSITION_3, POSITION_4, POSITION_7, POSITION_8),
) )
fun rotateVector(original: Vec3, angle: Double, axis: Axes): Vec3 { fun getRotatedValues(x: Float, y: Float, sin: Double, cos: Double): Vec2 {
fun getRotatedValues(x: Float, y: Float, sin: Double, cos: Double): Pair<Float, Float> { return Vec2((x * cos - y * sin).toFloat(), (x * sin + y * cos).toFloat())
return Pair((x * cos - y * sin).toFloat(), (x * sin + y * cos).toFloat())
} }
fun rotateVector(original: Vec3, angle: Double, axis: Axes): Vec3 {
return when (axis) { return when (axis) {
Axes.X -> { Axes.X -> {
val rotatedValues = getRotatedValues(original.y, original.z, glm.sin(angle), glm.cos(angle)) val rotatedValues = getRotatedValues(original.y, original.z, glm.sin(angle), glm.cos(angle))
Vec3(original.x, rotatedValues.first, rotatedValues.second) Vec3(original.x, rotatedValues)
} }
Axes.Y -> { Axes.Y -> {
val rotatedValues = getRotatedValues(original.x, original.z, glm.sin(angle), glm.cos(angle)) val rotatedValues = getRotatedValues(original.x, original.z, glm.sin(angle), glm.cos(angle))
Vec3(rotatedValues.first, original.y, rotatedValues.second) Vec3(rotatedValues.x, original.y, rotatedValues.y)
} }
Axes.Z -> { Axes.Z -> {
val rotatedValues = getRotatedValues(original.x, original.y, glm.sin(angle), glm.cos(angle)) val rotatedValues = getRotatedValues(original.x, original.y, glm.sin(angle), glm.cos(angle))
Vec3(rotatedValues.first, rotatedValues.second, original.z) Vec3(rotatedValues.x, rotatedValues.y, original.z)
} }
} }
} }

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.chunk.models.loading
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.data.Directions import de.bixilon.minosoft.data.Directions
import glm_.Java.Companion.glm
import glm_.vec2.Vec2 import glm_.vec2.Vec2
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import java.util.* import java.util.*
@ -53,10 +54,10 @@ class BlockModelFace(data: JsonObject, from: Vec3, to: Vec3, direction: Directio
} }
} }
positions = mutableListOf( positions = mutableListOf(
Vec2(uvToFloat(textureStart.x), uvToFloat(textureStart.y)), uvToFloat(Vec2(textureStart.x, textureStart.y)),
Vec2(uvToFloat(textureStart.x), uvToFloat(textureEnd.y)), uvToFloat(Vec2(textureStart.x, textureEnd.y)),
Vec2(uvToFloat(textureEnd.x), uvToFloat(textureEnd.y)), uvToFloat(Vec2(textureEnd.x, textureEnd.y)),
Vec2(uvToFloat(textureEnd.x), uvToFloat(textureStart.y)), uvToFloat(Vec2(textureEnd.x, textureStart.y)),
) )
val rotation = data["rotation"]?.asInt?.div(90) ?: 0 val rotation = data["rotation"]?.asInt?.div(90) ?: 0
Collections.rotate(positions, rotation) Collections.rotate(positions, rotation)
@ -71,6 +72,17 @@ class BlockModelFace(data: JsonObject, from: Vec3, to: Vec3, direction: Directio
return result return result
} }
fun rotate(angle: Double) {
if (angle == 0.0) {
return
}
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)
}
}
companion object { companion object {
private fun uvToFloat(uv: Float): Float { private fun uvToFloat(uv: Float): Float {

View File

@ -31,7 +31,7 @@ import glm_.vec4.Vec4
class ElementRenderer(element: BlockModelElement, rotation: Vec3, uvlock: Boolean, rescale: Boolean) { class ElementRenderer(element: BlockModelElement, rotation: Vec3, uvlock: Boolean, rescale: Boolean) {
private val fullFaceDirections: MutableSet<Directions> = mutableSetOf() private val fullFaceDirections: MutableSet<Directions> = mutableSetOf()
private val faces: MutableMap<Directions, BlockModelFace> = element.faces private val faces: MutableMap<Directions, BlockModelFace> = HashMap(element.faces)
private var positions: Array<Vec3> = element.positions.clone() private var positions: Array<Vec3> = element.positions.clone()
private val directionMapping: MutableMap<Directions, Directions> = mutableMapOf() private val directionMapping: MutableMap<Directions, Directions> = mutableMapOf()
@ -43,6 +43,9 @@ class ElementRenderer(element: BlockModelElement, rotation: Vec3, uvlock: Boolea
fullFaceDirections.add(direction) fullFaceDirections.add(direction)
} }
directionMapping[direction] = getRotatedDirection(rotation, direction) directionMapping[direction] = getRotatedDirection(rotation, direction)
for (face in faces.values) {
face.rotate(rotation.y.toDouble())
}
} }
} }
@ -111,7 +114,7 @@ class ElementRenderer(element: BlockModelElement, rotation: Vec3, uvlock: Boolea
val parentElements = mapping.blockModels[ModIdentifier(state["model"].asString.replace("block/", ""))]!!.elements val parentElements = mapping.blockModels[ModIdentifier(state["model"].asString.replace("block/", ""))]!!.elements
val result: MutableList<ElementRenderer> = mutableListOf() val result: MutableList<ElementRenderer> = mutableListOf()
for (parentElement in parentElements) { for (parentElement in parentElements) {
result.add(ElementRenderer(parentElement, rotation, uvlock, rescale)) result.add(ElementRenderer(parentElement, rotation, true, rescale)) // uvlock is not yet implemented in the data generator
} }
return result return result
} }