From 19385dbc57f566e27914a361768d3aa6dad95ec6 Mon Sep 17 00:00:00 2001 From: Julien Duroure Date: Thu, 20 Jan 2022 19:01:47 +0100 Subject: glTF exporter: Use custom range on action --- io_scene_gltf2/__init__.py | 4 +-- .../exp/gltf2_blender_gather_animation_channels.py | 41 ++++++++++++++-------- ...2_blender_gather_animation_sampler_keyframes.py | 23 +++++++----- .../exp/gltf2_blender_gather_animation_samplers.py | 8 ++++- 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 8decfb29..97ef843b 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -15,8 +15,8 @@ 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": (1, 8, 11), - 'blender': (3, 0, 0), + "version": (1, 8, 12), + 'blender': (3, 1, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', 'warning': '', 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 c60e7047..726104f4 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 @@ -40,18 +40,25 @@ def gather_animation_channels(blender_action: bpy.types.Action, # This is need if user set 'Force sampling' and in case we need to bake bake_range_start = None bake_range_end = None - groups = __get_channel_groups(blender_action, blender_object, export_settings) - # Note: channels has some None items only for SK if some SK are not animated - for chans in groups: - ranges = [channel.range() for channel in chans if channel is not None] - if bake_range_start is None: - bake_range_start = min([channel.range()[0] for channel in chans if channel is not None]) - else: - bake_range_start = min(bake_range_start, min([channel.range()[0] for channel in chans if channel is not None])) - if bake_range_end is None: - bake_range_end = max([channel.range()[1] for channel in chans if channel is not None]) - else: - bake_range_end = max(bake_range_end, max([channel.range()[1] for channel in chans if channel is not None])) + force_range = False + # If range is manually set, use it. Else, calculate it + if blender_action.use_frame_range is True: + bake_range_start = blender_action.frame_start + bake_range_end = blender_action.frame_end + force_range = True # keyframe_points is read-only, we cant restrict here + else: + groups = __get_channel_groups(blender_action, blender_object, export_settings) + # Note: channels has some None items only for SK if some SK are not animated + for chans in groups: + ranges = [channel.range() for channel in chans if channel is not None] + if bake_range_start is None: + bake_range_start = min([channel.range()[0] for channel in chans if channel is not None]) + else: + bake_range_start = min(bake_range_start, min([channel.range()[0] for channel in chans if channel is not None])) + if bake_range_end is None: + bake_range_end = max([channel.range()[1] for channel in chans if channel is not None]) + else: + bake_range_end = max(bake_range_end, max([channel.range()[1] for channel in chans if channel is not None])) if blender_object.type == "ARMATURE" and export_settings['gltf_force_sampling'] is True: @@ -84,6 +91,7 @@ def gather_animation_channels(blender_action: bpy.types.Action, p, bake_range_start, bake_range_end, + force_range, blender_action.name, None, (bone.name, p) in list_of_animated_bone_channels) @@ -98,7 +106,7 @@ def gather_animation_channels(blender_action: bpy.types.Action, if len(channel_group) == 0: # Only errors on channels, ignoring continue - channel = __gather_animation_channel(channel_group, blender_object, export_settings, None, None, bake_range_start, bake_range_end, blender_action.name, None, True) + channel = __gather_animation_channel(channel_group, blender_object, export_settings, None, None, bake_range_start, bake_range_end, force_range, blender_action.name, None, True) if channel is not None: channels.append(channel) @@ -115,6 +123,7 @@ def gather_animation_channels(blender_action: bpy.types.Action, None, bake_range_start, bake_range_end, + force_range, blender_action.name, obj, False) @@ -135,6 +144,7 @@ def gather_animation_channels(blender_action: bpy.types.Action, None, bake_range_start, bake_range_end, + force_range, blender_action.name, None, False) @@ -207,6 +217,7 @@ def __gather_animation_channel(channels: typing.Tuple[bpy.types.FCurve], bake_channel: typing.Union[str, None], bake_range_start, bake_range_end, + force_range: bool, action_name: str, driver_obj, node_channel_is_animated: bool @@ -216,7 +227,7 @@ def __gather_animation_channel(channels: typing.Tuple[bpy.types.FCurve], __target= __gather_target(channels, blender_object, export_settings, bake_bone, bake_channel, driver_obj) if __target.path is not None: - sampler = __gather_sampler(channels, blender_object, export_settings, bake_bone, bake_channel, bake_range_start, bake_range_end, action_name, driver_obj, node_channel_is_animated) + sampler = __gather_sampler(channels, blender_object, export_settings, bake_bone, bake_channel, bake_range_start, bake_range_end, force_range, action_name, driver_obj, node_channel_is_animated) if sampler is None: # After check, no need to animate this node for this channel @@ -275,6 +286,7 @@ def __gather_sampler(channels: typing.Tuple[bpy.types.FCurve], bake_channel: typing.Union[str, None], bake_range_start, bake_range_end, + force_range: bool, action_name, driver_obj, node_channel_is_animated: bool @@ -286,6 +298,7 @@ def __gather_sampler(channels: typing.Tuple[bpy.types.FCurve], bake_channel, bake_range_start, bake_range_end, + force_range, action_name, driver_obj, node_channel_is_animated, diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py index f1e94d9e..caf14217 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py @@ -192,22 +192,27 @@ def gather_keyframes(blender_object_if_armature: typing.Optional[bpy.types.Objec bake_channel: typing.Union[str, None], bake_range_start, bake_range_end, + force_range: bool, action_name: str, driver_obj, node_channel_is_animated: bool, export_settings ) -> typing.List[Keyframe]: """Convert the blender action groups' fcurves to keyframes for use in glTF.""" - if bake_bone is None and driver_obj is None: - # Find the start and end of the whole action group - # Note: channels has some None items only for SK if some SK are not animated - ranges = [channel.range() for channel in channels if channel is not None] - - start_frame = min([channel.range()[0] for channel in channels if channel is not None]) - end_frame = max([channel.range()[1] for channel in channels if channel is not None]) - else: + if force_range is True: start_frame = bake_range_start end_frame = bake_range_end + else: + if bake_bone is None and driver_obj is None: + # Find the start and end of the whole action group + # Note: channels has some None items only for SK if some SK are not animated + ranges = [channel.range() for channel in channels if channel is not None] + + start_frame = min([channel.range()[0] for channel in channels if channel is not None]) + end_frame = max([channel.range()[1] for channel in channels if channel is not None]) + else: + start_frame = bake_range_start + end_frame = bake_range_end keyframes = [] if needs_baking(blender_object_if_armature, channels, export_settings): @@ -270,6 +275,8 @@ def gather_keyframes(blender_object_if_armature: typing.Optional[bpy.types.Objec frames = [keyframe.co[0] for keyframe in [c for c in channels if c is not None][0].keyframe_points] # some weird files have duplicate frame at same time, removed them frames = sorted(set(frames)) + if force_range is True: + frames = [f for f in frames if f >= bake_range_start and f <= bake_range_end] for i, frame in enumerate(frames): key = Keyframe(channels, frame, bake_channel) # key.value = [c.keyframe_points[i].co[0] for c in action_group.channels] diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py index aca85e07..61fe17a6 100755 --- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py +++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py @@ -37,6 +37,7 @@ def gather_animation_sampler(channels: typing.Tuple[bpy.types.FCurve], bake_channel: typing.Union[str, None], bake_range_start, bake_range_end, + force_range: bool, action_name: str, driver_obj, node_channel_is_animated: bool, @@ -63,7 +64,7 @@ def gather_animation_sampler(channels: typing.Tuple[bpy.types.FCurve], matrix_parent_inverse = mathutils.Matrix.Identity(4).freeze() input = __gather_input(channels, blender_object_if_armature, non_keyed_values, - bake_bone, bake_channel, bake_range_start, bake_range_end, action_name, driver_obj, node_channel_is_animated, export_settings) + bake_bone, bake_channel, bake_range_start, bake_range_end, force_range, action_name, driver_obj, node_channel_is_animated, export_settings) if input is None: # After check, no need to animate this node for this channel @@ -82,6 +83,7 @@ def gather_animation_sampler(channels: typing.Tuple[bpy.types.FCurve], bake_channel, bake_range_start, bake_range_end, + force_range, action_name, driver_obj, node_channel_is_animated, @@ -235,6 +237,7 @@ def __gather_input(channels: typing.Tuple[bpy.types.FCurve], bake_channel: typing.Union[str, None], bake_range_start, bake_range_end, + force_range: bool, action_name, driver_obj, node_channel_is_animated: bool, @@ -248,6 +251,7 @@ def __gather_input(channels: typing.Tuple[bpy.types.FCurve], bake_channel, bake_range_start, bake_range_end, + force_range, action_name, driver_obj, node_channel_is_animated, @@ -317,6 +321,7 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve], bake_channel: typing.Union[str, None], bake_range_start, bake_range_end, + force_range: bool, action_name, driver_obj, node_channel_is_animated: bool, @@ -330,6 +335,7 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve], bake_channel, bake_range_start, bake_range_end, + force_range, action_name, driver_obj, node_channel_is_animated, -- cgit v1.2.3