I have a mocapped running animation, and I’ve extracted a small part of it in which the armature starts out on one foot, then takes a step with the other, then goes back to the first.
The beginning and end of the animation are similar but, obviously, not identical.
Is there a way to adjust the beginning and ending positions of the armature to make the animation loop seamlessly?
If your full run cycle is 15 frames where frame 1 is the start, you come back to the first frame at 16[SUP]th[/SUP] frame to make it seamless. Look at this video:
The animation in the video is hand-made, which makes it relatively easy to loop, because it’s made up of a few keyframes, spread out over the course of the animation.
The problem is that a mocapped animation consists entirely of keyframes, with a specific position and rotation at every frame for each bone in the armature; this would make tweaking individual frames somewhat time-consuming, to say the least.
I was wondering if Blender had a utility aimed at gradually modifying the last X keyframes at the end of an animation, in order to make them smoothly transition back to the first keyframe.
For those only interested in mocap retargeting and not in the rest of MakeHuman, I extracted the makewalk tool and put it here: https://hotfile.com/dl/248336086/75164f0/makewalk_v0913.rar.html
Notice however that this file will not be updated for bugfixes etc. until I put up a new version manually.
MakeWalk has been tested with a quite new build, which probably is a little more recent than 2.68. I doubt that it everything will work with something as old as 2.63.
In the end, I wrote a script that allowed me to select a number of keyframes, and adjust the motion to the last selected keyframe:
import bpy;
## Must be an armature.
armature = bpy.context.active_object;
fcurves = armature.animation_data.action.fcurves;
for curve in fcurves:
keys = curve.keyframe_points;
## Get a list of the selected keyframes
selectedKeys = [];
for k in keys:
if k.select_control_point:
selectedKeys.append( k );
lastVal = selectedKeys[-1].co.y;
step = 1 / len( selectedKeys );
influence = 0; ## The 1st image will not be changed; it marks the start of the transition.
for key in selectedKeys:
difference = lastVal - key.co.y;
key.co.y = key.co.y + ( difference * influence );
influence += step;
To use it:
Select the animated armature and keep only the keyframes that will be necessary for the loop.
In the DopeSheet (or Graph Editor), copy the first keyframe and use it to replace the last one. The animation will begin and end with this pose.
Select a number of keyframes at the end of the animation; these will be used to transition back to the (new) end pose. The greater the amount of keyframes, the longer (and smoother) the transition will be.
Run the script.
This code assumes linear interpolation between keyframes, and also that all selected keyframes are spaced equally in the timeline.
Many thanks again to ridix and ThomasL for the help.