mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 08:58:02 -04:00
remove rotation matrix, improve model baking speed
This commit is contained in:
parent
958df37f96
commit
81dd2f7535
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.models.unbaked.block
|
package de.bixilon.minosoft.gui.rendering.models.unbaked.block
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Axes
|
||||||
import de.bixilon.minosoft.data.direction.Directions
|
import de.bixilon.minosoft.data.direction.Directions
|
||||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
@ -24,22 +25,34 @@ import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedBlockModel
|
|||||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedModel
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
|
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.get
|
||||||
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.rad
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.toVec2iN
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2iUtil.toVec2iN
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.get
|
|
||||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.set
|
|
||||||
import de.bixilon.minosoft.util.KUtil.toBoolean
|
import de.bixilon.minosoft.util.KUtil.toBoolean
|
||||||
import de.bixilon.minosoft.util.KUtil.toInt
|
import de.bixilon.minosoft.util.KUtil.toInt
|
||||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
import glm_.func.rad
|
import glm_.func.rad
|
||||||
import glm_.mat4x4.Mat4
|
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
import glm_.vec4.Vec4
|
import glm_.vec3.swizzle.xz
|
||||||
import glm_.vec4.swizzle.xyz
|
import kotlin.collections.Map
|
||||||
import glm_.vec4.swizzle.xz
|
import kotlin.collections.MutableList
|
||||||
|
import kotlin.collections.MutableMap
|
||||||
|
import kotlin.collections.component1
|
||||||
|
import kotlin.collections.component2
|
||||||
|
import kotlin.collections.drop
|
||||||
|
import kotlin.collections.iterator
|
||||||
|
import kotlin.collections.mutableListOf
|
||||||
|
import kotlin.collections.mutableMapOf
|
||||||
|
import kotlin.collections.plus
|
||||||
|
import kotlin.collections.plusAssign
|
||||||
|
import kotlin.collections.set
|
||||||
|
import kotlin.collections.take
|
||||||
|
import kotlin.collections.toTypedArray
|
||||||
|
import kotlin.collections.withIndex
|
||||||
|
|
||||||
data class UnbakedBlockStateModel(
|
data class UnbakedBlockStateModel(
|
||||||
val model: UnbakedBlockModel,
|
val model: UnbakedBlockModel,
|
||||||
@ -47,8 +60,10 @@ data class UnbakedBlockStateModel(
|
|||||||
val uvLock: Boolean,
|
val uvLock: Boolean,
|
||||||
val weight: Int,
|
val weight: Int,
|
||||||
) : UnbakedModel {
|
) : UnbakedModel {
|
||||||
|
var baked: BakedBlockModel? = null
|
||||||
|
|
||||||
override fun bake(renderWindow: RenderWindow): BakedBlockModel {
|
override fun bake(renderWindow: RenderWindow): BakedBlockModel {
|
||||||
|
baked?.let { return it }
|
||||||
val textureArray = renderWindow.textureManager.staticTextures
|
val textureArray = renderWindow.textureManager.staticTextures
|
||||||
|
|
||||||
val resolvedTextures: MutableMap<String, AbstractTexture> = mutableMapOf()
|
val resolvedTextures: MutableMap<String, AbstractTexture> = mutableMapOf()
|
||||||
@ -85,37 +100,41 @@ data class UnbakedBlockStateModel(
|
|||||||
for (face in element.faces) {
|
for (face in element.faces) {
|
||||||
val texture = resolvedTextures[face.texture.removePrefix("#")]!! // ToDo: Allow direct texture names?
|
val texture = resolvedTextures[face.texture.removePrefix("#")]!! // ToDo: Allow direct texture names?
|
||||||
val positions = face.direction.getPositions(element.from, element.to)
|
val positions = face.direction.getPositions(element.from, element.to)
|
||||||
val rotationMatrix = Mat4()
|
|
||||||
element.rotation?.let {
|
element.rotation?.let {
|
||||||
rotationMatrix.rotateAssign(it.angle.rad, Vec3.EMPTY.apply { this[it.axis] = 1.0f })
|
val rad = it.angle.rad
|
||||||
}
|
|
||||||
rotation?.let {
|
|
||||||
rotationMatrix.rotateAssign(-rotation.y.rad, Vec3(0.0f, 1.0f, 0.0f))
|
|
||||||
rotationMatrix.rotateAssign(-rotation.x.rad, Vec3(1.0f, 0.0f, 0.0f))
|
|
||||||
}
|
|
||||||
|
|
||||||
val direction = Directions.byDirection((rotationMatrix * Vec4(face.direction.vectorf, 1.0f)).xyz)
|
|
||||||
|
|
||||||
for ((index, position) in positions.withIndex()) {
|
for ((index, position) in positions.withIndex()) {
|
||||||
positions[index] = (rotationMatrix * Vec4(position - 0.5f, 1.0f)).xyz + 0.5f
|
positions[index] = Vec3(position).apply { rotateAssign(rad, it.axis, it.origin, it.rescale) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val texturePositions = arrayOf(
|
var direction = face.direction
|
||||||
|
rotation?.let {
|
||||||
|
val rad = it.rad
|
||||||
|
|
||||||
|
direction = Directions.byDirection(Vec3(face.direction.vectorf).apply { rotateAssign(rad) })
|
||||||
|
for ((index, position) in positions.withIndex()) {
|
||||||
|
positions[index] = Vec3(position).apply { rotateAssign(rad) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var texturePositions = arrayOf(
|
||||||
Vec2(face.uvEnd.x, face.uvStart.y),
|
Vec2(face.uvEnd.x, face.uvStart.y),
|
||||||
face.uvStart,
|
face.uvStart,
|
||||||
Vec2(face.uvStart.x, face.uvEnd.y),
|
Vec2(face.uvStart.x, face.uvEnd.y),
|
||||||
face.uvEnd,
|
face.uvEnd,
|
||||||
).rotateLeft((face.rotation % 360) / 90).toTypedArray()
|
)
|
||||||
|
if (face.rotation != 0) {
|
||||||
|
texturePositions = texturePositions.rotateLeft((face.rotation % 360) / 90).toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
if (this.uvLock && this.rotation != null) {
|
if (this.uvLock && this.rotation != null && face.direction.axis != Axes.Z) {
|
||||||
val matrix = Mat4()
|
var rad = this.rotation[face.direction.axis].rad
|
||||||
//matrix.rotateAssign(this.rotation.x.rad, Vec3(1,0,0))
|
if (direction.negative) {
|
||||||
val rotationVec3 = Vec3(this.rotation, 0.0f)
|
rad = -rad
|
||||||
val angle = rotationVec3[face.direction.axis]
|
}
|
||||||
matrix.rotateAssign(-angle.rad, direction.vectorf)
|
|
||||||
//matrix.rotateAssign(this.rotation.x.rad, Vec3(0,1,0))
|
|
||||||
for ((index, position) in texturePositions.withIndex()) {
|
for ((index, position) in texturePositions.withIndex()) {
|
||||||
texturePositions[index] = (matrix * Vec4(position.x - 0.5f, 0.0f, position.y - 0.5f, 0.0f)).xz + 0.5f
|
texturePositions[index] = (Vec3(position.x - 0.5f, 0.0f, position.y - 0.5f).apply { rotateAssign(rad, direction.axis) }).xz + 0.5f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +157,9 @@ data class UnbakedBlockStateModel(
|
|||||||
finalFaces[index] = faceArray.toTypedArray()
|
finalFaces[index] = faceArray.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
return BakedBlockStateModel(finalFaces.unsafeCast())
|
val baked = BakedBlockStateModel(finalFaces.unsafeCast())
|
||||||
|
this.baked = baked
|
||||||
|
return baked
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -152,6 +173,5 @@ data class UnbakedBlockStateModel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Array<T>.rotateLeft(n: Int) = drop(n) + take(n)
|
fun <T> Array<T>.rotateLeft(n: Int) = drop(n) + take(n)
|
||||||
fun <T> Array<T>.rotateRight(n: Int) = takeLast(n) + dropLast(n)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import de.bixilon.minosoft.util.KUtil.toFloat
|
|||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
data class UnbakedElementRotation(
|
data class UnbakedElementRotation(
|
||||||
val origin: Vec3?,
|
val origin: Vec3,
|
||||||
val axis: Axes,
|
val axis: Axes,
|
||||||
val angle: Float,
|
val angle: Float,
|
||||||
val rescale: Boolean,
|
val rescale: Boolean,
|
||||||
@ -29,7 +29,7 @@ data class UnbakedElementRotation(
|
|||||||
|
|
||||||
operator fun invoke(data: Map<String, Any>): UnbakedElementRotation {
|
operator fun invoke(data: Map<String, Any>): UnbakedElementRotation {
|
||||||
return UnbakedElementRotation(
|
return UnbakedElementRotation(
|
||||||
origin = data["origin"]?.toVec3(),
|
origin = data["origin"]?.toVec3()?.apply { this /= UnbakedElement.BLOCK_RESOLUTION } ?: Vec3(0.5f), // default: center
|
||||||
axis = Axes[data["axis"].toString()],
|
axis = Axes[data["axis"].toString()],
|
||||||
angle = data["angle"].toFloat(),
|
angle = data["angle"].toFloat(),
|
||||||
rescale = data["rescale"]?.toBoolean() ?: false,
|
rescale = data["rescale"]?.toBoolean() ?: false,
|
||||||
|
@ -13,7 +13,10 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.gui.rendering.util.vec.vec2
|
package de.bixilon.minosoft.gui.rendering.util.vec.vec2
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Axes
|
||||||
import de.bixilon.minosoft.util.KUtil.toInt
|
import de.bixilon.minosoft.util.KUtil.toInt
|
||||||
|
import glm_.func.rad
|
||||||
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec2.Vec2i
|
import glm_.vec2.Vec2i
|
||||||
|
|
||||||
object Vec2iUtil {
|
object Vec2iUtil {
|
||||||
@ -57,6 +60,17 @@ object Vec2iUtil {
|
|||||||
return this.x > other.x || this.y > other.y
|
return this.x > other.x || this.y > other.y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val Vec2i.rad: Vec2
|
||||||
|
get() = Vec2(x.rad, y.rad)
|
||||||
|
|
||||||
|
operator fun Vec2i.get(axis: Axes): Int {
|
||||||
|
return when (axis) {
|
||||||
|
Axes.X -> x
|
||||||
|
Axes.Y -> y
|
||||||
|
Axes.Z -> throw IllegalArgumentException("A Vec2i has no Z coordinate!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Any?.toVec2i(default: Vec2i? = null): Vec2i {
|
fun Any?.toVec2i(default: Vec2i? = null): Vec2i {
|
||||||
return toVec2iN() ?: default ?: throw IllegalArgumentException("Not a Vec2i: $this")
|
return toVec2iN() ?: default ?: throw IllegalArgumentException("Not a Vec2i: $this")
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ object Vec3Util {
|
|||||||
get() = Vec3(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE)
|
get() = Vec3(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE)
|
||||||
|
|
||||||
|
|
||||||
fun rotate(x: Float, y: Float, sin: Float, cos: Float, rescale: Boolean): Vec2 {
|
fun rotateAssign(x: Float, y: Float, sin: Float, cos: Float, rescale: Boolean): Vec2 {
|
||||||
val result = Vec2(x * cos - y * sin, x * sin + y * cos)
|
val result = Vec2(x * cos - y * sin, x * sin + y * cos)
|
||||||
if (rescale) {
|
if (rescale) {
|
||||||
return result / cos
|
return result / cos
|
||||||
@ -48,17 +48,27 @@ object Vec3Util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Vec3.rotate(angle: Float, axis: Axes, rescale: Boolean = false) {
|
fun Vec3.rotateAssign(angle: Float, axis: Axes, rescale: Boolean = false) {
|
||||||
if (angle == 0.0f) {
|
if (angle == 0.0f) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
when (axis) {
|
when (axis) {
|
||||||
Axes.X -> this.yz = rotate(this.y, this.z, angle.sin, angle.cos, rescale)
|
Axes.X -> this.yz = rotateAssign(this.y, this.z, angle.sin, angle.cos, rescale)
|
||||||
Axes.Y -> this.xz = rotate(this.x, this.z, angle.sin, angle.cos, rescale)
|
Axes.Y -> this.xz = rotateAssign(this.x, this.z, angle.sin, angle.cos, rescale)
|
||||||
Axes.Z -> this.xy = rotate(this.x, this.y, angle.sin, angle.cos, rescale)
|
Axes.Z -> this.xy = rotateAssign(this.x, this.y, angle.sin, angle.cos, rescale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Vec3.rotateAssign(rotation: Vec2) {
|
||||||
|
rotateAssign(rotation.y, Axes.Y)
|
||||||
|
rotateAssign(rotation.x, Axes.X)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Vec3.rotateAssign(angle: Float, axis: Axes, origin: Vec3, rescale: Boolean) {
|
||||||
|
this -= origin
|
||||||
|
rotateAssign(angle, axis, rescale)
|
||||||
|
this += origin
|
||||||
|
}
|
||||||
|
|
||||||
operator fun <T : Number> Vec3t<T>.get(axis: Axes): T {
|
operator fun <T : Number> Vec3t<T>.get(axis: Axes): T {
|
||||||
return when (axis) {
|
return when (axis) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user