MfnAnimCurve.setKeys() Rotation values

I’m working on importing our game animation format to Maya

The data is stored as RST transforms per joint / per frame. Looping over each frame one at a time will be slow so I’m seeking a way to set many keyframes in one go. So far I’ve found OpenMaya.MfnAnimCurve.setKeys()

Experimenting with it , setting rotation keys, I have found that I am unsure precisely which units rotation plugs expect. The docs mention nothing under MfnAnimCurve.setKeys()

I tested with a range of ints and setting a value of 1 on rotate x yields value of about 52.2 in the channel box , which I guessed to be 1 radian. Converting each int from degrees to radians seems to comfirm this

But I have not found confirmation of this in the docs. I wonder if the value type expected for rotation keys is reliant on user settings, or some other setting, similar to the time value? Can I always expect .setkeys() to utilize radians for rotation channel values?

Another question is : my source data is quaternions , i wonder if there is an attr plug for setting multiple rotation keys using quats, or perhaps using a matrix to set all transform channels efficiently?

I’m 99% sure that the API always uses radians unless you’re explicitly interacting with a ui component.

I’ve got this link saved for myself, and I reference it from time to time when dealing with units in maya. Referencing a file converts its unit scale - #2 by tfox_TD

As for setting quaternion values directly: not that I know of. The way I understand it, animation curves each control a single floating point value. So there would be no way to set things that have multiple values without multiple anim curves.

The fact that this isn’t built into maya is really annoying :frowning: At work, we’ve got a python plugin to make a mel command that lets us set multiple keys across multiple attrs in one go. Plugin to set keys on multiple attributes over multiple frames · GitHub

2 Likes

Thanks, this info will probably come in handy for me quite soon.

In one of my scripts i do something like this for rotations :


trs = MTransformationMatrix(local_matrix) # i grab the matrix i need 
.
.
if set_rotate_order: 
	trs = trs.reorderRotation(rotate_order+1) # set the rotation order

euler = trs.rotation(asQuaternion=False) # grab rotation values from matrix
euler = om2.MEulerRotation(euler.x, euler.y, euler.z, rotate_order) 
euler.reorder(rotate_order) # re-order rotations 

# Write values per frames
keys["rotateX"].append((frame, euler.x))
keys["rotateY"].append((frame, euler.y))
keys["rotateZ"].append((frame, euler.z))
.
.
.

# Then after passing all my keys i apply them to anim curves.

# Use addKeys to set all keys in one go for efficiency

times = [om2.MTime(frame, om2.MTime.uiUnit()) for frame, _ in frame_values]|
values = [value for _, value in frame_values]|
animFn.addKeys(times, values)|