# Maya animation curves

This topic is 5410 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm trying to recreate the interpolation of maya's animation curves, and so far I've only had problems. For those of you who are not familiar with maya-curves they are implemented as a modified version of cubic 2 dimensional bezier curves. Or well rather some version of hermite curve(?). Internally they are saved as points with 2 tangents, an incoming and one outgoing. When calculating the interpolation between 2 points (p1 and p2) the outgoing tangent of p1 and the incoming tangent of p2 is used. I'm only going to use non-weighted tangents, which should simplify the process a lot. Here's a snippet from the maya-manual:
Quote:
 Animation curves may have either weighted or non-weighted tangents. With non-weighted tangents, tangents are implemented as vectors and P2 and P3 are internally adjusted to account for the time difference between P1 and P4. When evaluating a time within a segment, the following algortithms are used: For non-weighted tangents: where x is the start of the segment compute the parameter t as time - x with t (and the bezier y parameters a, b, c, d) compute the value as: v = (t^3 * a) + (t^2 + b) + (t * c) + d
You can find the complete document here. I believe my problem is this part "and the bezier y parameters a, b, c, d". How do I calculate a, b, c and d from the points? here's what I have at the moment:
struct KeyFrame
{
float ix, iy; // incoming tangent-vector
float ox, oy; // outgoing tangent-vector
float x; // point x
float y; // point y
};

// Grab the keyframes we are interpolating between
KeyFrame cur = getKeyFrame(animCurve, currKey);
KeyFrame nxt = getKeyFrame(animCurve, currKey+1);
float dist = (nxt.x - cur.x) / 3.0f;

// This is actually the x-coords of the points (seems to be working)
float a = nxt.y;
float b = nxt.y - nxt.iy * (dist / nxt.ix); // scale tangent to x=1/3
float c = cur.y + cur.oy * (dist / cur.ox); // scale tangent to x=1/3
float d = cur.y;

// Calculate the interpolated value
float t = 0.5f;
float v = (t*t*t*a) + (t*t+b) + (t*c) + d;
// I really doubt the "t*t+b" is correct, but the manual says so.
// I think "t*t*b" is more likely. Anyway, neither of them seems to
// work, so I suppose I'm doing something wrong when calculating the
// four coefficients.



##### Share on other sites
goto the devkit/animEngine example. They have code there that recreates the maya animation curve evaluation exactly as it is in maya.

As for your code problems, possibly the bezier interpolation is failing because bezier interpolation is :

float it = 1.0f-t;
float v = t*t*t*a + 3*t*t*it*b + 3*t*it*it*c + it*it*it*d;

In addition, your time value is always set to 0.5. This will always return the same mid position between keys. ? I think you may also be using the wrong tangents with the points? it's kinda a bit difficult to tell from your code.

I think though, you may be overcomplicating this stuff somewhat. All you need is a single 1D hermite curve, the time values don't really come into this too much. A hermite curve better fits the bill here simply because you have 2 points, and 2 tangents as you input data. A bezier curve is *not* ideal...

// i'll assume that in_t is the input time to evaluate the curve at // i'll also assume that cur.x < in_t and next.x > in_t // no idea why you are dividing by 3?float dist = nxt.x - cur.x;// scale the t value to 0 to 1 range between cur & next float t = (in_t-dist) /dist;// calculate the hermite blending values using our time valuefloat h1 =  2*t*t*t - 3*t*t + 1;float h2 = -2*t*t*t + 3*t*t;float h3 =    t*t*t - 2*t*t + t;float h4 =    t*t*t - t*t; // Calculate the interpolated valuefloat v = h1*cur.y +     // P1 - 1st point          h2*nxt.y +     // P2 - 2nd point          h3*cur.oy +    // R1 - tangent leaving P1          h4*nxt.iy;     // R2 - tangent arraving at P2

you might find a couple of useful maya bits and bobs here

##### Share on other sites
Thank you very much for the reply. I will try your method when I get back home. The site you provided along with the animEngine will surely help! I can't believe I didn't notice the animEngine sample.

As you might have noticed I don't really have any knowledge of curves, and in my frustration yesterday I attempted a trial-n-error without any success. I should've tried to understand the math instead.

Anyway, thank you again for the help!

• 13
• 18
• 29
• 11
• 20