//=========================== calcify V 1.2 ========================================= // // calcify 1.2 // // calify produces the appropiate Nurb geometry and groups it under bones so they // can in affect be renderered. // // should work fairly well with advanced rigging. Geometry properly adjusts to joints // transforms and rotation and scaling, but doesn't work with "broken rigs" // // geometry is scaled to match the curent display size of the joints, but there is no // history node so geometry will not match if joint display size is changed either // locally or globally // // by Andrew Osiow Copyright 2006 // andrewosiow@gmail.com // // To be used freely with the aknowledgement that the author is not responsible // for any perceived damage this script may directly (or indirectly) cause. // Please contact the author if you plan to use this script in a commercial project. // //=================================================================================== global proc skeletonWalk ( string $currentJoint, string $rootJoint ) { // grab postional data for current joint float $jointMatrix[] = `getAttr $currentJoint.worldMatrix`; // build a list of children a process each one of them select -r $currentJoint; string $descendingJoints[] = `listRelatives -c -type joint`; string $nextJoint; for ( $nextJoint in $descendingJoints ) { $nextJoint = $currentJoint + "|" + $nextJoint; select -r $nextJoint; skeletonWalk ( $nextJoint, $rootJoint); } // calculate scale to adjust sphere and cone // scale based on sphere scale on local radi float $globalJointScale = `jointDisplayScale -q`; float $sphereJointScale = $globalJointScale * `getAttr ($currentJoint+".radi")` * 0.5; float $coneScaleCompensate = 1/$sphereJointScale; // create sphere and geometry string $currentSphere = stringArrayToString ( `sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 0`,""); // create cone for non-end joints, aim to next joint and scale to the appropiate size for ( $nextJoint in $descendingJoints ) { string $currentCone = stringArrayToString ( `cone -p 0 0 0 -ax 1 0 0 -ssw 0 -esw 360 -r 1 -hr 1 -d 1 -ut 0 -tol 0.01 -s 4 -nsp 1 -ch 0`,""); move 1 0 0; move -r -1 0 0 ($currentCone+".rotatePivot"); scale ($coneScaleCompensate) 1 1; makeIdentity -apply true -t 1 -r 1 -s 1 -n 0; // joint scale equals distance between joints length - (radii average) // average joint radi $averageJointRadii =`shadingNode -asUtility plusMinusAverage -n (substituteAllString($currentJoint+"plus"+$nextJoint,"|",""))`; setAttr ($averageJointRadii+".operation") 3; // average operation connectAttr -f ($currentJoint+".radius") ($averageJointRadii+".input1D[0]"); connectAttr -f ($nextJoint+".radius") ($averageJointRadii+".input1D[1]"); // calculate distance between joints $currentJointDistance = `shadingNode -asUtility distanceBetween -n (substituteAllString("between"+$currentJoint+$nextJoint,"|",""))`; connectAttr -f ($currentJoint+".worldMatrix[0]") ($currentJointDistance+".inMatrix1"); connectAttr -f ($nextJoint+".worldMatrix[0]") ($currentJointDistance+".inMatrix2"); // subtract average from joint distance $subRadii =`shadingNode -asUtility plusMinusAverage -n(substituteAllString($nextJoint+"newLength","|",""))`; setAttr ($subRadii+".operation") 2; // subtract operation connectAttr -f ($currentJointDistance+".distance") ($subRadii+".input1D[0]"); connectAttr -f ($averageJointRadii+".output1D") ($subRadii+".input1D[1]"); // connect result of all this to scaleX of the cone connectAttr -f ($subRadii+".output1D") ($currentCone+".scaleX"); aimConstraint -offset 0 0 0 -weight 1 -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "vector" -worldUpVector 0 1 0 $nextJoint $currentCone; parent $currentCone $currentSphere; } // parent new geometry under current Joint select -r $currentSphere; // scale geometry based on globalJointScale scale $sphereJointScale $sphereJointScale $sphereJointScale; // move new geometry to joint position move $jointMatrix[12] $jointMatrix[13] $jointMatrix[14]; // parent constrain geometry to joint parent $currentSphere $currentJoint; // create extra group node to conpensate for scaling select -r $currentSphere; // extra transform node to compensate for joint scaling $currentGroup = `group -n (substituteAllString($currentJoint+"inverseScaleGrp","|",""))`; xform -os -pivots 0 0 0; $jointInvScale = `shadingNode -asUtility multiplyDivide -n (substituteAllString($currentJoint+"inverseScaleOp","|",""))`; setAttr ($jointInvScale+".input1X") 1; setAttr ($jointInvScale+".input1Y") 1; setAttr ($jointInvScale+".input1Z") 1; setAttr ($jointInvScale+".operation") 2; // divide operation connectAttr -f ($currentJoint+".scale") ($jointInvScale+".input2"); connectAttr -f ($jointInvScale+".output") ($currentGroup+".scale"); } global proc calcify () { // procedure grabs root info and start skeleton walk string $currentJointList[] = `ls -sl -head 1`; string $rootJoint = $currentJointList[0]; string $currentJoint = $rootJoint; skeletonWalk ( $currentJoint, $rootJoint ); select -r $rootJoint; }