Skip to content

Commit

Permalink
Fix KhronosGroup#354: When importing animation(s), stash any animatio…
Browse files Browse the repository at this point in the history
…n into NLA
  • Loading branch information
julienduroure committed May 28, 2019
1 parent 624736d commit 2c1cfec
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 0 deletions.
24 changes: 24 additions & 0 deletions addons/io_scene_gltf2/blender/imp/gltf2_blender_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,27 @@ def anim(gltf, anim_idx, node_idx):
if gltf.data.nodes[node_idx].children:
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)
25 changes: 25 additions & 0 deletions addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

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():
Expand All @@ -39,6 +40,30 @@ def set_interpolation(interpolation, kf):
else:
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."""
Expand Down
25 changes: 25 additions & 0 deletions addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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():
Expand All @@ -39,6 +40,30 @@ def set_interpolation(interpolation, kf):
else:
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."""
Expand Down
38 changes: 38 additions & 0 deletions addons/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 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
5 changes: 5 additions & 0 deletions addons/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,16 @@ def create(gltf, scene_idx):
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
Expand Down

0 comments on commit 2c1cfec

Please sign in to comment.