[Bf-extensions-cvs] [905f58d] master: FBX IO: fix handling or rigged meshes transformations.

Bastien Montagne noreply at git.blender.org
Sun Jul 20 20:56:06 CEST 2014


Commit: 905f58dedb4d8a7b98a1b71510afdea84a9a97ba
Author: Bastien Montagne
Date:   Sun Jul 20 18:53:46 2014 +0200
Branches: master
https://developer.blender.org/rBA905f58dedb4d8a7b98a1b71510afdea84a9a97ba

FBX IO: fix handling or rigged meshes transformations.

We have to convert them to global space on export, and back into local space on import...

Issue raised by jrestemeier (Jens Restemeier) in D607, thanks!

===================================================================

M	io_scene_fbx/export_fbx_bin.py
M	io_scene_fbx/fbx_utils.py
M	io_scene_fbx/import_fbx.py

===================================================================

diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index c71e2ce..de38f0a 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -1692,6 +1692,8 @@ def fbx_skeleton_from_armature(scene, settings, arm_obj, objects, data_meshes,
 
         # We don't want a regular parent relationship for those in FBX...
         arm_parents.add((arm_obj, ob_obj))
+        # Needed to handle matrices/spaces (since we do not parent them to 'armature' in FBX :/ ).
+        ob_obj.parented_to_armature = True
 
     objects.update(bones)
 
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index 32b5bbb..3dd234d 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -803,7 +803,10 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
     Note since a same Blender object might be 'mapped' to several FBX models (esp. with duplis),
     we need to use a key to identify each.
     """
-    __slots__ = ('name', 'key', 'bdata', '_tag', '_ref', '_dupli_matrix')
+    __slots__ = (
+        'name', 'key', 'bdata', 'parented_to_armature',
+        '_tag', '_ref', '_dupli_matrix'
+    )
 
     @classmethod
     def cache_clear(cls):
@@ -837,6 +840,7 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
             self.name = get_blenderID_name(bdata)
             self.bdata = bdata
             self._ref = armature
+        self.parented_to_armature = False
 
     def __eq__(self, other):
         return isinstance(other, self.__class__) and self.key == other.key
@@ -936,6 +940,10 @@ class ObjectWrapper(metaclass=MetaObjectWrapper):
         is_global = (not local_space and
                      (global_space or not (self._tag in {'DP', 'BO'} or self.has_valid_parent(scene_data.objects))))
 
+        # Objects (meshes!) parented to armature are not parented to anything in FBX, hence we need them
+        # in global space, which is their 'virtual' local space...
+        is_global = is_global or self.parented_to_armature
+
         # Since we have to apply corrections to some types of object, we always need local Blender space here...
         matrix = self.matrix_rest_local if rest else self.matrix_local
         parent = self.parent
diff --git a/io_scene_fbx/import_fbx.py b/io_scene_fbx/import_fbx.py
index 1e148b7..70af67b 100644
--- a/io_scene_fbx/import_fbx.py
+++ b/io_scene_fbx/import_fbx.py
@@ -502,7 +502,7 @@ def blen_read_armatures_add_bone(bl_obj, bl_arm, bones, b_uuid, matrices, fbx_tm
     return ebo
 
 
-def blen_read_armatures(fbx_tmpl, armatures, fbx_bones_to_fake_object, scene, global_matrix):
+def blen_read_armatures(fbx_tmpl, armatures, fbx_bones_to_fake_object, scene, global_matrix, arm_parents):
     from mathutils import Matrix
 
     if global_matrix is None:
@@ -557,6 +557,8 @@ def blen_read_armatures(fbx_tmpl, armatures, fbx_bones_to_fake_object, scene, gl
 
             ob_me.parent = bl_adata
             ob_me.matrix_basis = me_mat_back
+            # Store the pair for later space corrections (bring back mesh in parent space).
+            arm_parents.add((bl_adata, ob_me))
         bl_adata.matrix_basis = arm_mat_back
 
         # Set Pose transformations...
@@ -1636,10 +1638,11 @@ def load(operator, context, filepath="",
     _(); del _
 
     # II) We can finish armatures processing.
+    arm_parents = set()
     def _():
         fbx_tmpl = fbx_template_get((b'Model', b'KFbxNode'))
 
-        blen_read_armatures(fbx_tmpl, armatures, fbx_bones_to_fake_object, scene, global_matrix)
+        blen_read_armatures(fbx_tmpl, armatures, fbx_bones_to_fake_object, scene, global_matrix, arm_parents)
     _(); del _
 
     def _():
@@ -1684,6 +1687,12 @@ def load(operator, context, filepath="",
 
                 if blen_data.parent is None:
                     blen_data.matrix_basis = global_matrix * blen_data.matrix_basis
+
+            for (ob_arm, ob_me) in arm_parents:
+                # Rigged meshes are in global space in FBX...
+                ob_me.matrix_basis = global_matrix * ob_me.matrix_basis
+                # And reverse-apply armature transform, so that it gets valid parented (local) position!
+                ob_me.matrix_parent_inverse = ob_arm.matrix_basis.inverted()
     _(); del _
 
     def _():



More information about the Bf-extensions-cvs mailing list