Fix T41766: FBX (binary) exporter does not export actions with one frame animations.

When we are exporting actions or strips from NLA, and an evaluated anim leads to no anim
at all (like single-keyed actions or pure static ones), key all start and end frames.

Note this might be overkill (due to baked anim, we will key *all* transform channels),
but probably better than skipping completely those actions!
This commit is contained in:
Bastien Montagne 2014-09-19 14:31:17 +02:00
parent aeb4cb010e
commit f7ef101d09
Notes: blender-bot 2023-02-14 20:04:12 +01:00
Referenced by issue #41766, FBX (binary) exporter does not export actions with one frame animations
4 changed files with 32 additions and 18 deletions

View File

@ -1789,18 +1789,19 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
# Objects-like loc/rot/scale...
for ob_obj, anims in animdata_ob.items():
for anim in anims:
anim.simplfy(simplify_fac, bake_step)
if anim:
for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
anim_data = animations.get(obj_key)
if anim_data is None:
anim_data = animations[obj_key] = ("dummy_unused_key", OrderedDict())
anim_data[1][fbx_group] = (group_key, group, fbx_gname)
anim.simplfy(simplify_fac, bake_step, force_keep)
if not anim:
continue
for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
anim_data = animations.get(obj_key)
if anim_data is None:
anim_data = animations[obj_key] = ("dummy_unused_key", OrderedDict())
anim_data[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)
anim_shape.simplfy(simplify_fac, bake_step, force_keep)
if not anim_shape:
continue
for elem_key, group_key, group, fbx_group, fbx_gname in anim_shape.get_final_data(scene, ref_id, force_keep):

View File

@ -679,7 +679,7 @@ class AnimationCurveNodeWrapper:
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):
def simplfy(self, fac, step, force_keep=False):
"""
Simplifies sampled curves by only enabling samples when:
* their values differ significantly from the previous sample ones, or
@ -726,6 +726,12 @@ class AnimationCurveNodeWrapper:
p_keyed[idx] = (currframe, val)
are_keyed[idx] = True
p_currframe, p_key, p_key_write = currframe, key, key_write
# If we write nothing (action doing nothing) and are in 'force_keep' mode, we key everything! :P
# See T41766.
if (force_keep and not self):
are_keyed[:] = [True] * len(are_keyed)
# If we did key something, ensure first and last sampled values are keyed as well.
for idx, is_keyed in enumerate(are_keyed):
if is_keyed:

View File

@ -1880,18 +1880,19 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
# Objects-like loc/rot/scale...
for ob_obj, anims in animdata_ob.items():
for anim in anims:
anim.simplfy(simplify_fac, bake_step)
if anim:
for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
anim_data = animations.get(obj_key)
if anim_data is None:
anim_data = animations[obj_key] = ("dummy_unused_key", OrderedDict())
anim_data[1][fbx_group] = (group_key, group, fbx_gname)
anim.simplfy(simplify_fac, bake_step, force_keep)
if not anim:
continue
for obj_key, group_key, group, fbx_group, fbx_gname in anim.get_final_data(scene, ref_id, force_keep):
anim_data = animations.get(obj_key)
if anim_data is None:
anim_data = animations[obj_key] = ("dummy_unused_key", OrderedDict())
anim_data[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)
anim_shape.simplfy(simplify_fac, bake_step, force_keep)
if not anim_shape:
continue
for elem_key, group_key, group, fbx_group, fbx_gname in anim_shape.get_final_data(scene, ref_id, force_keep):

View File

@ -679,7 +679,7 @@ class AnimationCurveNodeWrapper:
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):
def simplfy(self, fac, step, force_keep=False):
"""
Simplifies sampled curves by only enabling samples when:
* their values differ significantly from the previous sample ones, or
@ -726,6 +726,12 @@ class AnimationCurveNodeWrapper:
p_keyed[idx] = (currframe, val)
are_keyed[idx] = True
p_currframe, p_key, p_key_write = currframe, key, key_write
# If we write nothing (action doing nothing) and are in 'force_keep' mode, we key everything! :P
# See T41766.
if (force_keep and not self):
are_keyed[:] = [True] * len(are_keyed)
# If we did key something, ensure first and last sampled values are keyed as well.
for idx, is_keyed in enumerate(are_keyed):
if is_keyed: