This document is about how to create keyframe animation by Maya API and Max SDK.

First, some basic idea. An animation curve can be regarded as Q = f(t), means at any given time t, you can calculate the value of Q by function f. Both Maya and Max uses modified cubic 2 dimensional bezier curve as f. The curve is a number of segments connected by knots call keyframes, or keys. Below is the diagram showing one segment.

Green dotted line is the curve, which is defined by 4 points, red ones are end points, blue ones are control points. You may call those yellow lines handles. Those points live in 2-dimensional space. Actually a key should have one end point and two control points, one for in segment, the other for out. Two keys defines one segment, and a curve should have at least one segment, so at least two keys.

Creating animation curve in Maya is fairly straightforward. You have the MPlug of any keyable attribute, create the curve by MFnAnimCurve::create(MPlug), then add keys by MFnAnimCurve::addKeyframe(MTime, double). So at the end point, Q is the double value, and t is MTime. For each control points, we need tangent type, angle, weight.

Tangent is the handle mentioned before. In the following image:

Tangent angle equals atan(dQ/dt), and tangent weight is length of the handle, which equals sqrt(dQ*dQ + dt*dt).

Set the tangent angle and weight by MFnAnimCurve::setTangent().

Tangent type is changed by MFnAnimCurve::setInTangentType() and MFnAnimCurve::setOutTangentType(). I think MFnAnimCurve::kTangentFixed is the most flexible and useful.

There are two kinds of animation curve, weighted and unweighted. We are talking about weighted version here, so MFnAnimCurve::setIsWeighted(true).

Not yet, tangent handles should be unlocked by calling MFnAnimCurve::setTangentsLocked() and MFnAnimCurve::setWeightsLocked() before those angles and weights can be correctly set.

The Max side of the story is a bit more confusing. In Max, keyframe animation is done via controllers. Controllers are attached to a parameter belongs to a IParamBlock2 of the INode, or just built into the INode. There are a few ways to access the controller, i.e.

node->GetTMController()->GetPositionController()->GetXController();

Once you have the controller, get the keyframe interface by

IKeyControl *ikeys = GetKeyControlInterface(c);

Keyframe is added by IKeyControl::SetKey(). Specific controller requires specific kind of keys. We only talk about IBezFloatKey here.

It has time (t) and val (Q).

Tangent type is set by SetInTanType() and SetOutTanType(). BEZKEY_USER is similar to Maya’s Fixed type.

A Max key has intan, outtan, inLength, and outLength. The value of intan and outtan equals dQ/dt. The value of inLength and outLength equals dt/time_span. The time_span for out tangent of first key is shown below

Remember multiply any time value by TicksPerFrame.