// Copyright © 2007 Jason Gill All rights reserved // www.3dgill.com // // This script creates a wind effect with blend shapes. If you need to edit multiple shapes, group them. // // Here are the steps it takes. // 1. duplicate the current selection twice renaming to ("wind" + original name) and ("masterWind" + original name) // 2. place a lattice over "wind" // 3. randomly move the vertices on the lattice within specified limits // 4. duplicate the selection again to lock in the shape // 5. repeat 3 and 4 to create the number of blendshapes directed // 6. delete lattice and clusters // 7. use the original duplicate as a bridge for the other blendshapes // 8. delete extra blendshapes // 9. create set driven key on "wind" and "masterWind", windShapes, to rotate between the shapes // 10. use "wind" as a blendshape on "masterWind" // 11a. now the user must paint blendshape weights on "masterWind", so things like skin don't deform // 11b. if you don't need to paint weights, you can delete "masterWind" and just use "wind" // // // MISCELLANIOUS PROCEDURES // global proc jgClusterLattice() { for ($lat in `ls -sl`) { select -r $lat; pickWalk -d down; for ($latShape in `ls -sl`) { select -r $latShape; for ($Svert = 0; $Svert < `getAttr ($latShape + ".sDivisions")`; $Svert ++) { for ($Tvert = 0; $Tvert < `getAttr ($latShape + ".tDivisions")`; $Tvert ++) { for ($Uvert = 0; $Uvert < `getAttr ($latShape + ".uDivisions")`; $Uvert ++) { select -r ($lat + ".pt[" + $Svert + "][" + $Tvert + "][" + $Uvert + "]"); cluster -n ($lat + "_cluster1"); } } } } select -cl; } } // // BUTTON PROCEDURE // global proc jgWindShapes(int $nS, int $lS, int $lT, int $lU, float $prmX, float $nrmX, float $prmY, float $nrmY, float $prmZ, float $nrmZ) { for ($mMesh in `ls -sl`) { duplicate -n ("masterWind_" + $mMesh); move -r 0 10 0; select -r $mMesh; duplicate -n ("wind_" + $mMesh); move -r 0 10 -10; blendShape -n masterWindBlendShape ("wind_" + $mMesh) ("masterWind_" + $mMesh); setAttr ("masterWindBlendShape.wind_" + $mMesh) 1; select -r ("wind_" + $mMesh); lattice -n windChange -dv $lS $lT $lU -oc true; jgClusterLattice; for ($var = 0; $var < $nS; $var ++) { select -r "windChangeLattice_clust*"; for ($latVert in `ls -sl`) { select -r $latVert; move -r (rand($nrmX, $prmX)) (rand($nrmY, $prmY)) (rand($nrmZ, $prmZ)); } select -r ("wind_" + $mMesh); duplicate; select -r "windChangeLattice_clust*"; for ($latVerts in `ls -sl`) { if (`attributeExists "translateX" $latVerts`) { setAttr ($latVerts + ".t") 0 0 0; } } } delete "windChange*"; select -r ("wind_" + $mMesh + "1"); for ($va = 2; $va <= $nS; $va ++) { select -tgl ("wind_" + $mMesh + $va); } select -tgl ("wind_" + $mMesh); blendShape -n windBlendShape; select -r ("wind_" + $mMesh + "1"); for ($vars = 2; $vars <= $nS; $vars ++) { select -tgl ("wind_" + $mMesh + $vars); } delete; select -r ("wind_" + $mMesh) ("masterWind_" + $mMesh); for ($addAttr in `ls -sl`) { addAttr -ln wind -at double -min 0 -max 10 -dv 0 $addAttr; setAttr -e -keyable true ($addAttr + ".wind"); } addAttr -ln windControl -at double -min 1 -max ($nS + 1) -dv 1 ("wind_" + $mMesh); setAttr -e -keyable true -channelBox false ("wind_" + $mMesh + ".windControl"); setDrivenKeyframe -itt "flat" -ott "flat" -dv 1 -dv ($nS + 1) -v 1 -cd ("wind_" + $mMesh + ".windControl") ("windBlendShape.wind_" + $mMesh + "1"); setDrivenKeyframe -itt "flat" -ott "flat" -dv 2 -dv $nS -v 0 -cd ("wind_" + $mMesh + ".windControl") ("windBlendShape.wind_" + $mMesh + "1"); for ($fr = 2; $fr <= $nS; $fr ++) { setDrivenKeyframe -dv ($fr - 1) -dv ($fr + 1) -v 0 -cd ("wind_" + $mMesh + ".windControl") ("windBlendShape.wind_" + $mMesh + $fr); setDrivenKeyframe -dv $fr -v 1 -cd ("wind_" + $mMesh + ".windControl") ("windBlendShape.wind_" + $mMesh + $fr); } setDrivenKeyframe -itt "linear" -ott "linear" -dv 0 -v 1 -cd ("wind_" + $mMesh + ".wind") ("wind_" + $mMesh + ".windControl"); setDrivenKeyframe -itt "linear" -ott "linear" -dv 10 -v ($nS + 1) -cd ("wind_" + $mMesh + ".wind") ("wind_" + $mMesh + ".windControl"); setAttr -keyable false -channelBox false ("wind_" + $mMesh + ".windControl"); connectAttr -f ("masterWind_" + $mMesh + ".wind") ("wind_" + $mMesh + ".wind"); rename masterWindBlendShape masterWindBlendShape1; rename windBlendShape windBlendShape1; } } // // UI TOOL PROCEDURE // global proc jgWind() { if (`window -ex jgWindUI`) deleteUI jgWindUI; window -t "Jason Gill - WindShapes - www.3dgill.com" -wh 300 385 -s false jgWindUI; columnLayout; columnLayout; text -w 200 -h 25 -al "center" -fn "boldLabelFont" -l "How many blendShapes?"; intSliderGrp -label " " -field true -min 1 -max 10 -fmn 1 -fmx 100 -v 6 -cw3 80 60 120 -ct3 "right" "left" "left" numShapesSliderGrp; separator -h 10 -w 300; text -w 200 -h 25 -al "center" -fn "boldLabelFont" -l "How many lattice verts?"; intSliderGrp -label "S Divisions" -field true -min 2 -max 30 -fmn 1 -fmx 100 -v 4 -cw3 80 60 120 -ct3 "right" "left" "left" sDivSliderGrp; intSliderGrp -label "T Divisions" -field true -min 2 -max 30 -fmn 1 -fmx 100 -v 4 -cw3 80 60 120 -ct3 "right" "left" "left" tDivSliderGrp; intSliderGrp -label "U Divisions" -field true -min 2 -max 30 -fmn 1 -fmx 100 -v 4 -cw3 80 60 120 -ct3 "right" "left" "left" uDivSliderGrp; separator -h 10 -w 300; text -w 200 -h 25 -al "center" -fn "boldLabelFont" -l "Movement range for verts"; floatSliderGrp -label "minimum X" -field true -min -10 -max 10 -fmn -1000 -fmx 1000 -v -.5 -cw3 80 60 120 -ct3 "right" "left" "left" minXSliderGrp; floatSliderGrp -label "maximum X" -field true -min -10 -max 10 -fmn -1000 -fmx 1000 -v .5 -cw3 80 60 120 -ct3 "right" "left" "left" maxXSliderGrp; floatSliderGrp -label "minimum Y" -field true -min -10 -max 10 -fmn -1000 -fmx 1000 -v -.5 -cw3 80 60 120 -ct3 "right" "left" "left" minYSliderGrp; floatSliderGrp -label "maximum Y" -field true -min -10 -max 10 -fmn -1000 -fmx 1000 -v .5 -cw3 80 60 120 -ct3 "right" "left" "left" maxYSliderGrp; floatSliderGrp -label "minimum Z" -field true -min -10 -max 10 -fmn -1000 -fmx 1000 -v -.5 -cw3 80 60 120 -ct3 "right" "left" "left" minZSliderGrp; floatSliderGrp -label "maximum Z" -field true -min -10 -max 10 -fmn -1000 -fmx 1000 -v .5 -cw3 80 60 120 -ct3 "right" "left" "left" maxZSliderGrp; separator -h 20 -w 300; setParent ..; rowLayout -nc 2 -cw2 40 200 -ct2 "both" "both"; text -l " "; button -w 150 -al "center" -l "Create Wind Shapes" -c "jgWindShapes `intSliderGrp -q -v numShapesSliderGrp` `intSliderGrp -q -v sDivSliderGrp` `intSliderGrp -q -v tDivSliderGrp` `intSliderGrp -q -v uDivSliderGrp` `floatSliderGrp -q -v maxXSliderGrp` `floatSliderGrp -q -v minXSliderGrp` `floatSliderGrp -q -v maxYSliderGrp` `floatSliderGrp -q -v minYSliderGrp` `floatSliderGrp -q -v maxZSliderGrp` `floatSliderGrp -q -v minZSliderGrp`"; setParent ..; setParent ..; showWindow; }