diff options
author | Julien Duroure <julien.duroure@gmail.com> | 2019-03-23 12:01:37 +0300 |
---|---|---|
committer | Julien Duroure <julien.duroure@gmail.com> | 2019-03-23 12:01:37 +0300 |
commit | cb0a9902f57b0a5802c92be6a5a24d810e2259dc (patch) | |
tree | 10c4e5c216bc5ebb8bd724e6ff9c1edbc9b0dc20 /io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py | |
parent | 5371d6eadeafa35be8bc4f81057c3c4bfaf6d0d9 (diff) |
glTF exporter: support objects parented to bones (without skinning)
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py')
-rwxr-xr-x | io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py index 0774c8ee..d8169f7f 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py @@ -14,7 +14,7 @@ import math import bpy -from mathutils import Quaternion +from mathutils import Matrix, Quaternion from . import gltf2_blender_export_keys from io_scene_gltf2.blender.com import gltf2_blender_math @@ -90,6 +90,11 @@ def __gather_children(blender_object, export_settings): children = [] # standard children for child_object in blender_object.children: + if child_object.parent_bone: + # this is handled further down, + # as the object should be a child of the specific bone, + # not the Armature object + continue node = gather_node(child_object, export_settings) if node is not None: children.append(node) @@ -102,9 +107,55 @@ def __gather_children(blender_object, export_settings): # blender bones if blender_object.type == "ARMATURE": + root_joints = [] for blender_bone in blender_object.pose.bones: if not blender_bone.parent: - children.append(gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings)) + joint = gltf2_blender_gather_joints.gather_joint(blender_bone, export_settings) + children.append(joint) + root_joints.append(joint) + # handle objects directly parented to bones + direct_bone_children = [child for child in blender_object.children if child.parent_bone] + def find_parent_joint(joints, name): + for joint in joints: + if joint.name == name: + return joint + parent_joint = find_parent_joint(joint.children, name) + if parent_joint: + return parent_joint + return None + for child in direct_bone_children: + # find parent joint + parent_joint = find_parent_joint(root_joints, child.parent_bone) + if not parent_joint: + continue + child_node = gather_node(child, export_settings) + if child_node is None: + continue + blender_bone = blender_object.pose.bones[parent_joint.name] + # fix rotation + if export_settings[gltf2_blender_export_keys.YUP]: + rot = child_node.rotation + if rot is None: + rot = [0, 0, 0, 1] + + rot_quat = Quaternion(rot) + axis_basis_change = 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))) + mat = gltf2_blender_math.multiply(axis_basis_change, child.matrix_basis) + mat = gltf2_blender_math.multiply(child.matrix_parent_inverse, mat) + + _, rot_quat, _ = mat.decompose() + child_node.rotation = [rot_quat[1], rot_quat[2], rot_quat[3], rot_quat[0]] + + # fix translation (in blender bone's tail is the origin for children) + trans, _, _ = child.matrix_local.decompose() + if trans is None: + trans = [0, 0, 0] + # bones go down their local y axis + bone_tail = [0, blender_bone.length, 0] + child_node.translation = [trans[idx] + bone_tail[idx] for idx in range(3)] + + parent_joint.children.append(child_node) return children |