--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"