Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
This fixes bone components not being imported if they aren't in the
top level of the hierarchy.

Note:
The gltf bones aren't in the same order as the armature bones, this
is by design.  I considered using the bone order to map the gltf
bones to the armature bones (potentially faster), but decided it would
be too fragile, and mapping it would have potentially been slower anyway.

I loop through the bones in the armature and access the gltf bones
by name rather than the other way around because Blender's internal
data structures are mostly based on linked lists, so looping over it
is much more performant than doing lookups for each item.
  • Loading branch information
Exairnous authored and keianhzo committed Nov 3, 2022
1 parent 30c9920 commit b2fe084
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ def add_bones(gltf):
gltf_bone, bone, gltf)


def store_bones_for_import(import_settings, vnode):
# Store the glTF bones with the armature so their components can be imported once the Blender bones are created.
global armatures
children = vnode.children[:]
gltf_bones = {}
while children:
child_index = children.pop()
child_vnode = import_settings.vnodes[child_index]
if child_vnode.type == vnode.Bone:
gltf_bones[child_vnode.name] = import_settings.data.nodes[child_index]
children.extend(child_vnode.children)

armatures[vnode.blender_object.name] = {'armature': vnode.blender_object, 'gltf_bones': gltf_bones}


class glTF2ImportUserExtension:

def __init__(self):
Expand Down Expand Up @@ -118,9 +133,7 @@ def gather_import_node_after_hook(self, vnode, gltf_node, blender_object, import
#  Node hooks are not called for bones. Bones are created together with their armature.
# Unfortunately the bones are created after this hook is called so we need to wait until all nodes have been created.
if vnode.is_arma:
global armatures
armatures[vnode.blender_object.name] = {'armature': vnode.blender_object, 'gltf_bones': [
import_settings.data.nodes[child_index] for child_index in vnode.children if import_settings.vnodes[child_index].type == vnode.Bone]}
store_bones_for_import(import_settings, vnode)

def gather_import_image_after_hook(self, gltf_img, blender_image, import_settings):
# As of Blender 3.2.0 the importer doesn't import images that are not referenced by a material socket.
Expand Down Expand Up @@ -169,9 +182,7 @@ def patched_BlenderNode_create_object(gltf, vnode_id):
#  Node hooks are not called for bones. Bones are created together with their armature.
# Unfortunately the bones are created after this hook is called so we need to wait until all nodes have been created.
if vnode.is_arma:
global armatures
armatures[vnode.blender_object.name] = {'armature': vnode.blender_object, 'gltf_bones': [
gltf.data.nodes[child_index] for child_index in vnode.children if gltf.vnodes[child_index].type == vnode.Bone]}
store_bones_for_import(gltf, vnode)

return blender_object

Expand Down

0 comments on commit b2fe084

Please sign in to comment.