Fix #104875: Animated dupli instances export frozen in place #104876

Merged
Thomas Barlow merged 4 commits from Mysteryem/blender-addons:fbx_export_anim_instances_104875 into main 2023-09-11 17:29:15 +02:00
Showing only changes of commit b76c9ec89f - Show all commits

View File

@ -2249,15 +2249,10 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
force_sek, (cam.dof.focus_distance,))
animdata_cameras[cam_key] = (acnode_lens, acnode_focus_distance, cam)
# Find all animated objects that have dupli instances, so that `depsgraph.object_instances` only has to be iterated
# at most once per frame.
original_parents_with_duplis = set()
for ob_obj in animdata_ob:
for dp_obj in ob_obj.dupli_list_gen(depsgraph):
if dp_obj in objects:
original_parents_with_duplis.add(ob_obj.bdata)
break
has_animated_duplis = bool(original_parents_with_duplis)
# Get all parent bdata of animated dupli instances, so that we can quickly identify which instances in
# `depsgraph.object_instances` are animated and need their ObjectWrappers' matrices updated each frame.
dupli_parent_bdata = {dup.get_parent().bdata for dup in animdata_ob if dup.is_dupli}
has_animated_duplis = bool(dupli_parent_bdata)
currframe = f_start
while currframe <= f_end:
@ -2268,11 +2263,9 @@ def fbx_animations_do(scene_data, ref_id, f_start, f_end, start_zero, objects=No
# Changing the scene's frame invalidates existing dupli instances. To get the updated matrices of duplis for
# this frame, we must get the duplis from the depsgraph again.
for dup in depsgraph.object_instances:
# This condition matches the condition for duplis to be returned by ObjectWrapper.dupli_list_gen, which
# was used to populate original_parents_with_duplis.
if (parent := dup.parent) and parent.original in original_parents_with_duplis:
# ObjectWrapper caches its instances. Creating a new instance updates the existing instance with the
# current frame's matrix.
if (parent := dup.parent) and parent.original in dupli_parent_bdata:
# ObjectWrapper caches its instances. Attempting to create a new instance updates the existing
# ObjectWrapper instance with the current frame's matrix and then returns the existing instance.
ObjectWrapper(dup)
for ob_obj, (anim_loc, anim_rot, anim_scale) in animdata_ob.items():
# We compute baked loc/rot/scale for all objects (rot being euler-compat with previous value!).