/* '' Author: Jeremiah Grant '' Title: jgTreads.mel '' Date: 02-10-2005 '' '' Description: Automates the creation of tank-like treads. '' '' Instructions: source jgTreads.mel. '' Select the path the treads will be following and press the '' "Select Path Curve" button. Do the same for the actual tread '' geometry object. Then again for the object that will control the '' treads. The control object can either be an object that will be '' translated and thereby rotating the treads or a control object '' that will rotate the treads via an attribute. '' '' Next, type in an offset. The offset is the amount of slipping of the treads. '' The higher the offset, the slower the treads will go. Note, this is only really '' affected when using translation. Also, if the treads are moving '' backwards on the curve, you need to Reverse Curve Direction. '' '' Enter a number of treads you wish to have on the curve. Then choose '' what translation you want the tread's rotation to be based on. For instance, '' if I move the tank on Z, the treads will rotate. Lastly, choose whether '' the tread rotation will be based on an Attribute added to your control '' object, or the translation of your control object. '' '' '' You can email me at jeremiah@jeremiahgrant.com '' Website: www.jeremiahgrant.com */ // // The UI proceedure // global proc jgTreads() { string $curvePath[]; string $tread[]; string $ctrl[]; int $offset, $numTreads; string $path_, $tread_, $ctrl_; int $offset_, $numTreads_; if (`window -ex jgTreadsWin`) deleteUI -wnd jgTreadsWin; string $window = `window -t "jgTreads Creator" -w 288 -h 273 -rtf 1 -mb 1 jgTreadsWin`; menu -l "Help"; menuItem -label "Help" -c "jgTreadsHelp"; menuItem -label "Website" -c "jgTreadsWeb"; columnLayout -adjustableColumn true; separator -h 10 -style "none"; string $layout = `rowColumnLayout -numberOfColumns 2 -columnWidth 1 150 -columnWidth 2 130`; string $tf1 = `textField -text "" -w 250 -editable 1 -ip 1 -it $curvePath[0] -ann "Select Path Curve" curvePath`; button -label "Select Path Curve" -ann "Select Path Curve" -c "$curvePath = `ls -sl`; textField -e -text $curvePath[0] curvePath;" loadCurveButton; string $tf2 = `textField -text "" -w 250 -editable 1 -ip 1 -it $tread[0] -ann "Select Tread Object" tread`; button -label "Select Tread Object" -ann "Select Tread Object" -c "$tread = `ls -sl`; textField -e -text $tread[0] tread;" loadTreadButton; string $tf3 = `textField -text "" -w 250 -editable 1 -ip 1 -it $ctrl[0] -ann "Select Object to Control the Treads" ctrl`; button -label "Select Ctrl Object" -ann "Select Object to Control the Treads" -c "$ctrl = `ls -sl`; textField -e -text $ctrl[0] ctrl;" loadCtrlButton; string $tf4 = `textField -text "" -w 250 -editable 1 -ip 1 -it $offset -ann "Offset is the amount of slipping. Must be a number above 0." offset`; text " : Offset"; string $tf5 = `textField -text "" -w 250 -editable 1 -ip 1 -it $numTreads -ann "Enter the number of treads."numTread`; text " : Number of Treads"; setParent..; separator -h 15 -style "none"; string $db = `optionMenu -w 280 -l " Direction: " -ann "Choose what direction the vehicle will be moving on." dirOption`; menuItem -label "Z"; menuItem -label "X"; menuItem -label "Y"; separator -h 15 -style "none"; rowColumnLayout -nc 2; string $ct = `radioCollection`; $rb1 = `radioButton -label "Translation" -onc ("optionMenu -e -en 1 dirOption;") -ann "Base tread rotation on translation of the Ctrl" translate`; $rb2 = `radioButton -label "Attribute" -onc ("optionMenu -e -en 0 dirOption;") -ann "Base tread rotation on an attribute of the Ctrl" attribute`; radioCollection -e -sl $rb1 $ct; setParent..; separator -h 15 -style "none"; button -l "Create Treads" -w 250 -c ("jgTreadAct "+$tf1+" "+$tf2+" "+$tf3+" "+$tf4+" "+$tf5+" "+$db+" "+$ct+";"); setParent..; showWindow; } // // proceedure called by the Create Treads button. Takes in UI crap and turns it into data. // Calls jgTreadMain // global proc jgTreadAct(string $tf1, string $tf2, string $tf3, string $tf4, string $tf5, string $db, string $ct) { string $path = `textField -q -text $tf1`; string $tread = `textField -q -text $tf2`; string $ctrl =`textField -q -text $tf3`; float $offset = `textField -q -text $tf4`; int $numTreads = `textField -q -text $tf5`; string $ctrlType = `radioCollection -q -sl $ct`; print $ctrlType; string $direction; if($ctrlType == "translate") $direction = ("translate"+(`optionMenu -q -v $db`)); else { addAttr -ln "treadCtrl" -k 1 -dv 0 -at "float" $ctrl; $direction = "treadCtrl"; } if($path == "") error "Please select a Path Curve"; if($tread == "") error "Please select a Tread Object"; if($ctrl == "") error "Please select a Control Object"; if($offset <= 0) error "Please enter an Offset greater than 0"; if($numTreads <= 0) error "Please enter a Treads Number greater than 0"; jgTreadMain $path $tread $ctrl $offset $numTreads $direction; } // // The main proceedure. Takes in the path, tread, ctrl, offset, # of treads and direction. // Returns 1 or 0 // global proc int jgTreadMain(string $path, string $tread, string $ctrl, float $offset, float $numTreads, string $direction) { cycleCheck -e 0; string $buf[]; string $treadGroup = `group -em -n treadObjects`; float $i=0; float $distTreads = 1/$numTreads; string $exp; if($distTreads >= 1 || $distTreads <= 0) return 0; select $tread; makeIdentity -apply true -t 1 -r 1 -s 1 -n 0; string $wuoPath[] = `duplicate $path`; xform -cp $wuoPath[0]; scale .025 .025 .025 $wuoPath[0]; hide $wuoPath; while($i < 1) { string $object[] = `instance $tread`; parent $object $treadGroup; string $moPath = `pathAnimation -stu 0 -etu 30 -fa z -ua y -f 1 -fm 1 -b 1 -wut "object" -wuo $wuoPath $path $object[0]`; string $name = `pathAnimation -q -n $moPath`; string $con[] = `listConnections -d off -s on ($name+".u")`; // print $con; disconnectAttr ($con[0]+".output") ($name+".uValue"); if($direction == "treadCtrl") { $exp = "if("+$ctrl+"."+$direction+" > 0)\n"; $exp += "{\n"; $exp += "float $a = ("+$ctrl+"."+$direction+"/"+$offset+")+"+$i+";\n"; $exp += "int $b = $a;\n"; $exp += "float $val = $a - $b;\n"; $exp += ($name+".uValue = ($val);\n"); $exp += "}\n"; $exp += "if("+$ctrl+"."+$direction+" < 0)\n"; $exp += "{\n"; $exp += "float $a = abs("+$ctrl+"."+$direction+"/"+$offset+")+"+$i+";\n"; $exp += "int $b = $a;\n"; $exp += "float $val = $a - $b;\n"; $exp += ($name+".uValue = 1-$val;\n"); $exp += "}\n"; } else { $exp = "float $os[] = `xform -q -os -t "+$ctrl+"`;\n"; $exp += "if($os[2] > 0)\n"; $exp += "{\n"; $exp += "float $a = ($os[2]/"+$offset+")+"+$i+";\n"; $exp += "int $b = $a;\n"; $exp += "float $val = $a - $b;\n"; $exp += ($name+".uValue = ($val);\n"); $exp += "}\n"; $exp += "if($os[2] < 0)\n"; $exp += "{\n"; $exp += "float $a = abs($os[2]/"+$offset+")+"+$i+";\n"; $exp += "int $b = $a;\n"; $exp += "float $val = $a - $b;\n"; $exp += ($name+".uValue = 1-$val;\n"); $exp += "}\n"; } expression -uc "none" -s $exp -n ($name+"_exp"); $i+=$distTreads; /* -- No longer needed... expression has unitConversion flag. $con = `listConnections -s true -d false -c true -p true $name`; print $con; tokenize $con[1] "." $buf; if(`gmatch $buf[0] "unit*"`) setAttr ($buf[0]+".conversionFactor") 1; */ } parent $wuoPath[0] $path; select -d; flushUndo; cycleCheck -e 1; return 1; } // // The Help Proc // global proc jgTreadsHelp() { if (`window -ex jgTreadsHelpUI`) deleteUI jgTreadsHelpUI; window -t "jgTreads Help" jgTreadsHelpUI; string $form = `formLayout`; string $sl = `scrollLayout`; columnLayout; rowColumnLayout -nc 2 -cw 1 75 -cw 2 300; text -label "Title: " -font boldLabelFont; text -label "jgTreads.mel"; text -label "Author: " -font boldLabelFont; text -label "Jeremiah Grant"; text -label "Email: " -font boldLabelFont; text -label "jeremiah@jeremiahgrant.com"; text -label "Website: " -font boldLabelFont; text -label "www.JeremiahGrant.com"; setParent..; text -label "\n\n Instructions: " -font boldLabelFont; string $helpText = "\n"; $helpText += " Select the path the treads will be following and press the\n"; $helpText += " \"Select Path Curve\" button. Do the same for the actual tread\n"; $helpText += " geometry object. Then again for the object that will control the\n"; $helpText += " treads. The control object can either be an object that will be\n"; $helpText += " translated and thereby rotating the treads or a control object\n"; $helpText += " that will rotate the treads via an attribute.\n\n"; $helpText += " Next, type in an offset. The offset is the amount of slipping of the treads.\n"; $helpText += " The higher the offset, the slower the treads will go. Note, this is only really\n"; $helpText += " affected when using translation.\n\n"; $helpText += " Enter a number of treads you wish to have on the curve. Then choose\n"; $helpText += " what translation you want the tread's rotation to be based on. For instance,\n"; $helpText += " if I move the tank on Z, the treads will rotate. Lastly, choose whether\n"; $helpText += " the tread rotation will be based on an Attribute added to your control\n"; $helpText += " object, or the translation of your control object.\n"; string $troubleText1 = "\n"; $troubleText1 += " The easiest way to fix this is to go into vertex mode on your original\n"; $troubleText1 += " tread object, select all the vertices and rotate them till they are oriented\n"; $troubleText1 += " the right way.\n"; string $troubleText2 = "\n"; $troubleText2 += " Select the path curve and go to Edit Curves -- Reverse Curve Direction\n"; string $troubleText3 = "\n"; $troubleText3 += " Select all the verts in the original tread and scale them negatively.\n"; $troubleText3 += " Note, it must be in component mode. Scaling in object mode won't change\n"; $troubleText3 += " the other treads. This is due to the properties of instances.\n"; text -label $helpText -align left; text -label "\n\n\n :-= Troubleshooting =-: " -font boldLabelFont; text -label "\n\n Treads are facing the wrong way... " -font boldLabelFont; text -label $troubleText1 -align left; text -label "\n Treads are rotating backwards... " -font boldLabelFont; text -label $troubleText2 -align left; text -label "\n Treads are upside down... " -font boldLabelFont; text -label $troubleText3 -align left; setParent..; setParent..; string $close = `button -l "Close jgTreads Help" -c "deleteUI jgTreadsHelpUI"`; setParent..; setParent..; formLayout -e -attachForm $sl left 0 -attachForm $sl top 0 -attachForm $sl right 0 -attachControl $sl bottom 0 $close -attachForm $close left 0 -attachNone $close top -attachForm $close right 0 -attachForm $close bottom 0 $form; showWindow; } // // Opens a web browser to www.jeremiahgrant.com // global proc jgTreadsWeb() { if (`window -ex jgTreadsWebUI`) deleteUI jgTreadsWebUI; window -t "jgTreads Web Browser" -wh 907 671 jgTreadsWebUI; columnLayout -adj 1; $browser = `webBrowser -width 800 -height 600 -url "www.jeremiahgrant.com" jgBrowser`; rowColumnLayout -nc 3; button -l "Back" -c "webBrowser -e -bk jgBrowser"; button -l "Home" -c "webBrowser -e -url \"www.jeremiahgrant.com\" jgBrowser"; button -l "Forward" -c "webBrowser -e -fwd jgBrowser"; setParent..; button -l "Close Window" -c "deleteUI jgTreadsWebUI"; showWindow; } jgTreads;