[Bf-extensions-cvs] [106cb51a] master: glTF exporter: fix object parented to bones with own animation

Julien Duroure noreply at git.blender.org
Wed Oct 5 10:08:11 CEST 2022


Commit: 106cb51ab9ad26c473afa95440db3f2958af3599
Author: Julien Duroure
Date:   Wed Oct 5 10:07:58 2022 +0200
Branches: master
https://developer.blender.org/rBA106cb51ab9ad26c473afa95440db3f2958af3599

glTF exporter: fix object parented to bones with own animation

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

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py

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

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 2a630e3f..8775084b 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -4,7 +4,7 @@
 bl_info = {
     'name': 'glTF 2.0 format',
     'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (3, 4, 31),
+    "version": (3, 4, 32),
     'blender': (3, 3, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
index b872aeaa..33af9b3e 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
@@ -19,15 +19,35 @@ from io_scene_gltf2.blender.exp.gltf2_blender_gather_tree import VExportNode
 from . import gltf2_blender_export_keys
 
 
-def gather_channels_baked(obj_uuid, export_settings):
+def gather_channels_baked(obj_uuid, frame_range, export_settings):
     channels = []
 
     # If no animation in file, no need to bake
     if len(bpy.data.actions) == 0:
         return None
 
-    start_frame = min([v[0] for v in [a.frame_range for a in bpy.data.actions]])
-    end_frame = max([v[1] for v in [a.frame_range for a in bpy.data.actions]])
+    blender_obj = export_settings['vtree'].nodes[obj_uuid].blender_object
+
+    if frame_range is None:
+        start_frame = min([v[0] for v in [a.frame_range for a in bpy.data.actions]])
+        end_frame = max([v[1] for v in [a.frame_range for a in bpy.data.actions]])
+    else:
+        if blender_obj.animation_data and blender_obj.animation_data.action:
+            # Coming from object parented to bone, and object is also animated. So using range action
+            start_frame, end_frame = blender_obj.animation_data.action.frame_range[0], blender_obj.animation_data.action.frame_range[1]
+        else:
+            # Coming from object parented to bone, and object is not animated. So using range from armature
+            start_frame, end_frame = frame_range
+
+    # use action if exists, else obj_uuid
+    # When an object need some forced baked, there are 2 situtations:
+    # - Non animated object, but there are some selection, so we need to bake
+    # - Object parented to bone. So we need to bake, because of inverse transforms on non default TRS armatures
+    # In this last case, there are 2 situations :
+    # - Object is also animated, so use the action name as key for caching
+    # - Object is not animated, so use obj_uuid as key for caching, like for non animated object (case 1)
+
+    key_action = blender_obj.animation_data.action.name if blender_obj.animation_data and blender_obj.animation_data.action else obj_uuid
 
     for p in ["location", "rotation_quaternion", "scale"]:
         channel = gather_animation_channel(
@@ -39,7 +59,7 @@ def gather_channels_baked(obj_uuid, export_settings):
             start_frame,
             end_frame,
             False,
-            obj_uuid, # Use obj uuid as action name for caching
+            key_action, # Use obj uuid as action name for caching (or action name if case of object parented to bone and animated)
             None,
             False #If Object is not animated, don't keep animation for this channel
             )
@@ -158,7 +178,7 @@ def gather_animation_channels(obj_uuid: int,
                 children_obj_parent_to_bones.extend([child for child in export_settings['vtree'].nodes[bone_uuid].children if export_settings['vtree'].nodes[child].blender_type not in [VExportNode.BONE, VExportNode.ARMATURE]])
             for child_uuid in children_obj_parent_to_bones:
 
-                channels_baked = gather_channels_baked(child_uuid, export_settings)
+                channels_baked = gather_channels_baked(child_uuid, (bake_range_start, bake_range_end), export_settings)
                 if channels_baked is not None:
                     channels.extend(channels_baked)
 
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
index 7a6fd6c3..cf067e53 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
@@ -41,7 +41,7 @@ def gather_animations(  obj_uuid: int,
             # We also have to check if this is a skinned mesh, because we don't have to force animation baking on this case
             # (skinned meshes TRS must be ignored, says glTF specification)
             if export_settings['vtree'].nodes[obj_uuid].skin is None:
-                channels = gltf2_blender_gather_animation_channels.gather_channels_baked(obj_uuid, export_settings)
+                channels = gltf2_blender_gather_animation_channels.gather_channels_baked(obj_uuid, None, export_settings)
                 if channels is not None:
                     animation = gltf2_io.Animation(
                             channels=channels,
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py
index 3539b968..4ca7cdf5 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py
@@ -89,6 +89,7 @@ def objectcache(func):
         if cache_key_args[0] not in func.__objectcache.keys():
             result = func(*args)
             func.__objectcache = result
+            # Here are the key used: result[obj_uuid][action_name][frame]
             return result[cache_key_args[0]][cache_key_args[1]][cache_key_args[4]]
         # object is in cache, but not this action
         # We need to keep other actions



More information about the Bf-extensions-cvs mailing list