diff options
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py')
-rwxr-xr-x | io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py | 143 |
1 files changed, 48 insertions, 95 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py index e5534c5a..136d654d 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py @@ -10,10 +10,12 @@ from io_scene_gltf2.io.com import gltf2_io_constants from io_scene_gltf2.blender.exp import gltf2_blender_gather_accessors from io_scene_gltf2.blender.exp import gltf2_blender_gather_joints from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions +from io_scene_gltf2.blender.exp import gltf2_blender_gather_tree +from io_scene_gltf2.blender.exp.gltf2_blender_gather_tree import VExportNode @cached -def gather_skin(blender_object, export_settings): +def gather_skin(armature_uuid, export_settings): """ Gather armatures, bones etc into a glTF2 skin object. @@ -21,78 +23,70 @@ def gather_skin(blender_object, export_settings): :param export_settings: :return: a glTF2 skin object """ - if not __filter_skin(blender_object, export_settings): + + blender_armature_object = export_settings['vtree'].nodes[armature_uuid].blender_object + + if not __filter_skin(blender_armature_object, export_settings): return None skin = gltf2_io.Skin( - extensions=__gather_extensions(blender_object, export_settings), - extras=__gather_extras(blender_object, export_settings), - inverse_bind_matrices=__gather_inverse_bind_matrices(blender_object, export_settings), - joints=__gather_joints(blender_object, export_settings), - name=__gather_name(blender_object, export_settings), - skeleton=__gather_skeleton(blender_object, export_settings) + extensions=__gather_extensions(blender_armature_object, export_settings), + extras=__gather_extras(blender_armature_object, export_settings), + inverse_bind_matrices=__gather_inverse_bind_matrices(armature_uuid, export_settings), + joints=__gather_joints(armature_uuid, export_settings), + name=__gather_name(blender_armature_object, export_settings), + skeleton=__gather_skeleton(blender_armature_object, export_settings) ) - export_user_extensions('gather_skin_hook', export_settings, skin, blender_object) + # If armature is not exported, joints will be empty. + # Do not construct skin in that case + if len(skin.joints) == 0: + return None + + export_user_extensions('gather_skin_hook', export_settings, skin, blender_armature_object) return skin -def __filter_skin(blender_object, export_settings): +def __filter_skin(blender_armature_object, export_settings): if not export_settings[gltf2_blender_export_keys.SKINS]: return False - if blender_object.type != 'ARMATURE' or len(blender_object.pose.bones) == 0: + if blender_armature_object.type != 'ARMATURE' or len(blender_armature_object.pose.bones) == 0: return False return True -def __gather_extensions(blender_object, export_settings): +def __gather_extensions(blender_armature_object, export_settings): return None -def __gather_extras(blender_object, export_settings): +def __gather_extras(blender_armature_object, export_settings): return None -def __gather_inverse_bind_matrices(blender_object, export_settings): +def __gather_inverse_bind_matrices(armature_uuid, export_settings): + + blender_armature_object = export_settings['vtree'].nodes[armature_uuid].blender_object + axis_basis_change = mathutils.Matrix.Identity(4) if export_settings[gltf2_blender_export_keys.YUP]: axis_basis_change = mathutils.Matrix( ((1.0, 0.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, -1.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0))) - if export_settings['gltf_def_bones'] is False: - # build the hierarchy of nodes out of the bones - root_bones = [] - for blender_bone in blender_object.pose.bones: - if not blender_bone.parent: - root_bones.append(blender_bone) - else: - _, children_, root_bones = get_bone_tree(None, blender_object) - - matrices = [] - - # traverse the matrices in the same order as the joints and compute the inverse bind matrix + bones_uuid = export_settings['vtree'].get_all_bones(armature_uuid) def __collect_matrices(bone): inverse_bind_matrix = ( axis_basis_change @ ( - blender_object.matrix_world @ + blender_armature_object.matrix_world @ bone.bone.matrix_local ) ).inverted_safe() matrices.append(inverse_bind_matrix) - if export_settings['gltf_def_bones'] is False: - for child in bone.children: - __collect_matrices(child) - else: - if bone.name in children_.keys(): - for child in children_[bone.name]: - __collect_matrices(blender_object.pose.bones[child]) - - # start with the "root" bones and recurse into children, in the same ordering as the how joints are gathered - for root_bone in root_bones: - __collect_matrices(root_bone) + matrices = [] + for b in bones_uuid: + __collect_matrices(blender_armature_object.pose.bones[export_settings['vtree'].nodes[b].blender_bone.name]) # flatten the matrices inverse_matrices = [] @@ -113,67 +107,26 @@ def __gather_inverse_bind_matrices(blender_object, export_settings): ) -def __gather_joints(blender_object, export_settings): - root_joints = [] - if export_settings['gltf_def_bones'] is False: - # build the hierarchy of nodes out of the bones - for blender_bone in blender_object.pose.bones: - if not blender_bone.parent: - root_joints.append(gltf2_blender_gather_joints.gather_joint(blender_object, blender_bone, export_settings)) - else: - _, children_, root_joints = get_bone_tree(None, blender_object) - root_joints = [gltf2_blender_gather_joints.gather_joint(blender_object, i, export_settings) for i in root_joints] - - # joints is a flat list containing all nodes belonging to the skin - joints = [] - - def __collect_joints(node): - joints.append(node) - if export_settings['gltf_def_bones'] is False: - for child in node.children: - __collect_joints(child) - else: - if node.name in children_.keys(): - for child in children_[node.name]: - __collect_joints(gltf2_blender_gather_joints.gather_joint(blender_object, blender_object.pose.bones[child], export_settings)) - - for joint in root_joints: - __collect_joints(joint) +def __gather_joints(armature_uuid, export_settings): + + blender_armature_object = export_settings['vtree'].nodes[armature_uuid].blender_object + + all_armature_children = export_settings['vtree'].nodes[armature_uuid].children + root_bones_uuid = [c for c in all_armature_children if export_settings['vtree'].nodes[c].blender_type == VExportNode.BONE] + # Create bone nodes + for root_bone_uuid in root_bones_uuid: + gltf2_blender_gather_joints.gather_joint_vnode(root_bone_uuid, export_settings) + + bones_uuid = export_settings['vtree'].get_all_bones(armature_uuid) + joints = [export_settings['vtree'].nodes[b].node for b in bones_uuid] return joints -def __gather_name(blender_object, export_settings): - return blender_object.name +def __gather_name(blender_armature_object, export_settings): + return blender_armature_object.name -def __gather_skeleton(blender_object, export_settings): +def __gather_skeleton(blender_armature_object, export_settings): # In the future support the result of https://github.com/KhronosGroup/glTF/pull/1195 - return None # gltf2_blender_gather_nodes.gather_node(blender_object, blender_scene, export_settings) - -@cached -def get_bone_tree(blender_dummy, blender_object): - - bones = [] - children = {} - root_bones = [] - - def get_parent(bone): - bones.append(bone.name) - if bone.parent is not None: - if bone.parent.name not in children.keys(): - children[bone.parent.name] = [] - children[bone.parent.name].append(bone.name) - get_parent(bone.parent) - else: - root_bones.append(bone.name) - - for bone in [b for b in blender_object.data.bones if b.use_deform is True]: - get_parent(bone) - - # remove duplicates - for k, v in children.items(): - children[k] = list(set(v)) - list_ = list(set(bones)) - root_ = list(set(root_bones)) - return [blender_object.data.bones[b] for b in list_], children, [blender_object.pose.bones[b] for b in root_] + return None |