diff options
Diffstat (limited to 'io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py')
-rwxr-xr-x | io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py | 78 |
1 files changed, 64 insertions, 14 deletions
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 39f09d52..828d1955 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py @@ -11,7 +11,36 @@ from ..com.gltf2_blender_extras import generate_extras from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions -def gather_animations(blender_object: bpy.types.Object, +def __gather_channels_baked(obj_uuid, 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]]) + + for p in ["location", "rotation_quaternion", "scale"]: + channel = gltf2_blender_gather_animation_channels.gather_animation_channel( + obj_uuid, + (), + export_settings, + None, + p, + start_frame, + end_frame, + False, + obj_uuid, # Use obj uuid as action name for caching + None, + False #If Object is not animated, don't keep animation for this channel + ) + if channel is not None: + channels.append(channel) + + return channels if len(channels) > 0 else None + +def gather_animations( obj_uuid: int, tracks: typing.Dict[str, typing.List[int]], offset: int, export_settings) -> typing.Tuple[typing.List[gltf2_io.Animation], typing.Dict[str, typing.List[int]]]: @@ -24,11 +53,29 @@ def gather_animations(blender_object: bpy.types.Object, """ animations = [] + blender_object = export_settings['vtree'].nodes[obj_uuid].blender_object + # Collect all 'actions' affecting this object. There is a direct mapping between blender actions and glTF animations blender_actions = __get_blender_actions(blender_object, export_settings) - # save the current active action of the object, if any - # We will restore it after export + if len([a for a in blender_actions if a[2] == "OBJECT"]) == 0: + # No TRS animation are found for this object. + # But we need to bake, in case we export selection + if export_settings['gltf_selected'] is True and blender_object.type != "ARMATURE": + channels = __gather_channels_baked(obj_uuid, export_settings) + if channels is not None: + animation = gltf2_io.Animation( + channels=channels, + extensions=None, # as other animations + extras=None, # Because there is no animation to get extras from + name=blender_object.name, # Use object name as animation name + samplers=[] + ) + + __link_samplers(animation, export_settings) + if animation is not None: + animations.append(animation) + current_action = None if blender_object.animation_data and blender_object.animation_data.action: current_action = blender_object.animation_data.action @@ -63,7 +110,7 @@ def gather_animations(blender_object: bpy.types.Object, # No need to set active shapekeys animations, this is needed for bone baking - animation = __gather_animation(blender_action, blender_object, export_settings) + animation = __gather_animation(obj_uuid, blender_action, export_settings) if animation is not None: animations.append(animation) @@ -91,21 +138,24 @@ def gather_animations(blender_object: bpy.types.Object, return animations, tracks -def __gather_animation(blender_action: bpy.types.Action, - blender_object: bpy.types.Object, - export_settings +def __gather_animation( obj_uuid: int, + blender_action: bpy.types.Action, + export_settings ) -> typing.Optional[gltf2_io.Animation]: + + blender_object = export_settings['vtree'].nodes[obj_uuid].blender_object + if not __filter_animation(blender_action, blender_object, export_settings): return None name = __gather_name(blender_action, blender_object, export_settings) try: animation = gltf2_io.Animation( - channels=__gather_channels(blender_action, blender_object, export_settings), + channels=__gather_channels(obj_uuid, blender_action, export_settings), extensions=__gather_extensions(blender_action, blender_object, export_settings), extras=__gather_extras(blender_action, blender_object, export_settings), name=name, - samplers=__gather_samplers(blender_action, blender_object, export_settings) + samplers=__gather_samplers(obj_uuid, blender_action, export_settings) ) except RuntimeError as error: print_console("WARNING", "Animation '{}' could not be exported. Cause: {}".format(name, error)) @@ -134,12 +184,12 @@ def __filter_animation(blender_action: bpy.types.Action, return True -def __gather_channels(blender_action: bpy.types.Action, - blender_object: bpy.types.Object, +def __gather_channels(obj_uuid: int, + blender_action: bpy.types.Action, export_settings ) -> typing.List[gltf2_io.AnimationChannel]: return gltf2_blender_gather_animation_channels.gather_animation_channels( - blender_action, blender_object, export_settings) + obj_uuid, blender_action, export_settings) def __gather_extensions(blender_action: bpy.types.Action, @@ -166,8 +216,8 @@ def __gather_name(blender_action: bpy.types.Action, return blender_action.name -def __gather_samplers(blender_action: bpy.types.Action, - blender_object: bpy.types.Object, +def __gather_samplers(obj_uuid: str, + blender_action: bpy.types.Action, export_settings ) -> typing.List[gltf2_io.AnimationSampler]: # We need to gather the samplers after gathering all channels --> populate this list in __link_samplers |