diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py index dc3551f33b7da65c9356a651f7c2de6c4d6fb580..8ab4b2a9a5d2bfc7d3fe98e5c5bc142390e677d1 100644 --- a/io_scene_fbx/fbx_utils.py +++ b/io_scene_fbx/fbx_utils.py @@ -881,7 +881,17 @@ class ObjectWrapper(metaclass=MetaObjectWrapper): def get_parent(self): if self._tag == 'OB': - return ObjectWrapper(self.bdata.parent) + if (self.bdata.parent and self.bdata.parent.type == 'ARMATURE' and + self.bdata.parent_type == 'BONE' and self.bdata.parent_bone): + # Try to parent to a bone. + bo_par = self.bdata.parent.pose.bones.get(self.bdata.parent_bone, None) + if (bo_par): + return ObjectWrapper(bo_par, self.bdata.parent) + else: # Fallback to mere object parenting. + return ObjectWrapper(self.bdata.parent) + else: + # Mere object parenting. + return ObjectWrapper(self.bdata.parent) elif self._tag == 'DP': return ObjectWrapper(self.bdata.parent or self._ref) else: # self._tag == 'BO' @@ -983,6 +993,14 @@ class ObjectWrapper(metaclass=MetaObjectWrapper): elif self.bdata.type == 'CAMERA': matrix = matrix * MAT_CONVERT_CAMERA + if self._tag in {'DP', 'OB'} and parent: + # To get *real* local matrix of a child object, we also need to take into account its inverted par mat! + matrix = self.bdata.matrix_parent_inverse * matrix + if parent._tag == 'BO': + # In bone parent case, we get transformation in **bone tip** space (sigh). + # Have to bring it back into bone root, which is FBX expected value. + matrix = Matrix.Translation((0, (parent.bdata.tail - parent.bdata.head).length, 0)) * matrix + # Our matrix is in local space, time to bring it in its final desired space. if parent: if is_global: diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py index 8a1028c95395c78783204e2f72928d1979a35a27..11f76ac5ff5283684894d2bfd611d3aa69952a29 100644 --- a/io_scene_fbx/import_fbx.py +++ b/io_scene_fbx/import_fbx.py @@ -1288,6 +1288,12 @@ class FbxImportHelperNode: if self._parent is not None: self._parent.children.append(self) + def __repr__(self): + if self.fbx_elem: + return self.fbx_elem.props[1].decode() + else: + return "None" + def print_info(self, indent=0): print(" " * indent + (self.fbx_name if self.fbx_name else "(Null)") + ("[root]" if self.is_root else "") @@ -1636,6 +1642,7 @@ class FbxImportHelperNode: child.pre_matrix = self.bone_child_matrix child_obj.matrix_basis = child.get_matrix() + return None else: # child is not a bone obj = self.build_node(fbx_tmpl, settings)