2
$\begingroup$

I have two armatures with all of the same bones. Armature A is a basic character T-stance, Armature B is of a run animation. I had first attempted to copy the pose from Armature B to Armature A, but realized that there was no pose, and that the positions of the bones of Armature B where baked into (I think that's the proper term) the armature, meaning there was no pose to copy.

Is there a way to create a pose of Armature A using the positions of the bones of Armature B?

An example blend can be found here:

Bip001 is the primary armature that the model is bound to, Bip001.001 is the armature with the animation I am attempting to apply to Bip001. (Bip001 == Armature A, Bip001.001 == Armature B from the above explanation).

$\endgroup$
  • $\begingroup$ Does armature B also have T-pose rest position? And if so can you just associate run action that is on armature B to armature A? $\endgroup$ – batFINGER Jan 24 '17 at 16:12
  • $\begingroup$ Armature B does not have T-pose rest position. I can associate the action from B to A, but since I do not have the initial stance from B, A is, well, messed up to say the least when the animation plays out. $\endgroup$ – nullReference Jan 24 '17 at 16:16
  • $\begingroup$ Can you post the blend file. (or cut down example of) As I have a script that may do this, but would like to test first. $\endgroup$ – batFINGER Jan 24 '17 at 16:32
  • $\begingroup$ Original question edited to include example blend file $\endgroup$ – nullReference Jan 24 '17 at 19:04
4
$\begingroup$

Here is a script I've been working on to do this for bvh files. Basically it adds a copy transform constraint to each pose bone, then using Object.convert_space, retargets animation to another rig with same bones.

It's good practice to keep scale on armatures to unity, to avoid issues. Applying scale to both armatures. Ctrl-A scale will make the scale (1, 1, 1). I applied rotation as well and put the armature objects at location (0, 0, 0) before running script..

enter image description here

import bpy
from bpy import context

remove_constraints = True
scene = context.scene
rig1 = scene.objects["Bip001.001"]

rig2 = scene.objects["Bip001"]
if not rig2.animation_data:
    rig2.animation_data_create()
rig2.animation_data.action = None

# add copy transform constraint to each bone
for pb in rig2.pose.bones:
    ct = pb.constraints.get(pb.name)    
    if ct is not None:
        ct.influence = 1
        continue
    ct = pb.constraints.new('COPY_TRANSFORMS')
    ct.name = pb.name
    ct.target = rig1
    ct.subtarget = pb.name

action = rig1.animation_data.action

f = action.frame_range.x
# add a keyframe to each frame of new rig
while f < action.frame_range.y:
    scene.frame_set(f)
    for pb in rig2.pose.bones:
        #pb2 = rig1.pose.bones.get(pb.name)
        m = rig2.convert_space(pb, pb.matrix, to_space='LOCAL')
        if pb.rotation_mode == 'QUATERNION':
            pb.rotation_quaternion = m.to_quaternion()
            pb.keyframe_insert("rotation_quaternion", frame=f)
        else:

        # add rot mode checking 
            pb.rotation_euler = m.to_euler(pb.rotation_mode)
            pb.keyframe_insert("rotation_euler", frame=f)
        pb.location = m.to_translation()

        pb.keyframe_insert("location", frame=f)
    f += 1

# set constraints to zero or remove entirely.
for pb in rig2.pose.bones:
    ct = pb.constraints.get(pb.name)    
    if ct is not None:
        if remove_constraints:
            pb.constraints.remove(ct)
        else:
            ct.influence = 0

$\endgroup$
  • $\begingroup$ The blend file you provided is excellent. However I am attempting to rebuild it from my original file so that I can understand exactly what all had to happen to get to that point. Whenever I run the script, Bip001 becomes very large. I know you had said you rescaled the armatures. Was there a specific size you scaled them too? This is what I am seeing after running the script: stashcube.com/stackexamples/armatures.PNG $\endgroup$ – nullReference Jan 26 '17 at 3:17
  • $\begingroup$ Yes that looks familiar had a similar result when I opened test file and ran script.. Prob could fix by multiplying by the inverse of the object's world matrix. Your scale was 0.05 or something hence the inverse is 20 x bigger in a roundabout way. On the other hand it's good practice to keep scale on armature to unity, to avoid issues. Applying scale to both armatures. Ctrl-A scale will make the scale (1, 1, 1). I applied rotation as well and put the armature objects at location (0, 0, 0) before running script. $\endgroup$ – batFINGER Jan 26 '17 at 4:23
  • $\begingroup$ That was indeed the step I was missing. Greatly appreciate the assistance! $\endgroup$ – nullReference Jan 27 '17 at 0:18

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.