diff options
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py')
-rwxr-xr-x | io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py | 78 |
1 files changed, 48 insertions, 30 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py index ffc1231b..f4fd6c51 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2018-2021 The glTF-Blender-IO authors. -import mathutils +from mathutils import Matrix, Quaternion, Vector from . import gltf2_blender_export_keys from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached @@ -9,9 +9,40 @@ from io_scene_gltf2.io.com import gltf2_io from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions from ..com.gltf2_blender_extras import generate_extras +from io_scene_gltf2.blender.exp import gltf2_blender_gather_tree + + + +# TODO these 3 functions move to shared file +def __convert_swizzle_location(loc, export_settings): + """Convert a location from Blender coordinate system to glTF coordinate system.""" + if export_settings[gltf2_blender_export_keys.YUP]: + return Vector((loc[0], loc[2], -loc[1])) + else: + return Vector((loc[0], loc[1], loc[2])) + + +def __convert_swizzle_rotation(rot, export_settings): + """ + Convert a quaternion rotation from Blender coordinate system to glTF coordinate system. + + 'w' is still at first position. + """ + if export_settings[gltf2_blender_export_keys.YUP]: + return Quaternion((rot[0], rot[1], rot[3], -rot[2])) + else: + return Quaternion((rot[0], rot[1], rot[2], rot[3])) + + +def __convert_swizzle_scale(scale, export_settings): + """Convert a scale from Blender coordinate system to glTF coordinate system.""" + if export_settings[gltf2_blender_export_keys.YUP]: + return Vector((scale[0], scale[2], scale[1])) + else: + return Vector((scale[0], scale[1], scale[2])) @cached -def gather_joint(blender_object, blender_bone, export_settings): +def gather_joint_vnode(vnode, export_settings): """ Generate a glTF2 node from a blender bone, as joints in glTF2 are simply nodes. @@ -19,28 +50,19 @@ def gather_joint(blender_object, blender_bone, export_settings): :param export_settings: the settings for this export :return: a glTF2 node (acting as a joint) """ - 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))) + vtree = export_settings['vtree'] + blender_object = vtree.nodes[vnode].blender_object + blender_bone = vtree.nodes[vnode].blender_bone - # extract bone transform - if blender_bone.parent is None: - correction_matrix_local = axis_basis_change @ blender_bone.bone.matrix_local - else: - correction_matrix_local = ( - blender_bone.parent.bone.matrix_local.inverted_safe() @ - blender_bone.bone.matrix_local - ) - - if (blender_bone.bone.use_inherit_rotation == False or blender_bone.bone.inherit_scale != "FULL") and blender_bone.parent != None: - rest_mat = (blender_bone.parent.bone.matrix_local.inverted_safe() @ blender_bone.bone.matrix_local) - matrix_basis = (rest_mat.inverted_safe() @ blender_bone.parent.matrix.inverted_safe() @ blender_bone.matrix) - else: - matrix_basis = blender_bone.matrix - matrix_basis = blender_object.convert_space(pose_bone=blender_bone, matrix=matrix_basis, from_space='POSE', to_space='LOCAL') - trans, rot, sca = (correction_matrix_local @ matrix_basis).decompose() + mat = vtree.nodes[vtree.nodes[vnode].parent_uuid].matrix_world.inverted_safe() @ vtree.nodes[vnode].matrix_world + + trans, rot, sca = mat.decompose() + + trans = __convert_swizzle_location(trans, export_settings) + rot = __convert_swizzle_rotation(rot, export_settings) + sca = __convert_swizzle_scale(sca, export_settings) + translation, rotation, scale = (None, None, None) if trans[0] != 0.0 or trans[1] != 0.0 or trans[2] != 0.0: translation = [trans[0], trans[1], trans[2]] @@ -52,14 +74,8 @@ def gather_joint(blender_object, blender_bone, export_settings): # traverse into children children = [] - if export_settings["gltf_def_bones"] is False: - for bone in blender_bone.children: - children.append(gather_joint(blender_object, bone, export_settings)) - else: - _, children_, _ = gltf2_blender_gather_skins.get_bone_tree(None, blender_bone.id_data) - if blender_bone.name in children_.keys(): - for bone in children_[blender_bone.name]: - children.append(gather_joint(blender_object, blender_bone.id_data.pose.bones[bone], export_settings)) + for bone_uuid in [c for c in vtree.nodes[vnode].children if vtree.nodes[c].blender_type == gltf2_blender_gather_tree.VExportNode.BONE]: + children.append(gather_joint_vnode(bone_uuid, export_settings)) # finally add to the joints array containing all the joints in the hierarchy node = gltf2_io.Node( @@ -79,6 +95,8 @@ def gather_joint(blender_object, blender_bone, export_settings): export_user_extensions('gather_joint_hook', export_settings, node, blender_bone) + vtree.nodes[vnode].node = node + return node def __gather_extras(blender_bone, export_settings): |