2
$\begingroup$

So I have one FBX that have it's own armature and one object. Let's call it T pose. I have second FBX that contains one armature with let's say walk animation.

I am trying to assign walk animation to object with t-pose with no success. What have I tried so far:

  • Adding just walk armature to object won't work. I mean I can add the armature, but walk armature's rest pose is different than t-pose's rest pose. If I just change armature, animation is awkward.

  • I wrote one simple Python script that copy rest pose of walk animation and paste it to rest pose of t-pose. That didn't helped.

  • tried Copying FBX animation to armature

Am I right that deformations in animations are just offsets from rest pose?

I see others had same problems like: Merge multiple fbx animations into single rig or Import fbx animation

Is there any solution for this? Any comment is appreciated.

$\endgroup$
0
$\begingroup$

The solution is rather simple.

You need to add Bone Constraint -> Copy Transforms to armature without animation. As Target add armature with animation, and as a Bone, bone with the same name. Rinse and repeat for all bones.

Here is the code that automates all:

  • Creates constraints and link bones with other armature
  • Iterate over all frames, apply transform, and insert keyframes for all bones
  • Delete constrains

Just fill source and target armature, and animation from and to. Moreover, you can just call add_constraints() function which will link armatures and bones.

import bpy

source = "Bip001"
target = "Bip001.001"
frame_from = 0
frame_to = 35

# add constrains and link them with target bones
def add_constraints():
    global source, target

    source_ob = bpy.data.objects[source]

    for bone in source_ob.pose.bones:
        sel_bone=source_ob.data.bones[bone.name]
        sel_bone.select=True
        bpy.context.object.data.bones.active=sel_bone

        trans_bone = bpy.context.object.pose.bones[bone.name]
        if trans_bone.constraints.find('Copy Transforms') == -1:
            if bpy.data.objects[target].pose.bones.get(bone.name) is not None:
                bpy.ops.pose.constraint_add(type='COPY_TRANSFORMS')
                trans_bone.constraints["Copy Transforms"].target = bpy.data.objects[target]
                trans_bone.constraints["Copy Transforms"].subtarget = bone.name

# delete previously created constrains     
def del_constraints( ):
    for bone in bpy.context.selected_pose_bones:
        copyLocConstraints = [ c for c in bone.constraints if c.type == 'COPY_TRANSFORMS' ]
        # Iterate over all the bone's copy location constraints and delete them all
        for c in copyLocConstraints:
            bone.constraints.remove( c ) # Remove constraint

def apply_animation():
    global source, target, frame_from, frame_to
    #set keying set to whole character
    #we have all bones selected
    scene = bpy.context.scene
    for frame in range(frame_from, frame_to ):
        scene.frame_current = frame
        scene.frame_set(scene.frame_current)
        # apply visual transfrom to pose Ctrl+A
        bpy.ops.pose.visual_transform_apply()
        # insert all keyframes -> press I
        bpy.ops.anim.keyframe_insert_menu(type='__ACTIVE__', confirm_success=True) 

def select_all_bones():
    global source, target
    ob = bpy.data.objects[source]
    for bone in ob.pose.bones:
        b=ob.data.bones[bone.name]
        b.select=True
        bpy.context.object.data.bones.active=b

ks = bpy.data.scenes["Scene"].keying_sets_all
ks.active = ks['Whole Character'] 

ob = bpy.data.objects[source]
bpy.context.scene.objects.active = ob
bpy.ops.object.mode_set(mode='POSE')  
#select_all_bones()
add_constraints()
apply_animation()
del_constraints()
$\endgroup$

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.