macroScript constrainAB category:"Comet Cartoons" toolTip:"ConstrainAB: Constrains the last selected object to the first two, and creates a ABmix attribute on it." Icon:#("CometCartoons",18) ( -- -- ConstrainAB.mcr - Michael B. Comet - comet@comet-cartoons.com -- http://www.comet-cartoons.com -- -- This script will Point and Orient constraint the 3rd selected object -- to the first two. It adds a custom attribute onto the 3rd "slave" -- object that allows the constraints to be easily animated so the -- slave is between the 1st and 2nd "masterA" and "masterB" objects. -- -- Version 1.00 - 02/18/02 -- /* * Global Variables: */ global cABStart = -1000; global cABEnd = 10000; -- Functions ------------------------------------------------------------------------------------- /* * setTimeline() - This will set the timeline to the given start and end times */ fn setTimeline start end = ( animationRange = (interval start end); ) -- ----------------------------------------------------------------------------------------------- /* * addConstrainABAttr() - Adds a constrainAB attribute to the given obj */ fn addConstrainABAttrs obj = ( if (obj == undefined) then ( format ("-- ConstrainAB INTERNAL ERROR: addConstrainABAttrs (), obj is undefined!\n"); return(); ) -- Make sure user installed the AttributeHolder modifier. if (EmptyModifier != undefined) then ( -- Add Attr Holder modifier addModifier obj (EmptyModifier()); ) -- -- main attr def stuff -- str = "ConstrainABAttrs = attributes Custom_Attributes\n"+ "(\n"+ "parameters main rollout:ConstrainABRO\n"+ " (\n"+ " constrainAB type:#float default:0.0 ui:constrainABSpin\n"+ " )\n"+ " \n"+ "rollout ConstrainABRO \"ConstrainAB Parameters\"\n"+ " (\n"+ " spinner 'constrainABSpin' \"constrainAB\" type:#float range:[0,100,50];\n"+ " )\n"+ ");\n"+ "\n" ; execute str; -- -- Add some custom def data like MAX does, so we can retrieve RANGE info later for things like my attrKey script. -- str = "\n"+ "pb1 = CAT_ParamBlock name:\"'constrainAB'\" type:\"Float\" ui:\"constrainABSpin\" default:\"50.0\";\n"+ "ui1 = CAT_UIItem ui:\"Spinner\" name:\"'constrainAB'\" type:\"Float\" range:\"[0,100,0]\";\n"+ "arr1 = #(pb1);\n"+ "arr2 = #(ui1);\n"+ "theArr = #(arr1, arr2)\n"+ "\n"+ "custAttributes.setDefData ConstrainABAttrs theArr;\n"; execute str; if (EmptyModifier != undefined) then str = "custAttributes.add $"+(obj.name)+".Attribute_Holder ConstrainABAttrs ;"; else str = "custAttributes.add $"+(obj.name)+" ConstrainABAttrs ;"; execute str; -- -- Now add a default controller too and set value -- if (EmptyModifier != undefined) then ( str = ""; str += "$"+(obj.name)+".Attribute_Holder.constrainAB.controller = Bezier_Float();\n"; str += "$"+(obj.name)+".Attribute_Holder.constrainAB = 50;\n"; ) else ( str = ""; str += "$"+(obj.name)+".constrainAB.controller = Bezier_Float();\n"; str += "$"+(obj.name)+".constrainAB = 50;\n"; ) execute str; ) -- ----------------------------------------------------------------------------------------------- /* * constrainAB() - Given two master nodes, constrains the slave * node with a pos and rot constraint between the two and * sets up a Custom Attribute on the slave to control * the mixing between A and B. */ fn constrainAB masterA masterB slave = ( if (masterA == undefined or masterB == undefined or slave == undefined) then return(); format "-- constrainAB() - Constraining % to % & %.\n" slave.name masterA.name masterB.name; pCntl = slave.pos.controller = position_constraint(); pCI = pCntl.constraints; -- Get interface to constraints pCI.appendTarget masterA 50; pCI.appendTarget masterB 50; rCntl = slave.rotation.controller = orientation_constraint(); rCI = rCntl.constraints; -- Get interface to constraints rCI.appendTarget masterA 50; rCI.appendTarget masterB 50; -- At this point the pos and rot constrains are done...we just want to add -- a custom attribute and then wire it all together. addConstrainABAttrs slave; -- add the attrs -- Now we wire it all up. if (EmptyModifier != undefined) then cAB = slave.Attribute_Holder.Custom_Attributes; else cAB = slave.Custom_Attributes; paramWire.connect cAB[#constrainAB] slave.position.controller[1] "100-constrainAB;"; paramWire.connect cAB[#constrainAB] slave.position.controller[2] "constrainAB;"; paramWire.connect cAB[#constrainAB] slave.rotation.controller[1] "100-constrainAB;"; paramWire.connect cAB[#constrainAB] slave.rotation.controller[2] "constrainAB;"; clearSelection(); select slave; format "-- constrainAB() Done. Added Custom Attribute and Wired connections.\n"; ) -- ----------------------------------------------------------------------------------------------- -- Main Entry starts here! objs = getCurrentSelection(); cnt = objs.count; if (cnt != 3) then ( format "-- ERROR: You must select 3 objects, with the last object being the slave.\n"; ) else ( max create mode; -- this speeds it up for some reason! setTimeline cABStart cABEnd; -- Do this so our constraints and wiring don't die on frame 100... constrainAB objs[1] objs[2] objs[3]; setTimeline 0 100; max modify mode; -- show the new attr ) )