Browse Source

Don't put outdated crap into non-scalar keyframes

pull/10/head
Adam Johnson 9 years ago
parent
commit
b34308198b
  1. 97
      korman/exporter/animation.py

97
korman/exporter/animation.py

@ -41,19 +41,19 @@ class AnimationConverter:
return tm
def make_pos_controller(self, fcurves, default_xform):
pos_curves = (i for i in fcurves if i.data_path == "location" and i.keyframe_points)
pos_curves = [i for i in fcurves if i.data_path == "location" and i.keyframe_points]
keyframes, bez_chans = self._process_keyframes(pos_curves)
if not keyframes:
return None
# At one point, I had some... insanity here to try to crush bezier channels and hand off to
# blah blah blah... As it turns out, point3 keyframe's tangents are vector3s :)
ctrl = self._make_point3_controller(keyframes, bez_chans, default_xform.to_translation())
ctrl = self._make_point3_controller(pos_curves, keyframes, bez_chans, default_xform.to_translation())
return ctrl
def make_rot_controller(self, fcurves, default_xform):
# TODO: support rotation_quaternion
rot_curves = (i for i in fcurves if i.data_path == "rotation_euler" and i.keyframe_points)
rot_curves = [i for i in fcurves if i.data_path == "rotation_euler" and i.keyframe_points]
keyframes, bez_chans = self._process_keyframes(rot_curves)
if not keyframes:
return None
@ -61,27 +61,27 @@ class AnimationConverter:
# Ugh. Unfortunately, it appears Blender's default interpolation is bezier. So who knows if
# many users will actually see the benefit here? Makes me sad.
if bez_chans:
ctrl = self._make_scalar_controller(keyframes, bez_chans, default_xform.to_euler("XYZ"))
ctrl = self._make_scalar_controller(rot_curves, keyframes, bez_chans, default_xform.to_euler())
else:
ctrl = self._make_quat_controller(keyframes, default_xform.to_euler("XYZ"))
ctrl = self._make_quat_controller(rot_curves, keyframes, default_xform.to_euler())
return ctrl
def make_scale_controller(self, fcurves, default_xform):
scale_curves = (i for i in fcurves if i.data_path == "scale" and i.keyframe_points)
scale_curves = [i for i in fcurves if i.data_path == "scale" and i.keyframe_points]
keyframes, bez_chans = self._process_keyframes(scale_curves)
if not keyframes:
return None
# There is no such thing as a compound scale controller... in Plasma, anyway.
ctrl = self._make_scale_value_controller(keyframes, bez_chans, default_xform)
ctrl = self._make_scale_value_controller(scale_curves, keyframes, bez_chans, default_xform)
return ctrl
def _make_point3_controller(self, keyframes, bezier, default_xform):
def _make_point3_controller(self, fcurves, keyframes, bezier, default_xform):
ctrl = plLeafController()
subctrls = ("X", "Y", "Z")
keyframe_type = hsKeyFrame.kBezPoint3KeyFrame if bezier else hsKeyFrame.kPoint3KeyFrame
exported_frames = []
last_xform = [default_xform[0], default_xform[1], default_xform[2]]
ctrl_fcurves = { i.array_index: i for i in fcurves }
for keyframe in keyframes:
exported = hsPoint3Key()
@ -93,15 +93,16 @@ class AnimationConverter:
out_tan = hsVector3()
value = hsVector3()
for i, subctrl in enumerate(subctrls):
fkey = keyframe.values.get(i, None)
if fkey is not None:
v = fkey.co[1]
last_xform[i] = v
setattr(value, subctrl, v)
fval = keyframe.values.get(i, None)
if fval is not None:
setattr(value, subctrl, fval)
setattr(in_tan, subctrl, keyframe.in_tans[i])
setattr(out_tan, subctrl, keyframe.out_tans[i])
else:
setattr(value, subctrl, last_xform[i])
try:
setattr(value, subctrl, ctrl_fcurves[i].evaluate(keyframe.frame_num_blender))
except KeyError:
setattr(value, subctrl, default_xform[i])
setattr(in_tan, subctrl, 0.0)
setattr(out_tan, subctrl, 0.0)
exported.inTan = in_tan
@ -111,11 +112,11 @@ class AnimationConverter:
ctrl.keys = (exported_frames, keyframe_type)
return ctrl
def _make_quat_controller(self, keyframes, default_xform):
def _make_quat_controller(self, fcurves, keyframes, default_xform):
ctrl = plLeafController()
keyframe_type = hsKeyFrame.kQuatKeyFrame
exported_frames = []
last_xform = [default_xform[0], default_xform[1], default_xform[2]]
ctrl_fcurves = { i.array_index: i for i in fcurves }
for keyframe in keyframes:
exported = hsQuatKey()
@ -124,30 +125,34 @@ class AnimationConverter:
exported.type = keyframe_type
# NOTE: quat keyframes don't do bezier nonsense
value = mathutils.Euler(last_xform, default_xform.order)
value = mathutils.Euler()
for i in range(3):
fkey = keyframe.values.get(i, None)
if fkey is not None:
v = fkey.co[1]
last_xform[i] = v
value[i] = v
fval = keyframe.values.get(i, None)
if fval is not None:
value[i] = fval
else:
try:
value[i] = ctrl_fcurves[i].evaluate(keyframe.frame_num_blender)
except KeyError:
value[i] = default_xform[i]
quat = value.to_quaternion()
exported.value = utils.quaternion(quat)
exported_frames.append(exported)
ctrl.keys = (exported_frames, keyframe_type)
return ctrl
def _make_scalar_controller(self, keyframes, bez_chans, default_xform):
def _make_scalar_controller(self, fcurves, keyframes, bez_chans, default_xform):
ctrl = plCompoundController()
subctrls = ("X", "Y", "Z")
for i in subctrls:
setattr(ctrl, i, plLeafController())
exported_frames = ([], [], [])
ctrl_fcurves = { i.array_index: i for i in fcurves }
for keyframe in keyframes:
for i, subctrl in enumerate(subctrls):
fkey = keyframe.values.get(i, None)
if fkey is not None:
fval = keyframe.values.get(i, None)
if fval is not None:
keyframe_type = hsKeyFrame.kBezScalarKeyFrame if i in bez_chans else hsKeyFrame.kScalarKeyFrame
exported = hsScalarKey()
exported.frame = keyframe.frame_num
@ -155,7 +160,7 @@ class AnimationConverter:
exported.inTan = keyframe.in_tans[i]
exported.outTan = keyframe.out_tans[i]
exported.type = keyframe_type
exported.value = fkey.co[1]
exported.value = fval
exported_frames[i].append(exported)
for i, subctrl in enumerate(subctrls):
my_keyframes = exported_frames[i]
@ -171,13 +176,13 @@ class AnimationConverter:
getattr(ctrl, subctrl).keys = (my_keyframes, my_keyframes[0].type)
return ctrl
def _make_scale_value_controller(self, keyframes, bez_chans, default_xform):
def _make_scale_value_controller(self, fcurves, keyframes, bez_chans, default_xform):
subctrls = ("X", "Y", "Z")
keyframe_type = hsKeyFrame.kBezScaleKeyFrame if bez_chans else hsKeyFrame.kScaleKeyFrame
exported_frames = []
ctrl_fcurves = { i.array_index: i for i in fcurves }
_scale = default_xform.to_scale()
last_xform = [_scale[0], _scale[1], _scale[2]]
default_scale = default_xform.to_scale()
unit_quat = default_xform.to_quaternion()
unit_quat.normalize()
unit_quat = utils.quaternion(unit_quat)
@ -192,15 +197,16 @@ class AnimationConverter:
out_tan = hsVector3()
value = hsVector3()
for i, subctrl in enumerate(subctrls):
fkey = keyframe.values.get(i, None)
if fkey is not None:
v = fkey.co[1]
last_xform[i] = v
setattr(value, subctrl, v)
fval = keyframe.values.get(i, None)
if fval is not None:
setattr(value, subctrl, fval)
setattr(in_tan, subctrl, keyframe.in_tans[i])
setattr(out_tan, subctrl, keyframe.out_tans[i])
else:
setattr(value, subctrl, last_xform[i])
try:
setattr(value, subctrl, ctrl_fcurves[i].evaluate(keyframe.frame_num_blender))
except KeyError:
setattr(value, subctrl, default_scale[i])
setattr(in_tan, subctrl, 0.0)
setattr(out_tan, subctrl, 0.0)
exported.inTan = in_tan
@ -224,28 +230,27 @@ class AnimationConverter:
fcurve.update()
for fkey in fcurve.keyframe_points:
frame_num, value = fkey.co
if fps == 30.0:
# hope you don't have a frame 29.9 and frame 30.0...
frame_num = int(frame_num)
else:
frame_num = int(frame_num * (30.0 / fps))
keyframe = keyframes.get(frame_num, None)
if keyframe is None:
keyframe = keyframe_data()
keyframe.frame_num = frame_num
if fps == 30.0:
# hope you don't have a frame 29.9 and frame 30.0...
keyframe.frame_num = int(frame_num)
else:
keyframe.frame_num = int(frame_num * (30.0 / fps))
keyframe.frame_num_blender = frame_num
keyframe.frame_time = frame_num / fps
keyframe.in_tans = {}
keyframe.out_tans = {}
keyframe.values = {}
keyframes[frame_num] = keyframe
idx = fcurve.array_index
keyframe.values[idx] = fkey
keyframe.values[idx] = value
# Calculate the bezier interpolation nonsense
if fkey.interpolation == "BEZIER":
og_frame = fkey.co[0]
keyframe.in_tans[idx] = -(value - fkey.handle_left[1]) / (og_frame - fkey.handle_left[0]) / fps / (2 * pi)
keyframe.out_tans[idx] = (value - fkey.handle_right[1]) / (og_frame - fkey.handle_right[0]) / fps / (2 * pi)
keyframe.in_tans[idx] = -(value - fkey.handle_left[1]) / (frame_num - fkey.handle_left[0]) / fps / (2 * pi)
keyframe.out_tans[idx] = (value - fkey.handle_right[1]) / (frame_num - fkey.handle_right[0]) / fps / (2 * pi)
bez_chans.add(idx)
else:
keyframe.in_tans[idx] = 0.0

Loading…
Cancel
Save