1

[I reformulate the question to something more concrete]

I have 2 different .bvh files with 2 poses. From one pose I want to find the transform to get the second pose. If I compute the rotation to align one bone to the other bone (see Figure 1)

enter image description here

I get that I should rotate Z axis 45º, and if I put this rotation in Pose mode I can align the 2 bones (see Figure 2)

enter image description here

However, if I write 45º in the .bvh file the alignment goes completely wrong (see Figure 3)

enter image description here

I think probably rotation should be expressed in armature coordinates but I can't find how to do that in the .bvh files.

m.ardito
  • 11,967
  • 2
  • 23
  • 36
  • The bvh importer exporter bundled with blender, both imports to and exports from joint empties. Suggest posting code if you want help with what you have. – batFINGER Mar 08 '18 at 12:24
  • I can share a couple of bvh files I'm trying as example. To compute rotation angles I use Matlab. What I want to do is to compute a bvh file that contains all skeleton positions. bvh1 bvh2 . In the second frame, I should find the rotations to get to the bvh target. – Jordi Sanchez Mar 08 '18 at 15:17

1 Answers1

1

Retarget animation

of one rig to another which differs only by rest pose

Given your two example bvh files produced rigs, toy_example_source and toy_example_target It looks like you want to do same as this qanda

Since your two rigs only differ by rest pose can snap target to source using a global copy transforms constraint. The new transforms of the snapped bone can be grabbed from the pose bones matrix. The local coordinates of the new transform using Object.convert_space(...)

Edit the name of source and target rigs to suit.

import bpy
from bpy import context

remove_constraints = True
scene = context.scene
rig1 = scene.objects["toy_example_source"]

rig2 = scene.objects["toy_example_target"]
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
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • Somehow this puts me in the way of solving my problem, but still is not enough for what I need to do. The approach I'm following is, 1) convert all my 3d points from skeleton to .bvh file with 1 frame, 2) align 1.bvh, with all other converted .bvh, 3) export .bvh with blender. However, this .bvh I want to use with MakeHuman, and blender .bvh exports 6 channels which makes it not compatible with MH. My problem still is how I convert these rotations of bones to world coordinates. convert_space(..) give me always same values no matter what I put in to_space – Jordi Sanchez Mar 13 '18 at 16:43