diff --git a/addon/io_scs_tools/exp/pia.py b/addon/io_scs_tools/exp/pia.py index 9d350ef..c194fef 100644 --- a/addon/io_scs_tools/exp/pia.py +++ b/addon/io_scs_tools/exp/pia.py @@ -82,6 +82,48 @@ def _get_custom_channels(scs_animation, action): bone_data = ("Prism Movement", bone_anim) custom_channels.append(bone_data) + rot_curves = {} # dictionary for storing "rotation_quaternion" curves of action + for fcurve in action.fcurves: + if fcurve.data_path == 'rotation_quaternion': + rot_curves[fcurve.array_index] = fcurve + + # write custom channel only if rotation curves were found + if len(rot_curves) > 0: + + # GO THROUGH FRAMES + actual_frame = frame_start + previous_frame_value = None + timings_stream = [] + rotation_stream = [] + while actual_frame <= frame_end: + rotation = Quaternion() + + # ROTATION MATRIX + if len(rot_curves) > 0: + for index in range(4): + if index in rot_curves: + rotation[index] = rot_curves[index].evaluate(actual_frame) + + # COMPUTE SCS FRAME ROTATION + frame_rot = _convert_utils.change_to_scs_quaternion_coordinates(rotation) + + if previous_frame_value is None: + previous_frame_value = frame_rot + + frame_rotation = frame_rot.rotation_difference( previous_frame_value ) + previous_frame_value = frame_rot + + lprint('S actual_frame: %s - value: %s', (actual_frame, frame_rot)) + timings_stream.append(("__time__", scs_animation.length / total_frames), ) + rotation_stream.append(frame_rotation) + actual_frame += anim_export_step + + anim_timing = ("_TIME", timings_stream) + anim_movement = ("_ROTATION", rotation_stream) + bone_anim = (anim_timing, anim_movement) + bone_data = ("Prism Rotation", bone_anim) + custom_channels.append(bone_data) + return custom_channels diff --git a/addon/io_scs_tools/imp/pia.py b/addon/io_scs_tools/imp/pia.py index 42e15c0..fbc9499 100644 --- a/addon/io_scs_tools/imp/pia.py +++ b/addon/io_scs_tools/imp/pia.py @@ -21,7 +21,7 @@ import os import bpy -from mathutils import Matrix, Vector +from mathutils import Matrix, Vector, Quaternion from io_scs_tools.consts import Bones as _BONE_consts from io_scs_tools.internals.containers import pix as _pix_container from io_scs_tools.imp import pis as _pis @@ -408,6 +408,49 @@ def load(root_object, pia_files, armature, pis_filepath=None, bones=None): for curve in pos_fcurves: for keyframe in curve.keyframe_points: keyframe.interpolation = 'LINEAR' + elif channel_name == 'Prism Rotation': + ''' + NOTE: skipped for now as no data needs to be readed + stream_count = custom_channels[channel_name][0] + keyframe_count = custom_channels[channel_name][1] + ''' + streams = custom_channels[channel_name][2] + # print(' channel %r - streams %s - keyframes %s' % (channel_name, stream_count, keyframe_count)) + + anim_group = anim_action.groups.new('Rotation') + + fcurve_rot_w = anim_action.fcurves.new('rotation_quaternion', index=0) + fcurve_rot_x = anim_action.fcurves.new('rotation_quaternion', index=1) + fcurve_rot_y = anim_action.fcurves.new('rotation_quaternion', index=2) + fcurve_rot_z = anim_action.fcurves.new('rotation_quaternion', index=3) + fcurve_rot_w.group = anim_group + fcurve_rot_x.group = anim_group + fcurve_rot_y.group = anim_group + fcurve_rot_z.group = anim_group + rot_fcurves = (fcurve_rot_w, fcurve_rot_x, fcurve_rot_y, fcurve_rot_z) + + rotation = None + for key_time_i, key_time in enumerate(streams[0]): + # print(' key_time: %s' % str(key_time[0])) + # keyframe = key_time_i * (key_time[0] * 10) ## TODO: Do proper timing... + keyframe = key_time_i + 1 + scs_offset = _convert_utils.change_to_scs_quaternion_coordinates(custom_channels[channel_name][2][1][key_time_i]) + offset = Quaternion(scs_offset) + if rotation is None: + rotation = offset + else: + rotation.rotate(offset) + #print(' > rotation: %s' % str(rotation)) + + rot_fcurves[0].keyframe_points.insert(frame=float(keyframe), value=rotation.w, options={'FAST'}) + rot_fcurves[1].keyframe_points.insert(frame=float(keyframe), value=rotation.x, options={'FAST'}) + rot_fcurves[2].keyframe_points.insert(frame=float(keyframe), value=rotation.y, options={'FAST'}) + rot_fcurves[3].keyframe_points.insert(frame=float(keyframe), value=rotation.z, options={'FAST'}) + + # SET LINEAR INTERPOLATION FOR ALL CURVES + for curve in rot_fcurves: + for keyframe in curve.keyframe_points: + keyframe.interpolation = 'LINEAR' else: lprint('W Unknown channel %r in "%s" file.', (channel_name, os.path.basename(pia_filepath))) diff --git a/addon/io_scs_tools/internals/containers/pix.py b/addon/io_scs_tools/internals/containers/pix.py index 9deb61c..0bdad7f 100644 --- a/addon/io_scs_tools/internals/containers/pix.py +++ b/addon/io_scs_tools/internals/containers/pix.py @@ -20,7 +20,7 @@ import os import re -from mathutils import Vector +from mathutils import Vector, Quaternion from io_scs_tools.internals.containers.parsers import pix as _pix_parser from io_scs_tools.internals.containers.writers import pix as _pix_writer from io_scs_tools.internals.structure import SectionData as _SectionData @@ -129,6 +129,8 @@ def make_stream_section(data, data_tag, aliases): elif type(data[0][0]) is type(0): data_type = 'INT' data_format = str(data_type + str(len(data[0]))) + elif type(data[0]) is Quaternion: + data_format = 'FLOAT4' elif data[0][0] == "__matrix__": data_format = 'FLOAT4x4' elif data[0][0] == "__time__":