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.

enter image description here Rest Poses: T-pose Armature A on left, Armature B's (the one with animation) on right

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$
4
  • $\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
    Commented Jan 24, 2017 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$ Commented Jan 24, 2017 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
    Commented Jan 24, 2017 at 16:32
  • $\begingroup$ Original question edited to include example blend file $\endgroup$ Commented Jan 24, 2017 at 19:04

1 Answer 1

5
$\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 = False
scene = context.scene
rig1 = scene.objects["hands_reference_skeleton"]

rig2 = scene.objects["hands_reference_skeleton.001"]
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(int(f))
    context.view_layer.update()
    r2 = rig2.evaluated_get(context.evaluated_depsgraph_get())
    for pb in r2.pose.bones:
        #pb2 = rig1.pose.bones.get(pb.name)
        m = rig2.convert_space(
            pose_bone=pb, 
            matrix=pb.matrix,
            from_space='POSE', 
            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$
3
  • $\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$ Commented Jan 26, 2017 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
    Commented Jan 26, 2017 at 4:23
  • $\begingroup$ That was indeed the step I was missing. Greatly appreciate the assistance! $\endgroup$ Commented Jan 27, 2017 at 0:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .