3
$\begingroup$

I am trying to apply skeleton to model. I can import BVH and see the animation just fine, however when I do "Apply as rest pose" which is necessary for the model to actually align with the skeleton's movement, the animation becomes completely distorted.

If I don't apply the rest pose the model gets distorted the moment I parent the model and skeleton.

What am I doing wrong?

EDIT:

$\endgroup$
7
  • $\begingroup$ Are you applying the rest pose when the skeleton is in a similar position to the mesh? $\endgroup$ Apr 2 '16 at 21:10
  • $\begingroup$ yes. actually the strange thing is that the moment I apply rest pose, the actual skeleton animation gets completely messed up $\endgroup$
    – Stpn
    Apr 2 '16 at 21:17
  • $\begingroup$ Can you post a .blend on blend-exchange.giantcowfilms.com? Its too hard to tell what might be going on without a .blend to look at. $\endgroup$ Apr 2 '16 at 21:23
  • $\begingroup$ Uploaded! Sorry I can't add the model, but even with BVH it will be obvious what's wrong - the "rest pose" completely messes up animation. Thank you! $\endgroup$
    – Stpn
    Apr 3 '16 at 0:08
  • $\begingroup$ Wow -- yeah the default pose in edit mode is all 'condensed' into a little chain. Honestly I've never seen anything like that. $\endgroup$ Apr 3 '16 at 1:54
2
$\begingroup$

Old blender artist thread to change the animation of bvh after changing rest pose.

http://blenderartists.org/forum/showthread.php?254060-modify-motion-capture-T-pose

The code in a zip file http://blenderartists.org/forum/attachment.php?attachmentid=283112&d=1389806292

The concept~~

  • Pose the armature into the new rest pose.
  • Make a copy of armature and make the pose the copies new rest pose.
  • Join the two armatures
  • Use the bone snapping code from rigify to snap the copied bones to the original bones, and keyframe the new animation from those.

run the script and you will get the following buttons in the armature data panel

enter image description here

Hit the New rest pose to rig button, this will give you a new set of bones to the armature. Have a look at the rest pose, the new set has the pose as a rest pose. Play the animation and you will see the new bones do nothing.

EDIT

The execute of the operator updated to 2.8,

import bpy
from bpy import context

###################################################
# dupe rig
# for copy
# add prop to point to original bone
# make current pose the rest pose
# join to original
####################################################

scene = context.scene

# original bvh rig
bvhrig = context.active_object

bpy.ops.object.mode_set() # object mode
bpy.ops.object.duplicate()
ob = context.object
print("DUPE", ob)
 
#add a custom prop for each bone in the copy

for bone in ob.pose.bones:
    bone['bvh'] = bone.name

# apply the pose as rest pose
bpy.ops.object.mode_set(mode='POSE')

bpy.ops.pose.armature_apply()

bpy.ops.object.mode_set(mode='OBJECT')
    
# join back to original
ob.select_set(True)
context.view_layer.objects.active = bvhrig
bvhrig.select_set(True)

bpy.ops.object.join()

The BVH action to new restpose rig button, copies the original's animation by snapping the bones for each frame of the action. Play the animation now and the new bones are animated same.

Then lastly, copy, paste, n run this code

import bpy

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"


    @classmethod
    def poll(cls, context):
        return context.active_object is not None


    def execute(self, context):
        #dupe the armature
        bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.duplicate()
        newarm = context.object
        # copy the action
        newaction = newarm.animation_data.action.copy()
        # strip out the old fcurves
        for fcurve in newaction.fcurves:
            if fcurve.data_path.find(".001") == -1:
                newaction.fcurves.remove(fcurve)
            else:
                fcurve.data_path = fcurve.data_path.replace(".001","")
        newarm.animation_data.action = newaction
            
        bones = [bone.name for bone in newarm.pose.bones if bone.get('bvh') is None]
        # remove original bones
        bpy.ops.object.mode_set(mode='EDIT')
        
        arm = newarm.data
        for name in bones:
            eb = arm.edit_bones.get(name)
            if eb is not None:
                arm.edit_bones.remove(eb)
                
        # rename bones to original names        
        bpy.ops.object.mode_set(mode='POSE')
        for pb in newarm.pose.bones:
            pb.name = pb["bvh"]
            
        return {'FINISHED'}

def register():
    bpy.utils.register_class(SimpleOperator)

def unregister():
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.simple_operator()

and you will have a new rig (single bone set) with the new animation and new rest pose.

As you are using the Male1__.bvh mocap set, you can use the same "double boned" rig with other actions imported from another file of same mocap subject.

Result.

$\endgroup$
1
$\begingroup$

When applying a new rest pose, the blender console states: Actions on this armature will be destroyed by this new rest pose as the transforms stored are relative to the old rest pose. So you might have to redo your animation, or work with a model that is posed according to the animations rest pose. The rest pose of your animation is totally weird though.

$\endgroup$
1
  • $\begingroup$ I see. I exported BVH from MotionBuilder. Any chance you'd know of any gotchas related to that? $\endgroup$
    – Stpn
    Apr 3 '16 at 16:07

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.