diff options
6 files changed, 119 insertions, 1 deletions
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py index 433aac63..2186c344 100755 --- a/io_scene_gltf2/__init__.py +++ b/io_scene_gltf2/__init__.py @@ -15,7 +15,7 @@ bl_info = { 'name': 'glTF 2.0 format', 'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors', - "version": (0, 9, 13), + "version": (0, 9, 14), 'blender': (2, 80, 0), 'location': 'File > Import-Export', 'description': 'Import-Export as glTF 2.0', diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation.py index 4180672a..93014d00 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_animation.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation.py @@ -33,3 +33,27 @@ class BlenderAnimation(): for child in gltf.data.nodes[node_idx].children: BlenderAnimation.anim(gltf, anim_idx, child) + @staticmethod + def stash_action(gltf, anim_idx, node_idx, action_name): + + if gltf.data.nodes[node_idx].is_joint: + BlenderBoneAnim.stash_action(gltf, anim_idx, node_idx, action_name) + else: + BlenderNodeAnim.stash_action(gltf, anim_idx, node_idx, action_name) + + if gltf.data.nodes[node_idx].children: + for child in gltf.data.nodes[node_idx].children: + BlenderAnimation.stash_action(gltf, anim_idx, child, action_name) + + @staticmethod + def restore_last_action(gltf, node_idx): + + if gltf.data.nodes[node_idx].is_joint: + BlenderBoneAnim.restore_last_action(gltf, node_idx) + else: + BlenderNodeAnim.restore_last_action(gltf, node_idx) + + if gltf.data.nodes[node_idx].children: + for child in gltf.data.nodes[node_idx].children: + BlenderAnimation.restore_last_action(gltf, child) + diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py index a97a02bc..2cb196ab 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py @@ -18,6 +18,7 @@ from mathutils import Matrix from ..com.gltf2_blender_conversion import loc_gltf_to_blender, quaternion_gltf_to_blender, scale_to_matrix from ...io.imp.gltf2_io_binary import BinaryData +from .gltf2_blender_animation_utils import simulate_stash, restore_last_action class BlenderBoneAnim(): @@ -40,6 +41,30 @@ class BlenderBoneAnim(): kf.interpolation = 'LINEAR' @staticmethod + def stash_action(gltf, anim_idx, node_idx, action_name): + node = gltf.data.nodes[node_idx] + obj = bpy.data.objects[gltf.data.skins[node.skin_id].blender_armature_name] + + if anim_idx not in node.animations.keys(): + return + + if (obj.name, action_name) in gltf.actions_stashed.keys(): + return + + start_frame = bpy.context.scene.frame_start + + simulate_stash(obj, bpy.data.actions[action_name], start_frame) + + gltf.actions_stashed[(obj.name, action_name)] = True + + @staticmethod + def restore_last_action(gltf, node_idx): + node = gltf.data.nodes[node_idx] + obj = bpy.data.objects[gltf.data.skins[node.skin_id].blender_armature_name] + + restore_last_action(obj) + + @staticmethod def parse_translation_channel(gltf, node, obj, bone, channel, animation): """Manage Location animation.""" blender_path = "pose.bones[" + json.dumps(bone.name) + "].location" diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py index 8ad86363..6540edec 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py @@ -18,6 +18,7 @@ from mathutils import Vector from ..com.gltf2_blender_conversion import loc_gltf_to_blender, quaternion_gltf_to_blender, scale_gltf_to_blender from ..com.gltf2_blender_conversion import correction_rotation from ...io.imp.gltf2_io_binary import BinaryData +from .gltf2_blender_animation_utils import simulate_stash, restore_last_action class BlenderNodeAnim(): @@ -40,6 +41,30 @@ class BlenderNodeAnim(): kf.interpolation = 'LINEAR' @staticmethod + def stash_action(gltf, anim_idx, node_idx, action_name): + node = gltf.data.nodes[node_idx] + obj = bpy.data.objects[node.blender_object] + + if anim_idx not in node.animations.keys(): + return + + if (obj.name, action_name) in gltf.actions_stashed.keys(): + return + + start_frame = bpy.context.scene.frame_start + + simulate_stash(obj, bpy.data.actions[action_name], start_frame) + + gltf.actions_stashed[(obj.name, action_name)] = True + + @staticmethod + def restore_last_action(gltf, node_idx): + node = gltf.data.nodes[node_idx] + obj = bpy.data.objects[node.blender_object] + + restore_last_action(obj) + + @staticmethod def anim(gltf, anim_idx, node_idx): """Manage animation.""" node = gltf.data.nodes[node_idx] diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py new file mode 100644 index 00000000..c2ac3bed --- /dev/null +++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py @@ -0,0 +1,39 @@ +# Copyright 2019 The glTF-Blender-IO authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +def simulate_stash(obj, action, start_frame): + # Simulate stash : + # * add a track + # * add an action on track + # * lock & mute the track + # * remove active action from object + tracks = obj.animation_data.nla_tracks + new_track = tracks.new(prev=None) + new_track.name = action.name + strip = new_track.strips.new(action.name, start_frame, action) + new_track.lock = True + new_track.mute = True + obj.animation_data.action = None + +def restore_last_action(obj): + + if not obj.animation_data: + return + tracks = obj.animation_data.nla_tracks + if len(tracks) == 0: + return + if len(tracks[0].strips) == 0: + return + obj.animation_data.action = tracks[0].strips[0].action + diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_scene.py b/io_scene_gltf2/blender/imp/gltf2_blender_scene.py index d7fc781a..dc19a549 100755 --- a/io_scene_gltf2/blender/imp/gltf2_blender_scene.py +++ b/io_scene_gltf2/blender/imp/gltf2_blender_scene.py @@ -96,11 +96,16 @@ class BlenderScene(): gltf.animation_managed = [] for anim_idx, anim in enumerate(gltf.data.animations): gltf.current_animation_names = {} + gltf.actions_stashed= {} if list_nodes is not None: for node_idx in list_nodes: BlenderAnimation.anim(gltf, anim_idx, node_idx) for an in gltf.current_animation_names.values(): gltf.animation_managed.append(an) + for node_idx in list_nodes: + BlenderAnimation.stash_action(gltf, anim_idx, node_idx, an) + for node_idx in list_nodes: + BlenderAnimation.restore_last_action(gltf, node_idx) if bpy.app.debug_value != 100: # Parent root node to rotation object |