1040 lines
29 KiB
Plaintext
Executable File
1040 lines
29 KiB
Plaintext
Executable File
--April 2013
|
|
--Matt Rennie
|
|
--Tool to reconnect animated normal maps on heads to joysticks
|
|
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
RsCollectToolUsageData (getThisScriptFilename())
|
|
|
|
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms")
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
foundPLayerShader = undefined
|
|
|
|
geoNames = #( --names from fbx file
|
|
#(
|
|
),
|
|
#( --names for gta
|
|
"head_000_",
|
|
"Teef_000_"
|
|
)
|
|
)
|
|
|
|
normalsXmlFile = undefined
|
|
wrinkleFolder = undefined
|
|
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
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
|
|
(c
|
|
format ("WARNING!: "+(newTexture1.count as string))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
--messagebox ("realFolder == undefined")
|
|
-- break()
|
|
contin = false
|
|
)
|
|
)
|
|
|
|
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
|
|
)
|
|
|
|
|
|
|
|
-- 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))
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
need to pass in:
|
|
1) expObj = name of object the expression is for
|
|
2) expCont = controller the expression is on (as a string)
|
|
3) scalarObjects = name of objects used as drivers as an array of string
|
|
4) scalarNames = name of scalars - do this as an array (of strings) so we cna loop through multiple scalars
|
|
5) scalarConts = controller the scalars point to - do this as array (of strings) with an entry for each item in the scalarNames array
|
|
6) expString = full expression string
|
|
*/
|
|
|
|
--first off we'll check if we need to do the scale by scale fixup to the expstring
|
|
|
|
-- if findString expCont "cale" == true do
|
|
-- (
|
|
-- foundScale = undefined
|
|
-- for i in scalarConts do
|
|
-- (
|
|
-- if findString i "cale" == true do
|
|
-- (
|
|
-- foundScale = true
|
|
-- )
|
|
-- )
|
|
--
|
|
-- if foundScale == true do
|
|
-- (
|
|
-- messagebox ("applying scale fixup for "+(expObj as string))
|
|
-- break()
|
|
-- scaleFixUpScaleByScale expString
|
|
-- )
|
|
-- )
|
|
|
|
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))
|
|
|
|
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 "```````````````````````````````````````````````````````"
|
|
)
|
|
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
|
|
)
|
|
)
|
|
|
|
|
|
--SCALEOFFSETTEMPDISABLED
|
|
--SVN2 = "ScaleOffset"
|
|
|
|
-- SVN2Cont = $ScaleOffset.pos.controller.Zero_Pos_XYZ.controller.Y_Position.controller.Limited_Controller__Bezier_Float.Controller
|
|
-- SVN2Cont = $ScaleOffset.pos.controller.Zero_Pos_XYZ.controller.Y_Position.controller
|
|
|
|
-- newFcStr.AddScalarTarget SVN2 SVN2Cont
|
|
debugPrint ("setting expression to :\r\n"+expString)
|
|
|
|
newfcStr.SetExpression expString
|
|
|
|
debugPrint ("Expression created on "+expObj+" for "+expCont)
|
|
debugPrint "```````````````````````````````````````````````````````"
|
|
)
|
|
)
|
|
|
|
|
|
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 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
|
|
|
|
select thisJS
|
|
RSTA_FreezeTransform()
|
|
setUserPropBuffer thisJS "translateTrackType = TRACK_ANIMATED_NORMAL_MAPS"
|
|
|
|
thisJsPar = thisJS.parent
|
|
|
|
thisJSPar.parent = textParent
|
|
|
|
-- in coordsys parent thisJSPar.position.controller.z_position = 0.0
|
|
in coordsys parent thisJSPar.position[3] = 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
|
|
)
|
|
)
|
|
|
|
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
|
|
)
|
|
)
|
|
)
|
|
|
|
fn setupWrinkleShader =
|
|
(
|
|
defaultFilePath = maxfilepath
|
|
normalsXmlFile = getOpenFileName caption:"Normals XML File" types:"XML Data (*slider*.xml)|*slider*.xml|All Files (*.*)|*.*|" filename:defaultFilePath
|
|
wrinkleFolder = getOpenFileName caption:"Wrinkle Folder " types:"Tga files (HEAD_Wrinkle_A.tga)|HEAD_Wrinkle_A.tga|All Files (*.*)|*.*|" filename:defaultFilePath
|
|
|
|
queryMat()
|
|
|
|
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
|
|
|
|
wrinkleMasks = #(
|
|
#(
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined
|
|
),
|
|
#(
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined,
|
|
undefined
|
|
)
|
|
)
|
|
--now need to find the wrinkleMap folder
|
|
if wrinkleFolder != undefined then
|
|
(
|
|
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]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
print "Warning wrinkleFolder == undefined"
|
|
)
|
|
)
|
|
|
|
--now we need to loop through all the other materials and set them to this wrinkle version
|
|
|
|
for slot = 14 to 24 do
|
|
(
|
|
if (classof meditmaterials[slot][1] as string) == "Rage_Shader" do
|
|
(
|
|
thisShader = meditMaterials[slot][1]
|
|
RstSetShaderName thisShader shadertoset
|
|
|
|
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]
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
parseNormalsXML()
|
|
)
|
|
|
|
setupWrinkleShader() |