[Bf-extensions-cvs] [dd32b1c] fbx_io_development: FBX export: add double-animation mess to shapes, this time they are read by Unity...
Bastien Montagne
noreply at git.blender.org
Mon Jun 16 14:46:03 CEST 2014
Commit: dd32b1cdbddf87ef8b5722fe7c6a8968823e4e8b
Author: Bastien Montagne
Date: Mon Jun 16 14:40:33 2014 +0200
https://developer.blender.org/rBAdd32b1cdbddf87ef8b5722fe7c6a8968823e4e8b
FBX export: add double-animation mess to shapes, this time they are read by Unity...
FBX makes me cry... :'(
I would not want my worst enemy to have to understand and follow that code.
===================================================================
M io_scene_fbx/export_fbx_bin.py
M io_scene_fbx/fbx_utils.py
===================================================================
diff --git a/io_scene_fbx/export_fbx_bin.py b/io_scene_fbx/export_fbx_bin.py
index 9eaf029..8c804ba 100644
--- a/io_scene_fbx/export_fbx_bin.py
+++ b/io_scene_fbx/export_fbx_bin.py
@@ -1721,7 +1721,10 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
if not me.shape_keys.use_relative:
continue
for shape, (channel_key, geom_key, _shape_verts_co, _shape_verts_idx) in shapes.items():
- animdata_shapes[channel_key] = (AnimationCurveNodeWrapper(channel_key, 'SHAPE_KEY', (0.0,)), me, shape)
+ acnode = AnimationCurveNodeWrapper(channel_key, 'SHAPE_KEY', (0.0,))
+ # Sooooo happy to have to twist again like a mad snake... Yes, we need to write those curves twice. :/
+ acnode.add_group(me_key, shape.name, shape.name, (shape.name,))
+ animdata_shapes[channel_key] = (acnode, me, shape)
p_rots = {}
@@ -1754,24 +1757,23 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
# And now, produce final data (usable by FBX export code)
# Objects-like loc/rot/scale...
for ob_obj, anims in animdata_ob.items():
- final_keys = OrderedDict()
for anim in anims:
anim.simplfy(simplify_fac, bake_step)
if anim:
- group_key, group, fbx_group, fbx_gname = anim.get_final_data(scene, ref_id, force_keep)
- final_keys[fbx_group] = (group_key, group, fbx_gname)
- if final_keys:
- #animations[ob_obj] = (get_blender_anim_layer_key(scene, ob_obj.bdata), final_keys)
- animations[ob_obj.key] = ("dummy_unused_key", final_keys)
+ for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
+ if obj_key not in animations:
+ animations[obj_key] = ("dummy_unused_key", OrderedDict())
+ animations[obj_key][1][fbx_group] = (group_key, group, fbx_gname)
# And meshes' shape keys.
for channel_key, (anim_shape, me, shape) in animdata_shapes.items():
final_keys = OrderedDict()
anim_shape.simplfy(simplify_fac, bake_step)
if anim_shape:
- group_key, group, fbx_group, fbx_gname = anim_shape.get_final_data(scene, ref_id, force_keep)
- final_keys[fbx_group] = (group_key, group, fbx_gname)
- animations[channel_key] = ("dummy_unused_key", final_keys)
+ for elem_key, group_key, group, fbx_group, fbx_gname in anim_shape.get_final_data(scene, ref_id, force_keep):
+ if elem_key not in animations:
+ animations[elem_key] = ("dummy_unused_key", OrderedDict())
+ animations[elem_key][1][fbx_group] = (group_key, group, fbx_gname)
astack_key = get_blender_anim_stack_key(scene, ref_id)
alayer_key = get_blender_anim_layer_key(scene, ref_id)
diff --git a/io_scene_fbx/fbx_utils.py b/io_scene_fbx/fbx_utils.py
index af5520b..4b477e8 100644
--- a/io_scene_fbx/fbx_utils.py
+++ b/io_scene_fbx/fbx_utils.py
@@ -614,13 +614,13 @@ class AnimationCurveNodeWrapper:
This class provides a same common interface for all (FBX-wise) AnimationCurveNode and AnimationCurve elements,
and easy API to handle those.
"""
- __slots__ = ('elem_key', '_keys', 'default_values', 'fbx_group', 'fbx_gname', 'fbx_props')
+ __slots__ = ('elem_keys', '_keys', 'default_values', 'fbx_group', 'fbx_gname', 'fbx_props')
kinds = {
'LCL_TRANSLATION': ("Lcl Translation", "T", ("X", "Y", "Z")),
'LCL_ROTATION': ("Lcl Rotation", "R", ("X", "Y", "Z")),
'LCL_SCALING': ("Lcl Scaling", "S", ("X", "Y", "Z")),
- 'SHAPE_KEY': ("DeformPercent", "DeformPercent", ("DeformPercent",))
+ 'SHAPE_KEY': ("DeformPercent", "DeformPercent", ("DeformPercent",)),
}
def __init__(self, elem_key, kind, default_values=...):
@@ -628,27 +628,38 @@ class AnimationCurveNodeWrapper:
bdata might be an Object, DupliObject, Bone or PoseBone.
If Bone or PoseBone, armature Object must be provided.
"""
- self.elem_key = elem_key
+ self.elem_keys = [elem_key]
assert(kind in self.kinds)
- self.fbx_group = self.kinds[kind][0]
- self.fbx_gname = self.kinds[kind][1]
- self.fbx_props = self.kinds[kind][2]
+ self.fbx_group = [self.kinds[kind][0]]
+ self.fbx_gname = [self.kinds[kind][1]]
+ self.fbx_props = [self.kinds[kind][2]]
self._keys = [] # (frame, values, write_flags)
if default_values is not ...:
- assert(len(default_values) == len(self.fbx_props))
+ assert(len(default_values) == len(self.fbx_props[0]))
self.default_values = default_values
else:
- self.default_values = (0.0) * len(self.fbx_props)
+ self.default_values = (0.0) * len(self.fbx_props[0])
def __bool__(self):
# We are 'True' if we do have some validated keyframes...
return self._keys and True in ((True in k[2]) for k in self._keys)
+ def add_group(self, elem_key, fbx_group, fbx_gname, fbx_props):
+ """
+ Add another whole group stuff (curvenode, animated item/prop + curvnode/curve identifiers).
+ E.g. Shapes animations is written twice, houra!
+ """
+ assert(len(fbx_props) == len(self.fbx_props[0]))
+ self.elem_keys.append(elem_key)
+ self.fbx_group.append(fbx_group)
+ self.fbx_gname.append(fbx_gname)
+ self.fbx_props.append(fbx_props)
+
def add_keyframe(self, frame, values):
"""
Add a new keyframe to all curves of the group.
"""
- assert(len(values) == len(self.fbx_props))
+ assert(len(values) == len(self.fbx_props[0]))
self._keys.append((frame, values, [True] * len(values))) # write everything by default.
def simplfy(self, fac, step):
@@ -705,7 +716,7 @@ class AnimationCurveNodeWrapper:
def get_final_data(self, scene, ref_id, force_keep=False):
"""
- Produce final anim data for this 'curvenode'.
+ Yield final anim data for this 'curvenode' (for all curvenodes defined).
force_keep is to force to keep a curve even if it only has one valid keyframe.
"""
curves = [[] for k in self._keys[0][1]]
@@ -714,15 +725,15 @@ class AnimationCurveNodeWrapper:
if wrt:
curve.append((currframe, val))
- group_key = get_blender_anim_curve_node_key(scene, ref_id, self.elem_key, self.fbx_group)
- group = OrderedDict()
- for c, def_val, fbx_item in zip(curves, self.default_values, self.fbx_props):
- fbx_item = FBX_ANIM_PROPSGROUP_NAME + "|" + fbx_item
- curve_key = get_blender_anim_curve_key(scene, ref_id, self.elem_key, self.fbx_group, fbx_item)
- # (curve key, default value, keyframes, write flag).
- group[fbx_item] = (curve_key, def_val, c, True if (len(c) > 1 or (len(c) > 0 and force_keep)) else False)
-
- return group_key, group, self.fbx_group, self.fbx_gname
+ for elem_key, fbx_group, fbx_gname, fbx_props in zip(self.elem_keys, self.fbx_group, self.fbx_gname, self.fbx_props):
+ group_key = get_blender_anim_curve_node_key(scene, ref_id, elem_key, fbx_group)
+ group = OrderedDict()
+ for c, def_val, fbx_item in zip(curves, self.default_values, fbx_props):
+ fbx_item = FBX_ANIM_PROPSGROUP_NAME + "|" + fbx_item
+ curve_key = get_blender_anim_curve_key(scene, ref_id, elem_key, fbx_group, fbx_item)
+ # (curve key, default value, keyframes, write flag).
+ group[fbx_item] = (curve_key, def_val, c, True if (len(c) > 1 or (len(c) > 0 and force_keep)) else False)
+ yield elem_key, group_key, group, fbx_group, fbx_gname
##### FBX objects generators. #####
More information about the Bf-extensions-cvs
mailing list