From 7dad53c46d54aefd985a1c5c2ad8a8127992a12e Mon Sep 17 00:00:00 2001 From: Yonnji Date: Fri, 3 Sep 2021 16:42:02 +0300 Subject: [PATCH] vrm bones info --- .gitignore | 1 + addon_build.py | 16 +++++++++++ install_addon.sh => addon_install.sh | 0 kitsunetsuki/__init__.py | 2 +- kitsunetsuki/base/matrices.py | 2 ++ kitsunetsuki/exporter/gltf/__init__.py | 37 +++++++++++++++++++------ kitsunetsuki/exporter/gltf/animation.py | 2 +- kitsunetsuki/gltf_inspect.py | 12 +++++++- 8 files changed, 60 insertions(+), 12 deletions(-) create mode 100755 addon_build.py rename install_addon.sh => addon_install.sh (100%) diff --git a/.gitignore b/.gitignore index 13da4bc..afb04f1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ *.blend1 *.pyc *.vrm +*.zip __pycache__ diff --git a/addon_build.py b/addon_build.py new file mode 100755 index 0000000..90d249d --- /dev/null +++ b/addon_build.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 + +import os +import zipfile +from kitsunetsuki import bl_info + + +version = '{}.{}.{}'.format(*bl_info['version']) + + +with open(f'KAT_blender_addon_{version}.zip', 'wb') as f: + with zipfile.ZipFile(f, 'w') as z: + for root, dirs, files in os.walk('kitsunetsuki'): + for i in files: + if i != '__pycache__' and not i.endswith('.pyc'): + z.write(os.path.join(root, i)) diff --git a/install_addon.sh b/addon_install.sh similarity index 100% rename from install_addon.sh rename to addon_install.sh diff --git a/kitsunetsuki/__init__.py b/kitsunetsuki/__init__.py index f63bbac..23489b9 100644 --- a/kitsunetsuki/__init__.py +++ b/kitsunetsuki/__init__.py @@ -17,7 +17,7 @@ bl_info = { 'name': 'KITSUNETSUKI Asset Tools', 'author': 'kitsune.ONE team', - 'version': (0, 6, 0), + 'version': (0, 6, 3), 'blender': (2, 92, 0), 'location': 'File > Import-Export', 'description': 'Exports: glTF, VRM', diff --git a/kitsunetsuki/base/matrices.py b/kitsunetsuki/base/matrices.py index 6770e5b..f52b9ba 100644 --- a/kitsunetsuki/base/matrices.py +++ b/kitsunetsuki/base/matrices.py @@ -28,6 +28,8 @@ def matrix_to_list(matrix): def get_bone_matrix_local(bone): if isinstance(bone, bpy.types.PoseBone): return bone.matrix + if isinstance(bone, bpy.types.EditBone): + return bone.matrix elif isinstance(bone, bpy.types.Bone): return bone.matrix_local diff --git a/kitsunetsuki/exporter/gltf/__init__.py b/kitsunetsuki/exporter/gltf/__init__.py index b78fe4c..4ac803a 100644 --- a/kitsunetsuki/exporter/gltf/__init__.py +++ b/kitsunetsuki/exporter/gltf/__init__.py @@ -263,10 +263,19 @@ def make_armature(self, parent_node, armature): } self._root['skins'].append(gltf_skin) + bone_tails_local = {} + for bone_name, bone in armature.data.bones.items(): + bone_tails_local[bone_name] = bone.tail + + bone_tails_off = {} + with Mode('EDIT'): + for bone_name, bone in armature.data.edit_bones.items(): + bone_tails_off[bone_name] = bone.tail - bone.head + if self._pose_freeze: set_active_object(armature) - # disconnect bones + # disconnect all bones with Mode('EDIT'): for bone_name, bone in armature.data.edit_bones.items(): bone.use_connect = False @@ -276,13 +285,6 @@ def make_armature(self, parent_node, armature): for bone_name, bone in armature.data.edit_bones.items(): bone.roll = 0 bone.length = 10 - - # pos_matrix = mathutils.Matrix.Translation(bone.matrix.to_translation()) - # rot_matrix = bone.matrix.to_quaternion().to_matrix() - # bone.transform(pos_matrix.inverted()) # reset origin - # bone.transform(rot_matrix.inverted()) # reset rotation - # bone.transform(pos_matrix) # restore origin - bone.tail = bone.head + mathutils.Vector((0, bone.length, 0)) bone.roll = 0 @@ -290,8 +292,21 @@ def make_armature(self, parent_node, armature): gltf_joints = {} for bone_name, bone in armature.data.bones.items(): bone_matrix = self._transform(get_bone_matrix(bone, armature)) + bone_tail_matrix = self._transform( + mathutils.Matrix.Translation(bone_tails_local[bone_name])) + if self._pose_freeze: bone_matrix = self._freeze(bone_matrix) + bone_tail_matrix = self._transform( + mathutils.Matrix.Translation(bone_tails_off[bone_name])) + + # print('\u2605' * 80) + # print(bone_name, bone_tails[bone_name], bone.matrix_basis) + # print(mathutils.Matrix.Translation(bone_tails[bone_name]).to_translation()) + # print((mathutils.Matrix.Translation(bone_tails[bone_name]) @ + # bone.matrix.to_4x4() @ + # bone.matrix.to_4x4().inverted()).to_translation()) + gltf_joint = { 'name': bone_name, @@ -299,7 +314,11 @@ def make_armature(self, parent_node, armature): 'rotation': quat_to_list(bone_matrix.to_quaternion()), 'scale': list(bone_matrix.to_scale()), 'translation': list(bone_matrix.to_translation()), - # 'matrix': matrix_to_list(bone_matrix), + 'extras': { + 'tail': { + 'translation': list(bone_tail_matrix.to_translation()), + } + } } gltf_joints[bone_name] = gltf_joint diff --git a/kitsunetsuki/exporter/gltf/animation.py b/kitsunetsuki/exporter/gltf/animation.py index 8feacb4..c60aa01 100644 --- a/kitsunetsuki/exporter/gltf/animation.py +++ b/kitsunetsuki/exporter/gltf/animation.py @@ -138,7 +138,7 @@ def make_action(self, node, armature, action): for gltf_joint_id in gltf_skin['joints']: gltf_joint = self._root['nodes'][gltf_joint_id] bone = armature.pose.bones[gltf_joint['name']] - bone_matrix = get_bone_matrix(bone, armature) + bone_matrix = self._transform(get_bone_matrix(bone, armature)) rotation = quat_to_list(bone_matrix.to_quaternion()) scale = list(bone_matrix.to_scale()) diff --git a/kitsunetsuki/gltf_inspect.py b/kitsunetsuki/gltf_inspect.py index 9cc8f97..7b8fbc6 100755 --- a/kitsunetsuki/gltf_inspect.py +++ b/kitsunetsuki/gltf_inspect.py @@ -87,10 +87,20 @@ def print_node(gltf_data, node_id, joints=None, indent=1, parent_node=None, extr extra += ' {' + ', '.join(['{}: {}'.format(*i) for i in refs]) + '}' if 'VRM' in gltf_data['extensions']: + vrm_extra = [] + vrm_bones = gltf_data['extensions']['VRM']['humanoid']['humanBones'] for vrm_bone in vrm_bones: if node_id == vrm_bone['node']: - extra += ' {VRM: %s}' % vrm_bone['bone'] + vrm_extra.append('VRM bone: {}'.format(vrm_bone['bone'])) + + for group in gltf_data['extensions']['VRM']['secondaryAnimation']['boneGroups']: + if node_id in group['bones']: + vrm_extra.append('bonegroup') + break + + if vrm_extra: + extra += ' {%s}' % ', '.join(vrm_extra) for child_node_id in gltf_node.get('children', []): child_gltf_node = gltf_data['nodes'][child_node_id]