580 lines
20 KiB
Plaintext
Executable File
580 lines
20 KiB
Plaintext
Executable File
--tool to query animations and then generate face fx 1d sliders
|
|
|
|
|
|
-- Load the common maxscript functions
|
|
--include "rockstar/export/settings.ms" -- This is SLOW!
|
|
filein "rockstar/export/settings.ms" -- This is fast
|
|
|
|
-- Figure out the project
|
|
theProjectRoot = RsConfigGetProjRootDir()
|
|
theProject = RSConfigGetProjectName()
|
|
theWildWest = RsConfigGetWildWestDir()
|
|
theProjectConfig = RsConfigGetProjBinConfigDir()
|
|
|
|
|
|
-- Load common functions
|
|
filein (theWildWest + "script/max/Rockstar_North/character/includes/FN_common.ms")
|
|
filein (theWildWest + "script/max/Rockstar_North/character/includes/FN_bone_tagger.ms")
|
|
filein (theWildWest + "script/max/Rockstar_North/character/includes/FN_Rigging.ms")
|
|
-- filein (theProjectRoot + "tools/dcc/current/max2010/scripts/pipeline/util/xml.ms")
|
|
|
|
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
facialBoneArray = #(
|
|
"FB_L_Brow_Out",
|
|
"FB_Brow_Centre",
|
|
"FB_L_Lid_Upper",
|
|
"FB_L_Eye",
|
|
"FB_L_CheekBone",
|
|
"FB_UpperLipRoot",
|
|
"FB_UpperLip",
|
|
"FB_L_Lip_Top",
|
|
"FB_R_Lip_Top",
|
|
"FB_L_Lip_Corner",
|
|
"FB_Jaw",
|
|
"FB_LowerLipRoot",
|
|
"FB_LowerLip",
|
|
"FB_L_Lip_Bot",
|
|
"FB_R_Lip_Bot",
|
|
"FB_Tongue",
|
|
"FB_R_Lid_Upper",
|
|
"FB_R_Eye",
|
|
"FB_R_CheekBone",
|
|
"FB_R_Brow_Out",
|
|
"FB_R_Lip_Corner"
|
|
)
|
|
|
|
|
|
ambientArray = #( --array of ambient joysticks
|
|
"Tongue",
|
|
"L_Blink",
|
|
"LookAT_Activator",
|
|
"L_Cheek",
|
|
"LowerLip",
|
|
"UpperLip_Curl",
|
|
"LowerLip_Curl",
|
|
"UpperLip",
|
|
"L_Mouth",
|
|
"Jaw",
|
|
"Mouth",
|
|
"R_Eye",
|
|
"L_Eye",
|
|
"R_Mouth",
|
|
"C_Brow",
|
|
"Tongue_In_Out",
|
|
"R_Cheek",
|
|
"R_Brow",
|
|
"L_Brow",
|
|
"R_Blink"
|
|
)
|
|
|
|
poseArray= #( --facefx 1d slider joystick Name and frame at which pose is derived and position for joystick
|
|
-- #("Neutral", 0, [0.0,0,0]),
|
|
#("open", 10, [0.1,0,0]),
|
|
#("W", 20, [0.2,0,0]),
|
|
#("ShCh", 30, [0.3,0,0]),
|
|
#("PBM", 40, [0.4,0,0]),
|
|
#("FV", 50, [0.5,0,0]),
|
|
#("wide", 60, [0.6,0,0]),
|
|
#("tBack", 70, [0.7,0,0]),
|
|
#("tTeeth", 80, [0.8,0,0]),
|
|
#("tRoof", 90, [0.9,0,0]),
|
|
#("Blink_Left", 100, [0,0,-0.2]),
|
|
#("Blink_Right", 110, [0.1,0,-0.3]),
|
|
#("Eyebrow_Raise_Left", 120, [0.2,0,-0.2]),
|
|
#("Eyebrow_Raise_Right", 130, [0.3,0,-0.3]),
|
|
#("Squint_Left", 140, [0.4,0,-0.2]),
|
|
#("Squint_Right", 150, [0.5,0,-0.3]),
|
|
|
|
-- #("Head_Pitch_Pos", 200),
|
|
-- #("Head_Yaw_Pos", 210),
|
|
-- #("Head_Roll_Pos", 220),
|
|
-- #("LeftEye_Pitch_Pos", 230, [0.6,0,-0.2]),
|
|
-- #("LeftEye_Yaw_Pos", 240, [0.7,0,-0.3]),
|
|
-- #("RightEye_Pitch_Pos", 250, [0.8,0,-0.2]),
|
|
-- #("RightEye_Yaw_Pos", 260, [0.9,0,-0.3]),
|
|
|
|
-- // Negative Rotations below
|
|
-- #("Head_Pitch_Neg", 270),
|
|
-- #("Head_Yaw_Neg", 280),
|
|
-- #("Head_Roll_Neg", 290),
|
|
-- #("LeftEye_Pitch_Neg", 300, [0.0,0,-0.4]),
|
|
-- #("LeftEye_Yaw_Neg", 310, [0.1,0,-0.5]),
|
|
-- #("RightEye_Pitch_Neg", 320, [0.2,0,-0.4]),
|
|
-- #("RightEye_Yaw_Neg", 330, [0.3,0,-0.5]),
|
|
|
|
-- #("AU1-Inner_Brow_Raiser_Left", 400, [0.4,0,-0.4]),
|
|
-- #("AU1-Inner_Brow_Raiser_Right", 410, [0.5,0,-0.5]),
|
|
-- #("AU2-Outer_Brow_Raiser_Left", 420, [0.6,0,-0.4]),
|
|
-- #("AU2-Outer_Brow_Raiser_Right", 430, [0.7,0,-0.5]),
|
|
-- #("AU4-Brow_Lowerer", 440, [0.8,0,-0.4]),
|
|
-- #("AU10-Upper_Lip_Raiser", 450, [0.9,0,-0.5]),
|
|
-- #("AU15-Lip_Corner_Depressor_Left", 460, [0,0,-0.6]),
|
|
-- #("AU15-Lip_Corner_Depressor_Right", 470, [0.1,0,-0.7]),
|
|
-- #("AU16-Lower_Lip_Depressor", 480, [0.2,0,-0.6]),
|
|
-- #("AU20-Lip_Stretcher", 490, [0.3,0,-0.7]),
|
|
-- #("AU23-Lip_Tightener", 500, [0.4,0,-0.6]),
|
|
-- #("AU26-Jaw_Drop", 510, [0.5,0,-0.7]),
|
|
-- #("AU29-Jaw_Sideways", 530, [0.6,0,-0.6]),
|
|
|
|
#("Cheek_Up_Left", 600, [0.7,0,-0.7]),
|
|
#("Cheek_Up_Right", 610, [0.8,0,-0.6]),
|
|
#("Snarl_Left", 620, [0.9,0,-0.7]),
|
|
#("Snarl_Right", 630, [0,0,-0.8])
|
|
)
|
|
|
|
dupJoystickArray = #( --array of ambient joysticks which we need to disconnect after facefx joystick creation
|
|
-- "Tongue",
|
|
"L_Blink",
|
|
-- "LookAT_Activator",
|
|
-- "L_Cheek",
|
|
-- "LowerLip",
|
|
-- "UpperLip_Curl",
|
|
-- "LowerLip_Curl",
|
|
-- "UpperLip",
|
|
-- "L_Mouth",
|
|
-- "Jaw",
|
|
-- "Mouth",
|
|
-- "R_Eye",
|
|
-- "L_Eye",
|
|
-- "R_Mouth",
|
|
-- "C_Brow",
|
|
-- "Tongue_In_Out",
|
|
-- "R_Cheek",
|
|
-- "R_Brow",
|
|
-- "L_Brow",
|
|
"R_Blink"
|
|
|
|
)
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
fn disconnectAmbientExpr joystickName = --this will disconnect expressions for specified joystickName
|
|
(
|
|
-- for o in objects do
|
|
for o in objects do
|
|
(
|
|
if (substring o.name 1 3 ) == "FB_" do
|
|
(
|
|
if classOf o.position.controller == position_list do
|
|
(
|
|
for p = 1 to o.position.controller.count do
|
|
(
|
|
if o.position.controller[p].name == joystickName do
|
|
(
|
|
o.position.controller.delete p
|
|
print ("Disconnected "+joystickName+" position from "+o.name)
|
|
)
|
|
)
|
|
)
|
|
|
|
if classOf o.rotation.controller == rotation_list do
|
|
(
|
|
for r = 1 to o.rotation.controller.count do
|
|
(
|
|
if o.rotation.controller[r].name == joystickName do
|
|
(
|
|
o.rotation.controller.delete r
|
|
print ("Disconnected "+joystickName+" rotation from "+o.name)
|
|
)
|
|
)
|
|
)
|
|
|
|
if classOf o.scale.controller == scale_list do
|
|
(
|
|
for s = 1 to o.scale.controller.count do
|
|
(
|
|
if o.scale.controller[s].name == joystickName do
|
|
(
|
|
o.scale.controller.delete s
|
|
print ("Disconnected "+joystickName+" scale from "+o.name)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
fn create1DSlider sliderCount mySliderName sliderPos =
|
|
(
|
|
-- call the joystick creation function with the UI data
|
|
jstemp = mySliderName as string
|
|
-- jstemp = edtSliderName.text as string
|
|
jsname = replacespace jstemp
|
|
jstyle = 2
|
|
jpos = sliderPos -- the default position on screen. This can overridden later, perhaps by mouse click.
|
|
|
|
-- Create a joystick slider and select it
|
|
|
|
seljoy = createJoystick ("FFX_CTRL_"+jsname) jstyle jpos 1 -- This can also be copied and pasted to a script to auto build a controller
|
|
|
|
)
|
|
|
|
|
|
fn create1DExpr facialBone contType fbAxis poseName ambientName scalarNames scalarTargets jsMultiplier scalarToChangeIndex theexpr =
|
|
(
|
|
if contType == "Position" then
|
|
(
|
|
contTypeB = "Position"
|
|
)
|
|
else
|
|
(
|
|
contTypeB = "Euler"
|
|
)
|
|
|
|
ambientJoystickName = (substring ambientName 6 30 )
|
|
--first off add a new controller to the face bone and name it to match the pose
|
|
contCount = ("$"+facialBone.name+"."+contType+".controller.count" )
|
|
contCount = execute contCount
|
|
-- print ("contCount = "+(contCount as string))
|
|
|
|
newCont = ("$"+facialBone.name+"."+contType+".Available.controller = "+contTypeB+"_XYZ ()")
|
|
newCnt = execute newCont
|
|
|
|
newControllerNameStr = ("FFX_"+poseName+"_"+ambientName)
|
|
|
|
newCont = ("$"+facialBone.name+"."+contType+".controller"+".setName "+((contCount + 1) as string)+" "+"\""+newControllerNameStr +"\"")
|
|
|
|
newCont = execute newCont
|
|
|
|
--now we can add a float expression to the relevant controller axis
|
|
|
|
fcStr = ( "$"+facialBone.name+"."+contType+".controller."+newControllerNameStr+"."+fbAxis+"_"+contType+".controller = Float_Expression() ")
|
|
newFcStr = execute fcStr
|
|
|
|
|
|
--now we can start to edit that expression
|
|
|
|
--first need to find the original driving scalar and then swap that to be the faceFX joystick with its multiplier
|
|
originalScalarName = undefined
|
|
replaceMentScalarName = undefined
|
|
|
|
for i = 1 to scalarNames.count do --this should loop through the array of scalars and their controllers and create a scalar for each
|
|
(
|
|
if i == scalarToChangeIndex then
|
|
(
|
|
originalScalarName = scalarNames[i]
|
|
replaceMentScalarName =( "("+"("+poseName+" / "+(jsMultiplier as string)+")"+" * 1)")
|
|
|
|
--ok we're going to point this scalar at the Y movement of the appropriate faceFX joystick
|
|
ffxJoystick = getNodeByName ("FFX_CTRL_"+poseName)
|
|
|
|
SVN = poseName --name of the scalar
|
|
|
|
scalContStr = ("$"+ffxJoystick.name+".position.controller.Zero_Pos_XYZ.controller.Y_Position.controller") --actually controller the scale points to
|
|
|
|
scalCont = execute scalContStr
|
|
)
|
|
else
|
|
(
|
|
SVN = scalarNames[i] --name of the scalar
|
|
|
|
scalContStr = (scalarTargets[i] as string) --actually controller the scale points to
|
|
|
|
scalCont = execute scalContStr
|
|
)
|
|
|
|
newfcStr.AddScalarTarget SVN scalCont --add scalar pointing to the controller of the scalar object
|
|
)
|
|
|
|
--now we need to edit 'theexpr' and replace the scalarNames[i] with the new 'scalarNames[i]' plus the jsMultiplier
|
|
--so we need to test the 'theExpr' string and replace originalScalarName with newScalarName
|
|
originalScalarNameLength = originalScalarName.count
|
|
|
|
replaceThisString = theExpr
|
|
for r = 1 to 3 do --need to loop through the expression string 3 times because the original scalar name is in the expression 3 times
|
|
(
|
|
newExprStrStart = findString replaceThisString originalScalarName
|
|
replaceThisString = replace replaceThisString newExprStrStart originalScalarNameLength replaceMentScalarName
|
|
)
|
|
|
|
-- print "--------------------------"
|
|
-- print "--------------------------"
|
|
-- print ("origninal expression:\r\n")
|
|
-- print theExpr
|
|
-- print "--------------------------"
|
|
-- print ("new expression:\r\n")
|
|
-- print replaceThisString
|
|
-- print "--------------------------"
|
|
-- print "--------------------------"
|
|
|
|
newfcStr.SetExpression replaceThisString
|
|
)
|
|
|
|
-- fn readExpression controller joystickAxis facialBone poseName axisUsed transType =
|
|
fn readExpression controller joystickAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier=
|
|
(
|
|
joystickAxis = exprformaxobject joystickAxis
|
|
scalarNames=#()
|
|
scalarTargets=#()
|
|
|
|
-- print ("Controller = "+controller)
|
|
theExprStr = ((controller as string)+".getExpression()")
|
|
|
|
theexpr = execute theExprStr
|
|
|
|
theScalarStr = ((controller as string)+".NumScalars()")
|
|
theScalarCount = execute theScalarStr
|
|
|
|
if theScalarCount != 4 do --need to remember there are always 4 for ticks, frames, secs and normalised-time
|
|
(
|
|
for i = 5 to theScalarCount do
|
|
(
|
|
thisScalarNameStr = ((controller as string)+".GetScalarName "+(i as string))
|
|
thisScalarName = execute thisScalarNameStr
|
|
appendIfUnique scalarNames thisScalarName
|
|
)
|
|
)
|
|
|
|
for i = 1 to scalarNames.count do
|
|
(
|
|
thisScalarTgtStr = ((controller as string)+".GetScalarTarget "+"\""+scalarNames[i]+"\""+" asController:true")
|
|
thisScalarTgt = execute thisScalarTgtStr
|
|
-- print ("Scalar value = "+(thisScalarTgt.value as string))
|
|
|
|
thisScalarTgtCont = exprformaxobject thisScalarTgt
|
|
appendIfUnique scalarTargets (thisScalarTgtCont as string)
|
|
-- print ("appending "+(thisScalarTgtCont as string)+" to controller array...")
|
|
)
|
|
|
|
--now we need to check if any of the scalaras match the joystick axis.
|
|
--if they do then we can do a create expression.
|
|
for i = 1 to scalarTargets.count do
|
|
(
|
|
-- print ("testing "+(scalarTargets[i] as string)+" against "+(joystickAxis as string))
|
|
if scalarTargets[i] == joystickAxis do
|
|
(
|
|
-- print ("WOOHOO "+(scalarTargets[i] as string)+" matched "+(joystickAxis as string)+"!")
|
|
--ok we now know that this jsAxis matches this expression.
|
|
--so we need to tell the expression creator what axis to add a controller to on what bone
|
|
-- print "\r\n"
|
|
-- print ("***************** Running create1dExpr on "+facialBone.name+", faceboneAxis "+fbax+", controller type "+conttype+", for pose "+poseName+" *******************")
|
|
-- print "\r\n"
|
|
|
|
scalarToChangeIndex = i
|
|
|
|
create1DExpr facialBone contType fbAx poseName ambientName scalarNames scalarTargets jsMultiplier scalarToChangeIndex theexpr
|
|
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
|
|
fn passDataToReadExpr ambientName jsAxis boneNumber jsAx poseName jsMultiplier =
|
|
(
|
|
for fb = 1 to facialBoneArray.count do
|
|
(
|
|
facialBone = getNodeByName (facialBoneArray[fb]+boneNumber)
|
|
|
|
posCount = facialBone.position.controller.count
|
|
for cC = 1 to posCount do
|
|
(
|
|
contType = "Position"
|
|
|
|
contName = facialBone.position.controller.getName cC
|
|
if contName == (ambientName) do
|
|
(
|
|
-- print ("found a "+ambientName+" Position controller on "+facialBone.name)
|
|
--ok so now we need to query if the x y or z pos controller are float expressions
|
|
--ok so now we need to query if the x y or z pos controller are float expressions
|
|
if (facialBone.position.controller[cC].X_position.controller as string) == "Controller:Float_Expression" do
|
|
(
|
|
--now we need to query if the jsAxis is the driver in the expression
|
|
-- print ("X ROT was an EXPR")
|
|
controller = ("$"+facialBone.name+".position.controller["+(cC as string)+"].X_position.controller")
|
|
fbAx = "X"
|
|
|
|
readExpression controller jsAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier
|
|
)
|
|
if (facialBone.position.controller[cC].Y_position.controller as string) == "Controller:Float_Expression" do
|
|
(
|
|
-- print ("Y ROT was an EXPR")
|
|
-- controller = facialBone.position.controller[cC].Y_position.controller
|
|
controller = ("$"+facialBone.name+".position.controller["+(cC as string)+"].Y_position.controller")
|
|
fbAx = "Y"
|
|
|
|
readExpression controller jsAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier
|
|
)
|
|
if (facialBone.position.controller[cC].Z_position.controller as string) == "Controller:Float_Expression" do
|
|
(
|
|
-- print ("Z ROT was an EXPR")
|
|
-- controller = facialBone.position.controller[cC].Z_position.controller
|
|
controller = ("$"+facialBone.name+".position.controller["+(cC as string)+"].Z_position.controller")
|
|
fbAx = "Z"
|
|
|
|
readExpression controller jsAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier
|
|
)
|
|
)
|
|
)
|
|
|
|
rotCount = facialBone.rotation.controller.count
|
|
for cC = 1 to rotCount do
|
|
(
|
|
contType = "Rotation"
|
|
|
|
contName = facialBone.rotation.controller.getName cC
|
|
if contName == (ambientName) do
|
|
(
|
|
-- print ("found a "+ambientName+" Rotation controller on "+facialBone.name)
|
|
--ok so now we need to query if the x y or z pos controller are float expressions
|
|
if (facialBone.rotation.controller[cC].X_rotation.controller as string) == "Controller:Float_Expression" do
|
|
(
|
|
--now we need to query if the jsAxis is the driver in the expression
|
|
-- print ("X ROT was an EXPR")
|
|
controller = ("$"+facialBone.name+".rotation.controller["+(cC as string)+"].X_Rotation.controller")
|
|
fbAx = "X"
|
|
|
|
readExpression controller jsAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier
|
|
)
|
|
if (facialBone.rotation.controller[cC].Y_rotation.controller as string) == "Controller:Float_Expression" do
|
|
(
|
|
-- print ("Y ROT was an EXPR")
|
|
-- controller = facialBone.rotation.controller[cC].Y_Rotation.controller
|
|
controller = ("$"+facialBone.name+".rotation.controller["+(cC as string)+"].Y_Rotation.controller")
|
|
fbAx = "Y"
|
|
|
|
readExpression controller jsAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier
|
|
)
|
|
if (facialBone.rotation.controller[cC].Z_rotation.controller as string) == "Controller:Float_Expression" do
|
|
(
|
|
-- print ("Z ROT was an EXPR")
|
|
-- controller = facialBone.rotation.controller[cC].Z_Rotation.controller
|
|
controller = ("$"+facialBone.name+".rotation.controller["+(cC as string)+"].Z_Rotation.controller")
|
|
fbAx = "Z"
|
|
|
|
readExpression controller jsAxis facialBone jsAx fbAx contType poseName ambientName jsMultiplier
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
fn parsePoses boneNumber =
|
|
(
|
|
clearListener()
|
|
|
|
for i = 1 to poseArray.count do
|
|
(
|
|
--first set frame to the 2nd element of this item ie frame number
|
|
poseFrame = posearray[i][2]
|
|
poseName = poseArray[i][1]
|
|
sliderTime = poseFrame
|
|
--now for each joystick query their x and y positions
|
|
|
|
for js = 1 to ambientArray.count do
|
|
(
|
|
thisJoystick = getNodeByName ("CTRL_"+ambientArray[js])
|
|
|
|
jsPos = in coordsys parent thisJoystick.position
|
|
|
|
myX = jsPos[1]
|
|
newX = ( 1 / myX )
|
|
-- jsXMultiplier = myX * newX as integer
|
|
jsXMultiplier = newX as float
|
|
|
|
|
|
myY = jsPos[2]
|
|
newY = ( 1 / myY )
|
|
-- jsYMultiplier = myY * newY as integer
|
|
jsYMultiplier = newY as float
|
|
|
|
|
|
if myX != 0 do
|
|
(
|
|
-- print ("jsXMultiplier ="+(jsXMultiplier as string)+" for "+thisJoystick.name+" with pose "+poseName)
|
|
-- print ("derived by myX ( 1 / "+(myX as string)+")"+" gives "+(jsXMultiplier as string))
|
|
--ok the joystick has moved in the x position
|
|
-- print ("Need to create X expr on "+ambientArray[js]+" for pose "+poseName)
|
|
|
|
jsAxis = thisJoystick.position.controller.zero_pos_xyz.x_position.controller
|
|
jsAx = "X"
|
|
|
|
passDataToReadExpr ambientArray[js] jsAxis boneNumber jsAx poseName jsXMultiplier
|
|
)
|
|
|
|
if myY != 0 do
|
|
(
|
|
-- print ("jsYMultiplier ="+(jsYMultiplier as string)+" for "+thisJoystick.name+" with pose "+poseName)
|
|
-- print ("derived by myY ( 1 / "+(myY as string)+")"+" gives "+(jsYMultiplier as string))
|
|
-- print ("Need to create Y expr on "+ambientArray[js]+" for pose "+poseName)
|
|
|
|
jsAxis = thisJoystick.position.controller.zero_pos_xyz.Y_position.controller
|
|
jsAx = "Y"
|
|
|
|
passDataToReadExpr ambientArray[js] jsAxis boneNumber jsAx poseName jsYMultiplier
|
|
)
|
|
)
|
|
|
|
sliderTime = 0f
|
|
)
|
|
)
|
|
|
|
|
|
fn connect1dToAmbientJoysticks =
|
|
(
|
|
--firstly make the 1d joysticks
|
|
for sl = 1 to poseArray.count do
|
|
-- for sl = 1 to 2 do
|
|
(
|
|
create1DSlider 1 poseArray[sl][1] poseArray[sl][3]
|
|
)
|
|
|
|
--now create the facefx text parent obj
|
|
faceFXText = text size:0.25 kerning:0 leading:0 transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [0.215069,0,-0.0633061]) isSelected:on
|
|
faceFXText.text = "FaceFX"
|
|
faceFXText.render_displayRenderMesh = true
|
|
faceFXText.thickness = 0.01
|
|
faceFXText.sides = 3
|
|
faceFXText.name = "FaceFX"
|
|
in coordsys world faceFXText.pos = [0.45,0,0.1]
|
|
|
|
--now link all the ffx rectangles to the faceFX object
|
|
for o in objects where (substring o.name 1 8) == "FFX_RECT" do
|
|
(
|
|
o.parent = faceFXText
|
|
)
|
|
|
|
faceFXText.scale = [0.3,0.3,0.3]
|
|
in coordsys world faceFXText.pos = [0.5,0.0,1.8]
|
|
|
|
--setup done.
|
|
|
|
--now we need to find all the facial bones in the scene
|
|
faceBoneIterations = #()
|
|
for o in objects do
|
|
(
|
|
if substring o.name 1 8 == "FaceRoot" do
|
|
(
|
|
--ok we've found a faceroot node and therefore a rig so we need to find the number of it
|
|
rigNumber = (substring o.name 14 4)
|
|
appendIfUnique faceBoneIterations rigNumber
|
|
)
|
|
)
|
|
|
|
--start the clever stuff!
|
|
|
|
for fNo = 1 to faceBoneIterations.count do
|
|
(
|
|
--boneNumber is the suffix numbers on the bones
|
|
--thisBoneNumber = "_000"
|
|
thisBoneNumber = faceBoneIterations[fNo]
|
|
parsePoses thisBoneNumber
|
|
)
|
|
)
|
|
|
|
|
|
-- generate1dStruct()
|
|
|
|
clearListener()
|
|
|
|
connect1dToAmbientJoysticks()
|
|
|
|
for i = 1 to dupJoystickArray.count do
|
|
(
|
|
disconnectAmbientExpr dupJoystickArray[i]
|
|
)
|
|
|
|
print ("FaceFx creation complete.")
|
|
-- select $FB_R_Lip_Corner_000 |