mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 02:45:13 -04:00
rendering: bugfix and code quality improvements
This commit is contained in:
parent
66c918d20e
commit
07654ca1ab
@ -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<Vec3>, 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)
|
||||
}
|
||||
|
@ -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<Vec2>
|
||||
val tint: Boolean
|
||||
private val positions: MutableList<Vec2>
|
||||
|
||||
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<Vec2?> {
|
||||
val template = textureTemplate[direction.ordinal]
|
||||
val result = arrayOfNulls<Vec2>(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)
|
||||
}
|
||||
}
|
||||
|
@ -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<Directions> = mutableSetOf()
|
||||
private val faces: MutableMap<Directions, BlockModelFace> = element.faces.toMutableMap()
|
||||
private var positions: Array<Vec3> = element.positions.clone()
|
||||
private val faces: MutableMap<Directions, BlockModelFace> = mutableMapOf()
|
||||
private var positions: Array<Vec3> = parent.positions.clone()
|
||||
private val directionMapping: HashBiMap<Directions, Directions> = 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<Vec3>, 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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user