Set keyframes for translation/rotation to a new animation layer

Set keyframes for translation/rotation to a new animation layer

Anonymous
Not applicable
1,712 Views
2 Replies
Message 1 of 3

Set keyframes for translation/rotation to a new animation layer

Anonymous
Not applicable

Hi, It's been several days that I'm working on a problem that I cannot manage to figure out. I tried searching online and asking people but unfortuantely I didn't find a solution.

 

I hope that you guys can help me out.

 

First I'm going to explain what I'm trying to achieve.

 

Use Case

The use case is: the user creates an animation on an animation layer, sends the information to another program, the program creates a new animation and sends some values back (translation and rotation in world space). I want so save these new keyframes inside a new animation layer.

 

Problem

For now everything works except when I try setting the new keyframes inside the new animation layer. For some reason the root (we are talking about a humanoid) has some values on the translation attributes, but every other joint has no rotation values (has keyframes with value 0 for rotateXYZ).

 

My procedure that causes the problems

Creating the new animation layer

 

# select all the joints I want to apply the keyframes to
cmds.select(clear=True)
for joint in joints: cmds.select(joint, hierarchy=False, deselect=False, add=True)

# create a new animation layer and add the selected objects to it
newAnimLayer = cmds.animLayer("generatedAnim", addSelectedObjects=True)

        

 

This piece of code should be fine. I create an animation layer that contains all the attributes of the selected object (correct me if I'm worng).

 

Applying the new keyframes

 I iterate through each keyframe and call this function:

 

# apply translation only for Hips (root)
if (joint.name == "Hips"):
   # set position transform 
   cmds.xform(joint.name, translation=joint.worldPosition, worldSpace=True)
   cmds.setKeyframe(joint.name, animLayer="generatedAnim", time=i+1, attribute="translate")

# set rotation transform 
cmds.xform(joint.name, rotateOrder='zxy') # because the data I receive has other conventions
cmds.xform(joint.name, rotation=joint.worldRotation, worldSpace=True)
cmds.xform(joint.name, rotateOrder=oldPreviouslyUsedOrder) # revert order to original 
cmds.setKeyframe(joint.name, animLayer="generatedAnim", time=i+1, attribute="rotate")

 

Note: I first call cmds.xform to change the transform so that I can set the keyframes with the correct values since the data I receive is in worldSpace and has also other conventions. That's why for rotations I change the order to the data's convention, apply the transform, revert the order back and finally set the keyframe [this is not the nicest way to do this but I couldn't find better ways, even considering the matrices it was a mess because for worldSpace rotations one has to consider also all the pre rotations maya can apply].

 

This code works fine if I choose animaLayer="BaseAnimation", which is the root animation layer, but as soon as I try to use another layer the joint get still keyframed at every timeframe but the values of the rotations are all 0 (on every component X, Y, Z).

 

I hope I'm just missing a simple but very relevant concept about animation layers. Thanks a lot for anyone trying to help.

0 Likes
1,713 Views
2 Replies
Replies (2)
Message 2 of 3

Anonymous
Not applicable

I found out that the problem lies in the change in rotateOrder. When changing rotate order the rotation that gets adapted is not the one that the object has currently set in its attribute editor (so not the one I just changed with xform) but another value, that I suppose is the one taken form an animation layer at the time where the time slider is. So changing rotateOrder will change the order of the rotation set in an animation layer.

I cannot figure out why though. There is some kind of connections that I'm missing. 

Maybe the best solution at this point is to get rid of the change in rotate order. Is there a way I can change the rotation order of an euler vector without using xform?

0 Likes
Message 3 of 3

Anonymous
Not applicable

I'm dropping my solution, it might be useful for someone else.

 

Instead of using xform for changing the order of the rotation vector I used pymel.core.datatypes.EulerRotation and used the reorder function and only then applied the xform with the correct rotation values. 

0 Likes