////////////////////////////////
// //
// cMotionTrail. Cam 2006 //
// //
////////////////////////////////
// overview: creates updating motion trails with spacer objects.
// install: copy script into local scripts folder, source the script ( or restart maya ), type "cMotionTrailUI" to launch the script.
// Arguments: "cMotionTrail" int `start time` , int `end time`, float `spacer scale`, string `object to trail`, int `set template` ( 0 or 1 ).
// Written by Cameron Fielding : cameron.fielding@bvg.com
// Tested with Maya 7.0
// --------------------------------------------------------------------------------------------------------------------------------------------
// proc to create the UI //
global proc cMotionTrailUI()
{
if (`window -exists cMTrailWin`)
deleteUI -window cMTrailWin;
if (`windowPref -exists cMTrailWin`)
windowPref -remove cMTrailWin;
window -t "cMotionTrail" -w 562 -h 350 cMTrailWin;
formLayout cMtopForm;
rowColumnLayout -nc 3 -cw 1 65 -cw 2 150 -cw 3 100 cMrow1;
text -l "Time Range";
radioCollection cMraiod1;
$cMradio1_1 = `radioButton -label "Start/End"`;
$cMradio1_2 = `radioButton -label "Time Slider"`;
radioCollection -e -select $cMradio1_2 cMraiod1;
setParent cMtopForm;
rowColumnLayout -nc 2 -cw 1 55 -cw 2 80 cMrow2;
text -l "Start Time ";
textField -text "1" cMstart;
text -l " End Time ";
textField -text "30" cMend;
setParent cMtopForm;
frameLayout -bs "out" -h 2 cMSep1;
setParent cMtopForm;
floatSliderGrp -pre 2 -label "Spacer display size" -field true -minValue 0.01 -maxValue 10 -v 0.5 cMslide;
checkBox -l " Template the trail's group" -v 0 cMcbox;
colorIndexSliderGrp -label "Trail Colour" -min 0 -max 31 -value 14 -en true cMslide2;
checkBox -l " Use object's own colour for the trail" -v 0 cMcbox2;
checkBox -l " Connect trail to object's visibility" -v 0 cMcbox3;
checkBox -l " Use spheres as spacer objects" -v 1 cMcbox4;
colorIndexSliderGrp -label "Spacer Colour" -min 0 -max 31 -value 17 -en true cMslide3;
rowColumnLayout -nc 3 -cw 1 180 -cw 2 180 -cw 3 180 cMbutrow;
button -l "Create cMotion Trail" -c "getcMPrefs 1" -h 27 ;
button -l "Apply" -c "getcMPrefs 0";
button -l "Close" -c "deleteUI cMTrailWin";
setParent cMtopForm;
formLayout -e
-attachForm cMrow1 "left" 100
-attachForm cMrow1 "top" 3
-attachForm cMrow2 "left" 111
-attachForm cMrow2 "top" 20
-attachForm cMSep1 "left" 0
-attachForm cMSep1 "right" 0
-attachForm cMSep1 "top" 70
-attachForm cMslide "left" 25
-attachForm cMslide "top" 78
-attachForm cMslide2 "left" 25
-attachForm cMslide2 "top" 104
-attachForm cMslide2 "right" 140
-attachForm cMslide3 "left" 25
-attachForm cMslide3 "top" 131
-attachForm cMcbox "left" 164
-attachForm cMcbox "top" 177
-attachForm cMcbox2 "left" 164
-attachForm cMcbox2 "top" 159
-attachForm cMcbox3 "left" 164
-attachForm cMcbox3 "top" 196
-attachForm cMcbox4 "left" 164
-attachForm cMcbox4 "top" 215
-attachForm cMbutrow "left" 5
-attachForm cMbutrow "bottom" 5
cMtopForm;
showWindow;
window -e -h 290 cMTrailWin;
}
// proc to launch the main function with flags from the UI //
global proc getcMPrefs( int $closecMwin )
{
int $startTime, $endTime, $template;
float $scale;
string $trailObjects[];
if ( `radioCollection -q -sl cMraiod1` == "radioButton1" )
{
$startTime = `textField -q -text cMstart`;
$endTime = `textField -q -text cMend`;
}
else
{
$startTime = `playbackOptions -q -min`;
$endTime = `playbackOptions -q -max`;
}
$template = `checkBox -q -v cMcbox`;
$scale = `floatSliderGrp -q -v cMslide`;
$trailObjects = `ls -sl -fl`;
for ( $trailObject in $trailObjects )
{
if ( `objExists ( $trailObject + "_extraNode_t" + $startTime + $endTime )` == 0 )
{
cMotionTrail $startTime $endTime $scale $trailObject $template;
}
else
{
catch ( error ( "a trail already exists for " + $trailObject + " from frames " + $startTime + " to " + $endTime ));
}
}
if ( $closecMwin == 1 )
{
deleteUI cMTrailWin;
}
}
// main trail creating proc //
global proc cMotionTrail ( int $startTime, int $endTime, float $scale, string $trailObject, int $template )
{
// get the name of the object thats going to be trailed, and the trail length //
string $originalName = $trailObject;
int $totalTime = $endTime - $startTime;
$totalTime ++;
// clear the array that will be used to group everything together, and create its index clock that will manage its members //
string $groupArray[];
clear $groupArray;
int $gAClock = 0;
// create the extra node needed ( I'm not sure why this node is needed - but it seems that the `getAttr -t` function needs it to successfully evaluate the
// position of the hiddenTrailObject, when the object being trailed is not a direct child of the world )
group -w -em -n ( $trailObject + "_extraNode_t" + $startTime + $endTime );
pointConstraint -offset 0 0 0 -weight 1 $trailObject ( $trailObject + "_extraNode_t" + $startTime + $endTime );
$groupArray[$gAClock] = ( $trailObject + "_extraNode_t" + $startTime + $endTime );
$gAClock ++;
$trailObject = ( $trailObject + "_extraNode_t" + $startTime + $endTime );
// create the hidden trail object that will be sampled //
// note: this is the actual object that the script uses to generate and alter the shape of the cMotion trail. NOT the object the user selected.
group -w -em -n ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime );
connectAttr ( $originalName + "_extraNode_t" + $startTime + $endTime + ".translateX" ) ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateX" );
connectAttr ( $originalName + "_extraNode_t" + $startTime + $endTime + ".translateY" ) ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateY" );
connectAttr ( $originalName + "_extraNode_t" + $startTime + $endTime + ".translateZ" ) ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateZ" );
$groupArray[$gAClock] = ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime );
$gAClock ++;
// prepare the curve data //
float $tPosX[], $tPosY[], $tPosZ[];
clear $tPosX $tPosY $tPosZ;
int $cMclock = $startTime;
for ( $i = 0; $i < $totalTime; $i ++ )
{
$tPosX[$i] = `getAttr -t $cMclock ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateX" )`;
$tPosY[$i] = `getAttr -t $cMclock ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateY" )`;
$tPosZ[$i] = `getAttr -t $cMclock ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateZ" )`;
$cMclock ++;
}
// create the eval string, and evaluate it to generate the curve //
string $evalMe = "curve -d 1 ";
int $cMclock = $startTime;
for ( $i = 0; $i < `size $tPosX`; $i ++ )
{
$evalMe = ( $evalMe + "-p " + $tPosX[$i] + " " + $tPosY[$i] + " " + $tPosZ[$i] + " " );
}
$evalMe = ( $evalMe + "-n " + $trailObject + "_cMotionTrail_curve" );
eval $evalMe;
$groupArray[$gAClock] = ( $trailObject + "_cMotionTrail_curve" );
$gAClock ++;
// lock the curve so it cant be accidently moved ( only the group as a whole can be user manipulated );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.tx" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.ty" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.tz" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.rx" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.ry" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.rz" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.sx" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.sy" );
setAttr -lock true ( $trailObject + "_cMotionTrail_curve.sz" );
// set the user colours of the curve
setAttr ( $trailObject + "_cMotionTrail_curve.overrideEnabled" ) 1;
setAttr ( $trailObject + "_cMotionTrail_curve.overrideColor" ) ( (`colorIndexSliderGrp -q -value cMslide2`) - 1 );
// if the user chose `use object colour` and object has override enabled - set its colour //
if ( `checkBox -q -v cMcbox2` == 1 || ($originalName + ".overrideEnabled") == 1 )
{
setAttr ( $trailObject + "_cMotionTrail_curve.overrideColor" ) ( `getAttr ( $originalName + ".overrideColor" )`);
}
// rename the curve's shape node for easy access //
string $findShape[];
$findShape = `listRelatives ( $trailObject + "_cMotionTrail_curve" )`;
rename $findShape[0] ( $trailObject + "_cMotionTrailShape" );
// create the eval string to make the scriptjob that will update each CV position on the curve //
string $evalMeExpr = "";
int $cMclock = $startTime;
for ( $i = 0; $i < `size $tPosX `; $i ++ )
{
$evalMeExpr = ( $evalMeExpr + "setAttr \\\"" + $trailObject + "_cMotionTrailShape" + ".controlPoints[" + $i + "].xValue\\\" ( `getAttr -t " + $cMclock + " " + $trailObject + ".tx`);" );
$evalMeExpr = ( $evalMeExpr + "setAttr \\\"" + $trailObject + "_cMotionTrailShape" + ".controlPoints[" + $i + "].yValue\\\" ( `getAttr -t " + $cMclock + " " + $trailObject + ".ty`);" );
$evalMeExpr = ( $evalMeExpr + "setAttr \\\"" + $trailObject + "_cMotionTrailShape" + ".controlPoints[" + $i + "].zValue\\\" ( `getAttr -t " + $cMclock + " " + $trailObject + ".tz`);" );
$cMclock ++;
}
// create the scriptJob to connect the update to a change in the trail null's translate attributes //
// note: for efficiency this scriptjob checks the current frame number and compares it with a previous stored frame number ( from a dynamically generated
// global variable ). The scriptjob will only run if these 2 values are the same ( so the scriptJob will ONLY evaluate when the user physically makes a
// change in the scene, rather than evaluating each time the user scrubs the timeslider, or steps through the timeSlider. )
int $randTag = `rand 999999`;
$evalMeExpr = ( "$cmtsc" + $randTag + "_sJob1 = `scriptJob -kws -cu true -ac \"" + $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translate\" \"" +
"global int $cmtscDG" + $randTag + "_hiddenTrailObject_t" + $startTime + $endTime + "r2; $r1 = `currentTime -q`; if ( $r1 == $cmtscDG" + $randTag + "_hiddenTrailObject_t" + $startTime + $endTime + "r2 ) {" + $evalMeExpr);
$evalMeExpr = ( $evalMeExpr + " print \\\"\\\"; }else{ $cmtscDG" + $randTag + "_hiddenTrailObject_t" + $startTime + $endTime + "r2 = `currentTime -q`; } \"`" );
eval $evalMeExpr;
// create the spacing locators and connect them to each point on the curve //
// note: for efficiency, the spacing locators are connected directly to each CV in the curve, much faster than depending on the scriptJob
// to also update all their positions.
int $cMclock = $startTime;
for ( $i = 0; $i < `size $tPosX `; $i ++ )
{
$tPosX[$i] = `getAttr -t $startTime ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateX" )`;
$tPosY[$i] = `getAttr -t $startTime ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateY" )`;
$tPosZ[$i] = `getAttr -t $startTime ( $originalName + "_hiddenTrailObject_t" + $startTime + $endTime + ".translateX" )`;
if ( `checkBox -q -v cMcbox4` == 0 )
{
spaceLocator -n ( $trailObject + "_spacingLocator_" + $i );
}
else
{
sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 4 -nsp 2 -ch 1 -n ( $trailObject + "_spacingLocator_" + $i );
setAttr ( $trailObject + "_spacingLocator_" + $i + ".overrideShading" ) 0 ;
}
scale -r $scale $scale $scale;
xform -ws -t $tPosX[$i] $tPosY[$i] $tPosZ[$i];
connectAttr ( $trailObject + "_cMotionTrailShape" + ".controlPoints[" + $i + "].xValue" ) ( $trailObject + "_spacingLocator_" + $i + ".tx" );
connectAttr ( $trailObject + "_cMotionTrailShape" + ".controlPoints[" + $i + "].yValue" ) ( $trailObject + "_spacingLocator_" + $i + ".ty" );
connectAttr ( $trailObject + "_cMotionTrailShape" + ".controlPoints[" + $i + "].zValue" ) ( $trailObject + "_spacingLocator_" + $i + ".tz" );
$groupArray[$gAClock] = ( $trailObject + "_spacingLocator_" + $i );
$gAClock ++;
$cMclock ++;
setAttr ( $trailObject + "_spacingLocator_" + $i + ".overrideEnabled" ) 1;
setAttr ( $trailObject + "_spacingLocator_" + $i + ".overrideColor" ) ( (`colorIndexSliderGrp -q -value cMslide3`) - 1 );
}
// create the final group of everything that was created, and set its user template value //
select -r $groupArray;
group -n ( $originalName + "_cMotionTrail_" + $startTime + "to" + $endTime );
setAttr ( $originalName + "_cMotionTrail_" + $startTime + "to" + $endTime + ".template") $template;
select -cl;
if ( `checkBox -q -v cMcbox3` == 1 )
{
catch ( `connectAttr ( $originalName + ".visibility" ) ( $originalName + "_cMotionTrail_" + $startTime + "to" + $endTime + ".visibility ") `);
}
}
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment