2
$\begingroup$

So I'm writing an animation import script...
since animation bone names can differ from the armature's bones in question, I want to create the actions and edit their group names manually, and then manually assign them to the armature.

The problem I'm having is I can create an unrelated action with unrelated groups, but the channels of those groups seem to require linked pose bones...

Since it's safe to say these pose bones don't exist, how can I assign keyframes to raw data?

$\endgroup$
3
$\begingroup$

The key concepts are as follows

  • animations are composed of fcurves
  • each fcurve has a data_path and maybe an index
  • each fcurve has multiple keyframe_points
  • each keyframe_point has a .co (coordinate), a .handle_left, a .handle_right, and an .interpolation.

You can see an example of an animation built using core python APIs at http://web.purplefrog.com/~thoth/blender/python-cookbook/animate-random-spin.html

I include an excerpt of the most relevant code:

def rig_quaternion_channel(action, channel, period, a, b):
    """
    This is heavy-duty voodoo to figure out what keyframes to use with sinusoidal easing
    to reconstruct a curve of the form
     a*cos(theta) + b*sin(theta)
     by converting it to the form
     c*sin(theta+phi)
    """
    c = sqrt(a * a + b * b)
    phi = -atan2(a, b)
    fc = action.fcurves.new(data_path="rotation_quaternion", index=channel)
    fc.keyframe_points.add(5)
    vals = [0, 1, 0, -1, 0]
    for j in range(5):
        kp = fc.keyframe_points[j]
        frame = 1 + ( phi / (2 * pi) + j / 4.0) * 2 * period
        kp.co = ( frame, c * vals[j])
        kp.interpolation = 'SINE'
        if 0 == j % 2:
            kp.easing = 'EASE_OUT'
        else:
            kp.easing = 'EASE_IN'
    fc.modifiers.new('CYCLES')

Mostly you care about stuff like action.fcurves.new , fc.keyframe_points.add, and kp.co= (frame,value)

$\endgroup$
  • $\begingroup$ Thank you, this really helped, but how do I link the fcurves with the bones once I link the action with the armature? $\endgroup$ – Tcll Oct 7 '16 at 16:33
  • $\begingroup$ Figured it out, data_path has an object-context relation, and index is the value index of the vector at data_path. $\endgroup$ – Tcll Oct 8 '16 at 13:44
  • 1
    $\begingroup$ Your data_path would be something like data_path="pose.bones[\"%s\"].rotation_euler"%bone_name. $\endgroup$ – Mutant Bob Oct 8 '16 at 20:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.