Friday, May 29, 2009

Vector Rig Translation Control

The translation data for the rig is controlled using a script on Cntrl groups above the main tailControls. In essence, each frame, two vectors are calculated based on the lead control's position in the last frame and its position in the current frame. Those are used to calculate the magnitude of change, which is then used to calculate where each of the tailControls should be placed.
Here is a sample of the code:

float $distance = 3;
int $time = `currentTime -q`;
vector $oldPos = `getAttr -time ($time -3) leadObject.translate`;
vector $newPos = `getAttr leadObject.translate`;
vector $vector = $oldPos - $newPos;
float $vectorMag = mag ($oldPos - $newPos);
if ($time == 0)
{
trailObject_01_cntrlGrp.translateX = $distance * -1;
trailObject_01_cntrlGrp.translateY = 0;
trailObject_01_cntrlGrp.translateZ = 0;
string $zeroTime = "time is at zero";
//print ($zeroTime + "\n");
}
else if ($newPos == $oldPos)
{
trailObject_01_cntrlGrp.translateX = trailObject_01_cntrlGrp.translateX;
trailObject_01_cntrlGrp.translateY = trailObject_01_cntrlGrp.translateY;
trailObject_01_cntrlGrp.translateZ = trailObject_01_cntrlGrp.translateZ;
string $vectorDistance = "the new vector equals the distance";
//print ($vectorDistance + "\n");
}
else
{
while ($time > 0)
{
$newPos = `getAttr -time $time leadObject.translate`;
$oldPos = `getAttr -time ($time -1) leadObject.translate`;
$vector = $oldPos - $newPos;
$vectorMag = mag ($oldPos - $newPos);
if ($vectorMag >= $distance)
{
float $vectorScalePercent = $distance / $vectorMag;
vector $vectorScale = $vector * $vectorScalePercent;
vector $newVector = $vectorScale + $newPos;
float $placement[] = $newVector;
trailObject_01_cntrlGrp.translateX = $placement[0];
trailObject_01_cntrlGrp.translateY = $placement[1];
trailObject_01_cntrlGrp.translateZ = $placement[2];
string $setFrameMessage = "vector was set using vector from frame ";
//print ($setFrameMessage + $time + "\n");
break;
}
else
{
$distance = $distance - $vectorMag;
$time --;
//print ("vector too small, moving back a frame" + "\n");
//print ("new distance is " + $distance + "\n");
//print ("time being calculated is" + $time +"\n");
}
}
if ($time == 0)
{
$newPos = `getAttr -time 1 leadObject.translate`;
$oldPos = `getAttr -time 0 leadObject.translate`;
$vector = $oldPos - $newPos;
$vectorMag = mag ($oldPos - $newPos);
float $vectorScalePercent = $distance / $vectorMag;
vector $vectorScale = $vector * $vectorScalePercent;
vector $newVector = $vectorScale + $newPos;
float $placement[] = $newVector;
trailObject_01_cntrlGrp.translateX = $placement[0];
trailObject_01_cntrlGrp.translateY = $placement[1];
trailObject_01_cntrlGrp.translateZ = $placement[2];
}
}

This method keeps the rig from squashing and stretching when the lead control moves faster or slower; which would happen if the tail controls were just placed at the lead controls location, minus the desired amount of frames.

Thursday, May 28, 2009

Automated Serpent Rig

The idea behind this project was to create an automated rig, where the animator would animate the first control, and the rest would automatically aniamte correctly behind it. The concept was a serpent like rig (think sea serpent or leg-less dragon) where it wouldn't be required to animate the length of the body. There are secondary controls that allow for animating off the main course, but the main motion is determined by the lead control.
Here is a quick example of the X-rotation in trial:



Only the front control is animated, and the back end responds based on the amount of rotation frame to frame.