mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-18 20:05:02 -04:00
wip refactor skeletal
This commit is contained in:
parent
4351b1567a
commit
c5ece6b11b
18
doc/rendering/Entities.md
Normal file
18
doc/rendering/Entities.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Entity rendering
|
||||
|
||||
Entity rendering is a quite hard topic.
|
||||
|
||||
## Classes
|
||||
|
||||
- Player renderer
|
||||
- player model
|
||||
- feature renderer:
|
||||
- armor
|
||||
- stuck arrows
|
||||
|
||||
## Skeletal models
|
||||
|
||||
- SkeletalModel (raw data)
|
||||
- BakedSkeletalModel (baked mesh)
|
||||
- SkeletalInstance (renders baked mesh, contains transform values)
|
||||
- Wrapper (indirectly accesses skeletal instance transforms)
|
63
src/integration-test/resources/model/skeletal/dummy.smodel
Normal file
63
src/integration-test/resources/model/skeletal/dummy.smodel
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"elements": {
|
||||
"body": {
|
||||
"from": [-8, 0, -8],
|
||||
"to": [8, 16, 8],
|
||||
"rotation": [-180, 0, 270],
|
||||
"texture": "minosoft:dummy_texture",
|
||||
"transform": false,
|
||||
"faces": {
|
||||
"down": {"uv": [0, 0, 16, 16]},
|
||||
"up": {"uv": [0, 0, 16, 16]},
|
||||
"north": {"uv": [0, 0, 16, 16]},
|
||||
"south": {"uv": [0, 0, 16, 16]},
|
||||
"west": {"uv": [0, 0, 16, 16]},
|
||||
"east": {"uv": [0, 0, 16, 16], "texture": "minosoft:second_texture"}
|
||||
},
|
||||
"children": {
|
||||
"head": {
|
||||
"pivot": [0, 16, 0],
|
||||
"origin": [0, 5, 0],
|
||||
"from": [-5, 0, -5],
|
||||
"to": [5, 10, 5],
|
||||
"faces": {
|
||||
"up": {"uv": [0, 0, 16, 16]},
|
||||
"north": {"uv": [0, 0, 16, 16]},
|
||||
"south": {"uv": [0, 0, 16, 16]},
|
||||
"west": {"uv": [0, 0, 16, 16]},
|
||||
"east": {"uv": [0, 0, 16, 16]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"textures": {
|
||||
"minosoft:dummy_texture": {
|
||||
"resolution": [128, 128]
|
||||
},
|
||||
"minosoft:second_texture": {
|
||||
"resolution": [1024, 1024]
|
||||
}
|
||||
},
|
||||
"animations": {
|
||||
"open": {
|
||||
"loop": "hold",
|
||||
"length": 0.3,
|
||||
"animators": [
|
||||
{
|
||||
"element": "body.head",
|
||||
"keyframes": [
|
||||
{
|
||||
"type": "rotate",
|
||||
"interpolation": "sine",
|
||||
"keyframes": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.3": [-90, 0, 0]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -16,9 +16,9 @@ package de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player
|
||||
import de.bixilon.kotlinglm.func.deg
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.entities.entities.player.Arms
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.outliner.SkeletalOutliner
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -14,7 +14,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player
|
||||
|
||||
import de.bixilon.kutil.math.interpolation.FloatInterpolation.interpolateLinear
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.CustomSkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.CustomSkeletalAnimation
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
abstract class ExtremitiesAnimator(
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -15,9 +15,9 @@ package de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player
|
||||
|
||||
import de.bixilon.kotlinglm.func.deg
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.outliner.SkeletalOutliner
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
|
||||
|
@ -24,8 +24,8 @@ import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.entity.models.SkeletalEntityModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader.Companion.bbModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.SkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.elements.SkeletalElement
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicStateChangeCallback
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -16,10 +16,10 @@ package de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.arm
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.entities.entities.player.Arms
|
||||
import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.PlayerModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.SkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.outliner.SkeletalOutliner
|
||||
|
||||
class FirstPersonArmAnimator(private val player: PlayerModel) : SkeletalAnimation {
|
||||
override val name: String = ""
|
||||
|
@ -14,28 +14,22 @@
|
||||
package de.bixilon.minosoft.gui.rendering.gui.mesh
|
||||
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FontProperties
|
||||
import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProperties
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.TexturePart
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
|
||||
|
||||
interface GUIVertexConsumer {
|
||||
val order: IntArray
|
||||
|
||||
fun addVertex(position: Vec2, texture: ShaderIdentifiable?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
|
||||
fun addVertex(position: Vec2i, texture: ShaderIdentifiable?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
addVertex(Vec2(position), texture, uv, tint, options)
|
||||
}
|
||||
fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?)
|
||||
|
||||
fun addQuad(start: Vec2, end: Vec2, texture: ShaderTexture?, uvStart: Vec2 = UV_START, uvEnd: Vec2 = UV_END, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val uvStart = texture?.transformUV(uvStart) ?: uvStart
|
||||
val uvEnd = texture?.transformUV(uvEnd) ?: uvEnd
|
||||
|
||||
fun addQuad(start: Vec2, end: Vec2, texture: Texture?, uvStart: Vec2 = UV_START, uvEnd: Vec2 = UV_END, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val uvStart = texture?.renderData?.transformUV(uvStart) ?: uvStart
|
||||
val uvEnd = texture?.renderData?.transformUV(uvEnd) ?: uvEnd
|
||||
addQuad(start, end, texture as ShaderIdentifiable?, uvStart, uvEnd, tint, options)
|
||||
}
|
||||
fun addQuad(start: Vec2, end: Vec2, texture: ShaderIdentifiable?, uvStart: Vec2 = UV_START, uvEnd: Vec2 = UV_END, tint: RGBColor, options: GUIVertexOptions?) {
|
||||
val positions = arrayOf(
|
||||
start,
|
||||
Vec2(end.x, start.y),
|
||||
|
@ -59,7 +59,7 @@ class SkeletalManager(
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val TRANSFORMS = 32
|
||||
private const val TRANSFORMS = 128
|
||||
private const val MAT4_SIZE = 4 * 4
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.bake
|
||||
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
|
||||
|
||||
data class BakedSkeletalModel(
|
||||
val mesh: SkeletalMesh,
|
||||
val transforms: MutableMap<String, SkeletalTransform>,
|
||||
// TODO: animations
|
||||
) {
|
||||
private var state = SkeletalModelStates.DECLARED
|
||||
|
||||
|
||||
fun load() {
|
||||
if (state != SkeletalModelStates.DECLARED) throw IllegalStateException("Can not load model!")
|
||||
mesh.load()
|
||||
state = SkeletalModelStates.LOADED
|
||||
}
|
||||
|
||||
fun unload() {
|
||||
if (state != SkeletalModelStates.LOADED) throw IllegalStateException("Can not unload model!")
|
||||
mesh.unload()
|
||||
state = SkeletalModelStates.UNLOADED
|
||||
}
|
||||
|
||||
fun createInstance(context: RenderContext, position: Vec3, transform: Mat4 = Mat4()): SkeletalInstance {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.bake
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
data class SkeletalBakeContext(
|
||||
val offset: Vec3 = Vec3.EMPTY,
|
||||
val rotation: Vec3 = Vec3.EMPTY,
|
||||
val inflate: Float = 0.0f,
|
||||
val transparency: Boolean = true,
|
||||
val texture: ResourceLocation? = null,
|
||||
|
||||
val textures: Map<ResourceLocation, SkeletalTextureInstance>,
|
||||
val transform: AtomicInteger = AtomicInteger(),
|
||||
val consumer: SkeletalVertexConsumer,
|
||||
) {
|
||||
|
||||
fun copy(element: SkeletalElement): SkeletalBakeContext {
|
||||
val offset = this.offset + element.pivot
|
||||
val rotation = this.rotation + element.rotation
|
||||
val inflate = this.inflate + element.inflate
|
||||
val transparency = this.transparency && element.transparency
|
||||
val texture = element.texture ?: texture
|
||||
|
||||
return copy(offset = offset, rotation = rotation, inflate = inflate, transparency = transparency, texture = texture)
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,11 +11,10 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.baked
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.bake
|
||||
|
||||
enum class SkeletalModelStates {
|
||||
DECLARED,
|
||||
PRE_LOADED,
|
||||
LOADED,
|
||||
UNLOADED,
|
||||
;
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,9 +11,9 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.resolution
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.bake
|
||||
|
||||
data class SkeletalResolution(
|
||||
val width: Int = 16,
|
||||
val height: Int = 16,
|
||||
class SkeletalTransform(
|
||||
val id: Int,
|
||||
val children: Map<String, SkeletalTransform>,
|
||||
)
|
@ -1,101 +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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.baked
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.element.ModelElement.Companion.BLOCK_SIZE
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
|
||||
import java.util.*
|
||||
|
||||
class BakedSkeletalModel(
|
||||
val model: SkeletalModel,
|
||||
val textures: Int2ObjectOpenHashMap<ShaderTexture>,
|
||||
) {
|
||||
lateinit var mesh: SkeletalMesh
|
||||
var state: SkeletalModelStates = SkeletalModelStates.DECLARED
|
||||
private set
|
||||
|
||||
private fun calculateOutlinerMapping(): Map<UUID, Int> {
|
||||
val mapping: Object2IntOpenHashMap<UUID> = Object2IntOpenHashMap()
|
||||
var offset = 0
|
||||
|
||||
fun addOutliner(child: Any, parentId: Int) {
|
||||
if (child is UUID) {
|
||||
mapping[child] = parentId
|
||||
return
|
||||
}
|
||||
if (child !is SkeletalOutliner) {
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
if (mapping.containsKey(child.uuid)) {
|
||||
return
|
||||
}
|
||||
val id = offset++
|
||||
mapping[child.uuid] = id
|
||||
|
||||
for (childChild in child.children) {
|
||||
addOutliner(childChild, id)
|
||||
}
|
||||
}
|
||||
|
||||
for (outliner in this.model.outliner) {
|
||||
addOutliner(outliner, -1)
|
||||
}
|
||||
|
||||
return mapping
|
||||
}
|
||||
|
||||
fun preload(context: RenderContext) {
|
||||
check(state == SkeletalModelStates.DECLARED) { "Can not preload model in $state" }
|
||||
val mesh = SkeletalMesh(context, 1000)
|
||||
|
||||
val outlinerMapping = calculateOutlinerMapping()
|
||||
|
||||
for (element in model.elements) {
|
||||
element.bake(model, textures, outlinerMapping, mesh)
|
||||
}
|
||||
|
||||
this.mesh = mesh
|
||||
state = SkeletalModelStates.PRE_LOADED
|
||||
}
|
||||
|
||||
fun load() {
|
||||
check(state == SkeletalModelStates.PRE_LOADED) { "Can not load model in state: $state" }
|
||||
mesh.load()
|
||||
state = SkeletalModelStates.LOADED
|
||||
}
|
||||
|
||||
fun unload() {
|
||||
check(state == SkeletalModelStates.LOADED) { "Can not unload model in state $state" }
|
||||
mesh.unload()
|
||||
state = SkeletalModelStates.UNLOADED
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun Vec3.fromBlockCoordinates(): Vec3 {
|
||||
return Vec3(this.x.toBlockCoordinate(), this.y / BLOCK_SIZE, this.z.toBlockCoordinate())
|
||||
}
|
||||
|
||||
inline fun Float.toBlockCoordinate(): Float {
|
||||
return this / BLOCK_SIZE + 0.5f
|
||||
}
|
||||
}
|
||||
}
|
@ -13,136 +13,8 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.instance
|
||||
|
||||
import de.bixilon.kotlinglm.func.rad
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kutil.time.TimeUtil.millis
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.renderer.drawable.DeltaDrawable
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalModelStates
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||
import java.util.*
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.bake.BakedSkeletalModel
|
||||
|
||||
class SkeletalInstance(
|
||||
val context: RenderContext,
|
||||
val model: BakedSkeletalModel,
|
||||
position: Vec3 = Vec3.EMPTY,
|
||||
transform: Mat4 = Mat4(),
|
||||
) {
|
||||
private var baseTransform = Mat4().translateAssign(position) * transform
|
||||
private var previousBaseTransform = baseTransform
|
||||
private var animations: MutableList<SkeletalAnimationInstance> = mutableListOf()
|
||||
private var transforms: List<Mat4> = emptyList()
|
||||
|
||||
private var lastDraw = -1L
|
||||
|
||||
|
||||
var light: Int = 0xFF
|
||||
|
||||
fun getAnimation(name: String): SkeletalAnimation? {
|
||||
for (animation in model.model.animations) {
|
||||
if (animation.name != name) {
|
||||
continue
|
||||
}
|
||||
return animation
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun playAnimation(animation: SkeletalAnimation) {
|
||||
val instance = SkeletalAnimationInstance(animation)
|
||||
animations.removeAll { it.animation == animation }
|
||||
animations += instance
|
||||
}
|
||||
|
||||
fun playAnimation(name: String) {
|
||||
playAnimation(getAnimation(name) ?: throw IllegalArgumentException("Can not find animation $name"))
|
||||
}
|
||||
|
||||
fun clearAnimation() {
|
||||
animations.clear()
|
||||
}
|
||||
|
||||
fun draw() {
|
||||
context.skeletal.draw(this, light)
|
||||
}
|
||||
|
||||
fun updatePosition(position: Vec3d, rotation: EntityRotation) {
|
||||
val matrix = Mat4()
|
||||
.translateAssign(Vec3(position - context.camera.offset.offset))
|
||||
.rotateAssign((EntityRotation.HALF_CIRCLE_DEGREE - rotation.yaw).rad, Y_ROTATION_VECTOR)
|
||||
.translateAssign(CENTER_OFFSET) // move to bottom center
|
||||
|
||||
if (baseTransform != matrix) {
|
||||
baseTransform = matrix
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateTransforms(base: Mat4 = this.baseTransform): List<Mat4> {
|
||||
val time = millis()
|
||||
if (animations.isNotEmpty()) {
|
||||
val iterator = animations.iterator()
|
||||
for (animation in iterator) {
|
||||
animation.draw(time)
|
||||
if (animation.canClear()) {
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (animations.isEmpty()) {
|
||||
if (this.transforms.isNotEmpty() && base === previousBaseTransform) {
|
||||
return this.transforms
|
||||
}
|
||||
}
|
||||
|
||||
val delta = time - lastDraw
|
||||
for (instance in animations) {
|
||||
val animation = instance.animation
|
||||
if (animation is DeltaDrawable) {
|
||||
animation.draw(delta)
|
||||
}
|
||||
}
|
||||
val transforms: MutableList<Mat4> = mutableListOf()
|
||||
for (outliner in model.model.outliner) {
|
||||
calculateTransform(base, animations, outliner, transforms)
|
||||
}
|
||||
this.transforms = transforms
|
||||
this.previousBaseTransform = base
|
||||
return transforms
|
||||
}
|
||||
|
||||
private fun calculateTransform(transform: Mat4, animations: List<SkeletalAnimationInstance>, outliner: Any /* UUID or SkeletalOutliner */, transforms: MutableList<Mat4>) {
|
||||
if (outliner is UUID) {
|
||||
return
|
||||
}
|
||||
check(outliner is SkeletalOutliner)
|
||||
val skeletalTransform = Mat4(transform)
|
||||
|
||||
for (animation in this.animations) {
|
||||
skeletalTransform *= animation.animation.calculateTransform(outliner, animation.time)
|
||||
}
|
||||
|
||||
transforms += skeletalTransform
|
||||
|
||||
for (child in outliner.children) {
|
||||
calculateTransform(skeletalTransform, animations, child, transforms)
|
||||
}
|
||||
}
|
||||
|
||||
fun unload() {
|
||||
val model = model
|
||||
if (model.state == SkeletalModelStates.LOADED) {
|
||||
model.unload()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val CENTER_OFFSET = Vec3(-0.5, 0.0f, -0.5)
|
||||
private val Y_ROTATION_VECTOR = Vec3(0, 1, 0)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -13,38 +13,47 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model
|
||||
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderContext
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.bake.BakedSkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalTransform
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.meta.SkeletalMeta
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.resolution.SkeletalResolution
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTexture
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
|
||||
|
||||
data class SkeletalModel(
|
||||
val meta: SkeletalMeta = SkeletalMeta(),
|
||||
val name: String = "empty",
|
||||
val resolution: SkeletalResolution = SkeletalResolution(),
|
||||
val elements: List<SkeletalElement> = emptyList(),
|
||||
val outliner: List<SkeletalOutliner> = emptyList(),
|
||||
val textures: List<SkeletalTexture> = emptyList(),
|
||||
val animations: List<SkeletalAnimation> = emptyList(),
|
||||
val elements: Map<String, SkeletalElement>,
|
||||
val textures: Map<ResourceLocation, SkeletalTexture>,
|
||||
val animations: Map<ResourceLocation, SkeletalAnimation>,
|
||||
) {
|
||||
val loadedTextures: MutableMap<ResourceLocation, SkeletalTextureInstance> = mutableMapOf()
|
||||
|
||||
fun bake(context: RenderContext, textureOverride: Map<Int, ShaderTexture>): BakedSkeletalModel {
|
||||
val textures: Int2ObjectOpenHashMap<ShaderTexture> = Int2ObjectOpenHashMap()
|
||||
for (entry in this.textures) {
|
||||
val override = textureOverride[entry.id]
|
||||
if (override != null) {
|
||||
textures[entry.id] = override
|
||||
continue
|
||||
}
|
||||
val texture = context.textures.staticTextures.createTexture(entry.resourceLocation)
|
||||
textures[entry.id] = texture
|
||||
fun load(context: RenderContext) {
|
||||
for ((name, properties) in this.textures) {
|
||||
if (!properties.load) continue
|
||||
context.textures.staticTextures.createTexture(name.texture())
|
||||
}
|
||||
return BakedSkeletalModel(this, textures)
|
||||
}
|
||||
|
||||
fun bake(context: RenderContext, override: Map<ResourceLocation, ShaderTexture>): BakedSkeletalModel {
|
||||
val mesh = SkeletalMesh(context, 1000)
|
||||
|
||||
val textures: MutableMap<ResourceLocation, SkeletalTextureInstance> = this.loadedTextures.toMutableMap()
|
||||
|
||||
for ((name, texture) in override) {
|
||||
textures[name]?.texture = texture
|
||||
}
|
||||
|
||||
val baked: MutableMap<String, SkeletalTransform> = mutableMapOf()
|
||||
|
||||
for ((name, element) in elements) {
|
||||
baked[name] = element.bake(mesh, textures) ?: continue
|
||||
}
|
||||
|
||||
return BakedSkeletalModel(mesh, baked)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -13,78 +13,11 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
|
||||
import de.bixilon.kotlinglm.func.rad
|
||||
import de.bixilon.kotlinglm.mat4x4.Mat4
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel.Companion.fromBlockCoordinates
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY_INSTANCE
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.AnimationLoops
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.SkeletalAnimator
|
||||
|
||||
@JsonDeserialize(`as` = StaticSkeletalAnimation::class)
|
||||
interface SkeletalAnimation {
|
||||
val name: String
|
||||
val loop: AnimationLoops
|
||||
val length: Float
|
||||
|
||||
fun get(channel: KeyframeChannels, outliner: SkeletalOutliner, time: Float): Vec3?
|
||||
|
||||
private fun tweakTime(time: Float): Float {
|
||||
when (loop) {
|
||||
AnimationLoops.LOOP -> return time % length
|
||||
AnimationLoops.ONCE -> {
|
||||
if (time > length) {
|
||||
return 0.0f
|
||||
}
|
||||
}
|
||||
AnimationLoops.HOLD -> {
|
||||
if (time > length) {
|
||||
return length
|
||||
}
|
||||
}
|
||||
}
|
||||
return time
|
||||
}
|
||||
|
||||
fun calculateTransform(outliner: SkeletalOutliner, animationTime: Float): Mat4 {
|
||||
val transform = Mat4()
|
||||
|
||||
val tweakedTime = tweakTime(animationTime)
|
||||
|
||||
val rotation = get(KeyframeChannels.ROTATION, outliner, tweakedTime)
|
||||
if (rotation != null && rotation != Vec3.EMPTY_INSTANCE) {
|
||||
transform.translateAssign(outliner.origin.fromBlockCoordinates())
|
||||
transform.rotateAssign(-rotation.x.rad, Vec3(1, 0, 0))
|
||||
transform.rotateAssign(-rotation.y.rad, Vec3(0, 1, 0))
|
||||
transform.rotateAssign(-rotation.z.rad, Vec3(0, 0, 1))
|
||||
transform.translateAssign(-outliner.origin.fromBlockCoordinates())
|
||||
}
|
||||
val scale = get(KeyframeChannels.SCALE, outliner, tweakedTime)
|
||||
if (scale != null && (scale.x != 1.0f || scale.y != 1.0f || scale.z != 1.0f)) {
|
||||
transform.scaleAssign(scale)
|
||||
}
|
||||
val position = get(KeyframeChannels.POSITION, outliner, tweakedTime)
|
||||
if (position != null && position != Vec3.EMPTY_INSTANCE) {
|
||||
transform[3, 0] += position.x
|
||||
transform[3, 1] += position.y
|
||||
transform[3, 2] += position.z
|
||||
}
|
||||
|
||||
return transform
|
||||
}
|
||||
|
||||
fun canClear(animationTime: Float): Boolean {
|
||||
if (loop == AnimationLoops.LOOP) {
|
||||
return false
|
||||
}
|
||||
if (animationTime < length) {
|
||||
return false
|
||||
}
|
||||
if (loop == AnimationLoops.ONCE) {
|
||||
return true
|
||||
}
|
||||
// ToDo: Check HOLD
|
||||
return false
|
||||
}
|
||||
}
|
||||
class SkeletalAnimation(
|
||||
val loop: AnimationLoops,
|
||||
val length: Float,
|
||||
val animators: List<SkeletalAnimator>
|
||||
)
|
||||
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.SkeletalAnimator
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
|
||||
import java.util.*
|
||||
|
||||
data class StaticSkeletalAnimation(
|
||||
val uuid: UUID,
|
||||
override val name: String,
|
||||
override val loop: AnimationLoops = AnimationLoops.LOOP,
|
||||
override val length: Float,
|
||||
val animators: Map<UUID, SkeletalAnimator>,
|
||||
) : SkeletalAnimation {
|
||||
|
||||
override fun get(channel: KeyframeChannels, outliner: SkeletalOutliner, time: Float): Vec3? {
|
||||
val animator = animators[outliner.uuid] ?: return null
|
||||
|
||||
return animator.get(channel, time)
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.KeyframeChannels
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes.SkeletalKeyframe
|
||||
|
||||
data class SkeletalAnimator(
|
||||
val name: String,
|
||||
val type: String, // ToDo: enum
|
||||
val keyframes: List<SkeletalKeyframe>,
|
||||
) {
|
||||
|
||||
fun get(channel: KeyframeChannels, time: Float): Vec3? {
|
||||
var firstKeyframe: SkeletalKeyframe? = null
|
||||
var secondKeyframe: SkeletalKeyframe? = null
|
||||
|
||||
for (keyframe in keyframes) {
|
||||
if (keyframe.channel != channel) {
|
||||
continue
|
||||
}
|
||||
if (firstKeyframe == null) {
|
||||
firstKeyframe = keyframe
|
||||
continue
|
||||
}
|
||||
if (time <= keyframe.time) {
|
||||
if (secondKeyframe != null) {
|
||||
firstKeyframe = secondKeyframe
|
||||
}
|
||||
secondKeyframe = keyframe
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if (firstKeyframe == null || secondKeyframe == null) {
|
||||
return null
|
||||
}
|
||||
val delta = (time - firstKeyframe.time) / (secondKeyframe.time - firstKeyframe.time)
|
||||
return firstKeyframe.interpolateDataWith(secondKeyframe.dataPoints, delta)
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateLinear
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateSine
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.toVec3
|
||||
import java.util.*
|
||||
|
||||
data class SkeletalKeyframe(
|
||||
val channel: KeyframeChannels,
|
||||
val dataPoints: List<Map<String, Any>>,
|
||||
val uuid: UUID,
|
||||
val time: Float,
|
||||
val interpolation: KeyframeInterpolations = KeyframeInterpolations.LINEAR,
|
||||
) {
|
||||
fun interpolateDataWith(other: List<Map<String, Any>>, delta: Float): Vec3 {
|
||||
val value1 = dataPoints[0].toVec3()
|
||||
val value2 = other[0].toVec3()
|
||||
|
||||
return when (interpolation) {
|
||||
KeyframeInterpolations.LINEAR -> interpolateLinear(delta, value1, value2)
|
||||
KeyframeInterpolations.SINE -> interpolateSine(delta, value1, value2)
|
||||
// ToDo
|
||||
else -> interpolateSine(delta, value1, value2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,7 +11,7 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators
|
||||
|
||||
enum class AnimationLoops {
|
||||
ONCE,
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,11 +11,11 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators
|
||||
|
||||
enum class KeyframeChannels {
|
||||
ROTATION,
|
||||
POSITION,
|
||||
SCALE,
|
||||
;
|
||||
}
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes.SkeletalKeyframe
|
||||
|
||||
data class SkeletalAnimator(
|
||||
val element: String,
|
||||
val keyframes: List<SkeletalKeyframe>,
|
||||
)
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,12 +11,11 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animator.keyframes
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes
|
||||
|
||||
enum class KeyframeInterpolations {
|
||||
enum class KeyframeInterpolation {
|
||||
NONE,
|
||||
LINEAR,
|
||||
CATMULLROM,
|
||||
STEP,
|
||||
SINE,
|
||||
;
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
|
||||
data class RotateKeyframe(
|
||||
val interpolation: KeyframeInterpolation = KeyframeInterpolation.NONE,
|
||||
val keyframes: Map<Float, Vec3>,
|
||||
) : SkeletalKeyframe {
|
||||
override val type get() = TYPE
|
||||
|
||||
companion object {
|
||||
const val TYPE = "rotate"
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,10 +11,17 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.meta
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes
|
||||
|
||||
enum class ModelFormats {
|
||||
FREE,
|
||||
SKIN,
|
||||
;
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
|
||||
data class ScaleKeyframe(
|
||||
val interpolation: KeyframeInterpolation = KeyframeInterpolation.NONE,
|
||||
val keyframes: Map<Float, Vec3>,
|
||||
) : SkeletalKeyframe {
|
||||
override val type get() = TYPE
|
||||
|
||||
companion object {
|
||||
const val TYPE = "scale"
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,25 +11,19 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.instance
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo
|
||||
|
||||
class SkeletalAnimationInstance(
|
||||
var animation: SkeletalAnimation,
|
||||
) {
|
||||
var time = 0.0f
|
||||
var lastFrame = -1L
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
@JsonSubTypes(
|
||||
JsonSubTypes.Type(value = RotateKeyframe::class, name = RotateKeyframe.TYPE),
|
||||
JsonSubTypes.Type(value = TintKeyframe::class, name = TintKeyframe.TYPE),
|
||||
JsonSubTypes.Type(value = TranslateKeyframe::class, name = TranslateKeyframe.TYPE),
|
||||
JsonSubTypes.Type(value = ScaleKeyframe::class, name = ScaleKeyframe.TYPE),
|
||||
)
|
||||
|
||||
fun draw(time: Long) {
|
||||
if (lastFrame > 0L) {
|
||||
val delta = time - lastFrame
|
||||
this.time += delta / 1000.0f
|
||||
}
|
||||
lastFrame = time
|
||||
}
|
||||
|
||||
fun canClear(): Boolean {
|
||||
return animation.canClear(time)
|
||||
}
|
||||
interface SkeletalKeyframe {
|
||||
val type: String
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,21 +11,25 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.renderer.drawable.DeltaDrawable
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.data.text.formatting.color.RGBColor
|
||||
|
||||
abstract class CustomSkeletalAnimation(override val name: String) : SkeletalAnimation, DeltaDrawable {
|
||||
protected var lastTick = -1L
|
||||
data class TintKeyframe(
|
||||
val interpolation: KeyframeInterpolation = KeyframeInterpolation.NONE,
|
||||
val channel: ColorChannel = ColorChannel.RGB,
|
||||
val keyframes: Map<Float, RGBColor>,
|
||||
) : SkeletalKeyframe {
|
||||
override val type get() = TYPE
|
||||
|
||||
|
||||
open fun tick() = Unit
|
||||
enum class ColorChannel {
|
||||
RGB,
|
||||
// TODO: hsv?
|
||||
;
|
||||
}
|
||||
|
||||
override fun draw(millis: Long) {
|
||||
if (millis - lastTick > ProtocolDefinition.TICK_TIME) {
|
||||
tick()
|
||||
lastTick = millis
|
||||
}
|
||||
companion object {
|
||||
const val TYPE = "tint"
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.animations.animators.keyframes
|
||||
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
|
||||
data class TranslateKeyframe(
|
||||
val interpolation: KeyframeInterpolation = KeyframeInterpolation.NONE,
|
||||
val keyframes: Map<Float, Vec3>,
|
||||
) : SkeletalKeyframe {
|
||||
override val type get() = TYPE
|
||||
|
||||
companion object {
|
||||
const val TYPE = "translate"
|
||||
}
|
||||
}
|
@ -13,45 +13,53 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.elements
|
||||
|
||||
import com.sun.marlin.MarlinConst.BLOCK_SIZE
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.faces.SkeletalFace
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalBakeContext
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalTransform
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.ONE
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import java.util.*
|
||||
|
||||
data class SkeletalElement(
|
||||
val name: String,
|
||||
val rescale: Boolean = false,
|
||||
val visible: Boolean = true,
|
||||
val from: Vec3 = Vec3.EMPTY,
|
||||
val to: Vec3 = Vec3.ONE,
|
||||
val from: Vec3,
|
||||
val to: Vec3,
|
||||
val origin: Vec3 = (from - to) / 2.0f,
|
||||
val pivot: Vec3 = Vec3.EMPTY,
|
||||
val rotation: Vec3 = Vec3.EMPTY,
|
||||
val origin: Vec3 = Vec3.EMPTY,
|
||||
val uvOffset: Vec2 = Vec2.EMPTY,
|
||||
val faces: Map<Directions, SkeletalFace> = emptyMap(),
|
||||
val uuid: UUID,
|
||||
val inflate: Float = 0.0f,
|
||||
val transparency: Boolean = true,
|
||||
val enabled: Boolean = true,
|
||||
val texture: ResourceLocation? = null,
|
||||
val transform: Boolean = true,
|
||||
val faces: Map<Directions, SkeletalFace>,
|
||||
val children: Map<String, SkeletalElement>,
|
||||
) {
|
||||
|
||||
fun bake(model: SkeletalModel, textures: Int2ObjectOpenHashMap<ShaderTexture>, outlinerMapping: Map<UUID, Int>, consumer: SkeletalVertexConsumer) {
|
||||
if (!visible) {
|
||||
return
|
||||
}
|
||||
fun bake(mesh: SkeletalMesh, textures: Map<ResourceLocation, SkeletalTextureInstance>): SkeletalTransform? {
|
||||
if (!enabled) return null
|
||||
|
||||
val outlinerId = outlinerMapping[uuid] ?: 0
|
||||
val context = SkeletalBakeContext(textures = textures, consumer = mesh)
|
||||
return bake(context)
|
||||
}
|
||||
|
||||
private fun bake(context: SkeletalBakeContext): SkeletalTransform? {
|
||||
if (!enabled) return null
|
||||
val context = context.copy(this)
|
||||
|
||||
val transform = if (!this.transform) context.transform.get() else context.transform.getAndIncrement()
|
||||
val transforms: MutableMap<String, SkeletalTransform> = mutableMapOf()
|
||||
|
||||
val inflate = (inflate / BLOCK_SIZE) / 2
|
||||
for ((direction, face) in faces) {
|
||||
face.bake(model, this, direction, inflate, outlinerId, textures, consumer)
|
||||
face.bake(context, direction, this, transform)
|
||||
}
|
||||
|
||||
for ((name, child) in children) {
|
||||
transforms[name] = child.bake(context) ?: continue
|
||||
}
|
||||
if (!this.transform) return null
|
||||
|
||||
return SkeletalTransform(transform, transforms)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.elements
|
||||
|
||||
import de.bixilon.kotlinglm.GLM
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.legacy.ModelBakeUtil
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalBakeContext
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
|
||||
|
||||
data class SkeletalFace(
|
||||
val uv: FaceUV,
|
||||
val texture: ResourceLocation? = null,
|
||||
) {
|
||||
|
||||
fun bake(context: SkeletalBakeContext, direction: Directions, element: SkeletalElement, transform: Int) {
|
||||
val positions = direction.getPositions(context.offset + (element.from / 16.0f - context.inflate), context.offset + (element.to / 16.0f + context.inflate))
|
||||
|
||||
val texture = context.textures[texture ?: context.texture ?: throw IllegalStateException("element has no texture set!")] ?: throw IllegalStateException("Texture not found!")
|
||||
|
||||
val texturePositions = ModelBakeUtil.getTextureCoordinates(uv.start / texture.properties.resolution, uv.end / texture.properties.resolution)
|
||||
|
||||
val origin = element.origin / 16.0f
|
||||
|
||||
element.rotation.let {
|
||||
val rad = -GLM.radians(it)
|
||||
for ((index, position) in positions.withIndex()) {
|
||||
val out = Vec3(position)
|
||||
out.rotateAssign(rad[0], Axes.X, origin, false)
|
||||
out.rotateAssign(rad[1], Axes.Y, origin, false)
|
||||
out.rotateAssign(rad[2], Axes.Z, origin, false)
|
||||
positions[index] = out
|
||||
}
|
||||
}
|
||||
|
||||
var flags = 0
|
||||
if (context.transparency) {
|
||||
flags = flags or 0x01
|
||||
}
|
||||
|
||||
val transform = transform.buffer()
|
||||
val textureShaderId = texture.texture.shaderId.buffer()
|
||||
val floatFlags = flags.buffer()
|
||||
|
||||
for (index in 0 until context.consumer.order.size step 2) {
|
||||
val indexPosition = positions[context.consumer.order[index]].array
|
||||
val transformedUV = texture.texture.transformUV(texturePositions[context.consumer.order[index + 1]])
|
||||
context.consumer.addVertex(indexPosition, transformedUV, transform, textureShaderId, floatFlags)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,78 +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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.elements.faces
|
||||
|
||||
import de.bixilon.kotlinglm.GLM
|
||||
import de.bixilon.kotlinglm.vec2.Vec2
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.kotlinglm.vec4.Vec4
|
||||
import de.bixilon.kotlinglm.vec4.swizzle.xy
|
||||
import de.bixilon.kotlinglm.vec4.swizzle.zw
|
||||
import de.bixilon.minosoft.data.Axes
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.gui.rendering.models.block.legacy.ModelBakeUtil
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel.Companion.fromBlockCoordinates
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
|
||||
data class SkeletalFace(
|
||||
val uv: Vec4,
|
||||
val texture: Int,
|
||||
val transparency: Boolean = true,
|
||||
) {
|
||||
val uvStart = uv.xy
|
||||
val uvEnd = uv.zw
|
||||
|
||||
|
||||
fun bake(model: SkeletalModel, element: SkeletalElement, direction: Directions, inflate: Float, outlinerId: Int, textures: Int2ObjectOpenHashMap<ShaderTexture>, consumer: SkeletalVertexConsumer) {
|
||||
val positions = direction.getPositions(element.from.fromBlockCoordinates() - inflate, element.to.fromBlockCoordinates() + inflate)
|
||||
|
||||
val uvDivider = Vec2(model.resolution.width, model.resolution.height)
|
||||
val texturePositions = ModelBakeUtil.getTextureCoordinates(uvStart / uvDivider, uvEnd / uvDivider)
|
||||
|
||||
val origin = element.origin.fromBlockCoordinates()
|
||||
|
||||
element.rotation.let {
|
||||
val rad = -GLM.radians(it)
|
||||
for ((index, position) in positions.withIndex()) {
|
||||
val out = Vec3(position)
|
||||
out.rotateAssign(rad[0], Axes.X, origin, element.rescale)
|
||||
out.rotateAssign(rad[1], Axes.Y, origin, element.rescale)
|
||||
out.rotateAssign(rad[2], Axes.Z, origin, element.rescale)
|
||||
positions[index] = out
|
||||
}
|
||||
}
|
||||
|
||||
var flags = 0
|
||||
if (element.transparency && transparency) {
|
||||
flags = flags or 0x01
|
||||
}
|
||||
|
||||
val texture = textures[texture]!!
|
||||
val transform = outlinerId.buffer()
|
||||
val textureShaderId = texture.shaderId.buffer()
|
||||
val floatFlags = flags.buffer()
|
||||
|
||||
for (index in 0 until consumer.order.size step 2) {
|
||||
val indexPosition = positions[consumer.order[index]].array
|
||||
val transformedUV = texture.transformUV(texturePositions[consumer.order[index + 1]])
|
||||
consumer.addVertex(indexPosition, transformedUV, transform, textureShaderId, floatFlags)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.outliner
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode
|
||||
import com.fasterxml.jackson.databind.node.TextNode
|
||||
import com.fasterxml.jackson.module.kotlin.convertValue
|
||||
import de.bixilon.kotlinglm.vec3.Vec3
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
|
||||
import de.bixilon.minosoft.util.json.Jackson
|
||||
import java.util.*
|
||||
|
||||
class SkeletalOutliner(
|
||||
val name: String,
|
||||
val origin: Vec3 = Vec3.EMPTY,
|
||||
val uuid: UUID,
|
||||
children: List<JsonNode>,
|
||||
) {
|
||||
val children: List<Any> // List<UUID | SkeletalOutliner>
|
||||
|
||||
init {
|
||||
val _children: MutableList<Any> = mutableListOf()
|
||||
|
||||
for (child in children) {
|
||||
_children += if (child is TextNode) {
|
||||
Jackson.MAPPER.convertValue<UUID>(child)
|
||||
} else {
|
||||
Jackson.MAPPER.convertValue<SkeletalOutliner>(child)
|
||||
}
|
||||
}
|
||||
|
||||
this.children = _children
|
||||
}
|
||||
}
|
@ -13,18 +13,9 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.textures
|
||||
|
||||
import de.bixilon.minosoft.data.registries.identified.Namespaces
|
||||
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
|
||||
import java.util.*
|
||||
import de.bixilon.kotlinglm.vec2.Vec2i
|
||||
|
||||
// ToDo: This does not follow the specification
|
||||
data class SkeletalTexture(
|
||||
val path: String,
|
||||
val name: String,
|
||||
val namespace: String = Namespaces.DEFAULT,
|
||||
val id: Int,
|
||||
val uuid: UUID,
|
||||
) {
|
||||
val resourceLocation = ResourceLocation(namespace, path).texture()
|
||||
}
|
||||
val resolution: Vec2i,
|
||||
val load: Boolean = true,
|
||||
)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2022 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -11,9 +11,11 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.meta
|
||||
package de.bixilon.minosoft.gui.rendering.skeletal.model.textures
|
||||
|
||||
data class SkeletalMeta(
|
||||
val formatVersion: String = "4.0",
|
||||
val modelFormat: ModelFormats = ModelFormats.FREE,
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
|
||||
|
||||
data class SkeletalTextureInstance(
|
||||
val properties: SkeletalTexture,
|
||||
var texture: ShaderTexture,
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user