Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import & Export rotation delta for animation. #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions addon/io_scs_tools/exp/pia.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
45 changes: 44 additions & 1 deletion addon/io_scs_tools/imp/pia.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)))

Expand Down
4 changes: 3 additions & 1 deletion addon/io_scs_tools/internals/containers/pix.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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__":
Expand Down