Browse Source

[-] Add ordered_bones method to ensure bone order matches armature hierarchy

- This is done for the iteration during `generate_bones_mapping`.
- Adds a test export blend file and reference export escn file.
- Another reference export needed to be updated due to a new (correct)
  bone order upon export, but does not affect the rest of that test.
Tim Klein 4 years ago
parent
commit
44a894f2ee

+ 24 - 1
io_scene_godot/converters/armature.py

@@ -81,11 +81,34 @@ def export_bone(pose_bone, bones_mapping):
     return bone
 
 
+def ordered_bones(bones):
+    """
+    Order bones by hierarchy of the bone structure. From this, the proper
+    index order of exported bones can be guaranteed.
+    """
+    ordered = []
+
+    def visit(bone):
+        nonlocal ordered
+        ordered.append(bone)
+
+        for child in bone.children:
+            visit(child)
+
+    for bone in bones:
+        if bone.parent is None:
+            visit(bone)
+
+    return ordered
+
+
 def generate_bones_mapping(export_settings, armature_obj):
     """Return a dict mapping blender bone name to godot bone id"""
     bone_id = 0
     bones_mapping = dict()
-    for pose_bone in armature_obj.pose.bones:
+
+    # Iterate in actual armature hierarchy order
+    for pose_bone in ordered_bones(armature_obj.pose.bones):
         if should_export(export_settings, armature_obj, pose_bone.bone):
             bones_mapping[pose_bone.name] = bone_id
             bone_id += 1

File diff suppressed because it is too large
+ 0 - 0
tests/reference_exports/action_with_constraint/constraint_with_undeform_bone.escn


+ 32 - 0
tests/reference_exports/armature/armature_with_arbitrary_bone_creation_order.escn

@@ -0,0 +1,32 @@
+[gd_scene load_steps=1 format=2]
+
+[node type="Spatial" name="Scene"]
+
+[node name="Armature" type="Skeleton" parent="."]
+
+bones_in_world_transform = true
+transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
+bones/0/name = "Bone.001"
+bones/0/parent = -1
+bones/0/rest = Transform(1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0)
+bones/0/pose = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
+bones/0/enabled = true
+bones/0/bound_children = []
+bones/1/name = "Root"
+bones/1/parent = 0
+bones/1/rest = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0)
+bones/1/pose = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
+bones/1/enabled = true
+bones/1/bound_children = []
+bones/2/name = "Bone.003"
+bones/2/parent = 1
+bones/2/rest = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0)
+bones/2/pose = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
+bones/2/enabled = true
+bones/2/bound_children = []
+bones/3/name = "Bone.002"
+bones/3/parent = 2
+bones/3/rest = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0)
+bones/3/pose = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)
+bones/3/enabled = true
+bones/3/bound_children = []

BIN
tests/test_scenes/armature/armature_with_arbitrary_bone_creation_order.blend


Some files were not shown because too many files changed in this diff