Files
2025-09-29 00:52:08 +02:00

1622 lines
45 KiB
Plaintext
Executable File

--cs_ResourcePrep functions file
RSTA_LoadCommonFunction #("FN_Materials.ms")
-- format "Starting import\n"
filein (theWildWest + "script/3dsMax/Characters/Rigging/mrSkeleton_v2/mrSkeleton_2_functions.ms")
filein (theWildWest + "script/3dsMax/Characters/Rigging/mrSkeleton_v2/expressionExport/mrExpression_SpringHack.ms")
filein (theWildWest + "script/3dsMax/Characters/Rigging/mrSkeleton_v2/expressionExport/mrExpression_CutPasteController.ms")
filein (theWildWest + "script/3dsMax/Characters/Rigging/mrSkeleton_v2/expressionExport/mrExpression_Export.ms")
-- Function to test if an object is skinned and return true or false
fn RSTA_isMeshSkinned MyObject =
(
isSkinned = undefined
if MyObject.modifiers[#Skin] != undefined do
(
isSkinned = true
format (MyObject.name+" is skinned.\n")
)
if MyObject.modifiers[#Skin] == undefined do
(
isSkinned = false
format (MyObject.name+" isn't skinned.\n")
)
return isSkinned
)
fn findLodObjects =
(
lodStrings = #(
"_LOD", --end of string
"_SLOD", --end of string
"_lod_" --anywhere in string
)
lodObjects = #()
for obj in objects do
(
if superclassof obj == GeometryClass do
(
nameCount = obj.name.count
if (substring (toLower(obj.name)) (nameCount - 3) -1) == toLower(lodStrings[1]) do
(
appendIfUnique lodObjects obj
--format ("Appending "+lodStrings[1]+" "+obj.name+" to lodObjects.\n")
)
if (findString (toLower(obj.name)) (toLower(lodStrings[2]))) != undefined do
(
appendIfUnique lodObjects obj
--format ("Appending "+lodStrings[2]+" "+obj.name+" to lodObjects.\n")
)
if (findString (toLower(obj.name)) (toLower(lodStrings[3]))) != undefined do
(
appendIfUnique lodObjects obj
--format ("Appending "+lodStrings[3]+" "+obj.name+" to lodObjects.\n")
)
)
)
return lodObjects
)
-- collects all children recursively. arguments:
-- found on http://forums.cgsociety.org/showpost.php?p=4427477&postcount=2
fn CollectChildren obj &allChildren includeParent:false includeHidden:false =
(
-- check if object should be collected
if (includeHidden or not obj.isHiddenInVpt) and includeParent and finditem allChildren obj == 0 then
append allChildren obj
-- collect current object's children
for c in obj.children do CollectChildren c &allChildren includeParent:true includeHidden:includeHidden
) -- end collectChildren
-- tidy up the user defined properties by sorting it alphabetically
fn ReorderTags tagMe =
(
currentUDP = getUserPropbuffer tagMe
filterUDP = filterString currentUDP "\r\n"
alphUDP = sort filterUDP
tag = ""
for t = 1 to alphUDP.count do
(
tag = tag + alphUDP[t] + "\r\n"
setUserPropbuffer tagMe tag
)
)-- end reorderTags
-- delete any mesh info tags. this includes selection sets and meshnames
-- deleteFromThese = the meshes to delete from
fn DelFileInfoTags deleteThisMesh =
(
keepUDP = #()
currentUDP = getUserPropbuffer deleteThisMesh
filterUDP = filterString currentUDP "\r\n"
for f = 1 to filterUDP.count do
(
tempUDP = uppercase filterUDP[f]
shortUDP = substring tempUDP 1 7
if (shortUDP != "MAXFILE") then
append keepUDP tempUDP
)
tag = ""
if keepUDP.count == 0 then
setUserPropbuffer deleteThisMesh tag
else
for k = 1 to keepUDP.count do
(
tag = tag + keepUDP[k] + "\r\n"
setUserPropbuffer deleteThisMesh tag
)
ReorderTags deleteThisMesh
)-- end delFileInfoTags
-- go through all geometry and tag it with the maxscene name
fn TagFileNameInfo meshToTag =
(
tagThis = ""
tagThis = "MaxFile=" + maxfilepath + maxfilename
oldTag = getUserPropbuffer meshToTag
tagThis = oldTag+"\r\n"+tagThis
tagThis = uppercase tagThis
setUserPropbuffer meshToTag tagThis
ReorderTags meshToTag --tidy up the tags
)-- end tagFileNameInfo
fn CaptureDisplay =
(
filein (RsConfigGetWildWestDir() + "script/3dsMax/Cutscene/CutsceneCaptureSphereDisplay.ms")
)
fn restoreMaterials rageMaterialsArray =
(
if rageMaterialsArray != undefined then
(
if rageMaterialsArray.count == 24 then
(
for i = 1 to rageMaterialsArray.count do
(
-- for tmp = 1 to rageMaterialsArray[i][1].count do
-- (
-- format ("Restoring "+(tmp as string)+" "+(rageMaterialsArray[i][1][tmp] as string)+"\n")
-- )
meditMaterials[i] = rageMaterialsArray[i][1][1]
rageMat = meditMaterials[i]
if rageMaterialsArray[i][2].count > 0 then
(
for obj = 1 to rageMaterialsArray[i][2].count do
(
thisObj = rageMaterialsArray[i][2][obj]
thisObj.material = rageMat
)
)
)
format ("Materials restored.")
)
else
(
format ("Could not find stored materials array.\n")
)
)
else
(
messagebox ("Rage materials have not been stored so we cannot restore them. Sorry\n") beep:true
)
)
fn Export mode =
(
case mode of
(
#cutscene:
(
messagebox "Export #cutscene"
)
#game:
(
messagebox "Export #game"
)
)
)
fn PrepareVehicle=
(
print "Preparing vehicle"
if selection.count != 0 then
(
vehicleMeshes = getCurrentSelection()
-- vehicleMeshes = #()
-- appendIfUnique vehicleMeshes driver
-- for obj in skelArray do
-- (
-- appendIfUnique vehicleMeshes obj
-- )
SortAndSwitch vehicleMeshes
VehicleSetup()-- driver skelArray
)
else
(
if queryBox "Nothing selected.\r\nI will attempt to perform this on all objects in the scene.\r\nThis could take a while.\r\nDo you want to continue?" beep:false do
(
hideByCategory.none() -- unhide all by categry
max unhide all -- unhide all
max select all --select all
vehicleMeshes = getCurrentSelection()
-- vehicleMeshes = #()
-- appendIfUnique vehicleMeshes driver
-- for obj in skelArray do
-- (
-- appendIfUnique vehicleMeshes obj
-- )
clearSelection()
SortAndSwitch vehicleMeshes
VehicleSetup()
-- VehicleSetup driver skelArray
)
)
)
fn PrepareMap =
(
print "Preparing map"
if queryBox "I will attempt to delete all materials in the scene.\r\nDo you want to continue?" beep:false do
(
-- clear_all_materials()
format ("Cleared all materials...\n")
-- kill_materials()
format ("Killed all materials...\n")
CSMapExport()
format ("CS Map Exported.\n")
)
)
fn SetupEnvironment =
(
filein (RsConfigGetWildWestDir() + "script/3dsMax/Cutscene/cs_enviroment_setup.ms")
)
------------------------------------------------------------------------------------------------------------------------------------------
--WORKHORSE FUNCTIONS
------------------------------------------------------------------------------------------------------------------------------------------
fn CullTextures =
(
print "Cull Textures"
local shaders = getClassInstances StandardMaterial
local diffuseMaps = for item in shaders where item.diffuseMap != undefined collect item.diffuseMap
local buffer = #()
local mapKeepList = #() --array of map id's that we are going to keep
--work out which maps to keep
(
if (CutsceneDataPrepUI.AlphaCheckBox.Checked) then
append mapKeepList 6
)
clearlistener()
-- for item in diffuseMaps where item.bitmap != undefined do
for item in diffuseMaps do
(
try
(
item.bitmap
append buffer item
)
catch (print "problem with " + item as string)
)
diffuseMaps = makeUniqueArray buffer
for item in diffuseMaps do
(
print item.bitmap
)
-- print diffuseMaps
)
fn UnskinnedProp theProp exportAlso =
--theProp = a single mesh
(
convertto theProp editable_poly --convert mesh to edit poly
ResetTransform theProp --reset xforms
convertto theProp editable_poly --convert mesh to edit poly again to be sure
--move selected to 0,0,0 worldspace
in coordsys world theProp.pos = [0,0,0]
print "Prop defined and moved to center"
-- newRootSystem = BuildRigRootSystem theProp
RSTA_buildPropRoot theProp false false
-- rootObj = newRootSystem[2][1]--this should be the dummy
-- movObj = newRootSystem[2][2]--this should be the mover
rootObj = getNodeByName ("Dummy_"+theProp.name)
movObj = getNodeByName ("Mover_"+theProp.name)
local newRootSystem = #(
#(),
#()
)
newRootSystem[1] = RSTA_getAllChildren rootObj arr:newRootSystem[1]#()
if classOf rootObj == Dummy do--we are going to tag the dummy with the filename
(
DelFileInfoTags rootObj --delete the tags off the children of the export dummy
TagFileNameInfo rootObj --tag mesh information
)
for boneDel=1 to newRootSystem[1].count do
(
if newRootSystem[1][boneDel] != rootObj then
(
if newRootSystem[1][boneDel] != movObj then
(
delete newRootSystem[1][boneDel]
)
)
)
theProp.parent = movObj--parent the prop to the mover
exportMeshes = #()
CollectChildren rootObj &exportMeshes includeParent:true includeHidden:true --collect all the skeleton heirarchy
appendIfUnique exportMeshes theProp
hideByCategory.none() -- unhide all by categry
max unhide all -- unhide all
clearSelection()
select exportMeshes
max hide inv
if exportAlso == true do
(
--hacky export selected as method. needs better way.
actionMan.executeAction 0 "40373" -- File: Export Selected
)
)--end UnskinnedProp
--****************************************************************************************
fn SkinnedProp theProp exportAlso =
--theProp = a single mesh
(
exportMeshes = #(theProp)
skinningBones = #()
objectsToShow = #()
rootObj = undefined
if (RSTA_isMeshSkinned theProp) == true do--if the mesh is skinned
(
skinMod = theProp.modifiers[#Skin]
modPanel.setCurrentObject skinMod
skinnedBoneCount = skinops.getNumberBones skinMod
if skinnedBoneCount > 0 do --if there are bones in the skin modifier
(
realBone = getBoneFromSkin skinMod 1 --find a real bone in the scene
rootObj = WWfindRootObject realBone --find the root of the heirarchy
CollectChildren rootObj &skinningBones includeParent:true includeHidden:true --collect all the skeleton heirarchy
)
)--if the mesh is skinned remember it
if classOf rootObj == Dummy do--we are going to tag the dummy with the filename
(
DelFileInfoTags rootObj --delete the tags off the children of the export dummy
TagFileNameInfo rootObj --tag mesh information
)
objectsToShow = exportMeshes
join objectsToShow skinningBones
selectionsets["*CS Export"] = objectsToShow --create selection set of everything
hideByCategory.none() -- unhide all by categry
max unhide all -- unhide all
clearSelection()
select objectsToShow
max hide inv
if exportAlso == true do
(
--hacky export selected as method. needs better way.
actionMan.executeAction 0 "40373" -- File: Export Selected
)
)--end SkinnedProp
--attempt to find the export dummy
fn findTheDummy =
(
characterNode = undefined
try
(
selectByWildCard "head_000" --there should always be a head mesh
if selection.count > 0 then --if we find at least 1 mesh
(
obj = selection[1]
exportDummy = WWfindRootObject obj
clearSelection()
exportDummy --pass out the export dummy
)
else
(
print "I couldn't find my head"
)
)catch()
)--end findTheDummy
fn ShowSkinningAndBones =
(
if ((progBar != undefined) and (progBar.isDisplayed)) do (destroyDialog progBar)
CreateDialog progBar width:300 Height:30
progBar.prog.color = [225, 110, 35] --green
max modify mode
exportMeshes = #()
skinningBones = #()
objectsToShow = #()
characterNode = FindTheDummy() --find the export dummy
if classOf characterNode == Dummy do--we are going to tag the dummy with the filename
(
DelFileInfoTags characterNode --delete the tags off the children of the export dummy
TagFileNameInfo characterNode --tag mesh information
)
if characterNode != undefined then
(
progBar.prog.value = 20
CollectChildren characterNode &exportMeshes includeParent:false includeHidden:true --collect all the skeleton heirarchy
if exportMeshes.count > 0 do
(
progBar.prog.value = 40
for checkMesh = 1 to exportMeshes.count while skinningBones.count == 0 do
(
if (RSTA_isMeshSkinned exportMeshes[checkMesh]) == true do--if the mesh is skinned
(
progBar.prog.value = 60
skinMod = exportMeshes[checkMesh].modifiers[#Skin]
modPanel.setCurrentObject skinMod
skinnedBoneCount = skinops.getNumberBones skinMod
if skinnedBoneCount > 0 do --if there are bones in the skin modifier
(
progBar.prog.value = 80
realBone = getBoneFromSkin skinMod 1 --find a real bone in the scene
rootObj = WWfindRootObject realBone --find the root of the heirarchy
CollectChildren rootObj &skinningBones includeParent:true includeHidden:true --collect all the skeleton heirarchy
progBar.prog.value = 100
)
)--if the mesh is skinned remember it
)
)
objectsToShow = exportMeshes
join objectsToShow skinningBones
appendIfUnique objectsToShow characterNode
selectionsets["*CS Export"] = objectsToShow --create selection set of everything
hideByCategory.none() -- unhide all by categry
max unhide all -- unhide all
clearSelection()
select objectsToShow
max hide inv
(destroyDialog progBar)
)
else
(
progBar.prog.color = [255,0,0]--red
progBar.prog.value = 100
print "Couldn't find the export dummy!"
(destroyDialog progBar)
)
exportMeshes--pass out the meshes for the shader change
)--end showSkinningAndBones
fn VehicleSetup =
--copied from vehicle_export_setup.ms
(
savePath = theProjectRoot + "/art/animation/resources/vehicles/"
maxName = undefined
vehicleMesh = #()
parentDummy = undefined
vehicleSkel = #()
everything = #()
--this is a neater way of getting all children. alt method to using actionMan.executeAction 0 "40180"
fn selectHierarchy whatGeo =
(
for p in whatGeo do
(
if p.children != undefined do
(
selectmore p.children
)
)
)--end selectHierarchy
maxName = filterstring maxFileName "_" --this should get the prefix of vehicle name which is always vehiclename_skinned.max
chassisBoneName = (maxName[1]+"_Skel")
try (delete $Dummy01) catch()--try and delete a dummy mesh if it exists already
parentDummy = dummy pos:[0,0,0]
parentDummy.name = "Dummy01"
skel = getNodeByName chassisBoneName
if (skel != undefined) then
(
skel.parent = parentDummy
print (chassisBoneName+" parented to "+parentDummy.name)
hideByCategory.none()--unhide everything by category
unhide (for obj in objects where obj.ishidden collect obj) --unhide all
maxName = filterstring maxFileName "_"
meshName = maxName[1] + "_skin"
try
(
vehicleMesh = getNodeByName meshName
) catch (print ("Couldn't find " +meshName))
hideByCategory.none()--unhide everything by category
unhide (for obj in objects where obj.ishidden collect obj) --unhide all
try
(
selectHierarchy parentDummy --select the children (and children's children) of the parentdummy
-- clearSelection()
-- select skelArray
selectmore parentDummy --add the dummy to the selection
selectionsets["*vehicleSkel"] = selection --create selection set of everything
vehicleSkel = getCurrentSelection()
clearSelection()
print "vehicle skeleton found"
) catch (messagebox "Can't Find Parent Dummy" title:"Materials Export Manager") --attempt to select the export dummy
everything = vehicleSkel
appendIfUnique everything vehicleMesh
select everything
saveFile = savePath + maxName[1]
exportFile saveFile #noPrompt selectedOnly:true using:FBXEXP
messageText = maxName[1] + " exported as FBX to " + saveFile + ".fbx"
messageBox messageText title:"Materials Export Manager"
)
else
(
messageBox "Selected vehicle has no skeleton." title:"Materials Export Manager"
)
)--end vehicleSetup
--function for getting the shader/material values and storing them
fn SwitchRageToStd matID =
(
if classof mlib[MatID] == Multimaterial then --if the material is a multisub then we want to look in it
(
for SubID = 1 to mlib[MatID].numSubs do --for every multisub in this material
(
if classof mlib[matid][subid] == Rage_Shader then
(
varValue = ""--set an undefined value for the bitmap path
for x=1 to RstGetVariableCount mlib[matid][subid] do
(
--if the variable type is texmap, the map type is diffuse and the path is not undefined
if (uppercase (RstGetVariableType mlib[matid][subid] x)) == "TEXMAP" and (findstring (uppercase (RstGetVariableName mlib[matid][subid] x)) "DIFFUSE TEXTURE") != undefined and (RstGetVariable mlib[matid][subid] x) != "" do
(
varValue = RstGetVariable mlib[matid][subid] x--store the bitmap path
)
)
mlib[matid][subid] = Standardmaterial () --change it to a standard material
mlib[matid][subid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
mlib[matid][subid].showInViewport = true
)
else
(
if classof mlib[matid][subid] == Standardmaterial then
(
if mlib[matid][subid].diffusemap != undefined do
(
varValue = mlib[matid][subid].diffusemap.filename
if varValue != undefined do
(
mlib[matid][subid] = Standardmaterial () --change it to a standard material
mlib[matid][subid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
mlib[matid][subid].showInViewport = true
)
)
)
else()
)
)
)
else
(
if classof mlib[matid] == Rage_Shader then
(
varValue = ""--set an undefined value for the bitmap path
for x=1 to RstGetVariableCount mlib[matid] do
(
--if the variable type is texmap, the map type is diffuse and the path is not undefined
if (uppercase (RstGetVariableType mlib[matid] x)) == "TEXMAP" and (findstring (uppercase (RstGetVariableName mlib[matid] x)) "DIFFUSE TEXTURE") != undefined and (RstGetVariable mlib[matid] x != "") do
(
varValue = RstGetVariable mlib[matid] x--store the bitmap path
)
)
mlib[matid] = Standardmaterial () --change it to a standard material
mlib[matid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
mlib[matid].showInViewport = true
)
else
(
if classof mlib[matid] == Standardmaterial then
(
if mlib[matid].diffusemap != undefined do
(
varValue = mlib[matid].diffusemap.filename
if varValue != undefined do
(
mlib[matid] = Standardmaterial () --change it to a standard material
mlib[matid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
mlib[matid].showInViewport = true
)
)
)
else()
)
)
)--end switchRageToStd
--function to filter selection and switch materials
fn SortAndSwitch meshesToSort =
(
--meshesToSort = an array of objects
--format ("Initialising sort and switch...\n")
meshesToChange = #()
if meshesToSort.count > 0 do
(
if ((progBar != undefined) and (progBar.isDisplayed)) do (destroyDialog progBar)
CreateDialog progBar width:300 Height:30
progBar.prog.color = [10,210,10] --green
for allSel = 1 to meshesToSort.count do
(
if superClassOf meshesToSort[allSel] == GeometryClass do
(
append meshesToChange meshesToSort[allSel]
format ("Added "+meshesToSort[allSel].name+" to meshesToChange.\n")
)
)
--format ((meshesToChange.count as string)+"")
if meshesToChange.count > 0 do
(
print "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
print "Starting Texture Swtich"
startTimer = timestamp()
print ("Converting "+ (meshesToChange.count as string) + " mesh materials.")
for selMesh=1 to meshesToChange.count do
(
if meshesToChange[selMesh].material != undefined do
(
mlib[24] = meshesToChange[selMesh].material
SwitchRageToStd 24
meshesToChange[selMesh].material = mlib[24]
)
progBar.prog.value = ((100* selMesh)/meshesToChange.count)
)
endTimer = timeStamp()
print "Texture Switch Complete"
format "Time taken: %s\n" ((endTimer - startTimer) / 1000.0)
print "^^^^^^^^^^^^^^^^^^^^^^"
)
destroyDialog progBar
)
)--end sortAndSwitch
--function for writing out the selection sets to a text file
fn WriteSelectionSets =
(
everything = #()
outputFolder = maxfilepath --output folder is the same as the max file
outputFile = outputFolder + "SelectionSets.txt" --save the file as "SelectionSets.txt"
selectionSetFile = createFile outputFile --now we make the text file using the above settings
--fileHeadText = ("Created on " + localtime)
--print fileHeadText to: selectionSetFile --write the system time to the text file
for ss = 1 to selectionsets.count do
(
singleSelSet = #(infoText = ("Selection Set " + ss as string + " of " + selectionsets.count as string)) --some header information
selSetName = SelectionSets[ss].name --the name of the selection set
append singleSelSet selSetName
matchSS = for obj in SelectionSets[ss] collect obj.name --turn sel.set into array
append singleSelSet matchSS
append everything singleSelSet
)
print everything to: selectionSetFile
close selectionSetFile --housekeeping. this closes the txt file
)--end writeSelectionSets
--function to setup map for cs export
--copied code from cs_enviroment_setup.ms
fn CSMapExport =
(
exportOk = false
if maxFileName != undefined then
(
--Unhide & unfreeze the dummy01 node
max unhide all
max unfreeze all
local rootNode = undefined
for rootName in #("Point01", "Point001") do
(
rootNode = getNodeByName rootName
if (isvalidNode rootNode) == true do
(
break
)
)
if (isvalidNode rootNode) == false do
(
messagebox ("Couldn't prep and export map as Point001/point01 not found. \n")
exportOk = false
return exportOk
)
rootNode.name = "PointOrig"
--Copy the "Point Orig" and rename
local setRoot = Copy rootNode
setRoot.name = "SetRoot"
--Set selection filter to select the geo and parent selection to the setroot
setSelectFilter 2
max select all
$.parent = setRoot
--Return Selection filter to all
SetSelectFilter 1
--Create "PointZerod2"
local PointZerod2 = Point pos:[0,0,0] isSelected:on name:"PointZerod2"
--Align Setroot to "PointZerod2"
setRoot.pos = PointZerod2.pos
--Parent the "PointZerod2" & "Point Orig" to the SetRoot
PointZerod2.parent = setRoot
rootNode.parent = setRoot
--select the "PointOrig" & Get offset information
offsetposition = rootNode.pos
Positionfilter = (offsetposition as string)
Position_offset_values = filterstring Positionfilter "[ ]"
PointOrigangle = rootNode.rotation as eulerAngles
offsetrotation= PointOrigangle.Z
Rotation_offset_values = (offsetrotation as string )
--Time & user stamp
timedate = localtime
Updatedby = sysInfo.username
Filename = maxFileName as string
Setname = filterString Filename "."
format ("Attempting to output offset file...\n")
-- create an offset co-ordinate file
makeDir @"X:\gta5\art\animation\resources\sets\Offsets"
output_name = ("X:\\gta5\\art\\animation\\resources\\sets\\Offsets\\"+ Setname[1] +".log")
outputFile = createfile output_name
format (("<<<<<< " +Setname[1] +" >>>>>>" )+"\n") to:outputFile
format (("Last updated by " + Updatedby + " on the " + timedate)+"\n") to:outputFile
format (("" )+"\n") to:outputFile
format (("Position Offset = " + Position_offset_values[1] )+"\n") to:outputFile
format (("Rotation Offset = " + Rotation_offset_values )+"\n") to:outputFile
close outputFile
format (output_name+" created.\n")
exportOk = true
)
else
(
messagebox ("Please save your max file and try again.\n")
)
return exportOk
)--csMapExport
fn PrepareProp exportAlso =
(
local initTrans = #(undefined, undefined)
if selection.count == 1 then
(
thisProp = getCurrentSelection()
--===========================================================================================================================
--a section to handle gun magazine meshes - bug 808586
gunMag == false
propName = upperCase thisProp[1].name --get the prop name
filterPropName = filterString propName "_" --filter the name for breaks
shortPropName = #() --an array to hold the shortened filter data
for x= 1 to filterPropName.count do (append shortPropName (subString filterPropName[x] 1 3))
magCheck = findItem shortPropName "MAG"
if magCheck !=0 do (if filterPropName[magCheck].count == 4 do gunMag = true)
--===========================================================================================================================
if ((RSTA_isMeshSkinned thisProp[1]) == true) and (gunMag != true) then--if the mesh is skinned
(
--if the mesh is skinned we need to zero the root of the rig
format "Preparing skinned prop...\n"
-- thisProp = getCurrentSelection()
thisProp = $
local rootObj = getNodeByName ("Dummy_"+thisProp.name)
if rootObj == undefined do
(
format ("Failed to find a root obj for "+thisProp.name+" of the form "+"\""+"Dummy_"+thisProp.name+"\""+"\n")
rootObj = getNodeByName (thisProp.name+"_Dummy")
)
if rootObj != undefined then
(
initTrans[1] = rootObj
initTrans[2] = rootObj.transform
rootObj.position = [0,0,0]
)
else
(
format ("Failed to find a root obj for "+thisProp.name+" of the form "+"\""+thisProp.name+"_Dummy"+"\""+"\n")
format ("No rig dummy found so skipping zeroing of position.\n")
)
SortAndSwitch #(thisProp)
SkinnedProp thisProp exportAlso
)
else
(
if queryBox "This appears to be an unskinned prop.\r\nI will attempt create a rig root setup for it.\r\nDo you want to continue?" beep:false title:"Materials Export Manager" do
(
--if the rig isnt skinned we zero its position first
format "Preparing unskinned prop\n"
thisProp = $
initTrans[1] = thisProp
initTrans[2] = thisProp.transform
thisProp.position = [0,0,0]
format (thisProp.name+".position = "+(thisProp.position as string)+"\n")
SortAndSwitch #(thisProp)
UnskinnedProp thisProp exportAlso
)
)
)
else (messageBox "Please run with only one object selected.")
return initTrans
)
fn PrepareCharacter =
(
print "Preparing character"
local pedMeshes = ShowSkinningAndBones()
SortAndSwitch pedMeshes
WriteSelectionSets()
-- addDummyData()
RSTA_addDummyData()
)
fn PrepareExpressions =
(
print "Preparing expressions"
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/usefulScripts/RSTA_cleanExpressionControllersForMotionBuilder.ms")
--from "X:\gta5\tools\wildwest\script\3dsMax\Characters\Rigging\riggingToolsGUI.ms" lines 154 -> 155
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/findExpressionObjects.ms")
print "Expression set Created"
exprItems = #()
selCount = getNumNamedSelSets()
for i = selCount to 1 by -1 do
(
if getNamedSelSetName i == "*expressionsToExport" then
(
setItems = getNamedSelSetItemCount i
for a = 1 to setItems do
(
thisItem = getNamedSelSetItem i a
appendIfUnique exprItems thisItem
)
)
)
select exprItems
--from "X:\gta5\tools\wildwest\script\3dsMax\Characters\Rigging\ExpressionExporter\expressionGUI.ms" lines 161 -> 164
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/ExpressionExporter/objectOutput.ms")
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/ExpressionExporter/expressionOutputXML.ms")
print "Expressions saved"
local dummyObj = getNodeByName "Dummy01"
local exprFile = undefined
local thisPath = maxFilePath
if thisPath != undefined do
(
if maxfileName != undefined do
(
local thisMaxFile = (filterstring (maxFileName as string) ".")
thisMaxFile = thisMaxFile[1]
local output_nameXML = (thisPath+thisMaxFile+"_RSNXML.xml")
if (doesFileExist output_NameXml) == true then
(
exprFile = output_nameXML
)
)
)
if dummyObj != undefined do
(
setUserProp dummyObj "exprFile" (exprFile as string)
)
)
fn rsta_exportFatExpressionXml fatXmlfileName =
(
format "Firing rsta_exportFatExpressionXml function\n"
max unhide all
local currsel = selection as array
-- local currsel = objects as array
max unfreeze all
tmpSel = objects as array
select tmpSel
max select all
-- local strName = filterstring fbxFileName "."
-- local fatxmlFile = strName[1]+".xml"
global missingDriverObjects = #() --used to store missing objects required in the expressions
global exprXmlFile = undefined -- used to store the name of the file the expressions will be saved to
global expressionObjects = #() --used to store which objects are epression driven
global ancilliaryLookAtNodes = #() --used to store look at targets / up vector nodes
global caDriverObjects = #()
global final_expressionData = #()--used to store all expression data
global final_springData = #()--used to store all spring data
global final_lookAtData = #() --used to store all lookAtData
global final_customAttrData = #() --used to store all custom attribute info
global controllersToZero = #() --used to store all expression controllers. We use this to zero their weights on export and then set back to 100%
RSTA_SaveExpressions fatXmlfileName undefined undefined
--now empty those arrays
global missingDriverObjects undefined
global exprXmlFile = undefined -- used to store the name of the file the expressions will be saved to
global expressionObjects = undefined
global ancilliaryLookAtNodes = undefined
global caDriverObjects = undefined
global final_expressionData = undefined
global final_springData = undefined
global final_lookAtData = undefined
global final_customAttrData = undefined
global controllersToZero = undefined
select currsel
format ("Fat xml expression export complete.\n")
)
fn rsta_findObjectsToKeep charDummy =
(
/**
WILL FIND ALL CHILDREN OF NODES IN NODES TO KEEP AND ENSURE THAT THESE ARE PASSED THROUGH AS A SELECTION
THIS CAN THEN BE USED TO FILTER WHAT WE TEMPORARILY DELETE FROM THE SCENE.
**/
objectsToKeep = #()
nodesToTest = #(
charDummy,
"FaceFX",
"Ambient_UI",
"Dummy01",
"faceControls_OFF",
"FacialAttrGUI",
"facialRoot_C_OFF",
"TEXT_Normals",
"WRINKLES_TEXT"
)
for obj in objects do
(
if substring obj.name 1 4 == "RECT" do
(
appendIfUnique nodesToTest obj.name
)
)
for item in nodesToTest do
(
thisNode = getNodeByName item
if thisNode != undefined then
(
append objectsToKeep thisNode
objectsToKeep = RSTA_getAllChildren thisNode arr:objectsToKeep#()
)
else
(
format ("Couldn't find "+(item as string)+"\n")
)
)
return objectsToKeep
)
fn rsta_exportFbx fbxFileName fbxVer exportSelected =
(
if fbxVer == 2010 then
(
format ("Exporting as fbx 2010\n")
--think i need to call the import here
pluginManager.loadClass FBXEXP
fbxExporterSetParam "FileVersion" "FBX 201000"
exportFile fbxFileName #noPrompt selectedOnly:exportSelected using:FBXEXP
)
else
(
if fbxVer == 2012 then
(
version = 2012
format ("Exporting as fbx 2012\n")
pluginManager.loadClass FBXEXP
fbxExporterSetParam "FileVersion" "FBX201200"
exportFile fbxFileName #noPrompt selectedOnly:exportSelected using:FBXEXP
)
else
(
format ("Couldn't export fbx file as version was set to "+(fbxVer as string)+"\n")
messagebox ("Couldn't export fbx file as version was set to "+(fbxVer as string)+"\n") beep:true title:"Save Error!"
)
)
)
fn rsta_prepForFBXExport =
(
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
if fbxFileName != undefined then
(
fbxVer = 2012
rsta_exportFbx fbxFileName fbxVer
)
else
(
format ("No valid fbx file picked.\n")
)
)
fn PrepAndExportCharacter =
(
start = timestamp()
local fbxFileName = undefined
undo label:"Prep and Epxort Character" on(
--first off we need to pick the name and location of the fbx file to save
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
if fbxFileName != undefined then
(
--first off remove any template heads.
filein (RsConfigGetWildWestDir() +"script\\3dsMax\\Characters\\Rigging\\ambientFacial\\removeGuideHead.ms")
--now we need to export the expressions to fat xml
-- local strName = filterstring fbxFileName "."
--
-- local fatXmlfileName = strName[1]+"_fat.xml"
-- format ("initialising fat xml export to "+fatXmlfileName+"\n")
--
-- rsta_exportFatExpressionXml fatXmlfileName
--
--now we will delete unselected nodes
charDummy = findTheDummy()
--format ("charDummy: "+(charDummy as string)+"\n")
selArray = rsta_findObjectsToKeep charDummy.name
select selArray
print ("SelCount: "+(selection.count as string)+"\n")
-- break()
pelvAux = getNodeByName "CTRLRIG_Pelvis_AUX"
if pelvAux != undeifned do
(
format ("Found "+pelvAux.name+"\n")
appendIfUnique selArray pelvAux
RSTA_getAllChildren pelvAux arr:selArray#()
)
gsPelvAux = getNodeByName "gs:CTRLRIG_Pelvis_AUX"
if gsPelvAux != undeifned do
(
format ("Found "+gsPelvAux.name+"\n")
appendIfUnique selArray gsPelvAux
RSTA_getAllChildren gsPelvAux arr:selArray#()
)
select selArray
print ("SelCount: "+(selection.count as string)+"\n")
-- break()
selectionSets["*selArray"] = selection
-- break()
objArray = objects as array
objToDelete = #()
for o = objArray.count to 1 by -1 do
(
obj = objArray[o]
fnd = finditem selArray obj
if fnd == 0 then
(
format ("Couldn't find "+obj.name+" in selArray\n")
if obj.name != "Target001" then
(
if obj.name != "LOD_Camera" then
(
append objToDelete obj
)
)
)
)
--
for obj = objToDelete.count to 1 by -1 do
(
format ("Trying to delete unneeded obj: "+objToDelete[obj].name+"\n")
delete objToDelete[obj]
)
--***THESE FUCKING LOD CAMERA ARE A MASSIVE PAIN IN THE FUCKING ARSE
local lodCam = getNodeByName "LOD_Camera"
if lodCam != undefined do (delete lodCam)
local camTgt = getNodeByName "Target001"
if camTgt != undefined do (delete camTgt)
--*** FUCKING THINGS.
--now we need to export the expressions to fat xml
local strName = filterstring fbxFileName "."
local fatXmlfileName = strName[1]+"_fat.xml"
format ("initialising fat xml export to "+fatXmlfileName+"\n")
rsta_exportFatExpressionXml fatXmlfileName
format ("Firing PrepareCharacter\n")
PrepareCharacter()
format ("Firing PrepareExpressions\n")
PrepareExpressions()
format ("Firing rsta_NukeMaterials\n")
rageMaterials = rsta_NukeMaterials true true
--NOW WE CAN EXPORT
--now if the character has an ambient ui then it needs to be exported as fbx2010 otherwise 2012
ambientUINode = getNodeByName "Ambient_UI"
local version = undefined
if ambientUINode != undefined then
(
format "Exporting as fbx 2010\n"
fbxVer = 2010
rsta_exportFbx fbxFileName fbxVer false
)
else
(
format "Exporting as fbx 2012\n"
fbxVer = 2012
rsta_exportFbx fbxFileName fbxVer false
)
)
else
(
format ("No valid fbx file specified.")
)
)
)
-- fn PrepAndExportVehicle genType =
fn PrepAndExportVehicle =
(
start = timestamp()
local fbxFileName = undefined
undo label:"Prep and Export Vehicle" on(
selectedVehicle = selectByName title:"Pick Vehicle skin mesh." showHidden:true
driver = selectedVehicle[1]
format "You selected Vehicle:'%'!\n" driver.name
filein ( theWildWest + "script/3dsMax/Cutscene/rsta_WheelDataXMLOutput.ms" )
-- if selection.count == 1 then
if driver != undefined then
(
select driver
format ("Exporting "+driver.name+"\n")
if driver.modifiers[#Skin] != undefined then
(
--first off we need to pick the name and location of the fbx file to save
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
if fbxFileName != undefined then
(
--now we will delete unselected nodes
local mainName = filterstring driver.name "_"
mainName = mainName[1]
local selArray = #()
skelRootNode = getNodeByName (mainName+"_"+"skel")
skelArray = undefined
if skelRootNode != undefined do
(
append selArray skelRootNode
selArray = RSTA_getAllChildren skelRootNode arr:selArray#()
skelArray = deepcopy selArray
)
append selArray driver
objArray = objects as array
objToDelete = #()
for o = objArray.count to 1 by -1 do
(
obj = objArray[o]
fnd = finditem selArray obj
if fnd == 0 then
(
--format ("Couldn't find "+obj.name+" in selArray\n")
append objToDelete obj
)
)
delete objToDelete
select selArray
-- PrepareVehicle driver skelArray
local parentDummy = dummy pos:[0,0,0]
parentDummy.name = "Dummy01"
skelRootNode.parent = parentDummy
meshesToSort = objects as array
SortAndSwitch meshesToSort
-- rageMaterials = rsta_NukeMaterials true true
--NOW WE CAN EXPORT
--now if the character has an ambient ui then it needs to be exported as fbx2010 otherwise 2012
fbxVer = 2012
rsta_exportFbx fbxFileName fbxVer false
format ("Exporting. This can take a little while...\n")
--now we can undo everytihng.
max undo
format ("Scene reset to initial state.\n")
fndFbx = doesFileExist fbxFileName
end = timestamp()
if fndFbx == true then
(
format ("Exported to "+fbxFileName+"\n")
format "Processing Prepare & Export took % seconds\n" ((end - start) / 1000.0)
messagebox ("Exported to "+fbxFileName+"\n") beep:true title:"Success!"
)
else
(
format "Processing Prepare & Export took % seconds\n" ((end - start) / 1000.0)
messagebox ("Exporting appears to have failed. Please see the listener.") beep:true title:"WARNING!"
)
)
else
(
format ("No valid fbx file specified.")
)
)
else
(
format ("No skin modifier found on "+driver.name+"\n")
messagebox ("No skin modifier found on "+driver.name+"\n") beep:true title:"WARNING!"
)
)
else
(
format "Please select only your vehicle mesh."
messagebox "Please select only your vehicle mesh." beep:true title:"Warning"
)
)
)
fn EnvSetupPrepMapAndExport =
(
start = timestamp()
local fbxFileName = undefined
undo label:"Prep and Export Map" on
(
--first off we need to pick the name and location of the fbx file to save
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
if fbxFileName != undefined then
(
rsta_NukeMaterials true true
filePath = "//gta5/art/animation/resources/sets/Max_Files/"
maxFile = filterString fbxFileName "."
maxFile = (maxFile[1]+".max")
if maxFile != undefined then
(
saveMaxFile maxFile
exportOk = CSMapExport()
if exportOk == true do
(
format ("Exporting as fbx 2012\n")
fbxVer = 2012
rsta_exportFbx fbxFileName fbxVer false
format ("Exporting. This can take a little while...\n")
--now we can undo everytihng.
max undo
format ("Scene reset to initial state.\n")
fndFbx = doesFileExist fbxFileName
end = timestamp()
if fndFbx == true then
(
format ("Exported to "+fbxFileName+"\n")
format "Processing Setup Prep and Export took % seconds\n" ((end - start) / 1000.0)
messagebox ("Exported to "+fbxFileName+"\n") beep:true title:"Success!"
)
else
(
format "Processing Setup Prep and Export took % seconds\n" ((end - start) / 1000.0)
messagebox ("Exporting appears to have failed. Please see the listener.") beep:true title:"WARNING!"
)
)
)
else
(
format ("No max file name set")
)
)
else
(
format ("No valid fbx file specified.")
)
)
)
fn ImportMapAssets interiorType =
(
success = true
undo label:"Prep Map Data" on(
viewpt = viewport.setLayout #layout_1
viewport.SetRenderLevel #wireframe
containerFileName = undefined
if interiorType == false then
(
containerFileName = getOpenFileName caption:"Container File" types:"Container File (*.MAXC)|*.maxc|All Files (*.*)|*.*|"
)
else
(
containerFileName = getOpenFileName caption:"Interior File" types:"Interior File (*.MAX)|*.max|All Files (*.*)|*.*|"
)
if containerFileName != undefined then
(
format ("Picked "+containerFileName+"...\n")
if interiorType == false then
(
cont1 = Containers.CreateInheritedContainer containerFileName
cont1.MakeUnique()
format "Made Unique\n"
--now unlink
for obj in objects do
(
obj.parent = undefined
)
delete cont1
lodObjs = findLodObjects()
delete lodObjs
objToDelete = #()
selArray = #()
for obj in objects do
(
if superclassof obj != GeometryClass do
(
append objToDelete obj
)
)
delete objToDelete
)
else
(
mergemaxFile containerFileName #prompt
objToDelete = #()
for obj in objects do
(
if superclassof obj != GeometryClass then
(
append objToDelete obj
)
)
delete objToDelete
)
format ("Initialising Editable_Mesh conversion...\n")
for obj in objects do
(
convertTo obj Editable_Mesh
-- format ("Converted "+obj.name+" to Editable_Mesh\n")
)
noEmCount = 0
for obj in objects do
(
if classof obj != Editable_mesh do
(
noEmCount = noEmCount + 1
format (obj.name+" isnt Editable_mesh. It's "+((classof obj) as string)+"\n")
)
)
format ("Total of "+(noEmCount as string)+" none Editable_Mesh objects\n")
)
else
(
format ("No container picked.\n")
)
)
max unhide all
if success == false do
(
max undo
)
messagebox ("Map Assets imported.") beep:true
)
fn prepareAndExportProp =
(
if selection.count == 1 then
(
if superclassof $ == GeometryClass then
(
-- prepareAndExportProp $
success = false
undo label:"Prep and Export prop" on(
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
if fbxFileName != undefined then
(
format ("Initialising Prep and Export Prop...\n")
if selection.count == 1 then
(
-- select obj
initPos = PrepareProp false
format ("Prepared prop..\n")
fbxVer = 2012
rsta_exportFbx fbxFileName fbxVer true
format ("Exported prop...\n")
success = true
if initPos[1] != undefined do
(
initPos[1].transform = initPos[2]
format ("Resetting transform on "+initPos[1].name+"\n")
)
)
else
(
format ("Please select only one object.\n")
messagebox ("Please select only one object.\n") beep:true title:"WARNING!"
)
)
else
(
format ("No valid fbx file picked.\n")
success = false
)
)
if success == true do
(
format ("Trying to Restore scene state...\n")
max undo
)
messagebox ("Prop Prepped and exported.") beep:true
)
else
(
format ($.name+" is not a valid geometry.\n")
messagebox ($.name+" is not a valid geometry.\n") beep:true
)
)
else
(
format ("Please only pick the prop mesh you wish to export.\n")
messagebox ("Please only pick the prop mesh you wish to export.\n")
)
)
-- format "Ending import\n"