From 779655b4af652685a190eabb36b05de60d64fff2 Mon Sep 17 00:00:00 2001 From: ShynRou Date: Fri, 1 Jul 2016 16:56:54 +0200 Subject: [PATCH] reverted animation-io see #9192 (#9263) --- src/animation/AnimationClip.js | 2 +- .../addons/io_three/exporter/api/animation.py | 145 +++++++++++------- 2 files changed, 90 insertions(+), 57 deletions(-) diff --git a/src/animation/AnimationClip.js b/src/animation/AnimationClip.js index 28903ff7b1..a5e64a8fe1 100644 --- a/src/animation/AnimationClip.js +++ b/src/animation/AnimationClip.js @@ -326,7 +326,7 @@ Object.assign( THREE.AnimationClip, { } else { // ...assume skeletal animation - var boneName = '.bones[' + bones[ hierarchyTracks[h].parent ].name + ']'; + var boneName = '.bones[' + bones[ h ].name + ']'; addNonemptyTrack( THREE.VectorKeyframeTrack, boneName + '.position', diff --git a/utils/exporters/blender/addons/io_three/exporter/api/animation.py b/utils/exporters/blender/addons/io_three/exporter/api/animation.py index ffaf2a0fe3..bf2528e19e 100644 --- a/utils/exporters/blender/addons/io_three/exporter/api/animation.py +++ b/utils/exporters/blender/addons/io_three/exporter/api/animation.py @@ -200,63 +200,78 @@ def _parse_pose_action(action, armature, options): start_frame = action.frame_range[0] frame_length = end_frame - start_frame - frame_step = options.get(constants.FRAME_STEP, 1) used_frames = int(frame_length / frame_step) + 1 - frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME] - keys = [] - - bone_index = 0; + channels_location = [] + channels_rotation = [] + channels_scale = [] for pose_bone in armature.pose.bones: logger.info("Processing channels for %s", pose_bone.bone.name) keys.append([]) + channels_location.append( + _find_channels(action, + pose_bone.bone, + 'location')) + channels_rotation.append( + _find_channels(action, + pose_bone.bone, + 'rotation_quaternion')) + channels_rotation.append( + _find_channels(action, + pose_bone.bone, + 'rotation_euler')) + channels_scale.append( + _find_channels(action, + pose_bone.bone, + 'scale')) + + frame_step = options[constants.FRAME_STEP] + frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME] + for frame_index in range(0, used_frames): + if frame_index == used_frames - 1: + frame = end_frame + else: + frame = start_frame + frame_index * frame_step - channels_location = _find_channels( action, pose_bone.bone, 'location' ) - channels_rotation_q = _find_channels( action, pose_bone.bone, 'rotation_quaternion' ) - channels_rotation = ( _find_channels( action, pose_bone.bone, 'rotation_euler' )) - channels_scale = _find_channels( action, pose_bone.bone, 'scale' ) + logger.info("Processing frame %d", frame) - keyframes_times_location = [] - keyframes_times_rotation = [] - keyframes_times_scale = [] - keyframes_times = [] + time = frame - start_frame + if frame_index_as_time is False: + time = time / fps - def add_keyframes_times(target, channels): - for channel in channels: - for keyframe in channel.keyframe_points: - time = int(keyframe.co[0]) - if not time in target: - target.append(time) - return target + context.scene.frame_set(frame) - add_keyframes_times(keyframes_times_location, channels_location) - add_keyframes_times(keyframes_times_rotation, channels_rotation_q) - add_keyframes_times(keyframes_times_rotation, channels_rotation) - add_keyframes_times(keyframes_times_scale, channels_scale) + bone_index = 0 - def merge_times( target, source): - for time in source: - if not time in target: - target.append(time) - return target + def has_keyframe_at(channels, frame): + """ - merge_times(keyframes_times, keyframes_times_location) - merge_times(keyframes_times, keyframes_times_rotation) - merge_times(keyframes_times, keyframes_times_scale) + :param channels: + :param frame: - keyframes_times.sort() + """ + def find_keyframe_at(channel, frame): + """ - for keyframe_time in keyframes_times: + :param channel: + :param frame: - context.scene.frame_set(keyframe_time) + """ + for keyframe in channel.keyframe_points: + if keyframe.co[0] == frame: + return keyframe + return None + + for channel in channels: + if not find_keyframe_at(channel, frame) is None: + return True + return False - time = keyframe_time - start_frame - if frame_index_as_time is False: - time = time / fps + for pose_bone in armature.pose.bones: logger.info("Processing bone %s", pose_bone.bone.name) if pose_bone.parent is None: @@ -269,37 +284,49 @@ def _parse_pose_action(action, armature, options): pos, rot, scl = bone_matrix.decompose() rot = _normalize_quaternion(rot) + pchange = True or has_keyframe_at( + channels_location[bone_index], frame) + rchange = True or has_keyframe_at( + channels_rotation[bone_index], frame) + schange = True or has_keyframe_at( + channels_scale[bone_index], frame) + pos = (pos.x, pos.z, -pos.y) rot = (rot.x, rot.z, -rot.y, rot.w) - scl = (scl.x, scl.z, -scl.y) - + scl = (scl.x, scl.z, scl.y) keyframe = {constants.TIME: time} - - if keyframe_time in keyframes_times_location: + if frame == start_frame or frame == end_frame: + keyframe.update({ + constants.POS: pos, + constants.ROT: rot, + constants.SCL: scl + }) + elif any([pchange, rchange, schange]): + if pchange is True: keyframe[constants.POS] = pos - if keyframe_time in keyframes_times_rotation: + if rchange is True: keyframe[constants.ROT] = rot - if keyframe_time in keyframes_times_scale: + if schange is True: keyframe[constants.SCL] = scl - if len(keyframe.keys()) > 0: + if len(keyframe.keys()) > 1: logger.info("Recording keyframe data for %s %s", pose_bone.bone.name, str(keyframe)) keys[bone_index].append(keyframe) else: logger.info("No anim data to record for %s", pose_bone.bone.name) - bone_index += 1 + + bone_index += 1 hierarchy = [] bone_index = 0 for pose_bone in armature.pose.bones: - if len(keys[bone_index]) > 0: - hierarchy.append({ - constants.PARENT: bone_index, - constants.KEYS: keys[bone_index], - }) + hierarchy.append({ + constants.PARENT: bone_index - 1, + constants.KEYS: keys[bone_index] + }) bone_index += 1 if frame_index_as_time is False: @@ -328,12 +355,18 @@ def _find_channels(action, bone, channel_type): """ result = [] - if len(action.groups) > 0: - for group in action.groups: + if len(action.groups): + + group_index = -1 + for index, group in enumerate(action.groups): if group.name == bone.name: - for channel in group.channels: - if channel_type in channel.data_path: - result.append(channel) + group_index = index + # @TODO: break? + + if group_index > -1: + for channel in action.groups[group_index].channels: + if channel_type in channel.data_path: + result.append(channel) else: bone_label = '"%s"' % bone.name -- GitLab