/* Creates on screen controls for facial animation. facialControl() Developed by David Knight :floatingworld2@yahoo.com.au */ --UpperFace Control positions --The morph targets have to be named exactly, but their position in the channel list doesn't matter, as the script searches for them itself and returns their index. --Make sure to name the system to ensure unique naming sets. --Having run the eyerig script, all needed unique naming should have been done --NameOfControlSystem = "MyControl" rollout myrollout "Facial Control System" width:200 height:230; ( fn pick_morph obj = ( if obj.modifiers[#Morpher] != undefined then return true else return false ) fn createboundrec Name Parent Width Length location = (rect=Rectangle length:Length width:Width name:( Name) wireColor:[0,0,200] displayRenderMesh:false rect.pos = location; if (Parent != null ) then ( rect.parent = getNodeByName Parent ); rect.rotation.x_rotation=90 ) fn facialControl Type Name Parent posfac = ( rec=Rectangle length:10 width:10 name:(uniqueName "FaceControl") wireColor:[0,0,200] displayRenderMesh:false cir=circle radius:1 name:(Name) wireColor:[200,0,0] displayRenderMesh:false cir.parent=rec rec.parent = getNodeByName Parent --setTransformLockFlags cir #{3..9} conName=text text:Type size:2 wireColor:[0,150,0] pos:[0,5.5,0] alignment:2 displayRenderMesh:false conName.parent=rec rec.pos = posfac addModifier conName (meshSelect()) conName.renderable = false; setTransformLockFlags conName #{1..9} rec.rotation.x_rotation=90 fl=float_limit() cir.pos.controller[1].controller=fl paramWire.connect rec.baseObject[#width] fl.limits[#upper_limit] "width/2" paramWire.connect rec.baseObject[#width] fl.limits[#lower_limit] "-width/2" fl=float_limit() cir.pos.controller[2].controller=fl paramWire.connect rec.baseObject[#length] fl.limits[#upper_limit] "length/2" paramWire.connect rec.baseObject[#length] fl.limits[#lower_limit] "-length/2" fl=float_limit() cir.pos.controller[3].controller=fl fl.limits[#upper_limit].value=0 fl.limits[#lower_limit].value=0 ) fn facialControltypeD Type Name Parent posfac = ( rec=Rectangle length:5 width:10 name:(uniqueName "FaceControl") wireColor:[0,0,200] displayRenderMesh:false cir=circle radius:1 name:( Name) wireColor:[200,0,0] displayRenderMesh:false cir.parent=rec --setTransformLockFlags cir #{3..9} conName=text text:Type size:2 wireColor:[0,150,0] pos:[0,3,0] alignment:2 displayRenderMesh:false conName.parent=rec rec.parent = getNodeByName Parent rec.pos = posfac addModifier conName (meshSelect()) conName.renderable = false; setTransformLockFlags conName #{1..9} rec.rotation.x_rotation=90 fl=float_limit() cir.pos.controller[1].controller=fl paramWire.connect rec.baseObject[#width] fl.limits[#upper_limit] "width/2" paramWire.connect rec.baseObject[#width] fl.limits[#lower_limit] "-width/2" fl=float_limit() cir.pos.controller[2].controller=fl paramWire.connect rec.baseObject[#length] fl.limits[#upper_limit] "length/2" paramWire.connect rec.baseObject[#length] fl.limits[#lower_limit] "-length/2" fl=float_limit() cir.pos.controller[3].controller=fl fl.limits[#upper_limit].value=0 fl.limits[#lower_limit].value=0 ) fn facialControltypeA Type Name Parent posfac = ( rec=Rectangle length:10 width:1 name:(uniqueName "FaceControl") wireColor:[0,0,200] displayRenderMesh:false cir=circle radius:1 name:(Name) wireColor:[200,0,0] displayRenderMesh:false cir.parent=rec rec.parent = getNodeByName Parent --setTransformLockFlags cir #{3..9} conName=text text:Type size:2 wireColor:[0,150,0] pos:[0,-6,0] alignment:2 displayRenderMesh:false conName.parent=rec rec.pos = posfac addModifier conName (meshSelect()) conName.renderable = false; setTransformLockFlags conName #{1..9} rec.rotation.x_rotation=90 --fl=float_limit() --cir.pos.controller[1].controller=fl --paramWire.connect rec.baseObject[#width] fl.limits[#upper_limit] "width/2" --paramWire.connect rec.baseObject[#width] fl.limits[#lower_limit] "-width/2" fl=float_limit() cir.pos.controller[2].controller=fl paramWire.connect rec.baseObject[#length] fl.limits[#upper_limit] "length/2" paramWire.connect rec.baseObject[#length] fl.limits[#lower_limit] "-length/2" fl=float_limit() cir.pos.controller[1].controller=fl fl.limits[#upper_limit].value=0 fl.limits[#lower_limit].value=0 fl=float_limit() cir.pos.controller[3].controller=fl fl.limits[#upper_limit].value=0 fl.limits[#lower_limit].value=0 ) fn facialControltypeB Type Name Parent posfac = ( rec=Rectangle length:1 width:10 name:(uniqueName "FaceControl") wireColor:[0,0,200] displayRenderMesh:false cir=circle radius:1 name:( Name) wireColor:[200,0,0] displayRenderMesh:false cir.parent=rec rec.parent = getNodeByName Parent --setTransformLockFlags cir #{3..9} conName=text text:Type size:2 wireColor:[0,150,0] pos:[0,-2,0] alignment:2 displayRenderMesh:false conName.parent=rec rec.pos = posfac addModifier conName (meshSelect()) conName.renderable = false; setTransformLockFlags conName #{1..9} rec.rotation.x_rotation=90 fl=float_limit() cir.pos.controller[1].controller=fl paramWire.connect rec.baseObject[#width] fl.limits[#upper_limit] "width/2" paramWire.connect rec.baseObject[#width] fl.limits[#lower_limit] "-width/2" --fl=float_limit() --cir.pos.controller[2].controller=fl --paramWire.connect rec.baseObject[#length] fl.limits[#upper_limit] "length/2" --paramWire.connect rec.baseObject[#length] fl.limits[#lower_limit] "-length/2" fl=float_limit() cir.pos.controller[2].controller=fl fl.limits[#upper_limit].value=0 fl.limits[#lower_limit].value=0 fl=float_limit() cir.pos.controller[3].controller=fl fl.limits[#upper_limit].value=0 fl.limits[#lower_limit].value=0 ) fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) fn connectmorphstypeBlrmouth UprLeftMorph UprRightMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph; upr = getmorphchannelnumber UprRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; p3up = p3+6; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; createReaction morph1; setReactionState morph1 2 100; createReaction morph2; setReactionState morph2 2 0; pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 100; p3dn = p3 - 6; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 50 then (print (Morphname + " not found")) ) ) ) function domorphchannelnumberpolymorphcheck poly Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName poly.Morpher i == Morphname ) then (return true) else if (WM3_MC_GetName poly.morpher 1 != Morphname) and i == 100 then (return false) ) ) fn connectmorphsneer UprLeftMorph UprRightMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph; upr = getmorphchannelnumber UprRightMorph; --lol = getmorphchannelnumber LowerLeftMorph; --lor = getmorphchannelnumber LowerRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 --p = float_list() --$.Morpher[lol].controller = p --p1= bezier_float() --p.available.controller = p1 -- p = float_list() --$.Morpher[lor].controller = p --p1= bezier_float() --p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() --morph3= $.Morpher[lol].controller[1].controller = Float_Reactor() --morph4= $.Morpher[lor].controller[1].controller = Float_Reactor() --morph5= $.Morpher[lteeth].controller[1].controller = Float_Reactor() --morph6 =$.Morpher[rteeth].controller[1].controller = Float_Reactor() --morph7= $.Morpher[oteeth].controller[1].controller = Float_Reactor() --also place float reactor controllers on the extra (second list controller) corrective morph tracks... --morph11 = $.Morpher[upl].controller[2].controller = Float_Reactor() --morph21=$.Morpher[upr].controller[2].controller = Float_Reactor() --morph31= $.Morpher[lol].controller[2].controller = Float_Reactor() --morph41=$.Morpher[lor].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 50; --createReaction morph2; setReactionState morph2 1 50; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 100; createReaction morph2; setReactionState morph2 2 100; --createReaction morph3; --setReactionState morph3 2 0; --createReaction morph4; --setReactionState morph4 2 0; --createReaction morph5; --setReactionState morph5 2 0; --createReaction morph6; --setReactionState morph6 2 0; --createReaction morph7; --setReactionState morph7 2 0; --createReaction morph11; --setReactionState morph11 2 0; --createReaction morph21; --setReactionState morph21 2 0; --createReaction morph31; --setReactionState morph31 2 0; --createReaction morph41; --setReactionState morph41 2 0 ; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; --createReaction morph3; --setReactionState morph3 3 100; --createReaction morph4; --setReactionState morph4 3 100; --createReaction morph5; --setReactionState morph5 3 0; --createReaction morph6; --setReactionState morph6 3 0; --createReaction morph7; --setReactionState morph7 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% --createReaction morph11; --setReactionState morph11 3 0; --createReaction morph21; --setReactionState morph21 3 0; --createReaction morph31; --setReactionState morph31 3 0; --createReaction morph41; --setReactionState morph41 3 0; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. --createReaction morph11; --setReactionState morph11 4 0; --createReaction morph21; --setReactionState morph21 4 -100; --createReaction morph31; --setReactionState morph31 4 0; --createReaction morph41; --setReactionState morph41 4 -100; createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 0; --createReaction morph3; --setReactionState morph3 4 0; --createReaction morph4; --setReactionState morph4 4 100; --createReaction morph5; --setReactionState morph5 4 100; --createReaction morph6; --setReactionState morph6 4 0; --createReaction morph7; --setReactionState morph7 4 0; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; --createReaction morph11; --setReactionState morph11 5 -100; --createReaction morph21; --setReactionState morph21 5 0; --createReaction morph31; --setReactionState morph31 5 -100; --createReaction morph41; --setReactionState morph41 5 0; createReaction morph1; setReactionState morph1 5 0; createReaction morph2; setReactionState morph2 5 100; --createReaction morph3; --setReactionState morph3 5 100; --createReaction morph4; --setReactionState morph4 5 0; --createReaction morph5; --setReactionState morph5 5 0; --createReaction morph6; --setReactionState morph6 5 100; --createReaction morph7; --setReactionState morph7 5 0; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; --createReaction morph11; --setReactionState morph11 6 0; --createReaction morph21; --setReactionState morph21 6 -100; --createReaction morph31; --setReactionState morph31 6 0; --createReaction morph41; --setReactionState morph41 6 -100; createReaction morph1; setReactionState morph1 6 0; createReaction morph2; setReactionState morph2 6 0; --createReaction morph3; --setReactionState morph3 6 100; --createReaction morph4; --setReactionState morph4 6 100; --createReaction morph5; --setReactionState morph5 6 100; --createReaction morph6; --setReactionState morph6 6 0; --createReaction morph7; --setReactionState morph7 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; --createReaction morph11; --setReactionState morph11 7 -100; --createReaction morph21; --setReactionState morph21 7 0; --createReaction morph31; --setReactionState morph31 7 -100; --createReaction morph41; --setReactionState morph41 7 0; createReaction morph1; setReactionState morph1 7 0; createReaction morph2; setReactionState morph2 7 0; --createReaction morph3; --setReactionState morph3 7 100; --createReaction morph4; --setReactionState morph4 7 100; --createReaction morph5; --setReactionState morph5 7 0; --createReaction morph6; --setReactionState morph6 7 100; --createReaction morph7; --setReactionState morph7 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; --createReaction morph11; --setReactionState morph11 8 0; --createReaction morph21; --setReactionState morph21 8 -100; --createReaction morph31; --setReactionState morph31 8 0; --createReaction morph41; --setReactionState morph41 8 -100; createReaction morph1; setReactionState morph1 8 50; createReaction morph2; setReactionState morph2 8 0; --createReaction morph3; --setReactionState morph3 8 0; --createReaction morph4; --setReactionState morph4 8 100; --createReaction morph5; --setReactionState morph5 8 100; --createReaction morph6; --setReactionState morph6 8 0; --createReaction morph7; --setReactionState morph7 8 50; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; --createReaction morph11; --setReactionState morph11 9 -100; --createReaction morph21; --setReactionState morph21 9 0; --createReaction morph31; --setReactionState morph31 9 -100; --createReaction morph41; --setReactionState morph41 9 0; createReaction morph1; setReactionState morph1 9 0; createReaction morph2; setReactionState morph2 9 50; --createReaction morph3; --setReactionState morph3 9 100; --createReaction morph4; --setReactionState morph4 9 0; --createReaction morph5; --setReactionState morph5 9 0; --createReaction morph6; --setReactionState morph6 9 100; --createReaction morph7; --setReactionState morph7 9 50; --now place controller in bottom position.. controlspline.pos = [p1,p2,p3dn]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 50 then (print (Morphname + " not found")) ) ) ) fn connectmorphsync UprLeftMorph UprRightMorph LowerLeftMorph LowerRightMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph upr = getmorphchannelnumber UprRightMorph; lol = getmorphchannelnumber LowerLeftMorph; lor = getmorphchannelnumber LowerRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lol].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lor].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() morph3= $.Morpher[lol].controller[1].controller = Float_Reactor() morph4= $.Morpher[lor].controller[1].controller = Float_Reactor() --also place float reactor controllers on the extra (second list controller) corrective morph tracks... morph11 = $.Morpher[upl].controller[2].controller = Float_Reactor() morph21=$.Morpher[upr].controller[2].controller = Float_Reactor() morph31= $.Morpher[lol].controller[2].controller = Float_Reactor() morph41=$.Morpher[lor].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont reactTo morph3 cont reactTo morph4 cont reactTo morph11 cont reactTo morph21 cont reactTo morph31 cont reactTo morph41 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; setReactionState morph3 1 0; --createReaction morph4; setReactionState morph4 1 0; setReactionState morph11 1 0; --createReaction morph21; setReactionState morph21 1 0; --createReaction morph31; setReactionState morph31 1 0; --createReaction morph41; setReactionState morph41 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 3; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 100; createReaction morph2; setReactionState morph2 2 100; createReaction morph3; setReactionState morph3 2 0; createReaction morph4; setReactionState morph4 2 0; createReaction morph11; setReactionState morph11 2 0; createReaction morph21; setReactionState morph21 2 0; createReaction morph31; setReactionState morph31 2 0; createReaction morph41; setReactionState morph41 2 0 ; --now for the reactions when controller is at bottom middle... p3dn = p3 - 3 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; createReaction morph3; setReactionState morph3 3 100; createReaction morph4; setReactionState morph4 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% createReaction morph11; setReactionState morph11 3 0; createReaction morph21; setReactionState morph21 3 0; createReaction morph31; setReactionState morph31 3 0; createReaction morph41; setReactionState morph41 3 0; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. createReaction morph11; setReactionState morph11 4 0; createReaction morph21; setReactionState morph21 4 -100; createReaction morph31; setReactionState morph31 4 0; createReaction morph41; setReactionState morph41 4 -100; createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 100; createReaction morph3; setReactionState morph3 4 0; createReaction morph4; setReactionState morph4 4 100; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph11; setReactionState morph11 5 -100; createReaction morph21; setReactionState morph21 5 0; createReaction morph31; setReactionState morph31 5 -100; createReaction morph41; setReactionState morph41 5 0; createReaction morph1; setReactionState morph1 5 100; createReaction morph2; setReactionState morph2 5 100; createReaction morph3; setReactionState morph3 5 100; createReaction morph4; setReactionState morph4 5 0; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; createReaction morph11; setReactionState morph11 6 0; createReaction morph21; setReactionState morph21 6 -100; createReaction morph31; setReactionState morph31 6 0; createReaction morph41; setReactionState morph41 6 -100; createReaction morph1; setReactionState morph1 6 0; createReaction morph2; setReactionState morph2 6 100; createReaction morph3; setReactionState morph3 6 100; createReaction morph4; setReactionState morph4 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; createReaction morph11; setReactionState morph11 7 -100; createReaction morph21; setReactionState morph21 7 0; createReaction morph31; setReactionState morph31 7 -100; createReaction morph41; setReactionState morph41 7 0; createReaction morph1; setReactionState morph1 7 100; createReaction morph2; setReactionState morph2 7 0; createReaction morph3; setReactionState morph3 7 100; createReaction morph4; setReactionState morph4 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; createReaction morph11; setReactionState morph11 8 0; createReaction morph21; setReactionState morph21 8 -100; createReaction morph31; setReactionState morph31 8 0; createReaction morph41; setReactionState morph41 8 -100; createReaction morph1; setReactionState morph1 8 0; createReaction morph2; setReactionState morph2 8 100; createReaction morph3; setReactionState morph3 8 0; createReaction morph4; setReactionState morph4 8 100; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; createReaction morph11; setReactionState morph11 9 -100; createReaction morph21; setReactionState morph21 9 0; createReaction morph31; setReactionState morph31 9 -100; createReaction morph41; setReactionState morph41 9 0; createReaction morph1; setReactionState morph1 9 100; createReaction morph2; setReactionState morph2 9 0; createReaction morph3; setReactionState morph3 9 100; createReaction morph4; setReactionState morph4 9 0; --now restore controller to original position.. controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) ) fn connectmorphs2 UprLeftMorph UprRightMorph LowerLeftMorph LowerRightMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph upr = getmorphchannelnumber UprRightMorph; lol = getmorphchannelnumber LowerLeftMorph; lor = getmorphchannelnumber LowerRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lol].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lor].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() morph3= $.Morpher[lol].controller[1].controller = Float_Reactor() morph4= $.Morpher[lor].controller[1].controller = Float_Reactor() --also place float reactor controllers on the extra (second list controller) corrective morph tracks... morph11 = $.Morpher[upl].controller[2].controller = Float_Reactor() morph21=$.Morpher[upr].controller[2].controller = Float_Reactor() morph31= $.Morpher[lol].controller[2].controller = Float_Reactor() morph41=$.Morpher[lor].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont reactTo morph3 cont reactTo morph4 cont reactTo morph11 cont reactTo morph21 cont reactTo morph31 cont reactTo morph41 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; setReactionState morph3 1 0; --createReaction morph4; setReactionState morph4 1 0; setReactionState morph11 1 0; --createReaction morph21; setReactionState morph21 1 0; --createReaction morph31; setReactionState morph31 1 0; --createReaction morph41; setReactionState morph41 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 100; createReaction morph2; setReactionState morph2 2 100; createReaction morph3; setReactionState morph3 2 0; createReaction morph4; setReactionState morph4 2 0; createReaction morph11; setReactionState morph11 2 0; createReaction morph21; setReactionState morph21 2 0; createReaction morph31; setReactionState morph31 2 0; createReaction morph41; setReactionState morph41 2 0 ; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; createReaction morph3; setReactionState morph3 3 100; createReaction morph4; setReactionState morph4 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% createReaction morph11; setReactionState morph11 3 0; createReaction morph21; setReactionState morph21 3 0; createReaction morph31; setReactionState morph31 3 0; createReaction morph41; setReactionState morph41 3 0; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. createReaction morph11; setReactionState morph11 4 0; createReaction morph21; setReactionState morph21 4 -100; createReaction morph31; setReactionState morph31 4 0; createReaction morph41; setReactionState morph41 4 -100; createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 100; createReaction morph3; setReactionState morph3 4 0; createReaction morph4; setReactionState morph4 4 100; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph11; setReactionState morph11 5 -100; createReaction morph21; setReactionState morph21 5 0; createReaction morph31; setReactionState morph31 5 -100; createReaction morph41; setReactionState morph41 5 0; createReaction morph1; setReactionState morph1 5 100; createReaction morph2; setReactionState morph2 5 100; createReaction morph3; setReactionState morph3 5 100; createReaction morph4; setReactionState morph4 5 0; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; createReaction morph11; setReactionState morph11 6 0; createReaction morph21; setReactionState morph21 6 -100; createReaction morph31; setReactionState morph31 6 0; createReaction morph41; setReactionState morph41 6 -100; createReaction morph1; setReactionState morph1 6 0; createReaction morph2; setReactionState morph2 6 100; createReaction morph3; setReactionState morph3 6 100; createReaction morph4; setReactionState morph4 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; createReaction morph11; setReactionState morph11 7 -100; createReaction morph21; setReactionState morph21 7 0; createReaction morph31; setReactionState morph31 7 -100; createReaction morph41; setReactionState morph41 7 0; createReaction morph1; setReactionState morph1 7 100; createReaction morph2; setReactionState morph2 7 0; createReaction morph3; setReactionState morph3 7 100; createReaction morph4; setReactionState morph4 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; createReaction morph11; setReactionState morph11 8 0; createReaction morph21; setReactionState morph21 8 -100; createReaction morph31; setReactionState morph31 8 0; createReaction morph41; setReactionState morph41 8 -100; createReaction morph1; setReactionState morph1 8 0; createReaction morph2; setReactionState morph2 8 100; createReaction morph3; setReactionState morph3 8 0; createReaction morph4; setReactionState morph4 8 100; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; createReaction morph11; setReactionState morph11 9 -100; createReaction morph21; setReactionState morph21 9 0; createReaction morph31; setReactionState morph31 9 -100; createReaction morph41; setReactionState morph41 9 0; createReaction morph1; setReactionState morph1 9 100; createReaction morph2; setReactionState morph2 9 0; createReaction morph3; setReactionState morph3 9 100; createReaction morph4; setReactionState morph4 9 0; --now restore controller to original position.. controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) ) fn connectmorphsbrowemotion UprLeftMorph UprRightMorph LowerLeftMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph; upr = getmorphchannelnumber UprRightMorph; lol = getmorphchannelnumber LowerLeftMorph; --lor = getmorphchannelnumber LowerRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lol].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() morph3= $.Morpher[lol].controller[1].controller = Float_Reactor() --also place float reactor controllers on the extra (second list controller) corrective morph tracks... morph11 = $.Morpher[upl].controller[2].controller = Float_Reactor() morph21=$.Morpher[upr].controller[2].controller = Float_Reactor() morph31= $.Morpher[lol].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont reactTo morph3 cont reactTo morph11 cont reactTo morph21 cont reactTo morph31 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; setReactionState morph3 1 0; setReactionState morph11 1 0; --createReaction morph21; setReactionState morph21 1 0; --createReaction morph31; setReactionState morph31 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 100; createReaction morph2; setReactionState morph2 2 100; createReaction morph3; setReactionState morph3 2 0; createReaction morph11; setReactionState morph11 2 0; createReaction morph21; setReactionState morph21 2 0; createReaction morph31; setReactionState morph31 2 0; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; createReaction morph3; setReactionState morph3 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% createReaction morph11; setReactionState morph11 3 0; createReaction morph21; setReactionState morph21 3 0; createReaction morph31; setReactionState morph31 3 0; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. createReaction morph11; setReactionState morph11 4 0; createReaction morph21; setReactionState morph21 4 -100; createReaction morph31; setReactionState morph31 4 0; createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 100; createReaction morph3; setReactionState morph3 4 0; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph11; setReactionState morph11 5 -100; createReaction morph21; setReactionState morph21 5 0; createReaction morph31; setReactionState morph31 5 -100; createReaction morph1; setReactionState morph1 5 100; createReaction morph2; setReactionState morph2 5 100; createReaction morph3; setReactionState morph3 5 100; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; createReaction morph11; setReactionState morph11 6 0; createReaction morph21; setReactionState morph21 6 -100; createReaction morph31; setReactionState morph31 6 0; createReaction morph1; setReactionState morph1 6 0; createReaction morph2; setReactionState morph2 6 100; createReaction morph3; setReactionState morph3 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; createReaction morph11; setReactionState morph11 7 -100; createReaction morph21; setReactionState morph21 7 0; createReaction morph31; setReactionState morph31 7 -100; createReaction morph1; setReactionState morph1 7 100; createReaction morph2; setReactionState morph2 7 0; createReaction morph3; setReactionState morph3 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; createReaction morph11; setReactionState morph11 8 0; createReaction morph21; setReactionState morph21 8 -100; createReaction morph31; setReactionState morph31 8 0; createReaction morph1; setReactionState morph1 8 0; createReaction morph2; setReactionState morph2 8 100; createReaction morph3; setReactionState morph3 8 0; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; createReaction morph11; setReactionState morph11 9 -100; createReaction morph21; setReactionState morph21 9 0; createReaction morph31; setReactionState morph31 9 -100; createReaction morph1; setReactionState morph1 9 100; createReaction morph2; setReactionState morph2 9 0; createReaction morph3; setReactionState morph3 9 100; --now restore controller to original position.. controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 50 then (print (Morphname + " not found")) ) ) ) function getmorphchannelnumberpolymorph poly Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName poly.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName poly.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) fn connectmorphsjaw UprLeftMorpht UprRightMorpht Openert poly UprLeftMorph UprRightMorph Opener poly2 ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the general function defined above, 'getmorphchannelnumberpolymorph', which takes the arguments of morphname and mesh. upl = getmorphchannelnumberpolymorph poly2 UprLeftMorph; upr = getmorphchannelnumberpolymorph poly2 UprRightMorph; lol = getmorphchannelnumberpolymorph poly2 Opener; uplt = getmorphchannelnumberpolymorph poly UprLeftMorpht; uprt= getmorphchannelnumberpolymorph poly UprRightMorpht ; lolt = getmorphchannelnumberpolymorph poly Openert; --lor = getmorphchannelnumber LowerRightMorph; --lteeth = getmorphchannelnumber "lTeeth"; --rteeth =getmorphchannelnumber "rTeeth"; --oteeth = getmorphchannelnumber "teethOpen"; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() poly.Morpher[uplt].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() poly.Morpher[uprt].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() poly.Morpher[lolt].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() poly2.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() poly2.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() poly2.Morpher[lol].controller = p p1= bezier_float() p.available.controller = p1 --teethup = execute("$"+Teeth) -- p = float_list() -- poly.Morpher[teethop].controller = p -- p1= bezier_float() -- p.available.controller = p1 -- poly.Morpher[lefteeth].controller = p -- p1= bezier_float() -- p.available.controller = p1 -- -- poly.Morpher[righteeth].controller = p -- p1= bezier_float() -- p.available.controller = p1 -- --Then declare that which is to be controlled... morph1= poly.Morpher[uplt].controller[1].controller = Float_Reactor() morph2= poly.Morpher[uprt].controller[1].controller = Float_Reactor() morph3= poly.Morpher[lolt].controller[1].controller = Float_Reactor() morph4= poly2.Morpher[upl].controller [1].controller = Float_Reactor() morph5= poly2.Morpher[upr].controller [1].controller = Float_Reactor() morph6 =poly2.Morpher[lol].controller [1].controller = Float_Reactor() --morph7= $.Morpher[oteeth].controller[1].controller = Float_Reactor() --also place float reactor controllers on the extra (second list controller) corrective morph tracks... --morph11 = $.Morpher[upl].controller[2].controller = Float_Reactor() --morph21=$.Morpher[upr].controller[2].controller = Float_Reactor() --morph31= $.Morpher[lol].controller[2].controller = Float_Reactor() --morph41=$.Morpher[lor].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline =getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont reactTo morph3 cont reactTo morph4 cont reactTo morph5 cont reactTo morph6 cont --reactTo morph7 cont --reactTo morph11 cont --reactTo morph21 cont --reactTo morph31 cont --reactTo morph41 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; setReactionState morph3 1 50; --createReaction morph4; setReactionState morph4 1 0 ; --now the teeth morphs setReactionState morph5 1 0; setReactionState morph6 1 50; --setReactionState morph7 1 50; ---setReactionState morph11 1 0; --createReaction morph21; --setReactionState morph21 1 0; --createReaction morph31; --setReactionState morph31 1 0; --createReaction morph41; --setReactionState morph41 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 0; createReaction morph2; setReactionState morph2 2 0; createReaction morph3; setReactionState morph3 2 0; createReaction morph4; setReactionState morph4 2 0; createReaction morph5; setReactionState morph5 2 0; createReaction morph6; setReactionState morph6 2 0; -- createReaction morph7; -- setReactionState morph7 2 0; --createReaction morph11; --setReactionState morph11 2 0; --createReaction morph21; --setReactionState morph21 2 0; --createReaction morph31; --setReactionState morph31 2 0; --createReaction morph41; --setReactionState morph41 2 0 ; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; createReaction morph3; setReactionState morph3 3 100; createReaction morph4; setReactionState morph4 3 0; createReaction morph5; setReactionState morph5 3 0; createReaction morph6; setReactionState morph6 3 100; -- createReaction morph7; -- setReactionState morph7 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% --createReaction morph11; --setReactionState morph11 3 0; --createReaction morph21; --setReactionState morph21 3 0; --createReaction morph31; --setReactionState morph31 3 0; --createReaction morph41; --setReactionState morph41 3 0; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. --createReaction morph11; --setReactionState morph11 4 0; --createReaction morph21; --setReactionState morph21 4 -100; --createReaction morph31; --setReactionState morph31 4 0; --createReaction morph41; --setReactionState morph41 4 -100; createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 0; createReaction morph3; setReactionState morph3 4 0; createReaction morph4; setReactionState morph4 4 100; createReaction morph5; setReactionState morph5 4 0; createReaction morph6; setReactionState morph6 4 0; -- createReaction morph7; -- setReactionState morph7 4 0; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; --createReaction morph11; --setReactionState morph11 5 -100; --createReaction morph21; --setReactionState morph21 5 0; --createReaction morph31; --setReactionState morph31 5 -100; --createReaction morph41; --setReactionState morph41 5 0; createReaction morph1; setReactionState morph1 5 0; createReaction morph2; setReactionState morph2 5 100; createReaction morph3; setReactionState morph3 5 0 createReaction morph4; setReactionState morph4 5 0; createReaction morph5; setReactionState morph5 5 100; createReaction morph6; setReactionState morph6 5 0; -- createReaction morph7; -- setReactionState morph7 5 0; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; --createReaction morph11; --setReactionState morph11 6 0; --createReaction morph21; --setReactionState morph21 6 -100; --createReaction morph31; --setReactionState morph31 6 0; --createReaction morph41; --setReactionState morph41 6 -100; createReaction morph1; setReactionState morph1 6 100; createReaction morph2; setReactionState morph2 6 0; createReaction morph3; setReactionState morph3 6 100; createReaction morph4; setReactionState morph4 6 100; createReaction morph5; setReactionState morph5 6 0; createReaction morph6; setReactionState morph6 6 100; -- createReaction morph7; -- setReactionState morph7 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; --createReaction morph11; --setReactionState morph11 7 -100; --createReaction morph21; --setReactionState morph21 7 0; --createReaction morph31; --setReactionState morph31 7 -100; --createReaction morph41; --setReactionState morph41 7 0; createReaction morph1; setReactionState morph1 7 0; createReaction morph2; setReactionState morph2 7 100; createReaction morph3; setReactionState morph3 7 100; createReaction morph4; setReactionState morph4 7 0; createReaction morph5; setReactionState morph5 7 100; createReaction morph6; setReactionState morph6 7 100; -- createReaction morph7; -- setReactionState morph7 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; --createReaction morph11; --setReactionState morph11 8 0; --createReaction morph21; --setReactionState morph21 8 -100; --createReaction morph31; --setReactionState morph31 8 0; --createReaction morph41; --setReactionState morph41 8 -100; createReaction morph1; setReactionState morph1 8 100; createReaction morph2; setReactionState morph2 8 0; createReaction morph3; setReactionState morph3 8 50; createReaction morph4; setReactionState morph4 8 100; createReaction morph5; setReactionState morph5 8 0; createReaction morph6; setReactionState morph6 8 50; --createReaction morph7; --setReactionState morph7 8 0; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; --createReaction morph11; --setReactionState morph11 9 -100; --createReaction morph21; --setReactionState morph21 9 0; --createReaction morph31; --setReactionState morph31 9 -100; --createReaction morph41; --setReactionState morph41 9 0; createReaction morph1; setReactionState morph1 9 0; createReaction morph2; setReactionState morph2 9 100; createReaction morph3; setReactionState morph3 9 50; createReaction morph4; setReactionState morph4 9 0; createReaction morph5; setReactionState morph5 9 100; createReaction morph6; setReactionState morph6 9 50; -- createReaction morph7; -- setReactionState morph7 9 50; --now restore controller to original position.. controlspline.pos = [p1,p2,p3up]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 50 then (print (Morphname + " not found")) ) ) ) fn connectmorphtypeAjaw meshmorph teethmorph teethmesh ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber meshmorph; --upr = getmorphchannelnumber UprRightMorph; --lol = getmorphchannelnumber LowerLeftMorph; --lor = getmorphchannelnumber LowerRightMorph; teethfwd = getmorphchannelnumberpolymorph teethmesh teethmorph ; $.Morpher.Use_limits = 0 teethmesh.Morpher.Use_limits = 0 -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() teethmesh.Morpher[teethfwd].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= teethmesh.Morpher[teethfwd].controller[1].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; --setReactionState morph3 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 -100; createReaction morph2; setReactionState morph2 2 -100; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 100; createReaction morph2; setReactionState morph2 3 100; controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) ) fn connectmorphtypeAbrowSqueeze squeezemorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. sq = getmorphchannelnumber squeezemorph; --upr = getmorphchannelnumber UprRightMorph; --lol = getmorphchannelnumber LowerLeftMorph; --lor = getmorphchannelnumber LowerRightMorph; $.Morpher.Use_limits = 0 -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() $.Morpher[sq].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morphsq = $.Morpher[sq].controller[3].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morphsq cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morphsq 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morphsq; setReactionState morphsq 2 100; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morphsq; setReactionState morphsq 3 -100; controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) ) fn connectmorphstypeE UprLeftMorph UprRightMorph polyobj ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph; upr = getmorphchannelnumber UprRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... p = float_list() polyobj.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() polyobj.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= polyobj.Morpher[upl].controller[1].controller = Float_Reactor() morph2= polyobj.Morpher[upr].controller[1].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 50; --createReaction morph2; setReactionState morph2 1 50; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 50; createReaction morph2; setReactionState morph2 2 100; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 50; createReaction morph2; setReactionState morph2 3 0; --sets upper lip down morphs to 100% and upper lip up morphs to zero% --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. createReaction morph1; setReactionState morph1 4 0; createReaction morph2; setReactionState morph2 4 100; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph1; setReactionState morph1 5 100; createReaction morph2; setReactionState morph2 5 100; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; createReaction morph1; setReactionState morph1 6 0; createReaction morph2; setReactionState morph2 6 0; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; createReaction morph1; setReactionState morph1 7 100; createReaction morph2; setReactionState morph2 7 0; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; createReaction morph1; setReactionState morph1 8 0; createReaction morph2; setReactionState morph2 8 50; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; createReaction morph1; setReactionState morph1 9 100; createReaction morph2; setReactionState morph2 9 50; --now place controller in bottom left corner controlspline.pos = [pleft,p2,p3dn]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) ) fn getmorphchannelnumberpoly Morphname poly = ( for i = 1 to 100 do ( --local poly = getNodeByName polyObject if (WM3_MC_GetName poly.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName poly.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) fn connectmorphstonque2 UprLeftMorph UprRightMorph LowerLeftMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph; upr = getmorphchannelnumber UprRightMorph; lol = getmorphchannelnumber LowerLeftMorph; --lor = getmorphchannelnumber LowerRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... --we turn off' use limits' in order to use tonque down as negative up. $.Morpher.Use_limits = 0 p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lol].controller = p p1= bezier_float() p.available.controller = p1 -- p = float_list() -- $.Morpher[lor].controller = p -- p1= bezier_float() -- p.available.controller = p1 -- --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() morph3= $.Morpher[lol].controller[1].controller = Float_Reactor() --morph4= $.Morpher[lor].controller[1].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont reactTo morph3 cont --reactTo morph4 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; setReactionState morph3 1 0; --createReaction morph4; --setReactionState morph4 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 6; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 0; createReaction morph2; setReactionState morph2 2 0; createReaction morph3; setReactionState morph3 2 100; --createReaction morph4; --setReactionState morph4 2 0; --now for the reactions when controller is at bottom middle... p3dn = p3 - 6 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; createReaction morph3; setReactionState morph3 3 -100; -- createReaction morph4; -- setReactionState morph4 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 0; createReaction morph3; setReactionState morph3 4 100; -- createReaction morph4; -- setReactionState morph4 4 0; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph1; setReactionState morph1 5 0; createReaction morph2; setReactionState morph2 5 100; createReaction morph3; setReactionState morph3 5 100; -- createReaction morph4; -- setReactionState morph4 5 0; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; createReaction morph1; setReactionState morph1 6 100; createReaction morph2; setReactionState morph2 6 0; createReaction morph3; setReactionState morph3 6 -100 -- createReaction morph4; -- setReactionState morph4 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; createReaction morph1; setReactionState morph1 7 100; createReaction morph2; setReactionState morph2 7 0; createReaction morph3; setReactionState morph3 7 -100; -- createReaction morph4; -- setReactionState morph4 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; createReaction morph1; setReactionState morph1 8 100; createReaction morph2; setReactionState morph2 8 0; createReaction morph3; setReactionState morph3 8 0; -- createReaction morph4; -- setReactionState morph4 8 0; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; createReaction morph1; setReactionState morph1 9 0; createReaction morph2; setReactionState morph2 9 100; createReaction morph3; setReactionState morph3 9 0; -- createReaction morph4; -- setReactionState morph4 9 0; --now restore controller to original position.. controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 100 then (print (Morphname + " not found")) ) ) ) fn connecteyelids upow upcl loup lodn rightsquint leftsquint eyelidsctrl = ( global rsq= getmorphchannelnumber rightsquint; global lsq = getmorphchannelnumber leftsquint ; --Since we are going to use the squint morphs for the lower lid movements, we bring them in. p = float_list() $.Morpher[rsq].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lsq].controller = p p1= bezier_float() p.available.controller = p1 morphrsq= $.Morpher[rsq].controller[1].controller = Float_Reactor() morphlsq= $.Morpher[lsq].controller[1].controller = Float_Reactor() -- We place extra controllers on these squint morphs, as we will use them when we come to the assym control , --when we will subtract a percentage of each from the value set in the main control. global morphrsqassym = $.Morpher[rsq].controller[2].controller = Float_Reactor() global morphlsqassym = $.Morpher[lsq].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline = getNodeByName eyelidsctrl cont =controlspline.pos.y_position.controller cont2 = controlspline.pos.y_position.controller --we set the angles of the eylids upowangle = degToRad upow upclwangle = degToRad upcl loupangle = degToRad loup lodnangle = degToRad lodn p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions --controlspline. pos.y_position.controller[1].value = 0; -- rightupperbone.rotation.controller.Reaction.controller.Z_Rotation cont =controlspline.pos.y_position.controller --reactTo rightrightupperrotreaction cont p3up = p3 + 10; -- controlspline.pos = [p1,p2,p3up] -- createReaction rightrightupperrotreaction -- setReactionState rightrightupperrotreaction 0 upowangle select rightupperbone p3dn = p3 - 10; -- controlspline.pos = [p1,p2,p3dn] -- createReaction rightrightupperrotreaction ; -- setReactionState rightupperrotreaction 1 upclangle; controlspline.pos = [p1,p2,p3dn] --Once the 'react to' function is called, a state is also created with default values. --These values should be changed using 'setReactionState', indexed to one. reactTo rightupperrotreaction cont setReactionState rightupperrotreaction 1 upclwangle controlspline.pos = [p1,p2,p3up] --Now moving the spline and calling 'createReaction', --creates another set whose values can be changed by 'setReactionState' once again. createReaction rightupperrotreaction setReactionState rightupperrotreaction 2 upowangle controlspline.pos = [p1,p2,p3] --this should be sufficent in this case to make a reaction connection. --We now do the same thing for all the other bones. select leftupperbone p3dn = p3 - 10; -- controlspline.pos = [p1,p2,p3dn] -- createReaction rightrightupperrotreaction ; -- setReactionState rightupperrotreaction 1 upclangle; controlspline.pos = [p1,p2,p3dn] reactTo leftupperrotreaction cont setReactionState leftupperrotreaction 1 upclwangle controlspline.pos = [p1,p2,p3up] createReaction leftupperrotreaction setReactionState leftupperrotreaction 2 upowangle controlspline.pos = [p1,p2,p3] --now for the lower bones, which also involve a squint morph which will put in the reaction list cont2 = controlspline.pos.x_position.controller select rightlowerbone pleft = p1 - 6; controlspline.pos = [pleft,p2,p3]; reactTo rightlowerrotreaction cont2 setReactionState rightlowerrotreaction 1 loupangle ; reactTo morphrsq cont2 setReactionState morphrsq 1 100 reactTo morphlsq cont2 setReactionState morphlsq 1 100 --now move to extreme upper right and set reactions... pright = p1 + 6; controlspline.pos = [pright,p2,p3]; --offset by six to ensure it hits limits of controller spline ... createReaction rightlowerrotreaction; setReactionState rightlowerrotreaction 2 lodnangle ; createReaction morphrsq setReactionState morphrsq 2 0 createReaction morphlsq setReactionState morphlsq 2 0 controlspline.pos = [p1,p2,p3] createReaction morphrsq setReactionState morphrsq 3 0 createReaction morphlsq setReactionState morphlsq 3 0 select leftlowerbone cont2 = controlspline.pos.x_position.controller pleft = p1 - 6; controlspline.pos = [pleft,p2,p3]; reactTo leftlowerrotreaction cont2 setReactionState leftlowerrotreaction 1 loupangle ; --now move to extreme upper right and set reactions... pright = p1 + 6; controlspline.pos = [pright,p2,p3]; --offset by six to ensure it hits limits of controller spline ... createReaction leftlowerrotreaction; setReactionState leftlowerrotreaction 2 lodnangle ; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% --now restore controller to original position.. controlspline.pos = [p1,p2,p3]; select headsup ) fn connectassym assymctrlhandle = ( --To get assymetry, we wire up the xpos of the spline controller to the weight of the reaction list rotation controller on each bone. controlsplineass = getNodeByName assymctrlhandle --we first assign another position controller called 'Tracking' to the controlspline so all movements are relative to center, and the absolute location is zeroed out. poslistcon = position_list() controlsplineass.position.controller = poslistcon controlsplineass.position.controller[2].controller = copy poslistcon --set second controller active controlsplineass.position.controller.setactive 2 --name controllers listctrl.setname controlsplineass.position.controller 1 "Zero" listctrl.setname controlsplineass.position.controller 2 "Tracking" --The expression below was pasted from the listener window after a manual operation of wiring. --The arguments have been changed to give sub anim indexes to the approp. controllers,using the listener window to determine approp. indices. --Note that the script moves the bones - not back to their default position, but to where they are 100% - at the top of the spline ctrl. --If this is not to your liking, you can alter the function expression at the far right to give a 50% result when moving the circle controller to the extremes. paramWire.connect controlsplineass.pos.controller.Tracking.controller.Position_XYZ.controller.X_Position.controller[1] rightupperbone.rotation.controller[5] [3] "if (Limited_Controller__Bezier_Float) > 0 then ( Weight_Reaction = (1-(Limited_Controller__Bezier_Float) /5)) else (Weight_Reaction = 1)" paramWire.connect controlsplineass.pos.controller.Tracking.controller.Position_XYZ.controller.X_Position.controller[1] leftupperbone.rotation.controller[5] [3] "if (Limited_Controller__Bezier_Float) < 0 then ( Weight_Reaction = (1+(Limited_Controller__Bezier_Float) /5)) else (Weight_Reaction = 1)" paramWire.connect controlsplineass.pos.controller.Tracking.controller.Position_XYZ.controller.X_Position.controller[1] rightlowerbone.rotation.controller[5] [3] "if (Limited_Controller__Bezier_Float) > 0 then ( Weight_Reaction = (1-(Limited_Controller__Bezier_Float) /5)) else (Weight_Reaction = 1)" paramWire.connect controlsplineass.pos.controller.Tracking.controller.Position_XYZ.controller.X_Position.controller[1] leftlowerbone.rotation.controller[5] [3] "if (Limited_Controller__Bezier_Float) < 0 then ( Weight_Reaction = (1+(Limited_Controller__Bezier_Float) /5)) else (Weight_Reaction = 1)" --The expression below connects the slider to the second bezier float controller on the morph target, which subtracts a percentage of the slider's x pos from the value of each squint morph. --In the middle, this value is zero - i.e, nothing is subtracted from the squint morphs at all. --Float wire is the value of the morph target. paramWire.connect controlsplineass.pos.controller.Tracking.controller.Position_XYZ.controller.X_Position.controller[1] $.modifiers[#Morpher][lsq].controller[2] "if (Limited_Controller__Bezier_Float) < 0 then ( Float_Wire= 100*(Limited_Controller__Bezier_Float /5)) else (Float_Wire = 0)" paramWire.connect controlsplineass.pos.controller.Tracking.controller.Position_XYZ.controller.X_Position.controller[1] $.modifiers[#Morpher][rsq].controller[2] "if (Limited_Controller__Bezier_Float) > 0 then ( Float_Wire=-100*(Limited_Controller__Bezier_Float /5)) else (Float_Wire = 0)" ) fn connecteyes eyesctrl eyectrlouter = ( controlsplineyes = getNodeByName eyesctrl --set extra controller on outer eye ctrl spline so we can work from initial offset... poslistcon = position_list() eyectrlouter.position.controller = poslistcon eyectrlouter.position.controller[2].controller = copy poslistcon --set second controller active eyectrlouter.position.controller.setactive 2 --name controllers listctrl.setname eyectrlouter.position.controller 1 "Zero" listctrl.setname eyectrlouter .position.controller 2 "UI_Control" --As usual, the expression below was simply pasted from the listener window after a manual paramwire operation... paramWire.connect controlsplineyes.pos.controller.X_Position.controller[1] eyectrlouter.pos.controller.UI_Control.controller.Position_XYZ.controller[1] "Limited_Controller__Bezier_Float" paramWire.connect controlsplineyes.pos.controller.Y_Position.controller[1] eyectrlouter .pos.controller.UI_Control.controller.Position_XYZ.controller[3] "Limited_Controller__Bezier_Float" eyectrlouter.position.controller.setactive 1 --(so the outer eye ctrl can be moved manually) ) fn connectmouthvol volumectrl = ( controlsplinevol = getNodeByName volumectrl p1= controlsplinevol.pos[1] p2 = controlsplinevol.pos[2] p3 = controlsplinevol.pos[3] controlsplinevol.pos = [p1,p2,p3] contvol =controlsplinevol.pos.y_position.controller p3up = p3 + 10; controlsplinevol.pos = [p1,p2,p3up]; --We now specify which morphs are to be affected by the vol. control, and create arrays for them: Mouthset = #("lFrown","rFrown","lLwrLipUp","rLwrLipUp", "rLwrLipUp","lLwrLipDn","rLwrLipDn","rLwrLipDn","lMouth", "rMouth", "lSneer","rSneer", "lUprLipDn","rUprLipDn", "lUprLipUp","rUprLipUp", "jawFwd","rJaw","open","lNarrow", "rNarrow", "lSmile", "rSmile", "lJaw","rWide","lWide"); Teethset = #("teethOpen","rTeeth","lTeeth","teethFwd"); Tonqueset = #( "tonqueUp","tonqueOut","rTonque","tonqueTipUp","lTonque" ); select headsup for i = 1 to Mouthset.count do( p = float_list() --The function 'getmorphchannelnumber' returns the channel number of a morphname, but it is dangerous to use this function - see note below. morphvolmouthset = getmorphchannelnumber Mouthset[i] $.Morpher[morphvolmouthset].controller = p pb= bezier_float() p.available.controller = pb morphvols = $.Morpher[morphvolmouthset].controller[3].controller = bezier_float() --now we move down to the weights node ([5][1]), and link its value to the slider.. paramWire.connect controlsplinevol.pos.controller.Y_Position.controller[#Limited_Controller__Bezier_Float] $.modifiers[#Morpher][morphvolmouthset][5][1] "( Limited_Controller__Bezier_Float)/10+.50" ) tonquemesh = getNodebyName Tonquel select tonquemesh for i = 1 to Tonqueset .count do( p = float_list() --Note the use of a function below ('getmorphchannelnumberpoly') that specifies a SPECIFIC poly object, rather than adapting other code THAT REFERS TO ONLY ONE MESH. --Had we used th e'getmorphchannelnumber' function, it wouldn't work, even if we HAD first selected the approriate mesh, --This is because the '$' in that function refers to the current selection AT THE TIME THE FUNCTION IS COMPILED, which obviously can't apply when another mesh is selected. tonquesetnumber = getmorphchannelnumberpoly Tonqueset[i] tonquemesh $.Morpher[tonquesetnumber].controller = p pb= bezier_float() p.available.controller = pb morphvols = $.Morpher[tonquesetnumber].controller[3].controller = bezier_float() --now we move down to the weights node ([5][1]), and link its value to the slider.. --The idea being, as we can't directly control the morph channel values, as they are under the control of reatcion manager, etc. --the 'weights' will control how much each of these channels is going to react to any other controls. paramWire.connect controlsplinevol.pos.controller.Y_Position.controller[#Limited_Controller__Bezier_Float] $.modifiers[#Morpher][tonquesetnumber][5][1] "( Limited_Controller__Bezier_Float)/10+.50" ) toot = getNodebyName Teeth select toot for i = 1 to Teethset.count do( p = float_list() teethsetnumber = getmorphchannelnumberpoly Teethset[i] toot $.Morpher[teethsetnumber].controller = p pb= bezier_float() p.available.controller = pb morphvols = $.Morpher[teethsetnumber].controller[3].controller = bezier_float() --now we move down to the weights node ([5][1]), and link its value to the slider.. paramWire.connect controlsplinevol.pos.controller.Y_Position.controller[#Limited_Controller__Bezier_Float] $.modifiers[#Morpher][teethsetnumber][5][1] "( Limited_Controller__Bezier_Float)/10+.50" ) controlsplinevol.pos = [p1,p2,p3up]; ) fn connectbrowvol volumectrl =( controlsplinevol = getNodeByName volumectrl p1= controlsplinevol.pos[1] p2 = controlsplinevol.pos[2] p3 = controlsplinevol.pos[3] controlsplinevol.pos = [p1,p2,p3] contvol =controlsplinevol.pos.y_position.controller p3up = p3 + 10; controlsplinevol.pos = [p1,p2,p3up]; Browset = #("rSquint" ,"lSquint" ,"browsSqueeze","browsMidUp","lBrowOutDn","rBrowOutDn", "lBrowOutUp", "rBrowOutUp","browsMidDn"); for i = 1 to Browset.count do( p = float_list() morphvolbrowset = getmorphchannelnumber Browset[i] --we should really use 'getmorphchannelnumberpoly' to be safe, but in this case it doesn't matter... $.Morpher[morphvolbrowset].controller = p pb= bezier_float() p.available.controller = pb morphvols = $.Morpher[morphvolbrowset].controller[3].controller = bezier_float() --now we move down to the weights node([5][1]), and link its value to the slider.. paramWire.connect controlsplinevol.pos.controller.Y_Position.controller[#Limited_Controller__Bezier_Float] $.modifiers[#Morpher][morphvolbrowset][5][1] "( Limited_Controller__Bezier_Float)/10+.50" ) controlsplinevol.pos = [p1,p2,p3up]; ) --Having defined the functions we will be using, we now create the user rollout. We want it to bring in the meshes we will work with, as well as --check to determine if all the required morphs are present... group "Head" ( pickbutton pickHead "Pick Head" filter:pick_morph button checkheadmorphs "Check Head Morphs" filter:pick_morph enabled:off ) group "Teeth" ( pickbutton pickTeeth "Pick Teeth" filter:pick_morph button checkteethmorphs "Check Teeth Morphs" filter:pick_morph enabled:off ) group "Tonque" ( pickbutton pickTonque "Pick Tongue" filter:pick_morph; button checktonquemorphs "Check Tonque Morphs" filter:pick_morph enabled:off ) group "Create Facial UI" ( button createFacialUI "Create Facial UI" enabled:on spinner size "SIze" range:[0,5.0,.3] width: 65 type:#float enabled:on ) on pickHead picked obj do ( headsup = obj pickHead.text = obj.name global NameOfControlSystem =obj.name global headsup = getNodeByName NameOfControlSystem checkheadmorphs.enabled = on ) on pickTeeth picked obj do ( teethup= obj pickTeeth .text = obj.name global Teeth =obj.name global teethup = getNodeByName Teeth checkteethmorphs.enabled = on ) on pickTonque picked obj do ( Tonquemes = obj pickTonque.text = obj.name global Tonquel =obj.name global Tonquemes = getNodeByName Tonquel checktonquemorphs.enabled = on ) on checkheadmorphs pressed do ( head = getNodeByName NameOfControlSystem Nameset = #("rSquint" ,"lSquint" ,"browsSqueeze","browsMidUp","lBrowOutDn","rBrowOutDn", "lBrowOutUp", "rBrowOutUp", "browsMidDn","lFrown","rFrown","lLwrLipUp","rLwrLipUp", "rLwrLipUp","lLwrLipDn","rLwrLipDn","rLwrLipDn","lMouth", "rMouth", "lSneer","rSneer", "lUprLipDn","rUprLipDn", "lUprLipUp","rUprLipUp", "jawFwd","rJaw","open","lNarrow", "rNarrow", "lSmile", "rSmile", "lJaw","rWide","lWide") Missingset = #() for t = 1 to Nameset.count do ( if (domorphchannelnumberpolymorphcheck head Nameset[t] ) then () else (append Missingset Nameset[t] ) ) names = Missingset if names.count ==0 then ( messageBox("All required Head morphs are present") )else( messageBox ("The following Head morphs are missing: \n"+names as string)) ) on checkteethmorphs pressed do ( toot =getNodeByName Teeth Nameset = #("teethOpen","rTeeth","lTeeth","teethFwd") Missingset = #() for t = 1 to Nameset.count do ( if (domorphchannelnumberpolymorphcheck toot Nameset[t] ) then () else (append Missingset Nameset[t] ) ) names = Missingset if names.count ==0 then ( messageBox("All required Teeth morphs are present") )else( messageBox ("The following Teeth morphs are missing: \n"+names as string)) ) on checktonquemorphs pressed do ( tonqu =getNodeByName Tonquel Nameset = #("tonqueUp","tonqueOut","rTonque","tonqueTipUp","lTonque") Missingset = #() for t = 1 to Nameset.count do ( if (domorphchannelnumberpolymorphcheck tonqu Nameset[t] ) then () else (append Missingset Nameset[t] ) ) names = Missingset if names.count ==0 then ( messageBox("All required Tonque morphs are present") )else( messageBox ("The following Tonque morphs are missing: \n"+names as string)) ) --The NameofControlSystem is determined by the name of the head mesh chosen on createFacialUI pressed do ( -- global headsup = execute("$"+NameOfControlSystem) -- global teethup = execute("$"+Teeth) --It is advised to use the 'getNodeByName' method rather than 'execute' --create bounding rectangle for upper and lower face to move elements around and parent to main bounding rectangle select headsup posboundingrectangle = [-32,0,26] Nameofctrlsys = "Facial_Ctrls_for_" + NameOfControlSystem createboundrec Nameofctrlsys null 64 50 posboundingrectangle; --Place name of controller above mainframe conName=text text:Nameofctrlsys size:4 wireColor:[0,150,0] pos:[0,-6,0] alignment:2 displayRenderMesh:false conName.rotation.x_rotation=90 conName.pos = posboundingrectangle + [0,0,27] --we add a mesh select modifier to make the text more readable but make it (of course) unrenderable addModifier conName (meshSelect()) conName.renderable = false; conName.parent = getNodeByName Nameofctrlsys posbrows = [-55,0,40] posbrowemotion = [-43,0,40] posbrowsqueeze = [-35,0,40] poseyelids = [-27,0,40] poseyelidsasym = [-27,0,33] poseyes = [-12,0,40] posbrowvolume = [-4,0,40] posupperboundingrectangle = [-32,0,40] --LowerFace Control positions possync = [-55,0,22]; poslrmouth = [-55,0,18]; posuprlip = [-55 ,0,8]; poslwrlip = [-40 ,0,8]; posjaw = [-43,0,21]; poslwrlip = [-43,0,8]; posmouthemotion = [-27 ,0,8]; posjawinout = [-35, 0, 20]; possneer = [-27,0,20]; postonque = [-12,0,20]; pos2tonque = [-12,0,8]; posmouthvolume = [-4, 0, 15]; poslowerboundingrectangle = [-32,0 ,15]; upperboundarrectangle = "UpperFace" + NameOfControlSystem; createboundrec upperboundarrectangle Nameofctrlsys 60 20 posupperboundingrectangle; --UpperFaceControls --Create unique names based on name of master ctrl brows = "Brows" + NameOfControlSystem BrowEmotion = "BrowEmotion" + NameOfControlSystem BS = "BS" + NameOfControlSystem Eyelids = "Eyelids" + NameOfControlSystem assym = "assym" + NameOfControlSystem Eyes = "Eyes" + NameOfControlSystem Browvol = "Browvol" + NameOfControlSystem --create the control boxes with these names and positions. -- --The ctrls are given names which will be referenced later when we hook them up to the morph targets. facialControl "Brows" brows upperboundarrectangle posbrows; facialControltypeD "BrowEmotion" BrowEmotion upperboundarrectangle posbrowemotion; facialControltypeA "BS" BS upperboundarrectangle posbrowsqueeze ; facialControl "Eyelids" Eyelids upperboundarrectangle poseyelids; facialControltypeB "assym" assym upperboundarrectangle poseyelidsasym; facialControl "Eyes" Eyes upperboundarrectangle poseyes; facialControltypeA "Browvol" Browvol upperboundarrectangle posbrowvolume ; lowerboundarrectangle = "LowerFace" + NameOfControlSystem; createboundrec lowerboundarrectangle Nameofctrlsys 60 27 poslowerboundingrectangle; --LowerFacecontrols --create another set of unique names for lower facial controls Sync = "Sync" + NameOfControlSystem LRMouth = "LRMouth" + NameOfControlSystem UprLip = "UprLip" + NameOfControlSystem Jaw = "Jaw" + NameOfControlSystem LwrLip = "LwrLip" + NameOfControlSystem Jawinout = "Jawinout" + NameOfControlSystem MouthEmotion = "MouthEmotion" + NameOfControlSystem Sneer = "Sneer" + NameOfControlSystem Tonque = "Tonque" + NameOfControlSystem Tonque2 = "Tonque2" + NameOfControlSystem MouthVol = "MouthVol" + NameOfControlSystem --create controls with these names facialControltypeD "Sync" Sync lowerboundarrectangle possync; facialControltypeB "LRMouth" LRMouth lowerboundarrectangle poslrmouth; facialControl "UprLip" UprLip lowerboundarrectangle posuprlip; facialControl "Jaw" Jaw lowerboundarrectangle posjaw; facialControl "LwrLip" LwrLip lowerboundarrectangle poslwrlip; facialControltypeA "Jawinout" Jawinout lowerboundarrectangle posjawinout ; facialControl "MouthEmotion" MouthEmotion lowerboundarrectangle posmouthemotion ; facialControltypeD "Sneer" Sneer lowerboundarrectangle possneer ; facialControltypeD "Tonque" Tonque lowerboundarrectangle postonque; facialControl "Tonque2" Tonque2 lowerboundarrectangle pos2tonque; facialControltypeA "MouthVol" MouthVol lowerboundarrectangle posmouthvolume; --Having completed the interface, we hook it up using the 'connectmorphs' class of functions already defined , --which take as many arguments as required to reference all the morph targets and meshes involved in the hook-up. --First, we name the Lower face controls..... --sync setup synctrl = "Sync" + NameOfControlSystem --As mouth emotion also uses lSmile and rSmile, --we can either add extra controllers or simply copy the morphs into seperate channels called 'lWide' and 'rWide'. --This is the option taken here. --we use the connectmorphs function to hook up the spline controller with the morphs with reaction manager... connectmorphsync "rNarrow" "lNarrow" "rWide" "lWide" synctrl --LRMouth lrmouthctrl = "LRMouth" + NameOfControlSystem connectmorphstypeBlrmouth "rMouth" "lMouth" lrmouthctrl -- Jaw setup. Here we must first create morphs for the teeth - teethOpen, lTeeth, rTeeth, -- as this control will call them in -- For these teeth shapes and the jaw, first create shapes using bones, then bake into mesh. --within the connectmorphsjaw function, we add an argument that calls in the extra mesh we are working on --(in this case, teeth-('teethup')), so that we don't have any conflicts of undefined variables, --and so that the other meshes can be referenced from within the function. --For convenience, we have created a specialized connectmorphs type function with arguments that involve all the morphs --and their corresponding meshes, called 'poly' and 'poly2',. which in this case are 'teethup' and 'headsup' respectively. --All these are both controlled by the same jawctrl spline. jawctrl ="Jaw" + NameOfControlSystem -- jawctrlmesh = execute("$"+jawctrl) -- jawctrl2 = copy jawctrlmesh -- jawctrl2.parent = jawctrlmesh -- jawctrlteeth= jawctrl2.namef --headsup = execute("$"+NameOfControlSystem) connectmorphsjaw "rTeeth" "lTeeth" "teethOpen" teethup "rJaw" "lJaw" "open" headsup jawctrl --sneerctrl setup global Sneerctrl = "Sneer" + NameOfControlSystem --global just in case another part of the code can't access it. Probably unnecessary, but included here as I had trouble once. --The only problem is a possible name conflict with another script running in the max scene, but that is very unlikely, as we make sure the name is unique --and based on the name of the control system, which in turn is based on the name of head mesh. connectmorphsneer "rSneer" "lSneer" Sneerctrl -- uprlipctrlsetup global uprLipctrl = "UprLip" + NameOfControlSystem connectmorphs2 "rUprLipUp" "lUprLipUp" "rUprLipDn" "lUprLipDn" uprLipctrl --lwrLipctrl setup global LwrLipctrl = "LwrLip" + NameOfControlSystem; connectmorphs2 "rLwrLipUp" "lLwrLipUp" "rLwrLipDn" "lLwrLipDn" LwrLipctrl -- jawinout setup.Note jaw in is negative of jaw out. --We disable the 'use limits' feature of the morpher in order to utilize this. --as we must also move teeth, we have two extra arguments:one for the teethmorph, another for teeth mesh. --These then can be referenced from within the function. Jawinoutctrl = "JawInOut" + NameOfControlSystem; teethup = getNodeByName Teeth connectmorphtypeAjaw "jawFwd" "teethFwd" teethup Jawinoutctrl --MouthEmotion setup mouthemotionctrl = "MouthEmotion" + NameOfControlSystem connectmorphs2 "rSmile" "lSmile" "rFrown" "lFrown" mouthemotionctrl --Tonque setup(1Tonque) tonquectrl = "Tonque" + NameOfControlSystem Tonquemes = getNodeByName Tonquel select Tonquemes connectmorphstypeE "tonqueOut" "tonqueUp" Tonquemes tonquectrl ; --Tonque setup(Tonque2) --'tonque tip down' is the inverse of 'tonque tip up', --so we disable 'use limits' on the tonque mesh morpher and make tonqueTipUp -100 % when we want tonquetipDn. tonque2ctrl = "Tonque2" + NameOfControlSystem connectmorphstonque2 "lTonque" "rTonque" "tonqueTipUp" tonque2ctrl mouthvolctrl = "MouthVol" + NameOfControlSystem connectmouthvol mouthvolctrl select headsup --Moving now to the Upper face control linkages... browctrl = "Brows" + NameOfControlSystem connectmorphs2 "rBrowOutUp" "lBrowOutUp" "rBrowOutDn" "lBrowOutDn" browctrl; browemotionctrl = "BrowEmotion" + NameOfControlSystem connectmorphsbrowemotion "browsMidUp" "browsMidDn" "browsSqueeze" browemotionctrl; browsqueezectrl = "BS" + NameOfControlSystem connectmorphtypeAbrowSqueeze "browsSqueeze" browsqueezectrl --The eyelids present a special case, as the controllers that are controlled by the spline ctrl here are actually rotating eyelid bones. --The necessary float controllers should have been placed there already using the eyerig script. eyelidsctrl = "Eyelids" + NameOfControlSystem --the arguments of the eyelidsconnect function are as set out below. --We need to supply values in degrees for the various states of the eyelid bones : open, closed, and default. --Note the angles corresponding to the eyelid positions: these relate to how far the eyelids must travel to close and fully open, and will vary from mesh to mesh. --connecteyelids upperopenwide upperclosed lowerup lowerdown rsquint lsquint eyelidsctrl connecteyelids 15 -30 20 -10 "rSquint" "lSquint" eyelidsctrl --The assym control simply uses a paramwire set-up to alter the reaction weights as needed from side to side. --It is also hooked up to some second float controllers on the squint morphs. assymctrl = "assym" + NameOfControlSystem connectassym assymctrl --connecting the eyes using straight- forward param wire adds another ctrler for the outer eye ctrl spline as well as being able to move the ctler itself... global eyesctrl = "Eyes" + NameOfControlSystem connecteyes eyesctrl eyectrlouter --Finally we connect the brow volume ctrl, which will control the weights on each upperface morph channel. browvolctrl = "Browvol" + NameOfControlSystem connectbrowvol browvolctrl --Having hooked everything up, we can now place custom attribute parameter holders on the outer rectangles in order to store poses.... mainbar = getNodeByName Nameofctrlsys lipsyncbar = getNodeByName lowerboundarrectangle upperfacebar = getNodeByName upperboundarrectangle select mainbar resize = size.value mainbar.scale = [resize,resize,resize] --Now we are in a position to place custom attributes onto the control splines to provide added functionality for the animators. --There is no need to provide UI items such as spinners or sliders for them, as they are used simply to store poses with. --We can then nest them, so that the inner splines ctrl limited sets of ctrl nodes, with the outer ones controlling more. --So that we can set up presets for a few inner ones, then when these are setup, we are able to group these --using the outer ones. -- However we first have to rename the pen attribute holder to 'PEN_Attribute_holder_2' in the startup folder file, as spaces are not allowed. --First we add a PEN attribute holder to the outside spline we wish to hold presets on. --REMEMBER, IN ORDER TO SET THE DEFAULT POSITION OF ALL THE CTRLS, SO THAT 'RESET' WILL FUNCTION AS EXPECTED, --SET A KEY (ON THE MAINBAR SPLINE), ON THE START-UP POSITIONS AT THE BEGINNING OF THE ANIMATION SESSION, AND SAVE IT AS A CPS FILE (CHARACTER PRESETS STORE). --THEN WHEN YOU WISH TO ZERO EVERYTHING OUT AS IT WAS ON CREATION OF THE UI, SELECT MAINBAR SPLINE AND LOAD PRESET. THIS IS BECAUSE PRESSING 'RESET 'ON THE PEN --ATTRIBUTE HOLDER, ONLY RETURNS CTRLS TO NUMERICAL DEFAULT. addmodifier mainbar (PEN_Attribute_holder_2()) addmodifier lipsyncbar (PEN_Attribute_holder_2()) addmodifier upperfacebar (PEN_Attribute_holder_2()) attdef = attributes facialctrl ( parameters face ( uprLipX type:#float; uprLipY type:#float; lwrLipX type:#float; lwrLipY type:#float; syncX type:#float; syncY type:#float; jawX type:#float; jawY type:#float; mouthEmotionX type:#float; mouthEmotionY type:#float; Tonque2X type:#float; Tonque2Y type:#float; TonqueX type:#float; TonqueY type:#float; SneerX type:#float; SneerY type:#float; BrowsX type:#float; BrowsY type:#float; BrowEmotionX type:#float; BrowEmotionY type:#float; BrowSqueezeY type:#float; EyelidsX type:#float; EyelidsY type:#float; EyesX type:#float; EyesY type:#float; LRMouthX type:#float; jawInOutY type:#float; MouthVolY type:#float; BrowsVolY type:#float; assymX type:#float; ) ) custAttributes.add mainbar.modifiers[1] attdef attdeflipsync = attributes facialctrlipsync ( parameters facemouth ( uprLipX type:#float; uprLipY type:#float; lwrLipX type:#float; lwrLipY type:#float; syncX type:#float; syncY type:#float; jawX type:#float; jawY type:#float; mouthEmotionX type:#float; mouthEmotionY type:#float; Tonque2X type:#float; Tonque2Y type:#float; TonqueX type:#float; TonqueY type:#float; SneerX type:#float; SneerY type:#float; LRMouthX type:#float; jawInOutY type:#float; MouthVolY type:#float; ) ) custAttributes.add lipsyncbar.modifiers[1] attdeflipsync attdefupperface = attributes facialctrlupperface ( parameters faceupperface ( BrowsX type:#float; BrowsY type:#float; BrowEmotionX type:#float; BrowEmotionY type:#float; EyelidsX type:#float; EyelidsY type:#float; EyesX type:#float; EyesY type:#float; BrowSqueezeY type:#float; BrowsVolY type:#float; assymX type:#float; ) ) custAttributes.add upperfacebar.modifiers[1] attdefupperface --now we instance the spline controllers to the custom attributes we just defined --in order to utilize the presets available with the pen attribute holder. --first we create an array contaiong all the circle controls so we can easily reference them by index... CircleControls= #(uprLipctrl,LwrLipctrl ,synctrl,jawctrl,mouthemotionctrl,tonque2ctrl,tonquectrl,Sneerctrl,browctrl,browemotionctrl,lrmouthctrl,Jawinoutctrl,eyelidsctrl,assymctrl,eyesctrl,MouthVolY,BrowsVolY ) --we now build the functions that will do the work of instancing the spline controllers to the bounding rectangles which have the pen modifier on them... Circlectrlcount = CircleControls.count --gives the number in the array - saves us counting them and maybe making a mistake(17,anyway) --the function instancecontrollers takes three parameters - --the circectrl itself, the spline we want to store the custom attribute parametrs on, and the index of the specific parameter we have already placed on the spline in the steps above. fn instancecontrollers circlectrl outerspline index = ( splinectrl = getNodeByName circlectrl p = 2*index-1 xctrl = outerspline.modifiers[1] .custAttributes[1][p] yctrl = outerspline.modifiers[1] .custAttributes[1][p+1] xctrl.controller = splinectrl.pos.controller.X_Position.controller; splinectrl.pos.controller.X_Position.controller = xctrl.controller ; yctrl.controller = splinectrl.pos.controller.Y_Position.controller; splinectrl.pos.controller.Y_Position.controller = yctrl.controller ; ) fn instancecontrollersX circlectrl outerspline index =( splinectrl = getNodeByName circlectrl xctrl = outerspline.modifiers[1] .custAttributes[1][index] xctrl.controller = splinectrl.pos.controller.X_Position.controller; splinectrl.pos.controller.X_Position.controller = xctrl.controller ; ) fn instancecontrollersY circlectrl outerspline index =( splinectrl = getNodeByName circlectrl yctrl = outerspline.modifiers[1] .custAttributes[1][index] yctrl.controller = splinectrl.pos.controller.Y_Position.controller; splinectrl.pos.controller.Y_Position.controller = yctrl.controller ; ) --we can now instance all the controllers on the mainbar, first... for i = 1 to 10 do( instancecontrollers CircleControls[i] mainbar i ) -- instancecontrollersX lrmouthctrl mainbar 26 instancecontrollersY Jawinoutctrl mainbar 27 instancecontrollersY browsqueezectrl mainbar 21 instancecontrollers eyelidsctrl mainbar 12 -- instancecontrollers eyesctrl mainbar 14 instancecontrollersY mouthvolctrl mainbar 28 instancecontrollersY browvolctrl mainbar 29 -- --assymctrl is a special case, as it has a second pos controller ('Tracking') ,which we have to navigate to.. splinectrlass = getNodeByName assymctrl xctrl = mainbar.modifiers[1] .custAttributes[1][30] xctrl.controller = splinectrlass.pos.controller[2][1].X_Position.controller; splinectrlass.pos.controller[2][1].X_Position.controller = xctrl.controller ; -- --then the lipsync bar... for i = 1 to 8 do ( instancecontrollers CircleControls[i] lipsyncbar i ) instancecontrollersX lrmouthctrl lipsyncbar 17 instancecontrollersY Jawinoutctrl lipsyncbar 18 instancecontrollersY mouthvolctrl lipsyncbar 19 -- --and finally the upperface bar... for i = 1 to 2 do( p = i+8 instancecontrollers CircleControls[p] upperfacebar i ) instancecontrollers eyelidsctrl upperfacebar 3 instancecontrollers eyesctrl upperfacebar 4 instancecontrollersY browsqueezectrl upperfacebar 9 instancecontrollersY browvolctrl upperfacebar 10 -- instancecontrollersX assymctrl upperfacebar 11 --assymctrl is a special case, as it has a second pos controller ('Tracking'), which we have to navigate to.. splinectrlass = getNodeByName assymctrl xctrl = upperfacebar.modifiers[1] .custAttributes[1][11] xctrl.controller = splinectrlass.pos.controller[2][1].X_Position.controller; splinectrlass.pos.controller[2][1].X_Position.controller = xctrl.controller ; --below are a couple of possibly useful methods...but we don't really need them here --Parameterlist = for i=1 to 20 collect (mainbar.modifiers[1] .custAttributes[1][i] ) --indexprime = findItem lCircleControls LwrLipctrl --We can use the 'showProperties' method to access the proeprties of the attribute holder if we wish. --showProperties $.modifiers[1] --$.modifiers[1].presetName_str fn connectmorphemote UprLeftMorph UprRightMorph LowerLeftMorph LowerRightMorph ctrlhandle = ( -- first we locate each required morph channel and find its position in the morpher stack, --using the function defined below, 'getmorphchannelnumber'. upl = getmorphchannelnumber UprLeftMorph; upr = getmorphchannelnumber UprRightMorph; lol = getmorphchannelnumber LowerLeftMorph; lor = getmorphchannelnumber LowerRightMorph; -- Next assign extra bezier float controllers for each of these morph channels... -- p = float_list() $.Morpher[upl].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[upr].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lol].controller = p p1= bezier_float() p.available.controller = p1 p = float_list() $.Morpher[lor].controller = p p1= bezier_float() p.available.controller = p1 --Then declare that which is to be controlled... morph1= $.Morpher[upl].controller[1].controller = Float_Reactor() morph2= $.Morpher[upr].controller[1].controller = Float_Reactor() morph3= $.Morpher[lol].controller[1].controller = Float_Reactor() morph4= $.Morpher[lor].controller[1].controller = Float_Reactor() --also place float reactor controllers on the extra (second list controller) corrective morph tracks... morph11 = $.Morpher[upl].controller[2].controller = Float_Reactor() morph21=$.Morpher[upr].controller[2].controller = Float_Reactor() morph31= $.Morpher[lol].controller[2].controller = Float_Reactor() morph41=$.Morpher[lor].controller[2].controller = Float_Reactor() --then the thing which is to be the controller.. controlspline =getNodeByName ctrlhandle cont =controlspline.pos.controller --store original position of controller... p1= controlspline.pos[1] p2 = controlspline.pos[2] p3 = controlspline.pos[3] controlspline.pos = [p1,p2,p3] --set up all the reactions reactTo morph1 cont reactTo morph2 cont reactTo morph3 cont reactTo morph4 cont reactTo morph11 cont reactTo morph21 cont reactTo morph31 cont reactTo morph41 cont --this automatically sets initial states and zeroes out all values as well... --but let's make sure anyway by setting them directly... setReactionState morph1 1 0; --createReaction morph2; setReactionState morph2 1 0; --createReaction morph3; setReactionState morph3 1 0; --createReaction morph4; setReactionState morph4 1 0; setReactionState morph11 1 0; --createReaction morph21; setReactionState morph21 1 0; --createReaction morph31; setReactionState morph31 1 0; --createReaction morph41; setReactionState morph41 1 0; --we move the controller to new position (5 units up in middle) p3up = p3 + 3; --(offset by six to ensure it hits limits of control spline) controlspline.pos = [p1,p2,p3up] --now that we have the controlhandle repositioned, we can set a state for the up morph value( 2, value 100%) -- "setReactionState" index is incremented for each new set of states set --sets upper lip up morphs to 100%, upper lip down morphs to zero% --note we increment the setReactionState index to 2 now to reflect a new state of controller... createReaction morph1; setReactionState morph1 2 100; createReaction morph2; setReactionState morph2 2 100; createReaction morph3; setReactionState morph3 2 0; createReaction morph4; setReactionState morph4 2 0; createReaction morph11; setReactionState morph11 2 0; createReaction morph21; setReactionState morph21 2 0; createReaction morph31; setReactionState morph31 2 0; createReaction morph41; setReactionState morph41 2 0 ; --now for the reactions when controller is at bottom middle... p3dn = p3 - 3 ; --offset by six to ensure it hits limits of control spline controlspline.pos = [p1,p2,p3dn]; --we increment the setReactionState index to 3 now to reflect new state of controller... createReaction morph1; setReactionState morph1 3 0; createReaction morph2; setReactionState morph2 3 0; createReaction morph3; setReactionState morph3 3 100; createReaction morph4; setReactionState morph4 3 100; --sets upper lip down morphs to 100% and upper lip up morphs to zero% createReaction morph11; setReactionState morph11 3 0; createReaction morph21; setReactionState morph21 3 0; createReaction morph31; setReactionState morph31 3 0; createReaction morph41; setReactionState morph41 3 0; --Now to set the x position reactions starting with exteme upper left... pleft = p1 - 6; --offset by 6 to make sure it hits limits of controller spline ... controlspline.pos = [pleft,p2,p3up]; --create reactions for each...we want the two left corrective morph tracks to be at -100% --note that this leaves only morph1 with a value of 100%. createReaction morph11; setReactionState morph11 4 0; createReaction morph21; setReactionState morph21 4 -100; createReaction morph31; setReactionState morph31 4 0; createReaction morph41; setReactionState morph41 4 -100; createReaction morph1; setReactionState morph1 4 100; createReaction morph2; setReactionState morph2 4 100; createReaction morph3; setReactionState morph3 4 0; createReaction morph4; setReactionState morph4 4 100; --now move to extreme upper right and set reactions... --we want the two right morphs corrective tracks values to be set at -100%, --so that the two right morphs (right from pov of mesh) both become zero. pright = p1 + 6; --offset by six to ensure it hits limits of controller spline ... controlspline.pos = [pright,p2,p3up]; createReaction morph11; setReactionState morph11 5 -100; createReaction morph21; setReactionState morph21 5 0; createReaction morph31; setReactionState morph31 5 -100; createReaction morph41; setReactionState morph41 5 0; createReaction morph1; setReactionState morph1 5 100; createReaction morph2; setReactionState morph2 5 100; createReaction morph3; setReactionState morph3 5 100; createReaction morph4; setReactionState morph4 5 0; --now move to extreme lower left and set up reactions... --after you add up all the morph values, we are left with only morph3 having 100% controlspline.pos = [pleft,p2,p3dn]; createReaction morph11; setReactionState morph11 6 0; createReaction morph21; setReactionState morph21 6 -100; createReaction morph31; setReactionState morph31 6 0; createReaction morph41; setReactionState morph41 6 -100; createReaction morph1; setReactionState morph1 6 0; createReaction morph2; setReactionState morph2 6 100; createReaction morph3; setReactionState morph3 6 100; createReaction morph4; setReactionState morph4 6 100; --finally move to extreme lower right and set up reactions... --after you add up all the morph values, we are left with only morph4 having 100% controlspline.pos = [pright,p2,p3dn]; createReaction morph11; setReactionState morph11 7 -100; createReaction morph21; setReactionState morph21 7 0; createReaction morph31; setReactionState morph31 7 -100; createReaction morph41; setReactionState morph41 7 0; createReaction morph1; setReactionState morph1 7 100; createReaction morph2; setReactionState morph2 7 0; createReaction morph3; setReactionState morph3 7 100; createReaction morph4; setReactionState morph4 7 100; --to make things react more smoothly, we need two more controller locations and corresponding set of reactions.. --first, midway down extreme left... --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pleft,p2,p3]; createReaction morph11; setReactionState morph11 8 0; createReaction morph21; setReactionState morph21 8 -100; createReaction morph31; setReactionState morph31 8 0; createReaction morph41; setReactionState morph41 8 -100; createReaction morph1; setReactionState morph1 8 0; createReaction morph2; setReactionState morph2 8 100; createReaction morph3; setReactionState morph3 8 0; createReaction morph4; setReactionState morph4 8 100; --and then midway down extreme right... --..as before, we want to make all right morphs zero by adding -100%.. --as can be seen if the morph values are added, this in effect sets all morphs to zero controlspline.pos = [pright,p2,p3]; createReaction morph11; setReactionState morph11 9 -100; createReaction morph21; setReactionState morph21 9 0; createReaction morph31; setReactionState morph31 9 -100; createReaction morph41; setReactionState morph41 9 0; createReaction morph1; setReactionState morph1 9 100; createReaction morph2; setReactionState morph2 9 0; createReaction morph3; setReactionState morph3 9 100; createReaction morph4; setReactionState morph4 9 0; --now restore controller to original position.. controlspline.pos = [p1,p2,p3]; --The function below searches for each required morph and returns its position in the morpher stack, --reporting if any have not been found. fn getmorphchannelnumberpoly poly Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName poly.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName poly.morpher 1 != Morphname) and i == 50 then (print (Morphname + " not found")) ) ) fn getmorphchannelnumber Morphname = ( for i = 1 to 100 do ( if (WM3_MC_GetName $.Morpher i == Morphname ) then (return i ) else if (WM3_MC_GetName $.morpher 1 != Morphname) and i == 50 then (print (Morphname + " not found")) ) ) ) ) ) createDialog myrollout 220 400-- set as a dialogue instead of a rollout