Files
gtav-src/tools_ng/wildwest/script/3dsMax/Characters/Rigging/3Lateral/ThreeLateralFacialConnect.ms
T
2025-09-29 00:52:08 +02:00

3905 lines
113 KiB
Plaintext
Executable File

escapeenable = true
-- tool to read in 3Lateral xml files to regenerate facial expressions
--June 11
--Matt Rennie
-- fbx import settings need to be add and units set to cm
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- This line loads the custom header
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
RsCollectToolUsageData (getThisScriptFilename())
-- Light settings are stored in a config file. Load the vertex and light settings required for the tool
vbakesettings = pathToConfigFiles + "general/max_vertex_bake_settings.dat"
try (filein vbakesettings) catch (messagebox ("Couldn't find project specific light settings file. \r\nWas expecting " + vbakesettings ))
filein "rockstar/export/settings.ms" -- This is fast
-- RsCollectToolUsageData (getThisScriptFilename())
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
global vtxWeight = 4
contin = true --hack to try and ensure valid exit
objName = undefined
rolloutName = undefined
attrObjs = undefined
attrName = #()
attrMin = #()
attrMax = #()
expObj = undefined
expCont = undefined
expString = undefined
scalarObjects = #()
scalarNames = #()
scalarConts = #()
facialRollout = ""
newObjects = undefined
normalsXmlFile = undefined
masterScene = undefined
headScene = undefined
shaderType = undefined
-- normalsXmlFile = undefined
wrinkleFolder = undefined
debugPrintVal = true --toggle this true/false to enable/disable --print statements
chkPsdheadVal = false
useZeroControllers = true --toggle this to allow use of frozen transform controllers
returnData = #(#(),#(), #()) --[1] == new expString [2] == countFrom -USED DURING SCALE EXPRESSION ADJUSTMENT
initCountFrom = undefined --used to see if countfrom has incremented. If it hasnt then we can stop -USED DURING SCALE EXPRESSION ADJUSTMENT
facialBonePrefix = "FACIAL" --set here so we know what the prefix on facial bones is for selecting via name
global generateScaleOffsetNode = false --used to track if we need to add a scale offset joystick into the scale expressions
toolsRoot = RsConfigGetToolsRootDir()
theWildWest = RsConfigGetWildWestDir()
boneTagMappingXmlFile = (toolsRoot + "/etc/content/animconfig/bone_tags.xml")
filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms" )
frameCTRLNodes = #(
"nose_L_CTRL",
"innerBrow_L_CTRL",
"outerBrow_L_CTRL",
"eye_R_CTRL",
"eye_L_CTRL",
"innerBrow_R_CTRL",
"mouth_CTRL",
"tongue_CTRL",
"jaw_CTRL",
"nose_R_CTRL",
"outerBrow_R_CTRL"
)
dupJoints = #(
"SKEL_Spine3",
"SKEL_Neck_1",
"SKEL_Head"
)
oldNames = #(
"SKEL_Head",
"RB_Neck_1",
"SKEL_Neck_1"
)
GTANames = #(
#(
"SKEL_Head_OLD",
"RB_Neck_1_OLD",
"SKEL_Neck_1_OLD"
),
#(
"SKEL_Head",
"RB_Neck_1",
"SKEL_Neck_1",
"SKel_Neck_1"
)
)
geoNames = #( --names from fbx file
#(
-- "AsymmetricMesh",
-- "Teef_000_u"
),
#( --names for gta
-- "head_000_r",
-- "Teef_000_u"
"head_000_",
"Teef_000_"
)
)
faceCTRLS = #( --on face controls that need the facial scale flags set
-- "lowerLip_L_CTRL",
-- "lowerLip_C_CTRL",
-- "lowerLip_R_CTRL",
-- "lipCorner_R_CTRL",
-- "upperLip_C_CTRL",
-- "upperLip_L_CTRL",
-- "lipCorner_L_CTRL",
-- "upperLip_R_CTRL",
-- "eyelidUpperOuter_L_CTRL",
-- "eyelidUpperInner_L_CTRL",
-- "eyelidLowerOuter_L_CTRL",
-- "eyelidLowerInner_L_CTRL",
-- "eyelidLowerOuter_R_CTRL",
-- "eyelidLowerInner_R_CTRL",
-- "eyelidUpperOuter_R_CTRL",
-- "eyelidUpperInner_R_CTRL"
"eyelidUpperInner_R_CTRL",
"eyelidLowerInner_R_CTRL",
"lowerLip_L_CTRL",
"eyelidLowerOuter_R_CTRL",
"lowerLip_C_CTRL",
"eyelidLowerInner_L_CTRL",
"lowerLip_R_CTRL",
"eyelidLowerOuter_L_CTRL",
"lipCorner_R_CTRL",
"eyelidUpperInner_L_CTRL",
"upperLip_C_CTRL",
"eyelidUpperOuter_L_CTRL",
"upperLip_L_CTRL",
"eyelidUpperOuter_R_CTRL",
"lipCorner_L_CTRL",
"upperLip_R_CTRL",
"upperLip_R_OFF",
"lipCorner_L_OFF",
"eyelidUpperOuter_L_OFF",
"upperLip_L_OFF",
"eyelidUpperInner_L_OFF",
"upperLip_C_OFF",
"eyelidLower_L_OFF",
"eyelidLowerOuter_L_OFF",
"lipCorner_R_OFF",
"eyelidLowerInner_L_OFF",
"lowerLip_R_OFF",
"eyelidLower_R_OFF",
"eyelidLowerOuter_R_OFF",
"lowerLip_C_OFF",
"eyelidLowerInner_R_OFF",
"lowerLip_L_OFF",
"eyelidUpper_R_OFF",
"eyelidUpperOuter_R_OFF",
"eyelidUpper_L_OFF",
"eyelidUpperInner_R_OFF",
"jaw_C_OFF"
)
rigBones = #() --dynamically populated array of bones which have had expressions on them
facialGUIFile = undefined
facialFbxFile = undefined
facialXmlFile = undefined
controlGUIObjects = #() -- array used to store all gui objects for later scale concatenation
autoClick = undefined --this is a simple tag for the fbx importer for if we can auto click everything or if the usr needs to manually click ok after updating a setting.
foundPLayerShader = undefined --used to store if scene has PLAYER materials or old school multisubs
rsGUIFile = (theProjectRoot + "art/peds/3LateralSetup/RockStar_GTAV_GUI.max") --aplhad GUI file
rsOffsetJSFile = (theProjectRoot + "art/peds/3LateralSetup/ScaleOffsetJS.max") --scale joystick
standardGui = #( --list of all geo based gui nodes which will get replaced by the alphad plane ones
"faceControls_FRAME",
"mouth_FRAME",
"mouth_CTRL",
"mouth_TEXT",
"jaw_FRAME",
"jaw_CTRL",
"jaw_TEXT",
"tongue_TEXT",
"tongueMove_FRAME",
"tongueMove_CTRL",
"tongueRoll_FRAME",
"tongueRoll_CTRL",
"tongueInOut_FRAME",
"tongueInOut_CTRL",
"outerBrow_R_FRAME",
"outerBrow_R_CTRL",
"innerBrow_L_FRAME",
"innerBrow_L_CTRL",
"outerBrow_L_FRAME",
"outerBrow_L_CTRL",
"brows_TEXT",
"innerBrow_R_FRAME",
"innerBrow_R_CTRL",
"eye_R_FRAME",
"eye_L_FRAME",
"eyes_TEXT",
"eye_C_FRAME",
"eye_C_CTRL",
"eye_L_CTRL",
"eye_R_CTRL",
"nose_L_FRAME",
"nose_L_CTRL",
"nose_R_FRAME",
"nose_R_CTRL",
"nose_TEXT",
"cheek_TEXT",
"cheek_L_FRAME",
"cheek_L_CTRL",
"cheek_R_FRAME",
"cheek_R_CTRL",
"lowerLip_L_CTRL",
"lowerLip_C_CTRL",
"lowerLip_R_CTRL",
"lipCorner_R_CTRL",
"upperLip_C_CTRL",
"upperLip_L_CTRL",
"lipCorner_L_CTRL",
"upperLip_R_CTRL",
"eyelidUpperOuter_L_CTRL",
"eyelidUpperInner_L_CTRL",
"eyelidLowerOuter_L_CTRL",
"eyelidLowerInner_L_CTRL",
"eyelidLowerOuter_R_CTRL",
"eyelidLowerInner_R_CTRL",
"eyelidUpperOuter_R_CTRL",
"eyelidUpperInner_R_CTRL"
)
attrObjs = #( --objects with attrs used to connect to alpha attr gui. If id 2 = undefined this gets the attr from the definition if not undefined its cos this attr name is shared on multiple objects.
#("eye_C_CTRL", undefined),
#("mouth_CTRL", undefined),
#("tongueInOut_CTRL", undefined),
#("tongueRoll_CTRL", undefined),
#("jaw_CTRL", undefined),
#("lipCorner_R_CTRL", "CIRC_stickyLips_A"),
#("upperLip_R_CTRL", "CIRC_thinThick_B" ),
#("upperLip_C_CTRL", "CIRC_thinThick_C"),
#("upperLip_L_CTRL", "CIRC_thinThick_D"),
#("lipCorner_L_CTRL", "CIRC_stickyLips_E"),
#("lowerLip_L_CTRL", "CIRC_thinThick_F"),
#("lowerLip_C_CTRL", "CIRC_thinThick_G"),
#("lowerLip_R_CTRL", "CIRC_thinThick_H")
)
nonConcatJoints = #( --joints which we do not want to concat scale
"FACIAL_R_lipUpperAnalog",
"FACIAL_R_lipLowerAnalog",
"FACIAL_lipUpperAnalog",
"FACIAL_L_lipLowerAnalog",
"FACIAL_L_lipCornerAnalog",
"FACIAL_L_lipUpperAnalog",
"FACIAL_R_lipCornerAnalog",
"FACIAL_lipLowerAnalog",
"FACIAL_R_eyelidUpperInnerAnalog",
"FACIAL_R_eyelidLowerInnerAnalog",
"FACIAL_R_eyelidUpperOuterAnalog",
--"FACIAL_R_eyelidLowerLowerAnalog",
"FACIAL_R_eyelidLowerOuterAnalog",
"FACIAL_L_eyelidUpperInnerAnalog",
"FACIAL_L_eyelidLowerInnerAnalog",
"FACIAL_L_eyelidUpperOuterAnalog",
--"FACIAL_L_eyelidLowerLowerAnalog",
"FACIAL_L_eyelidLowerOuterAnalog"
)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
fn getToolRevision toolFileName =
(
--toolFileName = (RsConfigGetWildWestDir() + "script\\3dsMax\\Characters\\Rigging\\ambientFacial\\faceRigger_arcGuiCreation.ms")
if runFromRigToolsPallette == true do
(
if rigToolsFileName != undeifned do
(
toolFileName = rigToolsFileName
)
)
fileLength = toolFileName.count
subst = (substring toolFileName (fileLength - 2) -1)
if subst == ".ms" then
(
testSync = true
)
else
(
testSync = false
)
versionNumber = undefined
if testSync == true then
(
local fstats = ( gRsPerforce.getFileStats toolFileName )[ 1 ]
local haveRev = fstats.Item[ "haveRev" ] as integer
local headRev = fstats.Item[ "headRev" ] as integer
versionNumber = haveRev
)
else
(
messagebox ("WARNING! Could not version rig as could not deduct which version of this tool you are running from p4") beep:true title:"Versioning"
)
--messagebox ("version # :"+(versionNumber as string))
print ("version # :"+(versionNumber as string))
return versionNumber
)
fn swapChars textString charFrom charTo =
(
flt = filterString textString charFrom
thisNewString = ""
for i = 1 to flt.count do
(
endStr = ""
if i < flt.count do
(
endStr = charTo
)
thisNewString = thisNewString+flt[i]+endStr
)
return thisNewString
)
fn copyTexture initialPath finalPath =
(
initStr = initialPath
newFile = finalPath
-- initStr = "X://gta5//art//peds//Story_Characters//CS_TracyDiSanto//From_3L//2012-04-17_RockStar_GTAV_TracyDiSanto_v05//textures//HEAD_Wrinkle_Mask_0.tga"
thisFile = initStr
--clearListener()
flt = filterString thisFile "//"
origThisFile = thisFile
thisFile = swapChars thisFile "//" "\\"
flt = filterString newFile "//"
thisNewFile = swapChars newFile "//" "\\"
origNewFile = newFile
ex = doesFileExist thisFile
if ex == true then
(
-- format ("\n"+"************** FILE EXISTS **********************"+"\n")
--newPath = swapChars thisNewFile "//" "\\"
--file exists so we should delete the original
free thisFile
deleteFile thisFile
ex2 = doesFileExist thisFile
if ex2 == true then
(
format ("\t"+"file deletion FAILED."+"\n")
format ("\t"+(thisFile as string)+"\n")
)
else
(
-- format ("\t"+"file deletion SUCCESS!"+"\n")
)
-- newFile = "c:\\textureCopy\\Head_Wrinkle_Mask_0.tga"
format ("\n\n"+"copying From: "+"\n\t"+origthisFile+"\n"+"To: "+"\n\t"+origNewFile+"\n\n\n")
--newFile = copyFile thisFile thisNewFile
newFile = copyFile origThisFile origNewFile
-- format ("\n\n"+"File copy status: "+(newFile as string)+"\n")
ex2 = doesFileExist origNewFile
if ex2 == true then
(
--print ("Copied to "+thisNewFile)
)
else
(
print "Copy failed. :("
)
)
else
(
print ("Couldn't find "+thisFile)
)
return thisNewFile
)
fn moveWrinkleMap wrinklePath mapNames = --copies wrinkles from original source 3lateral folder to characters textures\highres folder
(
--first we need to find the real texture folder
thisStr = findString wrinklePath "From" --searching for 'From' as textures are always inside a From_3l or From3L folder
realFolder = undefined
if thisStr != undefined then
(
realFolder = substring wrinklePath 1 (thisStr - 1)
---messagebox ("Found "+realFolder)
)
else
(
if queryBox ("Warning! Could not define character texture folder."+"\n"+"Please Click Yes to select character\\textures\\highres folder"+"\n"+"or No to cancel script.") beep:true then
(
realFolder = getOpenFileName caption:"Textures Folder" types:"Tga files (head*diff*.tga)|head_*diff*.tga|All Files (*.*)|*.*|"
)
else
(
contin = false
)
)
if realFolder != undefined then --now we do the real stuff
(
for wm = 1 to mapNames[2].count do
(
--first off check if the map already exists in the realFolder
fileName = filenameFromPath mapNames[1][wm]
mPath = (realFolder+"textures\\highres\\"+fileName)
bPath = swapChars mPath "\\" "//"
mPath = bPath
--messagebox ("Looking for: "+(mPath) as string)
--print ("Looking for existing: "+(mPath) as string)
fileExists = doesFileExist (mPath) --dont think i need this with the 4 funcitonality
format ("fileExists for "+(mPath)+" = "+(fileExists as string)+"\n")
--if it does then check out of p4 then copy the new one over the top
if fileExists == true then
(
print "Existing wrinkle Found!"
--messagebox "Copying over existing wrinkle"
thisFile = (mPath)
thisFile = swapChars thisFile "//" "\\"
--thisFile = copyFile mapNames[1][wm] (thisFile)
newTexture = copyTexture mapNames[1][wm] mPath
format ("Replacement texture: "+(newTexture as string)+"\n")
newTexture1 = getFiles newTexture
if newTexture1.count == 1 do
(
newTexture1 = newTexture1[1]
-- gRsPerforce.add_or_edit #( mPath ) silent:true queueAdd:false
gRsPerforce.add_or_edit #( newTexture1 ) silent:true queueAdd:false
--messagebox "Found existing wrinkle"
--now replace mapNames[1][wm] with the new path
print ("Replacing entry "+(wm as string)+" with "+newTexture1)
-- mapNames[1][wm] = mPath
-- newTexture = execute newTexture
mapNames[1][wm] = newTexture1
)
)
--else copy the new one to realfolder and add to p4
else
(
--messagebox ("adding new wrinkle to "+mpath)
--print ("adding new wrinkle to "+mpath)
thisFile = mPath
-- flt = filterString thisFile "//"
-- thisFile = ""
-- for i = 1 to flt.count do
-- (
-- thisFile = thisFile+flt[i]+"\\"
-- )
thisFile = swapChars thisFile "//" "\\"
--thisFile = copyFile mapNames[1][wm] (thisFile)
newTexture = copytexture mapNames[1][wm] mPath
if newTexture == false do
(
format ("Copy of "+mPath +" FAILED!")
)
format ("New texture: "+(newTexture as string)+"\n")
newTexture1 = getFiles newTexture
if newTexture1.count == 1 then
(
newTexture1 = newTexture1[1]
-- gRsPerforce.add_or_edit #( mPath ) silent:true queueAdd:false
gRsPerforce.add_or_edit #( newTexture1 ) silent:true queueAdd:false
--now replace mapNames[1][wm] with the new path
print ("Replacing entry "+(wm as string)+" with "+newTexture1)
-- mapNames[1][wm] = mPath
-- newTexture = execute newTexture
mapNames[1][wm] = newTexture1
)
else
(
format ("WARNING!: "+(newTexture1.count as string))
)
)
)
)
else
(
--messagebox ("realFolder == undefined")
-- break()
contin = false
)
)
fn deactivateHeels =
(
heelJs = getNodeByName "HeelHeight"
if heelJs != undefined do
(
in coordsys parent heelJs.position.controller[2].Y_Position = 1.0
)
)
fn connectAlphaGUIToAttrs =
(
--print "------------------"
for i = 1 to attrObjs.count do
(
obj = getNodeByName attrObjs[i][1]
if attrObjs[i][2] == undefined then
(
attrDef = custAttributes.get obj.modifiers[#Attribute_Holder] 1
attrNames = getPropNames attrDef
for a = 1 to attrNames.count do
(
--print ("Current attr = "+(attrNames[a] as string))
attName = (attrNames[a] as string)
attLength = attName.count
attributeName = (substring attName 1 (attLength - 3))
guiObj = getNodeByName ("CIRC_"+attributeName)
if guiObj != undefined then
(
--now we need to wire this attr to the gui object
--so now we build the path to the Attribute
attrStr = ("$"+obj.name+".modifiers[#Attribute_Holder]."+attrNames[a])
thisAttr = execute attrStr
if thisAttr != undefined then
(
fromStr = ("$"+obj.name+".modifiers[#Attribute_Holder]."+obj.name+"_A"+"[#"+attributeName+"_CA] ")
toStr = ("$CIRC_"+attributeName+".pos.controller.Zero_Pos_XYZ.controller.X_Position.controller[#Limited_Controller__Bezier_Float] "+"\""+"Limited_Controller__Bezier_Float"+"\""+" "+"\""+attributeName+"_CA"+"\"")
wireStr = ("paramWire.connect2way "+fromStr + toStr)
--print (wireStr)
execute wireStr
)
else
(
--print ("Attribute path generation failed for "+(attrObjs[i][1]+".modifiers[#Attribute_Holder]."+attrNames[a]))
)
)
else
(
--print ("Couldnt find "+("CIRC_"+attributeName))
)
)
)
else
(
guiObj = getNodeByName attrObjs[i][2]
guiObjNameLength = attrObjs[i][2].count
startChar = 6
trimmedLength = (guiObjNameLength - (1 + startChar))
attributeName = (substring guiObj.name startChar trimmedLength)
fromStr = ("$"+obj.name+".modifiers[#Attribute_Holder]."+obj.name+"_A"+"[#"+attributeName+"_CA] ")
toStr = ("$"+guiObj.name+".pos.controller.Zero_Pos_XYZ.controller.X_Position.controller[#Limited_Controller__Bezier_Float] "+"\""+"Limited_Controller__Bezier_Float"+"\""+" "+"\""+attributeName+"_CA"+"\"")
wireStr = ("paramWire.connect2way "+fromStr+toStr)
--print (wireStr)
execute wireStr
)
)
--print "Attrs connected"
)
fn convertStandardGuiToAlphaGUI =
(
mergeMaxFile rsGUIFile quiet:true
-- disableSceneRedraw()
max modify mode
for sG = 1 to standardGui.count do
(
stdGUI = getNodeByName standardGui[sG]
alpGUI = getNodeByName ("RS_"+standardGui[sG])
if alpGUI != undefined then
(
--do i need to parent the alpGUI to the stdGui.parent 1st?
alpGui.parent = stdGui.parent
in coordsys world alpGui.transform = in coordsys world stdGui.transform
select stdGui
--need to ensure we maintain existing attr holders
if stdGui.modifiers.count > 0 then
(
modCount = stdGUI.modifiers.count
val = (modCount - 1)
if val < 2 then
(
modPanel.setCurrentObject stdGui.baseObject
modPanel.addModToSelection (Edit_Poly ()) ui:on
maxOps.CollapseNodeTo stdGui 2 off
)
else
(
modPanel.setCurrentObject stdGui.modifiers[val]
modPanel.addModToSelection (Edit_Poly ()) ui:on
maxOps.CollapseNodeTo stdGui (modCount - 1) off
)
modPanel.setCurrentObject stdGui.baseObject
)
else
(
convertTo stdGui PolyMeshObject
)
subobjectLevel = 4
max select all
max delete
--now we can attach the alpha plane
stdGui.EditablePoly.attach alpGUI stDGUI
subobjectLevel = 0
)
else
(
--print ("Couldn't find RS node RS_"+standardGui[sG])
)
)
connectAlphaGUIToAttrs()
)
fn getNodeByNameWildcard nameString =
(
thisNode = undefined
for o in objects do
(
nameLength = nameString.count
thisName = nameString as Name
ObjectName = ((substring (o.name) 1 nameLength) as Name)
if objectName == thisName do
(
thisNode = o
debugprint ("WOOT "+o.name+" == "+thisName)
)
)
return thisNode
)
fn tagOnFaceCtrls =
(
tagDataArray = RSTA_populateBoneTagMappingArray boneTagMappingXmlFile
for i = 1 to faceCTRLS.count do
(
thisObj = getNodeByName faceCTRLS[i]
if thisObj != undefined do
(
scaleTag = ("True")
scaleTrackTag = "TRACK_FACIAL_SCALE"
existingTag = getUserPropBuffer thisObj
foundScale = findString existingTag "exportScale"
if foundScale != undefined do
(
scaleTag = "true"
)
foundScaleTrack = findString existingTag "scaleTrackType"
if foundScaleTrack != undefined do
(
scaleTrackTag = "TRACK_FACIAL_TRANSLATION"
)
bTag = RSTA_findBoneTag thisObj.name tagDataArray
if bTag != "UNKNOWN" do
(
setUserProp thisObj "tag" bTag
)
setUserProp thisObj "exportTrans" "True"
setUserProp thisObj "exportScale" scaleTag
setuserProp thisObj "scaleTrackType" scaleTrackTag
)
)
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/3Lateral/ThreeLateral_tagCustAttrGui.ms")
)
fn prepForTest =
(
oldFaceControls = #($innerBrow_R_FRAME, $faceControls_FRAME, $cheek_R_FRAME, $mouth_FRAME, $mouth_CTRL, $mouth_TEXT, $cheek_L_CTRL, $jaw_FRAME, $jaw_CTRL, $jaw_TEXT, $cheek_L_FRAME, $tongue_TEXT, $cheek_TEXT, $tongueMove_FRAME, $tongueMove_CTRL, $nose_TEXT, $tongueRoll_FRAME, $tongueRoll_CTRL, $nose_R_CTRL, $tongueInOut_FRAME, $tongueInOut_CTRL, $nose_R_FRAME, $nose_L_CTRL, $outerBrow_R_FRAME, $outerBrow_R_CTRL, $nose_L_FRAME, $innerBrow_L_FRAME, $innerBrow_L_CTRL, $eye_C_CTRL, $outerBrow_L_FRAME, $outerBrow_L_CTRL, $brows_TEXT, $eye_C_FRAME, $cheek_R_CTRL, $innerBrow_R_CTRL, $eyes_TEXT, $eye_L_CTRL, $eye_R_FRAME, $eye_L_FRAME, $eye_R_CTRL, $eye_R_DRIVER, $eye_L_OFF, $eye_R_SDK, $eye_L_SDK, $eye_R_OFF, $eye_L_DRIVER, $eyes_OFF, $eye_C_OFF, $innerBrow_R_OFF, $outerBrow_L_OFF, $nose_OFF, $nose_L_OFF, $innerBrow_L_OFF, $outerBrow_R_OFF, $nose_R_OFF, $brows_OFF, $tongueInOut_OFF, $tongueRoll_OFF, $cheeks_OFF, $tongueMove_OFF, $cheek_L_OFF, $tongue_OFF, $jaw_OFF, $cheek_R_OFF, $mouth_OFF, $faceControls_OFF, $lipCorner_R_CTRL, $upperLip_L_CTRL, $upperLip_C_CTRL, $lowerLip_L_CTRL, $upperLip_R_CTRL, $lowerLip_C_CTRL, $lipCorner_L_CTRL, $lowerLip_R_CTRL, $lipCorner_R_OFF, $lowerLip_R_OFF, $upperLip_R_OFF, $lowerLip_C_OFF, $upperLip_C_OFF, $lowerLip_L_OFF, $upperLip_L_OFF, $jaw_C_OFF, $lipCorner_L_OFF, $head_C_OFF)
oldFaceJoints = #($FACIAL_facialRoot, $FACIAL_jaw, $FACIAL_underChin, $FACIAL_L_underChin, $FACIAL_chin, $FACIAL_chinSkinBottom, $FACIAL_L_chinSkinBottom, $FACIAL_R_chinSkinBottom, $FACIAL_tongueA, $FACIAL_tongueB, $FACIAL_tongueC, $FACIAL_chinSkinTop, $FACIAL_L_chinSkinTop, $FACIAL_chinSkinMid, $FACIAL_L_chinSkinMid, $FACIAL_L_chinSide, $FACIAL_L_lipLower, $FACIAL_L_lipLowerAnalog, $FACIAL_L_lipLowerThicknessV, $FACIAL_L_lipLowerThicknessH, $FACIAL_lipLower, $FACIAL_lipLowerAnalog, $FACIAL_lipLowerThicknessV, $FACIAL_lipLowerThicknessH, $FACIAL_R_chinSkinMid, $FACIAL_R_chinSkinTop, $FACIAL_R_chinSide, $FACIAL_R_lipLower, $FACIAL_R_lipLowerAnalog, $FACIAL_R_lipLowerThicknessV, $FACIAL_R_lipLowerThicknessH, $FACIAL_R_underChin, $FACIAL_nose, $FACIAL_L_nostril, $FACIAL_L_nostrilThickness, $FACIAL_noseLower, $FACIAL_L_noseLowerThickness, $FACIAL_R_noseLowerThickness, $FACIAL_noseTip, $FACIAL_R_nostril, $FACIAL_R_nostrilThickness, $FACIAL_noseUpper, $FACIAL_L_noseUpper, $FACIAL_noseBridge, $FACIAL_L_nasolabialFurrow, $FACIAL_L_nasolabialBulge, $FACIAL_L_cheekLower, $FACIAL_L_cheekLowerBulge1, $FACIAL_L_cheekLowerBulge2, $FACIAL_L_cheekInner, $FACIAL_L_cheekOuter, $FACIAL_L_eyesackLower, $FACIAL_L_eyeball, $FACIAL_L_eyelidLower, $FACIAL_L_eyelashLowerOuter, $FACIAL_L_eyelashLowerInner, $FACIAL_L_eyelidUpper, $FACIAL_L_eyelashUpperOuter, $FACIAL_L_eyelashUpperInner, $FACIAL_L_eyesackUpperOuterBulge, $FACIAL_L_eyesackUpperInnerBulge, $FACIAL_L_eyesackUpperOuterFurrow, $FACIAL_L_eyesackUpperInnerFurrow, $FACIAL_forehead, $FACIAL_L_foreheadInner, $FACIAL_L_foreheadInnerBulge, $FACIAL_L_foreheadOuter, $FACIAL_skull, $FACIAL_foreheadUpper, $FACIAL_L_foreheadUpperInner, $FACIAL_L_foreheadUpperOuter, $FACIAL_R_foreheadUpperInner, $FACIAL_R_foreheadUpperOuter, $FACIAL_L_temple, $FACIAL_L_ear, $FACIAL_L_earLower, $FACIAL_L_masseter, $FACIAL_L_jawRecess, $FACIAL_L_cheekOuterSkin, $FACIAL_L_lipUpper, $FACIAL_L_lipUpperAnalog, $FACIAL_L_lipUpperThicknessH, $FACIAL_L_lipUpperThicknessV, $FACIAL_lipUpper, $FACIAL_lipUpperAnalog, $FACIAL_lipUpperThicknessH, $FACIAL_lipUpperThicknessV, $FACIAL_L_lipCorner, $FACIAL_L_lipCornerAnalog, $FACIAL_L_lipCornerThicknessUpper, $FACIAL_L_lipCornerThicknessLower, $FACIAL_R_lipUpper, $FACIAL_R_lipUpperAnalog, $FACIAL_R_lipUpperThicknessH, $FACIAL_R_lipUpperThicknessV, $FACIAL_R_lipCorner, $FACIAL_R_lipCornerAnalog, $FACIAL_R_lipCornerThicknessUpper, $FACIAL_R_lipCornerThicknessLower, $FACIAL_R_cheekLower, $FACIAL_R_cheekLowerBulge1, $FACIAL_R_cheekLowerBulge2, $FACIAL_R_masseter, $FACIAL_R_jawRecess, $FACIAL_R_ear, $FACIAL_R_earLower, $FACIAL_R_eyesackLower, $FACIAL_R_nasolabialBulge, $FACIAL_R_cheekOuter, $FACIAL_R_cheekInner, $FACIAL_R_noseUpper, $FACIAL_R_foreheadInner, $FACIAL_R_foreheadInnerBulge, $FACIAL_R_foreheadOuter, $FACIAL_R_cheekOuterSkin, $FACIAL_R_eyeball, $FACIAL_R_eyelidUpper, $FACIAL_R_eyelashUpperOuter, $FACIAL_R_eyelashUpperInner, $FACIAL_R_eyelidLower, $FACIAL_R_eyelashLowerOuter, $FACIAL_R_eyelashLowerInner, $FACIAL_R_eyesackUpperInnerFurrow, $FACIAL_R_eyesackUpperOuterFurrow, $FACIAL_R_eyesackUpperInnerBulge, $FACIAL_R_eyesackUpperOuterBulge, $FACIAL_R_nasolabialFurrow, $FACIAL_R_temple, $FACIAL_adamsApple)
oldGeoNodes = #($Teef_000_u, $head_000_r)
delete oldFaceControls
debugPrint "Deleted oldFaceControls"
delete oldFaceJoints
debugPrint "Deleted oldFaceJoints"
delete oldGeoNodes
debugPrint "Deleted oldGeoNodes"
)
rollout progBar "XML Parse Progress..."
(
progressBar prog pos:[10,10] color:green
)
fn debugPrint printStr = --this is a little function to replace the --print command. This allows us then to be able to globally turn on and off --print cstatements.
(
if debugPrintVal == true do
(
print printStr
)
)
fn LSW_EnvelopeCallbackFunction =
(
WindowHandle = DialogMonitorOPS.GetWindowHandle()
theDialogName = UIAccessor.GetWindowText WindowHandle
if theDialogName != undefined and matchpattern theDialogName pattern:"*Load Envelopes*" do
UIAccessor.PressButtonByName WindowHandle "Match by Name"
if theDialogName != undefined and matchpattern theDialogName pattern:"*Load Envelopes*" do
UIAccessor.PressButtonByName WindowHandle "OK"
true
)
fn loadSkinData geo =
(
boneList = #()
skinFile = ("c:/skins/"+"3Lat_"+geo.name+".env")
boneFile = ("c:/skins/"+"3Lat_"+geo.name+".bon")
for o in objects do
(
if (substring o.name 1 4) == "SKEL" do
(
appendIfUnique boneList o
)
)
-- This part adds a skin modifier, sets the bone limit, adds the bones
if geo.modifiers[#Skin] == undefined do
(
select geo
modPanel.addModToSelection (XForm ()) ui:on
execStr = ("collapseStack $"+geo.name)
execute execStr
modPanel.addModToSelection (Skin ()) ui:on
geo.modifiers[#Skin].bone_Limit = vtxWeight
geo.modifiers[#Skin].showNoEnvelopes = on
)
if boneFile != undefined then
(
f = openfile boneFile
inputData = #() -- define as array
while not eof f do
(
append inputData (filterstring (readLine f) ",")
)
close f
for i in inputData do
(
currBonename = (i as string)
currBoneLength = currBonename.count
currBone = ("$"+(substring currBonename 4 (currBonelength - 5)))
executeStr = ("if "+currBone+" != undefined do ("+"select "+currBone+")")
currentBone = execute executeStr
currentBone = execute currBone
if currentBone != undefined then
(
appendIfUnique boneList $
)
else
(
debugprint ("Couldn't find "+currBone+" in this scene.")
)
)
select geo
SetCommandPanelTaskMode mode:#modify
for i = 1 to boneList.count do
(
boneToAdd = getNodeByName bonelist[i].name
updateInt = 1
if i != boneList.count do
(
updateInt = 0
)
if boneToAdd != undefined do
(
foundThisBone = false
--now we check if this bone name is already in the skin
numberBones = skinops.GetNumberBones geo.modifiers[#Skin]
for nB = 1 to numberBones do
(
ThisBoneName = skinops.getBoneName geo.modifiers[#Skin] nB 0
if ThisBoneName == boneList[i].name do
(
foundThisBone = true
)
)
--ok so we CAN add this bone in
if foundThisBone == false do
(
skinOps.addbone geo.modifiers[#Skin] boneList[i] updateInt
)
)
)
)
-- Load the skin weights back on.
-- Need to use completeRedraw() or the weights wont load when in a loop. Madness.
-- Fix was from here: http://tech-artists.org/forum/showthread.php?p=4034
-- Use a callback to press the buttons
-- I found this here: http://forums.cgsociety.org/showthread.php?t=485300
DialogMonitorOPS.RegisterNotification LSW_EnvelopeCallbackFunction ID:#ANoon_Envelopes
DialogMonitorOPS.Enabled = true
completeRedraw()
skinOps.loadEnvelope geo.modifiers[#Skin] skinFile
DialogMonitorOPS.Enabled = false
DialogMonitorOPS.UnRegisterNotification ID:#ANoon_Envelopes
)
fn saveSkinData geo =
(
debugprint ("*** SAVE SKINNING on "+(geo as string)+" ***")
boneList = #()
makeDir "c:/skins"
select geo
max modify mode
subobjectLevel = 1
modPanel.setCurrentObject geo.modifiers[#Skin]
--save out the skin weights
skinFile = ("c:/skins/"+"3Lat_"+geo.name+".env")
skinOps.saveEnvelope geo.modifiers[#Skin] skinFile
boneFile = ("c:/skins/"+"3Lat_"+geo.name+".bon")
skinMod = geo.modifiers[#Skin]
totalSkinModBones = skinOps.getNumberBones skinMod
if totalSkinModBones > 0 then
(
output_name = boneFile
if output_name != undefined then
(
output_file = createfile output_name
for i = 1 to totalSkinModBones do
(
thebonename = skinOps.getBoneName skinMod i 1
append boneList theBoneName
format ((theBoneName as string)+"\n") to:output_file
)
close output_file
)--end if
)--end if
)
fn scaleFixUpScaleByScale expString = --adds in a -1 to all input values in scale driven by scale expressions due to game scale default being 0 but max being 1
(
strA = "> 3., 3.,"
strARep = "> (3.0 - 1), (3.0 - 1),"
strB = "< 0.333333, 0.333333,"
strBRep = "< (0.333333 - 1), (0.333333 - 1),"
strC = "< 1.,"
strCRep = "< (1.0 - 1),"
--first off we'll double check this hasnt already been done
exist = findString expString strARep
if exist == undefined do
(
startPoint = findString expString strA
expString = replace expString startPoint (strA.count) strARep
)
exist = findString expString strBRep
if exist == undefined do
(
startPoint = findString expString strB
expString = replace expString startPoint (strB.count) strBRep
)
exist = findString expString strCRep
if exist == undefined do
(
startPoint = findString expString strC
expString = replace expString startPoint (strC.count) strCRep
)
return expString
)
-- function to generate an expression
fn generateExpressionIM expObj expCont scalarObjects scalarNames scalarConts expString=
(
--TEMPHACK
findSoff = "ScaleOffset"
-- print ("ExpString: "+(expString as string))
findSO = findString expString findSoff
if findSO != undefined do
(
findSoff2 = "ScaleOffset + 1"
findSo2 = findString expString findSoff2
if findSo2 != undefined then
(
--expString = substring expString findSO2 findSoff2.count
expString = ("( 0"+(substring expString (findSoff2.count + 2) -1))
print "Removing ScaleOffset + 1"
print ("ExpString reset to : "+(expString as string))
)
else
(
expString = substring expString findSo findSoff.count
print "Removing ScaleOffset"
print ("ExpString reset to : "+(expString as string))
)
)
if generateScaleOffsetNode == false then
(
expString = ("("+expString+")")
debugPrint "----------------------------------------------------------------------------"
debugPrint "\r\n"
debugPrint ("Creating expression on "+expObj+". Scalar of "+(scalarObjects as string))
debugPrint ("Using expression:")
debugPrint expString
debugPrint "\r\n"
debugPrint "----------------------------------------------------------------------------"
fcStr = ( "$"+expObj+expCont) --rebuild the string so it can be used below
local newfcStr = execute fcStr
debugPrint ("newfcStr = "+(fcStr as string))
--HACK TO TRY AND RESOLVE ON FACE CTRL ISSUE WITH PSD HEADS
if chkPsdheadVal == true do
(
expContStr = filterString expCont "."
newExpCont = expContStr[1]
contAxis = undefined
while contAxis == undefined do
(
for ax = 1 to expContStr.count do
(
if (substring expContStr[ax] 1 2) == "X_" then
(
contAxis = expContStr[ax]
)
else
(
if (substring expContStr[ax] 1 2) == "Y_" then
(
contAxis = expContStr[ax]
)
else
(
if (substring expContStr[ax] 1 2) == "Z_" then
(
contAxis = expContStr[ax]
)
)
)
)
if ax == expContStr then
(
if contAxis == undefined do
(
--hmm ok we oculdnt find a X Y or Z controller
format ("hmm ok we oculdnt find a X Y or Z controller\n")
break()
)
)
)
ct = undefined
if newExpCont == "Position" then
(
ct = "Position_XYZ"
)
else
(
if newExpCont == "Rotation" then
(
ct = "Euler_XYZ"
)
else
(
ct = "ScaleXYZ"
)
)
fcStr = ( "$"+expObj+"."+newExpCont+".available.controller = "+ct+" ()")
--format ("1: fcStr: "+fcStr+"\n")
newFcStr = execute fcStr
--format "1 went thru\n"
cCountStr = ("$"+expObj+"."+newExpCont+".controller.count")
cCount = execute cCountStr
fcStr = ("$"+expObj+"."+newExpCont+".controller["+((cCount - 1) as string)+"]."+contAxis+".controller = Float_Expression ()")
--format ("2: fcStr: "+fcStr+"\n")
newFcStr = execute fcStr
--format "2 went thru\n"
--END PSD HACK
)
if scalarNames.count != 0 do
(
for i = 1 to scalarNames.count do --this should loop through the array of scalars and their controllers and create a scalar for each
(
SVN = scalarNames[i]
debugPrint ("SVN = "+(SVN as string))
scalContStr = (scalarConts[i] as string)
debugPrint ("scalCont = "+scalContStr)
scalCont = execute scalContStr
newfcStr.AddScalarTarget SVN scalCont --add scalar pointing to the controller of the scalar object
)
)
--format ("setting expression to :\r\n"+expString+"\n")
newfcStr.SetExpression expString
debugPrint ("Expression created on "+expObj+" for "+expCont)
debugPrint "```````````````````````````````````````````````````````"
)
else
(
--first test if theres a scaleOffsetJoystick and if not merge it in
offsetJS = getNodeByName "ScaleOffset"
if offsetJS == undefined do
(
mergeMaxFile rsOffsetJSFile
)
offsetJS = getNodeByName "ScaleOffset"
if offsetJS != undefined then
(
setUserPropBuffer offsetJS "exportTrans = true"
in coordsys parent offsetJS.position.controller[2].Y_position = -1
)
expString = ("("+expString+")")
debugPrint "----------------------------------------------------------------------------"
debugPrint "\r\n"
debugPrint ("Creating expression on "+expObj+". Scalar of "+(scalarObjects as string))
debugPrint ("Using expression:")
debugPrint expString
debugPrint "\r\n"
debugPrint "----------------------------------------------------------------------------"
fcStr = ( "$"+expObj+expCont) --rebuild the string so it can be used below
local newfcStr = execute fcStr
debugPrint ("newfcStr = "+(fcStr as string))
if scalarNames.count != 0 do
(
for i = 1 to scalarNames.count do --this should loop through the array of scalars and their controllers and create a scalar for each
(
SVN = scalarNames[i]
debugPrint ("SVN = "+(SVN as string))
scalContStr = (scalarConts[i] as string)
debugPrint ("scalCont = "+scalContStr)
scalCont = execute scalContStr
newfcStr.AddScalarTarget SVN scalCont --add scalar pointing to the controller of the scalar object
)
)
debugPrint ("setting expression to :\r\n"+expString)
newfcStr.SetExpression expString
debugPrint ("Expression created on "+expObj+" for "+expCont)
debugPrint "```````````````````````````````````````````````````````"
)
)
fn removeOldScaleControllers thisBone =
(
contCount = thisBone.scale.controller.count
for i = (contCount - 1) to 1 by -1 do
(
thisCont = thisBone.Scale.controller[i]
if thisCont = thisBone.Scale.controller[i].name != "ConcatScale" then
(
if thisCont = thisBone.Scale.controller[i].name != "Frozen Scale" then
(
if thisCont = thisBone.Scale.controller[i].name != "Zero Scale XYZ" then
(
--ok we can remove this controller
debugprint ("Deleting "+thisBone.Scale.controller[i].name+" from "+thisBone.name)
thisBone.scale.controller.delete i
)
)
)
)
)
fn concatScale thisBone scaleAxis spclCaseConCat =
(
generateScaleOffsetNode = false
--need to put a test in here for if we are a concat-able facial joint
--if spclCaseConCat == true then we dont want to add a +1 to the concatenation
debugprint ("Concatting "+scaleAxis+" on "+thisBone.name)
contCount = thisBone.scale.controller.count
sclrName = #()
sclrObjs = #()
sclrCont = #()
expStr = #()
driverValue = #()
for c = 2 to contCount do
(
contStr = ("$"+thisBone.name+".scale.controller["+(c as string)+"]."+scaleAxis+".controller")
cont = execute contStr
if (cont as string) == "Controller:Float_Expression" do
(
--need to get number of scalars and then loop through those
myScalarCount = cont.NumScalars()
for nScl = 5 to myScalarCount do
(
myScalarName = cont.GetScalarName nScl --index of 5 thanks to the ticks, secs, nt and f variables always present
myScalarObj = cont.getScalarTarget myScalarName asController:false
myScalarObj = exprForMAXObject myScalarObj
filteredStr = filterString myScalarObj "."
myScalarObj = filteredStr[1]
myScalarCont = cont.getScalarTarget myScalarName asController:true
myScalarCont = exprForMAXObject myScalarCont
myDriverValStr = (filterstring myScalarCont ".controller")
myDriverVal = (myDriverValStr[1])
toRemoveStr = ".controller"
toRemoveCount = toRemoveStr.count
contCharCount = myScalarCont.count
finalDriv = substring myScalarCont 1 (contCharCount - toRemoveCount)
myDriverVal = execute finalDriv
debugprint ("myDriverVal = "+(myDriverVal as string))
myExpression = cont.GetExpression()
--*** MAY NEED TO DFO A FUNKY WAY OF APPENDING IF UNIQUE HERE
append SclrName (myScalarName as string)
append sclrObjs (myScalarObj as string)
append sclrCont (myScalarCont as string)
append expStr (myExpression as string)
append driverValue (myDriverVal as string)
)
--print ("myExpression["+(c as string)+"]: "+(myExpression as string))
)
)
--now need to see if the scalar driver value is a 0 or not. If its a zero then we need to add the +1 otherwise we dont
expString = undefined
offsetContIndex = undefined
foundOffset = false
expString = ""
for c = 1 to SclrName.count do
(
expString = (expString + (" + "+(expStr[c])))
--print ("Mid con: "+expString)
)
if spclCaseConCat == true then
(
expString = ("(ScaleOffset + 1) "+expString)
generateScaleOffsetNode = true
)
else
(
expString = ("1 "+expString)
generateScaleOffsetNode = false
)
for a = 1 to contCount do
(
if thisBone.scale.controller[a].name == "ConcatScale" do
(
foundOffset = true
offsetContIndex = a
--now add a float expression
concatCtrlStr = ("$"+thisBone.name+".scale.controller["+(offsetContIndex as string)+"]."+scaleAxis+".controller = Float_Expression ()")
execute concatCtrlStr
)
)
if foundOffset == false do
(
thisBone.scale.controller.available.controller = ScaleXYZ ()
thisBone.scale.controller.setName (contCount + 1) ("ConcatScale")
offsetContIndex = (contCount + 1)
concatCtrlStr = ("$"+thisBone.name+".scale.controller["+(offsetContIndex as string)+"]."+scaleAxis+".controller = Float_Expression ()")
execute concatCtrlStr
)
expObj = thisBone.name
expCont = (".scale.controller["+((offsetContIndex) as string)+"]."+scaleAxis+".controller")
scalarObjects = sclrObjs
scalarNames = sclrName
scalarConts = sclrCont
if findString expObj "Analog" != undefined do
(
--format ("Testing "+expObj+" for scale drivers..."+"\n")
foundScale = undefined
for i in scalarConts do
(
if findString i "cale" != undefined do
(
foundScale = true
)
)
if foundScale == true do
(
expString = scaleFixUpScaleByScale expString
)
)
generateExpressionIM expObj expCont scalarObjects scalarNames scalarConts expString
)
fn prepScaleOffset =
(
--first we get all the joints in the skin modifier
geoName = geoNames[2][1]
geoObj = getNodeByNameWildcard geoName
thisSkin = geoObj.modifiers[#Skin]
theseBoneNames = #()
for o in objects do
(
if (substring o.name 1 6) == "FACIAL" do
(
appendIfUnique theseBoneNames o.name
)
if (substring o.name 1 4) == "SKEL" do
(
appendIfUnique theseBoneNames o.name
)
)
for i = 1 to theseBoneNames.count do
(
spclCaseConCat = false
thisBone = getNodeByName theseBoneNames[i]
if (classof thisBone.scale.controller as string) == "scale_list" do
(
if thisBone.scale.controller.count > 2 do
(
concatThis = true
for nc = 1 to nonConcatJoints.count do
(
if thisBone.name == nonConcatJoints[nc] do
(
-- concatThis = false
concatThis = TRUE
spclCaseConCat = true
)
)
if concatThis == true do
(
--now we need to check all existing controllers and see if they are x y or z so we know if we need to add a correspondig offset
xCont = false
yCont = false
zCont = false
for c = 2 to thisBone.scale.controller.count do
(
xC = thisBone.scale.controller[c].X_Scale.controller
yC = thisBone.scale.controller[c].Y_Scale.controller
zC = thisBone.scale.controller[c].Z_Scale.controller
if (xC as string) == "Controller:Float_Expression" do
(
xCont = true
)
if (yC as string) == "Controller:Float_Expression" do
(
yCont = true
)
if (zC as string) == "Controller:Float_Expression" do
(
zCont = true
)
)
if xCont == true do
(
concatScale thisBone "X_Scale" spclCaseConCat
)
if yCont == true do
(
concatScale thisBone "Y_Scale" spclCaseConCat
)
if zCont == true do
(
concatScale thisBone "Z_Scale" spclCaseConCat
)
)
)
)
)
)
fn FreezeTransform = --freezes transforms. Copied from the max macroscript as this does not like being run from other scripts.
(
local Obj = Selection as array
suspendEditing which:#motion
for i = 1 to Obj.count do
(
Try
(
local CurObj = Obj[i]
if classof CurObj.rotation.controller != Rotation_Layer do
(
-- freeze rotation
CurObj.rotation.controller = Euler_Xyz()
CurObj.rotation.controller = Rotation_list()
CurObj.rotation.controller.available.controller = Euler_xyz()
/* "Localization on" */
CurObj.rotation.controller.setname 1 "Frozen Rotation"
CurObj.rotation.controller.setname 2 "Zero Euler XYZ"
/* "Localization off" */
CurObj.rotation.controller.SetActive 2
)
if classof CurObj.position.controller != Position_Layer do
(
-- freeze position
CurObj.position.controller = Bezier_Position()
CurObj.position.controller = position_list()
CurObj.position.controller.available.controller = Position_XYZ()
/* "Localization on" */
CurObj.position.controller.setname 1 "Frozen Position"
CurObj.position.controller.setname 2 "Zero Pos XYZ"
/* "Localization off" */
CurObj.position.controller.SetActive 2
-- position to zero
CurObj.Position.controller[2].x_Position = 0
CurObj.Position.controller[2].y_Position = 0
CurObj.Position.controller[2].z_Position = 0
)
if classof CurObj.scale.controller != Scale_Layer do
(
-- freeze scale
CurObj.scale.controller = Bezier_Scale()
CurObj.scale.controller = scale_list()
CurObj.scale.controller.available.controller = ScaleXYZ()
/* "Localization on" */
CurObj.scale.controller.setname 1 "Frozen Scale"
CurObj.scale.controller.setname 2 "Zero Scale XYZ"
/* "Localization off" */
CurObj.scale.controller.SetActive 2
-- scale to zero
CurObj.scale.controller[2].x_Scale = 100
CurObj.scale.controller[2].y_Scale = 100
CurObj.scale.controller[2].z_Scale = 100
)
)
/* "Localization on" */
Catch( messagebox ("A failure occurred while freezing "+(Obj.name)+"'s transform." title:"Freeze Transform"))
/* "Localization off" */
)
resumeEditing which:#motion
)
fn clampCtrls = --sets joysticks to default clamp values
(
for i = 1 to frameCTRLNodes.count do
(
thisObj = getNodeByName frameCTRLNodes[i]
thisObj.pos.controller.Zero_Pos_XYZ.controller.X_Position.controller = float_limit ()
thisObj.pos.controller.Zero_Pos_XYZ.controller.Y_Position.controller = float_limit ()
thisObj.pos.controller.Zero_Pos_XYZ.controller.Z_Position.controller = float_limit ()
thisObj.pos.controller.Zero_Pos_XYZ.controller.X_Position.controller.upper_limit = 1
thisObj.pos.controller.Zero_Pos_XYZ.controller.X_Position.controller.lower_limit = -1
thisObj.pos.controller.Zero_Pos_XYZ.controller.Y_Position.controller.upper_limit = 1
thisObj.pos.controller.Zero_Pos_XYZ.controller.Y_Position.controller.lower_limit = -1
thisObj.pos.controller.Zero_Pos_XYZ.controller.Z_Position.controller.upper_limit = 0
thisObj.pos.controller.Zero_Pos_XYZ.controller.Z_Position.controller.lower_limit = 0
)
)
fn prepExpressionString expObj expCont scalarObjects scalarNames scalarConts expString =
(
initialString = expString
scalarNamesLength = scalarNames[1].count
substit = (substring scalarNames[1] (scalarNamesLength - 2) 3)
if substit == "Rot" do
(
stringToReplace = scalarNames[1]
replaceToString = (" radToDeg ("+stringToReplace+")" )
initialString = substituteString initialString stringToReplace replaceToString
)
formattIngStr = ("\r\n"+" + ")
replaceString = "+"
expString = substituteString initialString replaceString formattingStr
debugprint "---------------------------"
debugprint expString
debugprint "---------------------------"
debugprint ("expCont = "+expCont)
generateExpressionIM expObj expCont scalarObjects scalarNames scalarConts expString
)
fn parseScaleStrForNumbers expString countFrom =
(
numVals = #(
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"0",
"."
)
--print ("Passed to fullParse")
--print ("CountFrom = "+(countFrom as string))
stringLength = expString.count
--print ("stringLength = "+(stringLength as string))
firstNumFound = undefined
secondNumFound = undefined
returnData[3] = countFrom
for cnt = countFrom to stringLength do
(
if firstNumFound == undefined then
(
if (expString[cnt] == numVals[1]) or (expString[cnt] == numVals[2]) or (expString[cnt] == numVals[3]) or (expString[cnt] == numVals[4]) or (expString[cnt] == numVals[5]) or (expString[cnt] == numVals[6]) or (expString[cnt] == numVals[7]) or (expString[cnt] == numVals[8]) or (expString[cnt] == numVals[9]) or (expString[cnt] == numVals[10]) or (expString[cnt] == numVals[11]) do
(
firstNumFound = cnt
--print ("firstNumSet to "+(cnt as string))
)
)
else
(
--ok so we found the first num Value so we need to count from there
if secondNumFound == undefined then
(
for cnt = firstNumFound to stringLength do
(
if (expString[cnt] == numVals[1]) or (expString[cnt] == numVals[2]) or (expString[cnt] == numVals[3]) or (expString[cnt] == numVals[4]) or (expString[cnt] == numVals[5]) or (expString[cnt] == numVals[6]) or (expString[cnt] == numVals[7]) or (expString[cnt] == numVals[8]) or (expString[cnt] == numVals[9]) or (expString[cnt] == numVals[10]) or (expString[cnt] == numVals[11]) then
(
--ok found a num so carry on
)
else
(
secondNumFound = cnt
--now we need to replace the from and to to a new number.
fromVal = firstNumFound
toVal = (secondNumFound - firstNumFound)
strToChange = ((substring expString fromVal toVal ) as float)
----print (strToChange as string)
newStr = (strToChange + 1)
----print ("old:"+expString)
expString = replace expString firstNumFound (secondNumFound - firstNumFound) (newStr as string)
----print ("new:"+expString)
countFrom = (secondNumFound + 1)
returnData[1] = expString
returnData[2] = countFrom
return returnData
)
)
)
)
)
)
fn preParseScaleExpr expString countFrom expObj expCont scalarObjects scalarNames scalarConts =
(
while returnData[2] != returnData[3] do
(
--print ("Found returned data")
expString = returnData[1]
countFrom = returnData[2]
parseScaleStrForNumbers expString countFrom
)
--print "Creating scale offset expression"
expString = returnData[1]
prepExpressionString expObj expCont scalarObjects scalarNames scalarConts expString
)
--this function takes the parsed data from the xml and then prepares it so it can be passed to the generateExpressionIM function
fn prepStringForExpression expObj expCont expString scalarObjects scalarNames scalarConts facialRollout =
(
-- initDebugVal = debugPrintVal
-- if expObj == "upperLip_L_OFF" then
-- (
-- debugPrintVal = true
--
-- format ("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n")
-- )
axisToUse = (substring expCont 1 1)
transType = (substring expCont 3 50)
--firstly need to add a controller to the stack with the name of the first scalarName.
debugPrint ("trying to get node "+expObj)
expressionObj = getNodeByName expObj
appendIfUnique rigBones expressionObj
if expressionObj == undefined then
(
--print ("SSSSSSSSSSSSSSSSSHHHHHHHHHHHHHHHHHIT. Couldnt find "+expObj)
)
else
(
if (expressionObj.position.controller as string) != "Controller:Position_List" do
(
expressionObj.position.controller = Position_List ()
expressionObj.rotation.controller = Rotation_List ()
expressionObj.scale.controller = Scale_List ()
)
controllerCount = ("$"+expObj+"."+transType+".controller."+"count")
controllerCount = execute controllerCount
myBoneObj = getNodeByName expObj
foundCont = false
contName = scalarNames[1]
ctrlCountStr = ("$"+myBoneObj.name+"."+transType+".controller.count")
ctrlCount = execute ctrlCountStr
for i = ctrlCount to 1 by -1 do
(
myContStr = ("$"+myBoneObj.name+"."+transType+".controller["+(i as string)+"].name")
myContName = execute myContStr
if myContName == (contName) do
(
debugPrint ("Found "+transType+" on "+("$"+myBoneObj.name+"."+transType+".controller"))
foundCont = true
)
)
controllerCount = ("$"+expObj+"."+transType+".controller."+"count")
controllerCount = execute controllerCount
if foundCont == false then
(
if transType == "Rotation" then
(
expContForMaxStr = ("$"+expObj+"."+transType+".controller."+"available.controller = Euler_XYZ ()")
--debugPrint ("executing: "+expContForMaxStr)
expContForMax = execute expContForMaxStr
)
else
(
if transType == "Position" then
(
expContForMaxStr = ("$"+expObj+"."+transType+".controller."+"available.controller = Position_XYZ ()")
--debugPrint ("executing: "+expContForMaxStr)
expContForMax = execute expContForMaxStr
)
else
(
expContForMaxStr = ("$"+expObj+"."+transType+".controller."+"available.controller = ScaleXYZ ()")
--debugPrint ("executing: "+expContForMaxStr)
expContForMax = execute expContForMaxStr
)
)
expContForMaxStr = ("$"+expObj+"."+transType+".controller.setName "+((controllerCount + 1) as string)+" "+"\""+scalarNames[1]+"\"")
--debugPrint ("executing: "+expContForMaxStr)
execute expContForMaxStr
expContForMaxStr = ("$"+expObj+"."+transType+".controller["+((controllerCount + 1) as string)+"]."+expCont+".controller = Float_Expression ()")
--debugPrint ("executing: "+expContForMaxStr)
execute expContForMaxStr
expCont = ("."+transType+".controller["+((controllerCount + 1) as string)+"]."+expCont+".controller")
)
else
(
debugPrint ("scalarNames[1] = "+(scalarNames[1]))
debugPrint ("transType = "+transType)
debugPrint ("expCont = "+expCont)
debugPrint (" fullStr="+ ("."+transType+".controller."+(scalarNames[1])+"."+expCont+".controller"))
expContForMaxStr = ("$"+expObj+"."+transType+".controller."+(scalarNames[1])+"."+expCont+".controller = Float_Expression ()")
--debugPrint ("executing: "+expContForMaxStr)
execute expContForMaxStr
expCont = ("."+transType+".controller."+(scalarNames[1])+"."+expCont+".controller")
)
--now for each controller in the scalarConts array we need to build that controller string
for i = 1 to scalarConts.count do
(
if ((substring scalarConts[i] 1 1) == "c") or ((substring scalarConts[i] 1 1) == "C") then
(
scalCont = (substring scalarConts[i] 3 200)
debugPrint "====================================================="
facialRollout = ("."+scalarObjects[i]+"_A")
debugPrint ("Attempting to use "+facialRollout+" with object "+scalarObjects[i])
tmpScalarCont = ("$"+scalarObjects[i]+".modifiers[#Attribute_Holder]"+facialRollout+"."+scalCont+"_CA.controller")
debugPrint ("---FOUND CUSTOM ATTR: "+tmpScalarCont )
scalarConts[i] = tmpScalarCont
)
else
(
axisToUse = (substring scalarConts[i] 1 1)
transType = (substring scalarConts[i] 3 50)
debugPrint ("scalarConts["+(i as string)+"] = "+scalarConts[i])
debugPrint ("transType = "+transType)
cType = undefined
if (transType == "Rotation") or (transType == "rotation") then
(
debugPrint "transType = Rotation"
ctype = "Zero_Euler_XYZ."
)
else
(
if (transType == "Position") or (transType == "position") then
(
debugPrint "transType = Position"
cType = "Zero_Pos_XYZ."
)
else
(
debugPrint "transType = Scale"
cType = "Zero_Scale_XYZ."
)
)
if useZeroControllers == false do
(
cType = "" --this will stop us from looking for a frozen controller
)
tmpScalarCont = ("$"+scalarObjects[i]+"."+transType+".controller."+cType+scalarConts[i]+".controller")
scalarConts[i] = tmpScalarCont
)
)
debugprint "\r\n"
debugPrint ("NEW scalarConts = "+(scalarConts as string))
prepExpressionString expObj expCont scalarObjects scalarNames scalarConts expString
)
-- debugPrintVal = initDebugVal
)
fn createCattRollout objName rolloutName attrName attrMin attrMax= --function to create attribute holder and custom attributes inisde it
(
--objName = string of object to receive the attribute holder
--rolloutName = string for name of rollout
--attrName = name of the attribute as seen in the UI
currentJoystick = getNodeByName objName
debugPrint ("currentJoystick = "+currentJoystick.name)
if currentJoystick.modifiers[#Attribute_Holder] == undefined do
(
addModifier currentJoystick (EmptyModifier())
debugPrint ("Added Attr holder to "+currentJoystick.name)
)
-- need to put a test in here for if the custom attribute already exists
facialMultipliersCA = (currentJoystick.name +"CA")
posVal = "1"
negval = "-1"
defaultVal = "0"
------------------------------------------------
rolloutCreateStr1 = (facialMultipliersCA +" = attributes "+rolloutName +"\n" +"(" +"\n" +"\t" +"parameters main rollout:params"+"\n" +"\t"+"(" )
rolloutCreateStr2 = "" --start as empty string
for i = 1 to attrName.count do
(
codeTrackName= (attrName[i]+"_CA") --name as seen inside the code and track view
cAttrName = attrName[i]--name as seen in the ui
rolloutCreateStr2 = (rolloutCreateStr2 +( "\n" +"\t" +"\t" +codeTrackName+" type:#float ui:" +codeTrackName+" default:" +defaultVal ))
)
rolloutCreateStr3 = ("\n"+"\t"+")"+"\n" +"\t" +"rollout params "+" \"" +rolloutName+"\"" +"\n" +"\t" +"(" )
rolloutCreateStr4 = ""
for i = 1 to attrName.count do
(
posVal = attrMax[i]
negVal = attrMin[i]
codeTrackName= (attrName[i]+"_CA") --name as seen inside the code and track view
cAttrName = attrName[i]--name as seen in the ui
rolloutCreateStr4 = (rolloutCreateStr4 +"\n" +"\t"+"\t" +"spinner "+codeTrackName+" \"" +cAttrName+"\"" +" "+"fieldwidth:40 range:["+(negVal as string)+","+(posVal as string)+","+(defaultVal as string)+"] type:#float" )
)
rolloutCreateStr5 = ("\n" +"\t" +")" +"\n" +")"+"\n" +"\n" +"\t" +"custAttributes.add $" +currentJoystick.name+".modifiers[#'Attribute holder'] "+facialMultipliersCA)
rolloutCreation = (rolloutCreateStr1 + rolloutCreateStr2 + rolloutCreateStr3 +rolloutCreateStr4 +rolloutCreateStr5)
debugprint ("rolloutCreation should do:")
debugprint rolloutCreation
execute rolloutCreation
--now add bezier floats controllers to these attributes
for i = 1 to attrName.count do
(
codeTrackName= (attrName[i]+"_CA") --name as seen inside the code and track view
cont1 = ("$"+currentJoystick.name+".modifiers[#Attribute_Holder]."+rolloutName+"."+codeTrackName+".controller = bezier_float ()")
debugprint ("TRYING: "+cont1)
doneCont1 = execute cont1
if doneCont1 != undefined then
(
debugprint ("Custom Attribute created: "+("$"+currentJoystick.name+".modifiers[#Attribute_Holder]."+rolloutName+"."+codeTrackName+".controller"))
)
else
(
messagebox "FUCK SAKE! Couldnt make it" beep:true
)
)
)
fn parseXML =
(
rigBones = #()
if facialXmlFile == undefined do
(
facialXmlFile = getOpenFileName caption:"Facial XML File" types:"XML Data (*joint*.xml)|*joint*.xml|All Files (*.*)|*.*|"
)
debugPrint ("Picked "+facialXmlFile)
mappingXmlFile = facialXmlFile
xmlDoc = XmlDocument()
xmlDoc.init()
xmlDoc.load mappingXmlFile
xmlRoot = xmlDoc.document.DocumentElement
if facialXmlFile != undefined then
(
-- Parse the XML
dataElems = xmlRoot.childnodes
--print "Beginning XML Parse..."
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
createDialog progBar width:400 Height:30
--bit hacky way of ensuring that attribute holders and their attributes do not get regenerated.
for i = 0 to (dataElems.Count - 1 ) do
(
a = ((dataElems.count as float) / 100)
progBar.prog.value = (1.*i/a)
objName = undefined
rolloutName = undefined
attrName = #()
attrMin = #()
attrMax = #()
expObj = undefined
expCont = undefined
expString = undefined
scalarObjects = #()
scalarNames = #()
scalarConts = #()
facialRollout = ""
dataElement = dataElems.itemof(i)
debugPrint ("i = "+(i as string))
--need to do a pre-process here for all cAtt objects and delete existing attribute holders
if dataElement.name == "cAtt" do
(
elementAttrs = dataElement.attributes
debugPrint ("Found "+(elementAttrs.count as string)+" attributes")
for ea = 0 to (elementAttrs.count - 1 ) do
(
debugPrint (ea as string)
currentElem = elementAttrs.itemOf(ea)
debugPrint ("currentElem = "+(currentElem.name as string))
--now we can test for the values
if (currentElem.Name as string) == "objName" do
(
debugPrint (currentElem.Name+" matched "+"objName")
objName = (currentElem.value as string)
)
if (currentElem.Name as string) == "rolloutName" do
(
debugPrint (currentElem.Name+" matched "+"expCont")
rolloutName= (currentElem.value as string)
)
)
--now delete any old attribute modifiers and create a new one
currObj = getNodeByName objName
if currObj != undefined do
(
m = currObj.modifiers[#Attribute_Holder]
if m != undefined do
(
deleteModifier currObj m
)
addModifier currObj (EmptyModifier())
)
)
)
--now do the real stuff
for i = 0 to (dataElems.Count - 1 ) do
(
a = ((dataElems.count as float) / 100)
progBar.prog.value = (1.*i/a)
objName = undefined
rolloutName = undefined
attrName = #()
attrMin = #()
attrMax = #()
expObj = undefined
expCont = undefined
expString = undefined
scalarObjects = #()
scalarNames = #()
scalarConts = #()
facialRollout = ""
dataElement = dataElems.itemof(i)
debugPrint ("i = "+(i as string))
--need to do a pre-process here for all cAtt objects and delete existing attribute holders
if dataElement.name == "cAtt" do
(
elementAttrs = dataElement.attributes
debugPrint ("Found "+(elementAttrs.count as string)+" attributes")
for ea = 0 to (elementAttrs.count - 1 ) do
(
debugPrint (ea as string)
currentElem = elementAttrs.itemOf(ea)
debugPrint ("currentElem = "+(currentElem.name as string))
--now we can test for the values
if (currentElem.Name as string) == "objName" do
(
debugPrint (currentElem.Name+" matched "+"objName")
objName = (currentElem.value as string)
)
if (currentElem.Name as string) == "rolloutName" do
(
debugPrint (currentElem.Name+" matched "+"expCont")
rolloutName= (currentElem.value as string)
)
)
)
debugPrint ("dataElementName = "+(dataElement.name))
if dataElement.name == "cAtt" do
(
elementAttrs = dataElement.attributes
debugPrint ("Found "+(elementAttrs.count as string)+" attributes")
for ea = 0 to (elementAttrs.count - 1 ) do
(
debugPrint (ea as string)
currentElem = elementAttrs.itemOf(ea)
debugPrint ("currentElem = "+(currentElem.name as string))
--now we can test for the values
if (currentElem.Name as string) == "objName" do
(
debugPrint (currentElem.Name+" matched "+"objName")
objName = (currentElem.value as string)
)
if (currentElem.Name as string) == "rolloutName" do
(
debugPrint (currentElem.Name+" matched "+"expCont")
rolloutName= (currentElem.value as string)
)
)
--now we look at the children
dataElemChildren = dataElement.childNodes
debugPrint ("Found "+(dataElemChildren.count as string)+" attributes.")
for c = 0 to (dataElemChildren.count - 1) do
(
--ok we're now looking at the driven for this node
childElement = dataElemChildren.itemOf[c]
childAttrs = childElement.attributes
for cA = 0 to (childAttrs.count - 1) do
(
currentChildElem = childAttrs.itemOf(cA)
debugPrint ("currentChildElem = "+(currentChildElem.name))
debugPrint ("found "+currentChildElem.name )
if currentChildElem.name == "attrName" do
(
--**** NEED TO STRIP OFF THE c_ ON THE START OF THE STRING
valToAppend = (substring currentChildElem.value 3 50)
append attrName (valToAppend as string)
debugprint "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
debugprint "\r"
debugPrint ("adding "+valToAppend+" to attrName array...")
debugPrint ("attrName count = "+(attrName.count as string))
debugprint "\r"
debugprint "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
)
if currentChildElem.name == "attrMin" do
(
append attrMin currentChildElem.value
)
if currentChildElem.name == "attrMax" do
(
append attrMax currentChildElem.value
)
)
)
debugprint ("count A = "+(attrName.count as string))
--run the create rollout here
debugprint ("objName = "+objName)
debugprint ("rolloutName = "+rolloutName)
debugprint ("attrName = "+(attrName as string))
clearSelection()
createCattRollout objName rolloutName attrName attrMin attrMax
)
if dataElement.name == "driven" do
(
--ok now we need to query the attributes of this node
elementAttrs = dataElement.attributes
debugPrint ("Found "+(elementAttrs.count as string)+" attributes")
for ea = 0 to (elementAttrs.count - 1 ) do
(
debugPrint (ea as string)
currentElem = elementAttrs.itemOf(ea)
debugPrint ("currentElem = "+(currentElem.name as string))
--now we can test for the values
if (currentElem.Name as string) == "expObj" do
(
debugPrint (currentElem.Name+" matched "+"expObj")
expObj = currentElem.value
)
if (currentElem.Name as string) == "expCont" do
(
debugPrint (currentElem.Name+" matched "+"expCont")
expCont = currentElem.value
)
if (currentElem.Name as string) == "expString" do
(
debugPrint (currentElem.Name+" matched "+"expString")
expString = currentElem.value
)
)
--------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------
--now we look at the children
dataElemChildren = dataElement.childNodes
debugPrint ("\r\n"+"Found "+(dataElemChildren.count as string)+" attributes.")
for c = 0 to (dataElemChildren.count - 1) do
(
--ok we're now looking at the driven for this node
childElement = dataElemChildren.itemOf[c]
childAttrs = childElement.attributes
debugPrint ("c = "+(c as string))
for cA = 0 to (childAttrs.count - 1) do
(
-- I CAN DO A TEST TO SEE THE COUNT OF CA AND IF ITS 4 WE
--KNOW ITS A CUSTOM ATTR SO MAYBE THAT WAY WE CAN DO THEM FIRST?
debugPrint ("cA = "+(cA as string))
currentChildElem = childAttrs.itemOf(cA)
debugPrint "-------------------------------------------------------------------------------------"
debugPrint ("**** currentChildElem = "+(currentChildElem.name))
if currentChildElem.name == "scalarObjects" do
(
append scalarObjects currentChildElem.value
debugPrint ("adding "+currentChildElem.value+" to scalarObjects array...")
debugPrint ("scalarObjects count = "+(scalarObjects.count as string))
)
if currentChildElem.name == "scalarNames" do
(
append scalarNames currentChildElem.value
debugPrint ("adding "+currentChildElem.value+" to scalarNames array...")
debugPrint ("scalarNames count = "+(scalarNames.count as string))
)
if currentChildElem.name == "scalarConts" do
(
append scalarConts currentChildElem.value
debugPrint ("adding "+currentChildElem.value+" to scalarConts array...")
debugPrint ("scalarConts count = "+(scalarConts.count as string))
)
if currentChildElem.name == "rolloutName" do
(
facialRollout = ("."+currentChildElem.value)
debugPrint ("facialRollout = "+(currentChildElem.value as string))
)
)
)
debugPrint "-----------------------------------------------------------------------"
debugPrint ("expObj = "+expObj)
debugPrint ("expCont = "+expCont)
debugPrint ("expStr = "+expString)
debugPrint ("scalarObjects = "+scalarObjects as string)
debugPrint ("scalarNames = "+scalarNames as string)
debugPrint ("scalarConts = "+scalarConts as string)
debugPrint ("facialRollout = "+facialRollout as string)
debugPrint "-----------------------------------------------------------------------"
prepStringForExpression expObj expCont expString scalarObjects scalarNames scalarConts facialRollout
)
)
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
prepScaleOffset()
for tb = 1 to rigBones.count do
(
spclCase = false
thisBone = rigBones[tb]
if thisBone != undefined then
(
--need to ensure we dont remove controllers on the nonConcatJoints as they arent concatted
concatThis = true
for nc = 1 to nonConcatJoints.count do
(
if thisBone.name == nonConcatJoints[nc] do
(
--concatThis = false
)
)
if concatThis == true do
(
debugprint ("Running removeOldScaleControllers on "+thisBone.name)
removeOldScaleControllers thisBone
)
)
else
(
--print ("WARNING! Couldn't find "+(rigBones[tb] as string))
)
)
)
else
(
messagebox "Please select a valid xml file." Beep:true
)
)
-- use a callback to press the buttons
-- I found this here: http://forums.cgsociety.org/showthread.php?t=485300
fn LSW_FBXImportCallbackFunction =
(
WindowHandle = DialogMonitorOPS.GetWindowHandle()
theDialogName = UIAccessor.GetWindowText WindowHandle
if theDialogName != undefined and matchpattern theDialogName pattern:"*FBX Import*" do
UIAccessor.PressButtonByName WindowHandle "OK"
true
)
fn importSelectedFBX facialFBXFile autoClick =
(
-- Fix was from here: http://tech-artists.org/forum/showthread.php?p=4034
-- Use a callback to press the buttons
-- I found this here: http://forums.cgsociety.org/showthread.php?t=485300
if autoClick == true do
(
DialogMonitorOPS.RegisterNotification LSW_FBXImportCallbackFunction ID:#myFBXImporterFunction
DialogMonitorOPS.Enabled = true
)
--think i need to call the import here
-- pluginManager.loadClass FBXIMP
pluginManager.loadClass FBXIMPORTER
FbxImporterSetParam "Animation" false
FbxImporterSetParam "Shape" true
FbxImporterSetParam "Skin" true
-- FbxImporterSetParam "ImportBoneAsDummy"
FbxImporterSetParam "Mode" "merge"
-- FbxImporterSetParam "ScaleConversion" false
-- FbxImporterSetParam "ConvertUnit" "merge" "cm"
FbxImporterSetParam "ConvertUnit" "cm"
FbxImporterSetParam "ScaleFactor" 1.0
-- FbxImporterSetParam "ImportBoneAsDummy" false
importFile facialFBXFile using:FBXIMPORTER --have to do this with the #noPrompt flag turned off cos the fbx importer is buggy as shit and otherwise ignores the settings
if autoClick == true do
(
DialogMonitorOPS.Enabled = false
DialogMonitorOPS.UnRegisterNotification ID:#myFBXImporterFunction
)
)
fn addBonesToExpressionSet selectionSetName nodesToAdd =
(
expSet = selectionSets[selectionSetName]
tmpObjs = #()
if expSet != undefined then
(
for ss = 1 to expSet.count do
(
append tmpObjs expSet[ss]
)
)
else
(
expSet = #()
)
for ts = 1 to nodesToAdd.count do
(
appendIfUnique tmpObjs nodesToAdd[ts]
debugPrint ("adding "+nodesToAdd[ts].name+" to "+selectionSetName+" selection set")
)
deleteItem selectionSets selectionSetName
selectionSets[selectionSetName] = tmpObjs
)
fn addTags =
(
offFaceCTRLS = #($mouth_CTRL, $jaw_CTRL, $tongueMove_CTRL, $tongueRoll_CTRL, $tongueInOut_CTRL, $outerBrow_R_CTRL, $innerBrow_L_CTRL, $outerBrow_L_CTRL, $innerBrow_R_CTRL, $eye_C_CTRL, $eye_L_CTRL, $eye_R_CTRL, $nose_L_CTRL, $nose_R_CTRL, $cheek_L_CTRL, $cheek_R_CTRL)
mySel = #()
for o in objects do
(
oName = o.name
oNameLength = o.name.count
if (substring o.name 1 6) == "FACIAL" do
(
append mySel o
)
)
-- for o in offfaceCTRLS do
-- (
-- --COMMENTED OUT AS WE DONT WANT TO TAG CTRL OBJECTS
-- --appendIfUnique mySel o
-- )
format "initialising tag arrays... \n"
tagDataArray = RSTA_populateBoneTagMappingArray boneTagMappingXmlFile
format "tag arrays initialised.\n"
for b = 1 to mySel.count do
(
setUserPropBuffer mySel[b] "" --clear off any existing shit
if mySel[b].name == "SKEL_Head" then
(
bTag = RSTA_findBoneTag mySel[b].name tagDataArray
if bTag != "UNKNOWN" do
(
setUserProp mySel[b] "tag" bTag
)
setUserProp mySel[b] "exportTrans = " "False"
setUserProp mySel[b] "exportScale = " "False"
)
else
(
if mySel[b].name == "SKEL_Neck_1" then
(
bTag = RSTA_findBoneTag mySel[b].name tagDataArray
if bTag != "UNKNOWN" do
(
setUserProp mySel[b] "tag" bTag
)
setUserProp mySel[b] "exportTrans = " "False"
setUserProp mySel[b] "exportScale = " "False"
)
else
(
if mySel[b].name == "RB_Neck_1" then
(
bTag = RSTA_findBoneTag mySel[b].name tagDataArray
if bTag != "UNKNOWN" do
(
setUserProp mySel[b] "tag" bTag
)
setUserProp mySel[b] "exportTrans = " "False"
setUserProp mySel[b] "exportScale = " "False"
)
else
(
nameTag = ""
if mySel[b].name == "FACIAL_facialRoot" then
(nameTag = ("tag"+"FACIAL_facialRoot")
)
else
(
nameTag = ("tagBONETAG_"+mySel[b].name)
)
scaleTag = ("False")
transTag = ("False")
relScaleTag = "False"
if (mySel[b].scale.controller as string) == "Controller:Scale_List" DO
(
scaleContCount = mySel[b].scale.controller.count
for sc = 2 to scaleContCount do
(
if (classOf mySel[b].scale.controller[sc].X_Scale.controller as string) == "Float_Expression" do
(
scaleTag = "True"
relScaleTag = "true"
)
if (classOf mySel[b].scale.controller[sc].Y_Scale.controller as string) == "Float_Expression" do
(
scaleTag = "True"
relScaleTag = "true"
)
if (classOf mySel[b].scale.controller[sc].Z_Scale.controller as string) == "Float_Expression" do
(
scaleTag = "True"
relScaleTag = "true"
)
)
)
if (mySel[b].position.controller as string) != "Controller:Position_XYZ" do
(
transContCount = mySel[b].position.controller.count
for tc = 2 to transContCount do
(
if ((mySel[b].position.controller[tc]) as string) != "SubAnim:RsSpring" do
(
if (classOf mySel[b].position.controller[tc].X_Position.controller as string) == "Float_Expression" do
(
transTag = ("\r\n"+"exportTrans = True")
)
if (classOf mySel[b].position.controller[tc].Y_Position.controller as string) == "Float_Expression" do
(
transTag = ("\r\n"+"exportTrans = True")
)
if (classOf mySel[b].position.controller[tc].Z_Position.controller as string) == "Float_Expression" do
(
transTag = ("\r\n"+"exportTrans = True")
)
)
)
)
nameTag = RSTA_findBoneTag mySel[b].name tagDataArray
if mySel[b].name == "FACIAL_facialRoot" then
(
nameTag = ("FACIAL_facialRoot")
)
if nameTag != "UNKNOWN" do
(
setUserProp mySel[b] "tag" nameTag
)
setUserProp mySel[b] "exportTrans" transTag
setUserProp mySel[b] "exportScale" scaleTag
setUserProp mySel[b] "relScale" relScaleTag
)
)
)
)
--now tag the on face controls
tagOnFaceCtrls()
)
--called during full prep
fn prepSceneForMashup =
(
max unhide all
--first of all we need to merge into a new scene the GUI file
--so we need to pick it from somewhere
if facialGUIFile == undefined do
(
facialGUIFile = getOpenFileName caption:"Max GUI File" types:"Max Data (*.Max)|*.max|All Files (*.*)|*.*|"
)
if facialGUIFile != undefined do
(
--now we need to pick the fbx file with the mesh etc
if facialFbxFile == undefined do
(
facialFbxFile = getOpenFileName caption:"FBX Facial File" types:"FBX Data (*.FBX)|*.fbx|All Files (*.*)|*.*|"
)
if facialFbxFile != undefined do --ok we've picked the gui and mesh files so we can now go ahead and merge shit
(
if facialXmlFile == undefined do
(
facialXmlFile = getOpenFileName caption:"Facial XML File" types:"XML Data (*joint*.xml)|*joint*.xml|All Files (*.*)|*.*|"
)
currentObjects = objects as array
mergeMaxFile facialGUIFile
--now tag the on face controls
tagOnFaceCtrls()
--need to find all nodes added since the merge
postMergeObjs = objects as array
for cO = currentObjects.count to 1 by -1 do
(
for pM = postMergeObjs.count to 1 by -1 do
(
if currentObjects[cO] == postMergeObjs[pM] do
(
deleteItem postMergeObjs pM
)
)
)
controlGUIObjects = deepcopy postmergeObjs
for cGo = 1 to controlGUIObjects.count do
(
select controlGUIObjects[cGo]
FreezeTransform()
)
if useZeroControllers == true then
(
currentObjects = objects as array
unitSetting = FBXImporterGetParam "ConvertUnit"
if unitSetting != #cm then
(
messagebox ("FBX Importer not set to cm."+"\r\n"+"Please manually adjust and click ok.") beep:true
autoClick = false
)
else
(
autoClick = true
)
importSelectedFBX facialFBXFile autoClick --have to use a function with a callback so we can auto click the ok button
postMergeObjs = objects as array
for cO = currentObjects.count to 1 by -1 do
(
for pM = postMergeObjs.count to 1 by -1 do
(
if currentObjects[cO] == postMergeObjs[pM] do
(
deleteItem postMergeObjs pM
)
)
)
for i = 1 to postMergeObjs.count do
(
objectName = postMergeObjs[i].name
objectLength = objectName.count
if (substring postMergeObjs[i].name (objectLength - 3) 4) != "CTRL" do
(
select postMergeObjs[i]
FreezeTransform()
)
)
select postMergeObjs
newObjects = objects as array
nodesToAdd = #()
for nO = 1 to newObjects.count do
(
if (substring newObjects[nO].name 1 6) == "FACIAL" do
(
append nodesToAdd newObjects[nO]
)
)
--now need to tag too
addTags()
selectionSetName = "*EXPRESSIONS"
addBonesToExpressionSet selectionSetName nodesToAdd --this will add the facial bones to the *EXPRESSIONS selection set
)
else
(
currentObjects = objects as array
unitSetting = FBXImporterGetParam "ConvertUnit"
if unitSetting != #cm then
(
messagebox ("FBX Importer not set to cm."+"\r\n"+"Please manually adjust and click ok.") beep:true
autoClick = false
)
else
(
autoClick = true
)
importSelectedFBX facialFBXFile autoClick--have to use a function with a callback so we can auto click the ok button
postMergeObjs = objects as array
for cO = currentObjects.count to 1 by -1 do
(
for pM = postMergeObjs.count to 1 by -1 do
(
if currentObjects[cO] == postMergeObjs[pM] do
(
deleteItem postMergeObjs pM
)
)
)
select postMergeObjs
newObjects = selection as array
nodesToAdd = #()
for nO = 1 to newObjects.count do
(
if classOf newObjects[nO] != PolyMeshObject do
(
append nodesToAdd newObjects[nO]
)
)
selectionSetName = "*EXPRESSIONS"
addBonesToExpressionSet selectionSetName nodesToAdd --this will add the facial bones to the *EXPRESSIONS selection set
)
)
)
)
--function used when doing a simple clean scene prep
fn prepScene =
(
max unhide all
facialGUIFile = undefined
allObjects = objects as array
if facialGUIFile == undefined do
(
facialGUIFile = getOpenFileName caption:"Max GUI File" types:"Max Data (*.Max)|*.max|All Files (*.*)|*.*|"
)
if facialGUIFile != undefined do
(
--now we need to pick the fbx file with the mesh etc
facialFbxFile = undefined
if facialFbxFile == undefined do
(
facialFbxFile = getOpenFileName caption:"FBX Facial File" types:"FBX Data (*.FBX)|*.fbx|All Files (*.*)|*.*|"
)
if facialFbxFile != undefined do --ok we've picked the gui and mesh files so we can now go ahead and merge shit
(
facialXmlFile = undefined
if facialXmlFile == undefined do
(
facialXmlFile = getOpenFileName caption:"Facial XML File" types:"XML Data (*joint*.xml)|*joint*.xml|All Files (*.*)|*.*|"
originalObjects = objects as array
mergeMaxFile facialGUIFile
if useZeroControllers == true then
(
unitSetting = FBXImporterGetParam "ConvertUnit"
if unitSetting != #cm then
(
messagebox ("FBX Importer not set to cm."+"\r\n"+"Please manually adjust and click ok.") beep:true
autoClick = false
)
else
(
autoClick = true
)
importSelectedFBX facialFBXFile autoClick--have to use a function with a callback so we can auto click the ok button
currentObjects = objects as array
for i = 1 to currentObjects.count do
(
if (substring currentObjects[i].name 1 6) == "FACIAL" do
(
select currentObjects[i]
FreezeTransform()
)
)
newObjects = objects as array
--now find which are original objects and which have been merged in
for mO = newObjects.count to 1 by -1 do
(
for oo = 1 to originalObjects.count do
(
if originalObjects[oo] == newObjects[mO] do
(
deleteItem newObjects mO
)
)
)
nodesToAdd = #()
for nO = 1 to newObjects.count do
(
if classOf newObjects[nO] != PolyMeshObject do
(
append nodesToAdd newObjects[nO]
)
)
selectionSetName = "*EXPRESSIONS"
addBonesToExpressionSet selectionSetName nodesToAdd --this will add the facial bones to the *EXPRESSIONS selection set
)
else --ok we're not using zeroed controllers
(
currentObjects = objects as array
unitSetting = FBXImporterGetParam "ConvertUnit"
if unitSetting != #cm then
(
messagebox ("FBX Importer not set to cm."+"\r\n"+"Please manually adjust and click ok.") beep:true
autoClick = false
)
else
(
autoClick = true
)
importSelectedFBX facialFBXFile autoClick--have to use a function with a callback so we can auto click the ok button
select currentObjects
max select invert
newObjects = selection as array
nodesToAdd = #()
for nO = 1 to newObjects.count do
(
if classOf newObjects[nO] != PolyMeshObject do
(
append nodesToAdd newObjects[nO]
)
)
selectionSetName = "*EXPRESSIONS"
addBonesToExpressionSet selectionSetName nodesToAdd --this will add the facial bones to the *EXPRESSIONS selection set
)
)
)
parsexml()
for i = 1 to geoNames[2].count do
(
--hack
head = getNodeByName geoNames[2][1]
--end hack
if head != undefined do
(
head.modifiers[#Skin].always_deform = false
head.modifiers[#Skin].always_deform = true
)
)
)
)
fn createNormalsJoystick jsname jpos =
(
jstyle = 2 -- 2 = vertical slider
foundJS = getnodeByName jsName
if foundJS == undefined then
(
debugprint (jsName+" not found so initialising creation...")
createJoystick jsname jstyle jpos 1
--now add animated normals track
thisJS = getNodeByName jsname
setUserPropBuffer thisJs ("translateTrackType=TRACK_ANIMATED_NORMAL_MAPS")
--now set params for text and joytstick bounding box thing to not be frozen as gray then freeze
surrBox = (getNodeByName ("RECT_"+jsName))
surrBox.showFrozenInGray = false
surrBox.isFrozen = true
textItem = (getNodeByName ("TEXT_"+jsName))
textItem.showFrozenInGray = false
textItem.isFrozen = true
--now add joysticks to expression set
selectionSetName = "*EXPRESSIONS"
thisJSArray = #()
append thisJSArray thisJS
addBonesToExpressionSet selectionSetName thisJSArray
)
else
(
debugprint (jsName+" found so skipping creation.")
)
)
fn parseNormalsXML =
(
jp = 0.5
jCount = 0
jHeight = 0
if normalsXmlFile == undefined do
(
normalsXmlFile = getOpenFileName caption:"Normals XML File" types:"XML Data (*slider*.xml)|*slider*.xml|All Files (*.*)|*.*|"
)
debugPrint ("Picked "+normalsXmlFile)
mappingXmlFile = normalsXmlFile
xmlDoc = XmlDocument()
xmlDoc.init()
xmlDoc.load mappingXmlFile
xmlRoot = xmlDoc.document.DocumentElement
if normalsXmlFile != undefined then
(
-- Parse the XML
dataElems = xmlRoot.childnodes
--print "Beginning Normal XML Parse..."
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
createDialog progBar width:400 Height:30
for i = 0 to (dataElems.Count - 1 ) do
(
a = ((dataElems.count as float) / 100)
progBar.prog.value = (1.*i/a)
maskExpStringArray = #() --array of expression strings
maskNameArray = #() --array of mask textures
maskSliderArray = #() --array of sliders
maskDriverSpnObjArray = #() --array of driver objects which are custom attributes
maskDriverSpnNameArray = #() --array of names of custom attributes
maskDriverSpnScalarNameArray = #() --array of scalar names for custom attributes
maskDriverJSObjArray = #() -- array of joysticks used as drivers
maskDriverJSTransformArray = #() --array of transform used from joysticks
maskDriverJSScalarNameArray = #() --array of scalar names from joysticks
dataElement = dataElems.itemof(i)
debugPrint ("i = "+(i as string))
debugPrint ("dataElementName = "+(dataElement.name))
if dataElement.name == "mask" do
(
elementAttrs = dataElement.attributes
debugPrint ("Found "+(elementAttrs.count as string)+" attributes")
for ea = 0 to (elementAttrs.count - 1 ) do
(
currentElem = elementAttrs.itemOf(ea)
--now we can test for the values
if (currentElem.Name as string) == "maskExpString" do
(
maskExpString = (currentElem.value as string)
append maskExpStringArray maskExpString
)
if (currentElem.Name as string) == "maskName" do
(
maskName= (currentElem.value as string)
append maskNameArray maskName
)
if (currentElem.Name as string) == "maskSlider" do
(
maskSlider = (currentElem.value as string)
append maskSliderArray maskSlider
)
)
--now we look at the children
dataElemChildren = dataElement.childNodes
for c = 0 to (dataElemChildren.count - 1) do
(
--ok we're now looking at the driven for this node
childElement = dataElemChildren.itemOf[c]
childAttrs = childElement.attributes
for cA = 0 to (childAttrs.count - 1) do
(
currentChildElem = childAttrs.itemOf(cA)
if currentChildElem.name == "maskDriverJSObj" do
(
append maskDriverJSObjArray currentChildElem.value
)
if currentChildElem.name == "maskDriverJSTransform" do
(
append maskDriverJSTransformArray currentChildElem.value
)
if currentChildElem.name == "maskDriverJSScalarName" do
(
append maskDriverJSScalarNameArray currentChildElem.value
)
if currentChildElem.name == "maskDriverSpnObj" do
(
append maskDriverSpnObjArray currentChildElem.value
)
if currentChildElem.name == "maskDriverSpnName" do
(
append maskDriverSpnNameArray currentChildElem.value
)
if currentChildElem.name == "maskDriverSpnScalarName" do
(
append maskDriverSpnScalarNameArray currentChildElem.value
)
)
)
--now we need to build the joysticks
--first off we need to make the joystick parent text so we can move them all around at once....
textParent = undefined
textParent = getNodeByName "TEXT_Normals"
if textParent == undefined do
(
textParent = text size:0.1 kerning:0 leading:0 pos:[0.81,-0.0,0.105736] isSelected:on
textParent.name = "TEXT_Normals"
textParent.text = "Normals"
in coordsys world textParent.rotation = (quat 0.707107 0 0 0.707107)
textParent.render_displayRenderMesh = true
textParent.thickness = 0.0025
textParent.sides = 3
max modify mode
modPanel.addModToSelection (Edit_Poly ()) ui:on
collapsestack textParent
)
jCount = jCount+1
divider = 2.3
if jCount < 5 then --1 to 4
(
jp = (0+((jCount as float)/ divider ))
jHeight = -0.0
)
else
(
if JCount < 9 then -- 5 to 8
(
jp = (0+(((jCount as float)- 4) / divider ))
jHeight = -0.15
)
else
(
if JCount < 13 then --9 to 12
(
jp = (0+(((jCount as float)- 8) / divider ))
jHeight = -0.3
)
else
(
if JCount <17 then --13 to 16
(
jp = (0+(((jCount as float)- 12) / divider ))
jHeight = -0.60
)
else
(
if JCount <21 then --17 to 20
(
jp = (0+(((jCount as float) - 16) / divider ))
jHeight = -0.75
)
else
(
jp = (0+(((jCount as float) - 20) / divider ))
jHeight = -0.9
)
)
)
)
)
jPos = [(0.5 +( jp / 3.5)),-0.5,jHeight]
jsName = maskSliderArray[1]
debugprint ("jsName: "+jsName)
createNormalsJoystick jsname jpos
thisJS = getNodeByName jsName
setUserPropBuffer thisJS "translateTrackType = TRACK_ANIMATED_NORMAL_MAPS"
thisJsPar = thisJS.parent
thisJSPar.parent = textParent
in coordsys parent thisJSPar.position.controller.z_position = 0.0
expObj = ("'"+maskSliderArray[1]+"'")
expCont = (".position.controller[2].Y_Position.controller")
scalarObjects = #()
scalarNames = #()
scalarConts = #()
--now we need to first setup the expressions from joysticks
--we need to create the paths for the driver controllers ( be they joysticks or cAtts)
theseConts = #()
for c = 1 to maskDriverJSObjArray.count do
(
thisTrans = (substring maskDriverJSTransformArray[c] 3 60)
thisContObjStr = ("$"+maskDriverJSObjArray[c]+"."+thisTrans+".controller[2]."+maskDriverJSTransformArray[c]+".controller")
append scalarObjects maskDriverJSObjArray[c]
append scalarConts thisContObjStr
append scalarNames maskDriverJSScalarNameArray[c]
)
for c = 1 to maskDriverSpnScalarNameArray.count do
(
tmpScalarCont = ("$"+maskDriverSpnObjArray[c]+".modifiers[#Attribute_Holder]."+maskDriverSpnObjArray[c]+"_A"+"."+maskDriverSpnNameArray[c]+"_CA.controller")
append scalarObjects maskDriverSpnObjArray[c]
append scalarConts tmpScalarCont
append scalarNames maskDriverSpnScalarNameArray[c]
)
expString = maskExpStringArray[1]
--before we add the expression we need to change the expCont into a float Expression
execStr = ("$"+expObj+expCont+" = Float_Expression()")
execute execStr
generateExpressionIM expObj expCont scalarObjects scalarNames scalarConts expString
)
)
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
--now position and scale the parent of all the normal joysticks
rootObject = getNodeByName "TEXT_Normals"
in coordsys world rootObject.position = [0.45,0,1.6]
in coordsys world rootObject.scale = [0.25,0.25,0.25]
hide rootObject
)
else
(
messagebox "Please select a valid xml file." Beep:true
)
)
--function for running when doing a full prep creation
fn prepHeadForMashup =
(
masterScene = (maxFilePath + maxFileName)
hideByCategory.none
--save skinning info on all skinned objects
for o in objects do
(
if o.modifiers[#Skin] != undefined do
(
saveSkinData o
)
)
--we need to add a prefix onto the original dupJoints
for o = 1 to dupJoints.count do
(
myJnt = getNodeByName dupJoints[o]
if myJnt != undefined do
(
myJnt.name = ("ORIG_"+myJnt.name)
)
)
prepSceneForMashup()
hideByCategory.none
currentObjects = objects as array
for i = 1 to geoNames[2].count do
(
geo = getNodeByNameWildcard geoNames[2][i]
if geo == undefined do
(
messagebox ("warning! couldnt find a node called "+geoNames[2][i])
--print ("warning! couldnt find a node called "+geoNames[2][i])
)
saveSkinData geo
)
for i = 1 to dupJoints.count do --give the 3Lateral joints a prefix
(
thisJoint = getNodeByName dupJoints[i]
thisJoint.name = ("3L_"+thisJoint.name)
)
hideByCategory.none
for i = 1 to geoNames[2].count do --now parent the geo to the geo dummy
(
max unhide all
max unfreeze all
geo = getNodeByName "uppr_000_u"
if geo == undefined do (geo = getNodeByNameWildcard "uppr_000")
geoPar = geo.parent
geo = getNodeByNameWildcard geoNames[2][i]
geo.parent = geoPar
)
--now we can delete the 3L joints
for i = 1 to dupJoints.count do
(
thisJoint = getNodeByName ("3L_"+dupJoints[i])
debugPrint ("Deleting 3Later Joint: "+("3L_"+dupJoints[i]))
delete thisJoint
)
for i = 1 to dupJoints.count do --name the original joints back
(
thisJoint = getNodeByName ("ORIG_"+dupJoints[i])
if thisJoint != undefined do
(
thisJoint.name = dupJoints[i]
)
)
--now parent the facialRoot node to the head
facialRootNode = getNodeByName "FACIAL_facialRoot"
facialRootParent = getNodeByName "SKEL_Head"
facialRootNode.parent = facialRootParent
skelJoints = #()
for o in objects do
(
if (substring o.name 1 4) == "SKEL" do
(
appendIfUnique skelJoints o
)
)
--re-create the skin modifiers
for i = 1 to geoNames[2].count do
(
geo = getNodeByNameWildcard geoNames[2][i]
if geo.modifiers[#Skin] != undefined do
(
select geo
execStr = ("collapseStack $"+geo.name)
execute execStr
)
loadSkinData geo
)
newObjects = objects as array
nodesToAdd = #()
for nO = 1 to newObjects.count do
(
if (substring newObjects[nO].name 1 6) == "FACIAL" do
(
append nodesToAdd newObjects[nO]
)
)
selectionSetName = "*EXPRESSIONS"
addBonesToExpressionSet selectionSetName nodesToAdd
parseXml()
newObjects = nodesToAdd
addTags()
for i = 1 to geoNames[2].count do
(
head = getNodeByNameWildcard geoNames[2][i]
if head != undefined do
(
head.modifiers[#Skin].always_deform = false
head.modifiers[#Skin].always_deform = true
)
)
--we now need to assign shaders to teef and tongue
matToUse = undefined
if shaderType == "Player" then
(
for i = 1 to 24 do
(
head = getNodeByNameWildcard geoNames[2][1]
teef = getNodeByNameWildcard geoNames[2][2]
if meditMaterials[i].name == "Head_RAGE" do
(
thisShader = meditMaterials[i].materialList[1]
matToUse = meditMaterials[i]
head.material = matToUse
debugprint "Updating head shader"
-- And set it to the correct default shader for characters
shadertoset = "ped_wrinkle_cs.sps"
RstSetShaderName thisShader shadertoset
--now need to find the wrinkleMap folder
if wrinkleFolder != undefined do
(
debugprint ("wrinkleFolder = "+wrinkleFolder)
--now we strip the wrinkleFolder path to prior to the texture name so we have the folder
pathLength = wrinkleFolder.count
imageLength = pathlength - 18
wrinklePath = (substring wrinkleFolder 1 imageLength)
debugprint ("Folder = "+wrinklePath)
wrinkleMasks = #(
#(
(wrinklePath+"HEAD_Wrinkle_Mask_0.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_1.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_2.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_3.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_4.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_5.tga"),
(wrinklePath+"HEAD_Wrinkle_A.tga"),
(wrinklePath+"HEAD_Wrinkle_B.tga")
),
#(
"Wrinkle Mask 0",
"Wrinkle Mask 1",
"Wrinkle Mask 2",
"Wrinkle Mask 3",
"Wrinkle Mask 4",
"Wrinkle Mask 5",
"Wrinkle A",
"Wrinkle B"
)
)
--NOW WE NEED TO COPY THE WRINKLES TO THE CHARACTERS TEXTURES\HIGHRES\ FOLDER
moveWrinkleMap wrinklePath wrinkleMasks
shdrParams = RstGetVariableCount thisShader
if shdrParams != undefined do
(
-- for sParam = 1 to shdrParams.count do
for sParam = 1 to shdrParams do
(
thisParam = RstGetVariableName thisShader sParam
for wm = 1 to wrinkleMasks[2].count do
(
if thisParam == wrinkleMasks[2][wm] do
(
print ("wrinkleMasks[1]["+(wm as string)+"]: "+(wrinkleMasks[1][wm] as string))
--now we need to set this parameter to be wrinkleMasks[1][wm]
RstSetVariable thisShader sParam wrinkleMasks[1][wm]
)
)
)
)
)
)
if meditMaterials[i].name == "Hair 2_RAGE" do
(
matToUse = meditMaterials[i]
teef.material = matToUse
debugprint ("updating TEEF shader")
)
)
)
else
(
head = getNodeByNameWildcard geoNames[2][1]
if head == undefined do
(
thisGeoName = undefined
if (substring geoNames[2][1] 1 1 ) == "H" do
(
thisGeoName = ("h"+(substring geoNames[2][1] 2 60 ) )
)
head = getNodeByNameWildcard thisGeoName
)
teef = getNodeByNameWildcard geoNames[2][2]
if teef == undefined do
(
thisGeoName = undefined
if (substring geoNames[2][1] 1 1 ) == "T" do
(
thisGeoName = ("t"+(substring geoNames[2][1] 2 60 ) )
)
teef = getNodeByNameWildcard thisGeoName
)
thisShader = meditMaterials[13].materialList[1]
matToUse = meditMaterials[13]
head.material = matToUse
debugprint "Updating head shader"
-- And set it to the correct default shader for characters
shadertoset = "ped_wrinkle_cs.sps"
RstSetShaderName thisShader shadertoset
--now need to find the wrinkleMap folder
if wrinkleFolder != undefined do
(
debugprint ("wrinkleFolder = "+wrinkleFolder)
--now we strip the wrinkleFolder path to prior to the texture name so we have the folder
pathLength = wrinkleFolder.count
imageLength = pathlength - 18
wrinklePath = (substring wrinkleFolder 1 imageLength)
debugprint ("Folder = "+wrinklePath)
wrinkleMasks = #(
#(
(wrinklePath+"HEAD_Wrinkle_Mask_0.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_1.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_2.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_3.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_4.tga"),
(wrinklePath+"HEAD_Wrinkle_Mask_5.tga"),
(wrinklePath+"HEAD_Wrinkle_A.tga"),
(wrinklePath+"HEAD_Wrinkle_B.tga")
),
#(
"Wrinkle Mask 0",
"Wrinkle Mask 1",
"Wrinkle Mask 2",
"Wrinkle Mask 3",
"Wrinkle Mask 4",
"Wrinkle Mask 5",
"Wrinkle A",
"Wrinkle B"
)
)
moveWrinkleMap wrinklePath wrinkleMasks
shdrParams = RstGetVariableCount thisShader
for sParam = 1 to shdrParams do
(
thisParam = RstGetVariableName thisShader sParam
for wm = 1 to wrinkleMasks[2].count do
(
if thisParam == wrinkleMasks[2][wm] do
(
print ("wrinkleMasks[1]["+(wm as string)+"]: "+(wrinkleMasks[1][wm] as string))
--now we need to set this parameter to be wrinkleMasks[1][wm]
RstSetVariable thisShader sParam wrinkleMasks[1][wm]
)
)
)
)
if foundPLayerShader ==true then
(
matToUse = meditMaterials[16]
)
else
(
matToUse = meditMaterials[13]
)
debugprint ("Original teef material = "+(teef.material as string))
teef.material = matToUse
debugprint ("Final teef material = "+(teef.material as string))
debugprint ("updating TEEF shader")
)
--now we setup the normals shit
parseNormalsXML()
-- now we need to ensure any scale controllers on the gui objects have also been concatenated
for i = 1 to controlGUIObjects.count do
(
thisBone = controlGUIObjects[i]
spclCaseConCat = false
if (classof thisBone.scale.controller as string) == "scale_list" do
(
concatThis = true
for nc = 1 to nonConcatJoints.count do
(
if thisBone.name == nonConcatJoints[nc] do
(
concatThis = false
spclCaseConCat = true
)
)
if concatThis == true do
(
if thisBone.scale.controller.count > 2 do
(
--now we need to check all existing controllers and see if they are x y or z so we know if we need to add a correspondig offset
xCont = false
yCont = false
zCont = false
for c = 2 to thisBone.scale.controller.count do
(
xC = thisBone.scale.controller[c].X_Scale.controller
yC = thisBone.scale.controller[c].Y_Scale.controller
zC = thisBone.scale.controller[c].Z_Scale.controller
if (xC as string) == "Controller:Float_Expression" do
(
xCont = true
)
if (yC as string) == "Controller:Float_Expression" do
(
yCont = true
)
if (zC as string) == "Controller:Float_Expression" do
(
zCont = true
)
)
if xCont == true do
(
concatScale thisBone "X_Scale" spclCaseConCat
)
if yCont == true do
(
concatScale thisBone "Y_Scale" spclCaseConCat
)
if zCont == true do
(
concatScale thisBone "Z_Scale" spclCaseConCat
)
)
removeOldScaleControllers thisBone
)
)
)
--now run the external file to set the joystick limits back
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/3Lateral/addJoyystickLimits.ms")
-- Now convert the spline geo joysticks and text to alphad planes for speed in motionbuilder
convertStandardGuiToAlphaGUI()
)
fn justXml = --this will prep all nodes for the just xml segment
(
--first we need to get all joints in the head
--then we need to freeze all controllers
bonesInSkin = #()
facialXmlFile = undefined
if facialXmlFile == undefined do
(
facialXmlFile = getOpenFileName caption:"Facial XML File" types:"XML Data (*joint*.xml)|*joint*.xml|All Files (*.*)|*.*|"
)
headNode = getNodeByName geoNames[2][1]
if headNode != undefined do
(
select headNode
max modify mode
modPanel.setCurrentObject $.modifiers[#Skin]
if headNode.modifiers[#Skin] != undefined do
(
--now we need to get all joints in the skin modifier and add to the bonesInSkin array
boneIndexes = skinOps.GetNumberBones headNode.modifiers[#Skin]
for i = 1 to boneIndexes do
(
currentBoneName = skinOps.GetBoneName headNode.modifiers[#Skin] i 0
appendIfUnique bonesInSkin currentBoneName
)
)
--now we need to freeze transforms on bonesInSkin nodes
for i = 1 to bonesInSkin.count do
(
fbL = facialBonePrefix.count
if (substring bonesInSkin[i] 1 fbl) == facialBonePrefix do
(
thisNode = getNodeByName bonesInSkin[i]
select thisNode
freezeTransform()
)
)
)
parseXml()
for i = 1 to geoNames[2].count do
(
--hack
head = getNodeByName geoNames[2][1]
--end hack
if head != undefined do
(
head.modifiers[#Skin].always_deform = false
head.modifiers[#Skin].always_deform = true
)
)
-- messagebox "Done!" Beep:true
print "Done!"
)
fn queryMat = --function which queries shader names to see if shaders in scene are old school or new PLAYER style
(
for i = 1 to 24 do
(
if meditMaterials[i].name == "Upper_RAGE" do
(
foundPLayerShader = true
)
)
)
-- A function here will prebake all selected model parts to a default gray
fn vertPrebake =
(
setCommandPanelTaskMode #modify
selectMeshes2Bake = #()
for meshes2Bake=1 to geoNames[2].count do
(
selectByWildcard geoNames[2][meshes2Bake]
tempSelection = getCurrentSelection()
appendIfUnique selectMeshes2Bake tempSelection[1]
)
for i = 1 to selectMeshes2Bake.count do
(
obj = selectMeshes2Bake[i]
-- Turn on the Vertex colours, set to channel 0
obj.showVertexColors = on
obj.vertexColorType = 0
try-- For each object in turn, go to the base mesh
(
modPanel.setCurrentObject obj.baseObject
subobjectLevel = 1 -- Go to vertex mode
nv=0 -- get number of verts in the object
if classof obj == Editable_Poly then
(
nv = obj.numverts
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
createDialog progBar width:400 Height:30
for i = 1 to nv do
(
polyop.setvertcolor $ TheColourChannel i Ped_BakeColour
polyop.setvertcolor $ TheRimChannel i Ped_RimColour
polyop.setvertcolor $ TheWindChannel i Ped_WindColour
polyop.setvertcolor $ TheEnvEffChannel i Ped_EnvEffColour
polyop.setvertcolor $ TheAlphaChannel i Ped_AlphaColour
a = (nv / 100)
progBar.prog.value = (1.*i/a)
)
)
if classof obj == Editable_Mesh then
(
nv = obj.numverts
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
createDialog progBar width:400 Height:30
for i = 1 to nv do
(
meshop.setvertcolor $ TheColourChannel i Ped_BakeColour
meshop.setvertcolor $ TheRimChannel i Ped_RimColour
meshop.setvertcolor $ TheWindChannel i Ped_WindColour
meshop.setvertcolor $ TheEnvEffChannel i Ped_EnvEffColour
meshop.setvertcolor $ TheAlphaChannel i Ped_AlphaColour
a = (nv / 100)
progBar.prog.value = (1.*i/a)
)
)
if ((progBar != undefined) and (progBar.isDisplayed)) do
(destroyDialog progBar)
subobjectLevel = 0
)catch (print"Couldn't get to object base Epoly/EMesh")
) -- object selection loop
clearSelection()
) -- End vertPrebake
--a function to set "Weld Without Quantise" attribute on head and teef meshes
fn weldAttributes =
(
for meshes2Quantise = 1 to geoNames[2].count do
(
thisMesh = getNodeByNameWildcard geoNames[2][meshes2Quantise]
if thisMesh != undefined do
(
setAttribute thisMesh "Weld Without Quantise" true
)
)
)--end weldAttributes
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if ((highEndFacialSetupGUI != undefined) and (highEndFacialSetupGUI.isDisplayed)) do
(destroyDialog highEndFacialSetupGUI)
rollout highEndFacialSetupGUI "Highclass Facial"
(
checkBox chkDebugPrnt "DebugPrint" checked:false tooltip:"Check to enable debug --print output."
checkBox chkPsdhead "PSD" checked:false tooltip:"Enable if this is a Pose Space Deformer head."
spinner spn_vtxWeight "Influences" default:4 tooltip:"Number of weights per vertex" type:#integer
button btnPrepFull "Head & Body" width:110 tooltip:"Add head to a scene with a body."
button btnReconnectNormals "Re Wrinkle Map" width:110 tooltip:"Reconnect animated normal textures and shader"
on highEndFacialSetupGUI open do
(
chkDebugPrnt.state = false
debugPrintVal = false
spn_vtxWeight.value = 4
chkPsdheadVal = false
)
on chkDebugPrnt changed theState do
(
if chkDebugPrnt.state == false then
(
debugPrintVal = false
)
else
(
debugPrintVal = true
)
)
on chkPsdhead changed theState do
(
if chkPsdhead.state == false then
(
chkPsdheadVal = false
)
else
(
chkPsdheadVal = true
)
)
on btnPrepFull pressed do
(
while contin == true do --had to add a while as sometimes the script wouldnt exit correctly.
(
vtxWeight = spn_vtxWeight.value
startFr = timestamp()
deactivateHeels() --reset any heel joystick shit
--first off ensure we delete any existing facial_ nodes
iwannaDelete = #()
for o in objects do
(
if (substring o.name 1 7) == "FACIAL_" do
(
append iwannadelete o
)
)
delete iwannaDelete
upprGeo = getNodeByNameWildcard "uppr_000"
if upprGeo != undefined then
(
--first find what type of shaderType this character is
queryMat()
--need to query scene and if we find a shader called upper and lower then its player style and if its got Rage001 then its old school. If none then query
-- if queryBox "Click Yes if this is a player shader file or No for old style." beep:true then
if foundPLayerShader == true then
(
shaderType = "Player"
)
else
(
shaderType = "OldSchool"
)
facialXmlFile = undefined
facialXmlFile = getOpenFileName caption:"Facial XML File" types:"XML Data (*joint*.xml)|*joint*.xml|All Files (*.*)|*.*|"
facialFbxFile = getOpenFileName caption:"FBX Facial File" types:"FBX Data (*.FBX)|*.fbx|All Files (*.*)|*.*|"
facialGUIFile = getOpenFileName caption:"Max GUI File" types:"Max Data (*.Max)|*.max|All Files (*.*)|*.*|"
normalsXmlFile = getOpenFileName caption:"Normals XML File" types:"XML Data (*slider*.xml)|*slider*.xml|All Files (*.*)|*.*|"
wrinkleFolder = getOpenFileName caption:"Wrinkle Folder " types:"Tga files (HEAD_Wrinkle_A.tga)|HEAD_Wrinkle_A.tga|All Files (*.*)|*.*|"
prepHeadForMashup()
vertPrebake()
weldAttributes()
print ("Facial Hookup Complete.")
-- messagebox "Done!" Beep:true
)
else
(
messagebox ("Please ensure you have a character scene open to mash head onto.") beep:true
)
gc()
end = timeStamp()
format "Processing 3Lateral Hookup took % seconds\n" ((end - startFr) / 1000.0)
format "Processing 3Lateral Hookup took % minutes\n" (((end - startFr) / 1000.0) / 60)
--break()
testSync = true
toolFileName = getThisScriptFilename()
--messagebox (toolFileName as string)
versionNumber = getToolRevision toolFileName
versionTag = ("Generated with tool revision: "+(versionNumber as string)+"\n")
faceUI = getNodeByName "faceControls_FRAME"
setUserPropBuffer FaceUI versionTag
contin = false
if contin == false do exit --another attempt to hack an exit upon completion - some large files print the completion message thern hang using 100% system resources
)
)
on btnReconnectNormals pressed do
(
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/3Lateral/reconnectWrinkleMaps.ms")
)
)
CreateDialog highEndFacialSetupGUI width:125 pos:[1450, 100]