From d8d7a9408b33c7078de738f339a83e4e7febc6f4 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Wed, 14 Dec 2022 15:24:38 +0100 Subject: [PATCH] arm rendering --- .../models/minecraft/player/PlayerModel.kt | 4 +-- .../world/overlay/overlays/arm/ArmOverlay.kt | 34 ++++++++---------- .../overlays/arm/FirstPersonArmAnimator.kt | 36 +++++++++++++++++++ .../skeletal/baked/BakedSkeletalModel.kt | 6 +++- .../skeletal/instance/SkeletalInstance.kt | 12 +++---- .../model/animations/SkeletalAnimation.kt | 6 ++-- .../models/entities/player/slim.bbmodel | 11 ++---- .../player/{normal.bbmodel => wide.bbmodel} | 9 ++--- 8 files changed, 71 insertions(+), 47 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/FirstPersonArmAnimator.kt rename src/main/resources/assets/minecraft/models/entities/player/{normal.bbmodel => wide.bbmodel} (98%) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/minecraft/player/PlayerModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/minecraft/player/PlayerModel.kt index 58beb3905..d74addfb4 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/minecraft/player/PlayerModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/entity/models/minecraft/player/PlayerModel.kt @@ -56,7 +56,7 @@ open class PlayerModel(renderer: EntityRenderer, player: PlayerEntity) : Skeleta private fun createModel(properties: PlayerProperties?): SkeletalInstance? { val skin = renderWindow.textureManager.skins.getSkin(entity, properties) ?: return null val skinModel = skin.model - val unbaked = renderWindow.modelLoader.entities.loadUnbakedModel(if (skinModel == SkinModel.SLIM) SLIM_MODEL else NORMAL_MODEL) + val unbaked = renderWindow.modelLoader.entities.loadUnbakedModel(if (skinModel == SkinModel.SLIM) SLIM_MODEL else WIDE_MODEL) val elements: MutableList = mutableListOf() elementLoop@ for (element in unbaked.elements) { @@ -126,7 +126,7 @@ open class PlayerModel(renderer: EntityRenderer, player: PlayerEntity) : Skeleta companion object { - private val NORMAL_MODEL = "minecraft:entities/player/normal".toResourceLocation().bbModel() + private val WIDE_MODEL = "minecraft:entities/player/wide".toResourceLocation().bbModel() private val SLIM_MODEL = "minecraft:entities/player/slim".toResourceLocation().bbModel() } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt index 805373fa2..06578d531 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/ArmOverlay.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.arm +import de.bixilon.kotlinglm.GLM import de.bixilon.kotlinglm.func.rad import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.vec3.Vec3 @@ -20,10 +21,12 @@ import de.bixilon.kutil.cast.CastUtil.nullCast import de.bixilon.kutil.cast.CastUtil.unsafeNull import de.bixilon.minosoft.data.entities.entities.player.Arms import de.bixilon.minosoft.gui.rendering.RenderWindow -import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.ArmAnimator +import de.bixilon.minosoft.gui.rendering.camera.CameraDefinition import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.PlayerModel import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.Overlay import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.OverlayFactory +import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel.Companion.fromBlockCoordinates +import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel.Companion.toBlockCoordinate import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes import de.bixilon.minosoft.gui.rendering.system.base.RenderingCapabilities import de.bixilon.minosoft.gui.rendering.system.base.texture.skin.PlayerSkin @@ -38,9 +41,6 @@ class ArmOverlay(private val renderWindow: RenderWindow) : Overlay { private var skin: PlayerSkin? = null private var model: PlayerModel? = null private var mesh: ArmMesh = unsafeNull() - private var animator: ArmAnimator? = null - - private var a = 0.0f override fun postInit() { shader.load() @@ -67,7 +67,6 @@ class ArmOverlay(private val renderWindow: RenderWindow) : Overlay { } val model = renderWindow.connection.player.model.nullCast() this.model = model - this.animator = model?.let { ArmAnimator(it) } val skin = model?.skin ?: return if (this.skin == skin) { return @@ -78,26 +77,21 @@ class ArmOverlay(private val renderWindow: RenderWindow) : Overlay { } private fun calculateTransform(): Mat4 { - val projection = renderWindow.camera.matrixHandler.projectionMatrix + val screen = renderWindow.window.sizef + val projection = GLM.perspective(60.0f.rad, screen.x / screen.y, CameraDefinition.NEAR_PLANE, CameraDefinition.FAR_PLANE) - val matrix = Mat4() - matrix.rotateAssign(45.0f.rad, Vec3(0, 0, 1)) - matrix.rotateAssign(-5.0f.rad, Vec3(0, 1, 0)) - matrix.rotateAssign(130.0f.rad, Vec3(1, 0, 0)) - a += 1 + val model = this.model ?: return Mat4() + val outliner = model.instance?.model?.model?.outliner?.find { it.name == if (arm == Arms.LEFT) "LEFT_ARM" else "RIGHT_ARM" } ?: return Mat4() + outliner.origin.z = 15.0f.toBlockCoordinate() + val matrix = FirstPersonArmAnimator(model).calculateTransform(outliner, 0.0f) + val screenMatrix = Mat4() - matrix.translateAssign(Vec3(if (arm == Arms.LEFT) 0.25f else -0.25f, 0, 0)) // move inner side of arm to 0|0|0 + screenMatrix.translateAssign(Vec3(if (arm == Arms.LEFT) -0.2f else 0.2f, 0, 0)) // move inner side of arm to 0|0|0 - // matrix.scaleAssign(BLOCK_RESOLUTION) // make a pixel one pixel - matrix.translateAssign(-0.5f) - matrix.translateAssign(Vec3(0, 0.3, 1.0)) + screenMatrix.translateAssign(Vec3(-18, -55, -10).fromBlockCoordinates()) - val a = projection * matrix - - - // "${a * Vec4(Vec3(4, 12, -2).fromBlockCoordinates(), 1)} -> ${a * Vec4(Vec3(7, 24, 2).fromBlockCoordinates(), 1)}" - return projection * matrix + return projection * screenMatrix * matrix } override fun draw() { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/FirstPersonArmAnimator.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/FirstPersonArmAnimator.kt new file mode 100644 index 000000000..5b0756d5b --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/arm/FirstPersonArmAnimator.kt @@ -0,0 +1,36 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.arm + +import de.bixilon.kotlinglm.vec3.Vec3 +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 + +class FirstPersonArmAnimator(private val player: PlayerModel) : SkeletalAnimation { + override val name: String = "" + override val loop = AnimationLoops.LOOP + override val length: Float = 100.0f + + // TODO (swinging: move arm to front, rotate) + + override fun get(channel: KeyframeChannels, outliner: SkeletalOutliner, time: Float): Vec3? { + if (channel != KeyframeChannels.ROTATION) { + return null + } + return Vec3(140, -20, -10) + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt index bfe130b7d..9872dc680 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/baked/BakedSkeletalModel.kt @@ -91,7 +91,11 @@ class BakedSkeletalModel( companion object { fun Vec3.fromBlockCoordinates(): Vec3 { - return Vec3(this.x / BLOCK_RESOLUTION + 0.5f, this.y / BLOCK_RESOLUTION, this.z / BLOCK_RESOLUTION + 0.5f) + return Vec3(this.x.toBlockCoordinate(), this.y.toBlockCoordinate(), this.z.toBlockCoordinate()) + } + + inline fun Float.toBlockCoordinate(): Float { + return this / BLOCK_RESOLUTION + 0.5f } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt index 6e611bf00..60092dac6 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/instance/SkeletalInstance.kt @@ -17,6 +17,7 @@ import de.bixilon.kotlinglm.func.rad import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kutil.time.TimeUtil +import de.bixilon.kutil.time.TimeUtil.millis import de.bixilon.minosoft.data.entities.EntityRotation import de.bixilon.minosoft.gui.rendering.RenderWindow import de.bixilon.minosoft.gui.rendering.renderer.drawable.DeltaDrawable @@ -82,9 +83,8 @@ class SkeletalInstance( } } - fun calculateTransforms(): List { - val baseTransform = baseTransform - val time = TimeUtil.millis + fun calculateTransforms(base: Mat4 = this.baseTransform): List { + val time = millis() if (animations.isNotEmpty()) { val toRemove: MutableSet = mutableSetOf() for (animation in animations) { @@ -98,7 +98,7 @@ class SkeletalInstance( } } if (animations.isEmpty()) { - if (this.transforms.isNotEmpty() && baseTransform === previousBaseTransform) { + if (this.transforms.isNotEmpty() && base === previousBaseTransform) { return this.transforms } } @@ -112,10 +112,10 @@ class SkeletalInstance( } val transforms: MutableList = mutableListOf() for (outliner in model.model.outliner) { - calculateTransform(baseTransform, animations, outliner, transforms) + calculateTransform(base, animations, outliner, transforms) } this.transforms = transforms - this.previousBaseTransform = baseTransform + this.previousBaseTransform = base return transforms } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/animations/SkeletalAnimation.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/animations/SkeletalAnimation.kt index ea9d2fa55..c3d0efffe 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/animations/SkeletalAnimation.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/skeletal/model/animations/SkeletalAnimation.kt @@ -55,9 +55,9 @@ interface SkeletalAnimation { 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.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) diff --git a/src/main/resources/assets/minecraft/models/entities/player/slim.bbmodel b/src/main/resources/assets/minecraft/models/entities/player/slim.bbmodel index c65e957f9..3be84a0d7 100644 --- a/src/main/resources/assets/minecraft/models/entities/player/slim.bbmodel +++ b/src/main/resources/assets/minecraft/models/entities/player/slim.bbmodel @@ -2,7 +2,7 @@ "meta": { "__comment": "This model was created by the creators of blockbench: https://github.com/JannisX11/blockbench", "format_version": "4.0", - "model_format": "skin", + "model_format": "free", "box_uv": true }, "geometry_name": "steve", @@ -437,7 +437,6 @@ { "name": "HEAD", "origin": [0, 24, 0], - "rotation": [-6, 5, 0], "uuid": "6da490f7-5540-bf4a-7f0a-12a5df3f3ce0", "children": ["842246c7-d06c-8ec1-c4d0-3dd83fd2ddfc", "be9eb8b9-9c9e-8f03-89be-623f059ad715"] }, { @@ -447,26 +446,22 @@ "children": ["9e3de0ee-4f3f-f74f-3c61-d8fe865b5103", "7d5b2fb8-9d28-f485-0b15-0241ff9171af"] }, { "name": "RIGHT_ARM", - "origin": [5, 22, 0], - "rotation": [-10, 0, 0], + "origin": [5.5, 24, 0], "uuid": "aa61460e-38d0-40f0-6291-3e8521bdd98c", "children": ["feeb8a9e-1099-d4ed-8e4b-53dd68b5357b", "a05a34bc-73df-2361-b8fc-e9cbeda48ea1"] }, { "name": "LEFT_ARM", - "origin": [-5, 22, 0], - "rotation": [12, 0, 0], + "origin": [-5.5, 24, 0], "uuid": "310e097e-7820-987e-7f08-9f8823e76e29", "children": ["1773dbda-88eb-b14d-2e53-f91077dcf6a6", "0bc9a70e-d062-27a1-4864-1ca1eef87225"] }, { "name": "RIGHT_LEG", "origin": [1.9, 12, 0], - "rotation": [11, 0, 2], "uuid": "ea6793ea-8198-47f1-cba7-a49ce5d18538", "children": ["94bb1759-86c5-f896-18d3-b5ec9de29975", "2faa3e41-dfb4-7bed-5e40-58590236f620"] }, { "name": "LEFT_LEG", "origin": [-1.9, 12, 0], - "rotation": [-10, 0, -2], "uuid": "75e815a2-97a3-6b0c-8529-e48852251b02", "children": ["0cad4dc2-fc12-43ac-0610-f5692a0764b7", "478b4925-5e2b-235f-0d95-d5d028ad624d"] } diff --git a/src/main/resources/assets/minecraft/models/entities/player/normal.bbmodel b/src/main/resources/assets/minecraft/models/entities/player/wide.bbmodel similarity index 98% rename from src/main/resources/assets/minecraft/models/entities/player/normal.bbmodel rename to src/main/resources/assets/minecraft/models/entities/player/wide.bbmodel index e4d7743a9..465d54829 100644 --- a/src/main/resources/assets/minecraft/models/entities/player/normal.bbmodel +++ b/src/main/resources/assets/minecraft/models/entities/player/wide.bbmodel @@ -437,7 +437,6 @@ { "name": "HEAD", "origin": [0, 24, 0], - "rotation": [-6, 5, 0], "uuid": "6da490f7-5540-bf4a-7f0a-12a5df3f3ce0", "children": ["842246c7-d06c-8ec1-c4d0-3dd83fd2ddfc", "be9eb8b9-9c9e-8f03-89be-623f059ad715"] }, { @@ -447,26 +446,22 @@ "children": ["9e3de0ee-4f3f-f74f-3c61-d8fe865b5103", "7d5b2fb8-9d28-f485-0b15-0241ff9171af"] }, { "name": "RIGHT_ARM", - "origin": [5, 22, 0], - "rotation": [-10, 0, 0], + "origin": [6, 24, 0], "uuid": "aa61460e-38d0-40f0-6291-3e8521bdd98c", "children": ["feeb8a9e-1099-d4ed-8e4b-53dd68b5357b", "a05a34bc-73df-2361-b8fc-e9cbeda48ea1"] }, { "name": "LEFT_ARM", - "origin": [-5, 22, 0], - "rotation": [12, 0, 0], + "origin": [-6, 24, 0], "uuid": "310e097e-7820-987e-7f08-9f8823e76e29", "children": ["1773dbda-88eb-b14d-2e53-f91077dcf6a6", "0bc9a70e-d062-27a1-4864-1ca1eef87225"] }, { "name": "RIGHT_LEG", "origin": [1.9, 12, 0], - "rotation": [11, 0, 2], "uuid": "ea6793ea-8198-47f1-cba7-a49ce5d18538", "children": ["94bb1759-86c5-f896-18d3-b5ec9de29975", "2faa3e41-dfb4-7bed-5e40-58590236f620"] }, { "name": "LEFT_LEG", "origin": [-1.9, 12, 0], - "rotation": [-10, 0, -2], "uuid": "75e815a2-97a3-6b0c-8529-e48852251b02", "children": ["0cad4dc2-fc12-43ac-0610-f5692a0764b7", "478b4925-5e2b-235f-0d95-d5d028ad624d"] }