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!
This commit is contained in:
parent
1ead56feb5
commit
905f58dedb
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 _():
|
||||
|
|
Loading…
Reference in New Issue