Project 1: Interpolation

 

Due: Jan 30, 2015, 10AM


Project description

In this project, you will implement three different types of interpolation algorithms to create keyframe animation. You will work within Maya environment to leverage the powerful modeling and animation tools it provides. However, you will write your own interpolation scripts in MEL to override Maya’s default interpolation method. Maya also supports Python scripting. You can write your scripts in Python if you wish, but the example script we provide is in MEL.


Requirements

You will implement the following three curve/spline types:

  1. Cubic Bézier (splined together with C0 continuity, you will need 4 + 3 * i keyframes, where i is an arbitrary nonnegative integer)

  2. Catmull-Rom

  3. B-spline (defined by de Boor points)

Write three separate MEL scripts according to the prototypes described below. To simplify the problem, you can assume the keyframes are equally spaced on the timeline (e.g. keyframes are set at t = 3, t = 6, t = 9, etc).


Example: Linear interpolation

The most efficient way to learn MEL is by looking at examples. Here is an example script for linear interpolating keyframes in Maya. Before you write your own script, copy and paste this procedure to the Maya Script Editor. Hit the “run” button (or ctrl-enter) to define the function “linearInterpolation”. Now you can call this function by executing the command: linearInterpolation(“joint2.rotateX”); (Sometime the double quotation marks get messed up when you directly copy/paste this command to Maya.)


This will interpolate the rotationX channel for joint2, assuming you have a joint named “joint2” with some assigned keyframes in its rotationX channel. You should see a red bar on every  frame of your animation timeline. To interpolate other joints or channels, replace “joint2.rotateX” accordingly and call linearInterpolation again.


For your assignment, you will do the similar things but use different types of interpolation methods. The example script basically does three things: (1) read current keyframes from Maya environment, (2) interpolate keyframes linearly and store all the inbetween frames, and (3) use “setKeyframe” command to set the value of every inbetweens in Maya. You can reuse (1) and (3) but replace (2) with the required interpolation methods.


proc linearInterpolation(string $curveName)

{

// query number of keys on curveName

        // note Maya command is enclosed in back ticks (`) rather than apostrophes (‘)

int $keyCount = `keyframe -query -keyframeCount $curveName`;


// get keys on curvename, keys[0] = firstKeyTime, keys[1] = firstKeyValue, keys[2] = secondKeyTime, keys[3] = secondKeyValue, etc

float $keys[] = `keyframe -query -timeChange -valueChange $curveName`;


// linearly interpolate keyframes and store interpolated values in ctrlPoints

float $ctrlPoints[];

int $count = 0;

for($i = 0; $i < $keyCount - 1; $i++){

$point1X = $keys[$i * 2];

$point1Y = $keys[$i * 2 + 1];

$point2X = $keys[$i * 2 + 2];

$point2Y = $keys[$i * 2 + 3];

for($j = $point1X; $j < $point2X; $j++){

$ctrlPoints[$count++] = $point1Y + ($j - $point1X) * ($point2Y - $point1Y) / ($point2X - $point1X);

}

}


// assign each frame an interpolated value using Maya command “setKeyframe”

$count = 0;

float $maxTime = `playbackOptions -query -maxTime`;

for($i = 1; $i < $maxTime; $i++){

float $value;

// three cases: before first keyframe, after last keyframe, and in between

if($i < $keys[0])

$value = $keys[1];

else if($i >= $keys[$keyCount * 2 - 2])

$value = $keys[$keyCount * 2 -1];

else

$value = $ctrlPoints[$count++];

setKeyframe -time $i -value $value $curveName;

}

};


Function prototypes

Please use these function prototypes for the three interpolation methods you implement. The input to each of the procedures is a string that specifies the joint name and the channel (e.g. joint3.translateX, or joint2.rotateZ)


proc BezierInterpolate(string $curveName)

proc CatmullRomInterpolate(string $curveName)

proc BSplineInterpolate(string $curveName)


Working with matrix class

Maya provides very basic matrix computation functionality but is sufficient for this assignment. Here is a simple example of matrix multiplication.


proc testing()

{

    // to define a matrix, use commas to separate columns and semicolons to separate rows

    // mA is a 4 by 4 matrix, vB is a 4 by 1 vector, vC is a 1 by 4 vector, and sD is a scalar

    matrix $mA[4][4] = <<1, 2, 3, 4; 2, 3, 4, 5; 5, 4, 3, 2; 4, 3, 2, 1>>;

    matrix $vB[4][1] = <<2; 3; 4; 2>>;

    matrix $vC[1][4] = <<2, 3, 2, 1>>;

    matrix $sD[1][1] = $vC * $mA * $vB;

    print $sD;

};


Graph editor

How do you know if your interpolation does the right thing? One easy way to check the results is to use Graph Editor provided by Maya (Window->Animation editors->Graph editor). Select the joint and channel of interest and observe if the curve exhibits the properties of the interpolation method.


Tutorials on MEL

Although the example script should be sufficient for you to complete this assignment, there are a lot of useful tutorials on MEL you can find online. For example,


http://web.archive.org/web/20111120180214/http://caad.arch.ethz.ch/info/maya/manual/Commands/melCommands/melFAQ.html


Extra points

  1. 1.For each curve, you can implement support for "wrapping," which means that the curve has C0 continuity between the end of the animation and the beginning.  As a result, looping the animation does not result in abrupt jumps

  2. 2.Implement a C2-Interpolating curve.

  3. 3.Handle the situations when keyframes are not evenly spaced on the timeline.

  4. 4.Write a script that interpolates all the objects in the Maya scene at once, including all the skeletons, geometries, lights, and cameras. The prototype of the procedure looks like “proc InterpolateAll(string $interpolationType)”. The argument $interpolationType indicates the desired interpolation method, which can be “bspline”, “catmull”, or “linear”.


Submission instruction

Please save your scripts in three separate .mel files. If you implement any code for the extra credits, please attach a short description of what you have done and how to test the code. Submit your files to t-square before the deadline.