-- -- **************************************************************************************** -- -- CS Export Preperation Tools -- -- **************************************************************************************** -- -- Basic functionality combined from other scripts. -- -- Script removes rage shaders and generates standard materials with diffuse maps only. -- -- In addition to the above: -- -- Prepare Character selects all meshes and skeleton hierarchy -- -- Prepare Prop creates dummy meshes and opens export -- -- Map and vehicle functions are texture switchover only -- -- **************************************************************************************** -- -- Stewart Wright - Rockstar North - 19/06/12 -- -- Initial Tool Creation -- -- **************************************************************************************** -- -- Andy Davis - Rockstar London - 23/04/13 -- -- DotNet form layout -- -- Extra material functionality added -- -- **************************************************************************************** filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") --wildwest header filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/RSL_dotNetUIOps.ms") --RS_dotNetPreset structure filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms") -- filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/mrSkeleton_v2/mrSkeleton_2_propRigging_functions.ms") --used for prop root building filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/mrSkeleton_v2/mrSkeleton_2_functions.ms") --used for prop root building filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_RSTA_UI.ms") --have to do a test on project here due to the differing tools. --this is a temporary fix until I get time to go through the modifications made to the rdr version --and try to integrate them so they match what should be sitting in wildwest. if theProject == "rdr3" then ( RsCollectToolUsageData (getThisScriptFilename()) global CutsceneDataPrepUI struct CutSceneDataPrepStruct ( ------------------------------------------------------------------------------------------------------------------------------------------ --GENERAL FUNCTIONS ------------------------------------------------------------------------------------------------------------------------------------------ -- fn addDummyData = -- ( -- format ("Adding max data to dummy node") -- -- obj = getNodeByName "Dummy01" -- -- fileNameStr = ("filename = "+ (maxFilePath + maxFileName)+"\r\n") -- timeStampStr = ("timestamp = " +((localTime) as string)+"\r\n") -- userStr = ("user = " +(RsUserGetUserName())+"\r\n") -- -- addFileName = false -- addtimeStamp = false -- addUserStr = false -- -- existingUdp = getUserProp obj "filename" -- if existingUdp != undefined then -- ( -- format ("Found udp for filename: "+existingUdp+"\n") -- setUserProp obj "filename" (maxFilePath + maxFileName) -- ) -- else -- ( -- addFileName = true -- ) -- -- existingUdp = getUserProp obj "timestamp" -- if existingUdp != undefined then -- ( -- format ("Found udp for timestamp: "+existingUdp+"\n") -- setUserProp obj "timestamp" ((localTime) as string) -- ) -- else -- ( -- addtimeStamp = true -- ) -- -- existingUdp = getUserProp obj "user" -- if existingUdp != undefined then -- ( -- format ("Found udp for user: "+existingUdp+"\n") -- setUserProp obj "user" (RsUserGetUserName()) -- ) -- else -- ( -- addUserStr = true -- ) -- -- currentudp = getUserPropBuffer obj -- -- if addFileName == true do -- ( -- newUdp = (currentUdp+"\r\n"+fileNameStr) -- setUserPropBuffer obj newUdp -- ) -- -- currentudp = getUserPropBuffer obj -- -- if addtimeStamp == true do -- ( -- newUdp = (currentUdp+"\r\n"+timeStampStr) -- setUserPropBuffer obj newUdp -- ) -- currentudp = getUserPropBuffer obj -- -- if addUserStr == true do -- ( -- newUdp = (currentUdp+"\r\n"+userStr) -- setUserPropBuffer obj newUdp -- ) -- ), fn CaptureDisplay = ( filein (RsConfigGetWildWestDir() + "script/3dsMax/Cutscene/CutsceneCaptureSphereDisplay.ms") ), fn NukeMaterials = ( print "Wiping Materials" if queryBox "I will attempt to delete all materials in the scene.\r\nDo you want to continue?" beep:false title:"Materials Export Manager" do ( clear_all_materials() --appears to be an external generic script kill_materials() --appears to be an external generic script ) ), fn PrepareCharacter = ( print "Preparing character" local pedMeshes = this.ShowSkinningAndBones() this.SortAndSwitch pedMeshes this.WriteSelectionSets() -- this.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" ), fn Export mode = ( case mode of ( #cutscene: ( messagebox "Export #cutscene" ) #game: ( messagebox "Export #game" ) ) ), fn PrepareProp = ( 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 ((isMeshSkinned thisProp[1]) == true) and (gunMag != true) then--if the mesh is skinned ( print "Preparing skinned prop" thisProp = getCurrentSelection() this.SortAndSwitch thisProp this.SkinnedProp thisProp[1] ) 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 ( print "Preparing unskinned prop" thisProp = getCurrentSelection() this.SortAndSwitch thisProp this.UnskinnedProp thisProp[1] ) ) ) else (messageBox "Please run with only one object selected.") ), fn PrepareVehicle = ( print "Preparing vehicle" if selection.count != 0 then ( vehicleMeshes = getCurrentSelection() this.SortAndSwitch vehicleMeshes this.VehicleSetup() ) 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() clearSelection() this.SortAndSwitch vehicleMeshes this.VehicleSetup() ) ) ), fn PrepareMap = ( print "Preparing map" -- if selection.count != 0 then -- ( -- mapMeshes = getCurrentSelection() -- this.SortAndSwitch mapMeshes -- ) -- 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 -- mapMeshes = getCurrentSelection() -- clearSelection() -- this.SortAndSwitch mapMeshes -- ) if queryBox "I will attempt to delete all materials in the scene.\r\nDo you want to continue?" beep:false do ( clear_all_materials() kill_materials() this.CSMapExport() ) -- ) ), 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 = --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 ( this.DelFileInfoTags rootObj --delete the tags off the children of the export dummy this.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 = #() this.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 -- -- Thanh: Automate the export process, including texture filepath update, and p4 checkin. -- getPath = getSavePath initialDir: (RsConfigGetProjRootDir() + "art\\animation\\resources\\props") presetLocation = "X:\\tphan\\script\\max\\RS FBX Export Preset.fbxexportpreset\\" lNewFilePath = undefined lNewTxtPath = undefined lObjName = undefined if getPath != undefined then ( for item in selection do ( if (filterstring item.name "_")[1] == "Mover" do ( lOldTxtPath = undefined lMat = undefined lObj = item.children[1] if (ClassOf item.children[1].material) as string == "Standardmaterial" then ( lMat = item.children[1].material lOldTxtPath = lMat.diffusemap.filename ) else ( lMat = item.children[1].material[1] lOldTxtPath = lMat.diffusemap.filename ) lTxtNameArray = filterstring lOldTxtPath "\\" lTxtName = lTxtNameArray[lTxtNameArray.count] lObjName = lObj.name lFileName = lObjName + ".FBX" lNewTxtFilePath = getPath + "\\" + lObjName + ".fbm" lNewTxtPath = getPath + "\\" + lObjName + ".fbm\\" + lTxtName lNewFilePath = getPath + "\\" + lFileName makeDir lNewTxtFilePath if doesFileExist lNewTxtPath do ( print "Deleting file" setFileAttribute lNewTxtPath #readOnly false deleteFile lNewTxtPath ) if gRsPerforce.connected() == false then gRsPerforce.connect() gRsPerforce.sync lOldTxtPath silent:true copyfile lOldTxtPath lNewTxtPath lMat.diffusemap.filename = lNewTxtPath ) ) if lNewFilePath != undefined then ( -- EXPORT SETTINGS ---------------------------- --Geometry------------------------------------------------------------------------ FBXExporterSetParam "SmoothingGroups" false FBXExporterSetParam "NormalsPerPoly" false FBXExporterSetParam "TangentSpaceExport" false FBXExporterSetParam "SmoothMeshExport" false FBXExporterSetParam "Preserveinstances" false FBXExporterSetParam "SelectionSetExport" false FBXExporterSetParam "GeomAsBone" true FBXExporterSetParam "ColladaTriangulate" false FBXExporterSetParam "PreserveEdgeOrientation" false --Animation------------------------------------------------------------------------ FBXExporterSetParam "Animation" false --Cameras------------------------------------------------------------------------ FBXExporterSetParam "Cameras" false --Lights------------------------------------------------------------------------ FBXExporterSetParam "Lights" false --Embed Media-------------------------------------------------------------------- FBXExporterSetParam "EmbedTextures" false --Units---------------------------------------------------------------------------- FBXExporterSetParam "ScaleFactor" 100 --Axis Conversion----------------------------------------------------------------- FBXExporterSetParam "AxisConversionMethod" "None" FBXExporterSetParam "UpAxis" "Y" --UI---------------------------------------------------------------- FBXExporterSetParam "ShowWarnings" true FBXExporterSetParam "GenerateLog" true --FBX File Format---------------------------------------------------------------- FBXExporterSetParam "ASCII" false FBXExporterSetParam "FileVersion" "FBX201000" exportFile lNewFilePath #noPrompt selectedOnly:true using:FBXEXP if gRsPerforce.connected() == false then gRsPerforce.connect() lChangelist = gRsPerforce.createChangelist ("Prop and Texture FBX Conversion: " + lObjName) gRsPerforce.add lNewTxtPath gRsPerforce.addToChangelist lChangelist lNewTxtPath gRsPerforce.add lNewFilePath gRsPerforce.addToChangelist lChangelist lNewFilePath gRsPerforce.edit lNewFilePath gRsPerforce.addToChangelist lChangelist lNewFilePath ) else ( print "Unsuccessful export. Unable to acquire filepath." ) ) else ( print "USER CANCELLED." ) --hacky export selected as method. needs better way. --actionMan.executeAction 0 "40373" -- File: Export Selected ),--end UnskinnedProp --**************************************************************************************** fn SkinnedProp theProp = --theProp = a single mesh ( exportMeshes = #(theProp) skinningBones = #() objectsToShow = #() rootObj = undefined if (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 this.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 ( this.DelFileInfoTags rootObj --delete the tags off the children of the export dummy this.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 --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 -- 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 this.CollectChildren c &allChildren includeParent:true includeHidden:includeHidden ), -- end collectChildren -- 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 ) this.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 this.ReorderTags meshToTag --tidy up the tags ),-- end tagFileNameInfo -- 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 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 = this.FindTheDummy() --find the export dummy if classOf characterNode == Dummy do--we are going to tag the dummy with the filename ( this.DelFileInfoTags characterNode --delete the tags off the children of the export dummy this.TagFileNameInfo characterNode --tag mesh information ) if characterNode != undefined then ( progBar.prog.value = 20 this.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 (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 this.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 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 to filter selection and switch materials fn SortAndSwitch meshesToSort = --meshesToSort = an array of objects ( if ((progBar != undefined) and (progBar.isDisplayed)) do (destroyDialog progBar) CreateDialog progBar width:300 Height:30 progBar.prog.color = [10,210,10] --green meshesToChange = #() if meshesToSort.count > 0 do ( for allSel=1 to meshesToSort.count do ( if superClassOf meshesToSort[allSel] == GeometryClass do append meshesToChange meshesToSort[allSel] ) 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 this.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 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 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 = ( --Unhide & unfreeze the dummy01 node max unhide all max unfreeze all --Select the original scene root, it can be called either Dummy01 or Dummy001 try( select $Point01 $.name = "PointOrig" )catch() try( select $Point001 $.name = "PointOrig" )catch() --Copy the "Point Orig" and rename Copy $ select $PointOrig001 $.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 --Clear the selection clearSelection() --Create "PointZerod2" Point pos:[0,0,0] isSelected:on $.name = "PointZerod2" --Align Setroot to "PointZerod2" select $SetRoot $.pos = $PointZerod2.pos --Parent the "PointZerod2" & "Point Orig" to the SetRoot select $PointZerod2 $.parent = $SetRoot select $PointOrig $.parent = $SetRoot --Clear the selection clearSelection() --select the "PointOrig" & Get offset information select $PointOrig offsetposition = $PointOrig.pos Positionfilter = (offsetposition as string) Position_offset_values = filterstring Positionfilter "[ ]" PointOrigangle = $PointOrig.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 "." -- create an offset co-ordinate file makeDir (RsConfigGetArtDir() + "animation/resources/sets/Offsets") output_name = (RsConfigGetArtDir() + "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 )--csMapExport ) struct CutsceneDataPrepUIStruct ( Form, Table, ToolTip, PrepareCharacterButton, PrepareExpressionsButton, ExportGameButton, ExportCutSceneButton, ShowCapturesButton, NukeMaterialsButton, SetupEnvironmentButton, CheckBoxTable, AlphaCheckBox, SpecularCheckBox, NormalCheckBox, AllMapsCheckBox, ModeComboBox, CharacterTable, PropTable, VehicleTable, MapTable, IniFilePath = (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Cutscene_Tools.ini"), Method = CutSceneDataPrepStruct(), ------------------------------------------------------------------------------------------------------------------------------------------ --EVENT HANDLERS ------------------------------------------------------------------------------------------------------------------------------------------ fn CaptureDisplay = CutsceneDataPrepUI.Method.CaptureDisplay(), fn NukeMaterials = CutsceneDataPrepUI.Method.NukeMaterials(), fn PrepareCharacter = CutsceneDataPrepUI.Method.PrepareCharacter(), fn PrepareExpressions = CutsceneDataPrepUI.Method.PrepareExpressions(), fn ExportForCutscene = CutsceneDataPrepUI.Method.Export #cutscene, fn ExportForGame = CutsceneDataPrepUI.Method.Export #game, fn PrepareProp = CutsceneDataPrepUI.Method.PrepareProp(), fn PrepareVehicle = CutsceneDataPrepUI.Method.PrepareVehicle(), fn PrepareMap = CutsceneDataPrepUI.Method.PrepareMap(), fn SetupEnvironment = CutsceneDataPrepUI.Method.SetupEnvironment(), -- fn ToggleAllMaps = -- ( -- if (CutsceneDataPrepUI.AllMapsCheckBox.Checked) then -- ( -- CutsceneDataPrepUI.AlphaCheckBox.Enabled = false -- CutsceneDataPrepUI.SpecularCheckBox.Enabled = false -- CutsceneDataPrepUI.NormalCheckBox.Enabled = false -- ) -- -- else -- ( -- CutsceneDataPrepUI.AlphaCheckBox.Enabled = true -- CutsceneDataPrepUI.SpecularCheckBox.Enabled = true -- CutsceneDataPrepUI.NormalCheckBox.Enabled = true -- ) -- ), fn UpdateTool s e = ( CutsceneDataPrepUI.InstallTable CutsceneDataPrepUI.ModeComboBox.SelectedIndex ), ------------------------------------------------------------------------------------------------------------------------------------------ --OPEN/CLOSE FUNCTIONS ------------------------------------------------------------------------------------------------------------------------------------------ fn FormClose = ( setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinLocX" (CutsceneDataPrepUI.Form.Location.x as string) setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinLocY" (CutsceneDataPrepUI.Form.Location.y as string) setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinWidth" (CutsceneDataPrepUI.Form.Width as string) setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinHeight" (CutsceneDataPrepUI.Form.Height as string) setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "Mode" (CutsceneDataPrepUI.ModeComboBox.SelectedIndex as string) -- setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "AlphaChecked" (CutsceneDataPrepUI.AlphaCheckBox.Checked as string) -- setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "SpecularChecked" (CutsceneDataPrepUI.SpecularCheckBox.Checked as string) -- setINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "NormalChecked" (CutsceneDataPrepUI.NormalCheckBox.Checked as string) (dotnetclass "System.gc").ReRegisterForFinalize CutsceneDataPrepUI.ModeComboBox CutsceneDataPrepUI.ModeComboBox.Dispose() ), fn FormOpen = ( --default values local WinLocX = 100 local WinLocY = 100 local WinWidth = 200 local WinHeight = 200 local mode = 0 -- local alphaChecked = true -- local specularChecked = true -- local normalChecked = true try ( WinLocX = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinLocX" as integer WinLocY = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinLocY" as integer WinWidth = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinWidth" as integer WinHeight = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "WinHeight" as integer mode = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "Mode" as integer -- alphaChecked = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "AlphaChecked" as BooleanClass -- specularChecked = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "SpecularChecked" as BooleanClass -- normalChecked = getINISetting CutsceneDataPrepUI.IniFilePath "CutsceneDataPrepUI" "NormalChecked" as BooleanClass ) catch() CutsceneDataPrepUI.Form.Location = dotNetObject "system.drawing.point" WinLocX WinLocY -- CutsceneDataPrepUI.Form.Size = dotNetObject "System.Drawing.Size" WinWidth WinHeight CutsceneDataPrepUI.Form.Width = WinWidth -- CutsceneDataPrepUI.ToggleAllMaps() CutsceneDataPrepUI.ModeComboBox.SelectedIndex = mode -- CutsceneDataPrepUI.AlphaCheckBox.Checked = alphaChecked -- CutsceneDataPrepUI.SpecularCheckBox.Checked = specularChecked -- CutsceneDataPrepUI.NormalCheckBox.Checked = normalChecked CutsceneDataPrepUI.InstallTable mode ), ------------------------------------------------------------------------------------------------------------------------------------------ --GENERAL FUNCTIONS ------------------------------------------------------------------------------------------------------------------------------------------ --function removes the previous button table and replaces it with the table corresponding with the current mode fn InstallTable index = ( local tableHeight = 112 if CutsceneDataPrepUI.Table.Controls.count == 3 then CutsceneDataPrepUI.Table.Controls.RemoveAt 2 case index of ( 0: ( CharacterTable = dotNetObject "TableLayoutPanel" CharacterTable.RowCount = 4 CharacterTable.Margin = dotNetObject "System.Windows.Forms.Padding" 2 CharacterTable.Dock = RS_dotNetPreset.DS_Fill -- CharacterTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 75) --checkboxes CharacterTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) CharacterTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) CharacterTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) CharacterTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) CharacterTable.ColumnCount = 1 CharacterTable.ColumnStyles.add (RS_dotNetObject.columnStyleObject "percent" 100) -- CharacterTable.Controls.Add CutsceneDataPrepUI.CheckBoxTable 0 0 PrepareCharacterButton = RS_DotNetUI.InitButton "Prepare Character" dotNet.AddEventHandler PrepareCharacterButton "Click" PrepareCharacter CharacterTable.Controls.Add PrepareCharacterButton 0 0 PrepareExpressionsButton = RS_DotNetUI.InitButton "Prepare Expressions" dotNet.AddEventHandler PrepareExpressionsButton "Click" PrepareExpressions CharacterTable.Controls.Add PrepareExpressionsButton 0 1 -- ExportCutSceneButton = RS_DotNetUI.InitButton "Export For Cutscene" -- dotNet.AddEventHandler ExportCutSceneButton "Click" ExportForCutscene -- CharacterTable.Controls.Add ExportCutSceneButton 0 3 -- ExportGameButton = RS_DotNetUI.InitButton "Export For Game" -- dotNet.AddEventHandler ExportGameButton "Click" ExportForGame -- CharacterTable.Controls.Add ExportGameButton 0 4 NukeMaterialsButton = RS_DotNetUI.InitButton "Nuke Materials" dotNet.AddEventHandler NukeMaterialsButton "Click" NukeMaterials CharacterTable.Controls.Add NukeMaterialsButton 0 2 CutsceneDataPrepUI.Table.Controls.Add CharacterTable 0 2 tableHeight += (25 * 3) ) 1: ( PropTable = dotNetObject "TableLayoutPanel" PropTable.RowCount = 2 PropTable.Margin = dotNetObject "System.Windows.Forms.Padding" 2 PropTable.Dock = RS_dotNetPreset.DS_Fill PropTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) PropTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) PropTable.ColumnCount = 1 PropTable.ColumnStyles.add (RS_dotNetObject.columnStyleObject "percent" 100) PreparePropButton = RS_DotNetUI.InitButton "Prepare Prop" PropTable.Controls.Add PreparePropButton 0 0 dotNet.AddEventHandler PreparePropButton "Click" PrepareProp NukeMaterialsButton = RS_DotNetUI.InitButton "Nuke Materials" dotNet.AddEventHandler NukeMaterialsButton "Click" NukeMaterials PropTable.Controls.Add CutsceneDataPrepUI.NukeMaterialsButton 0 1 CutsceneDataPrepUI.Table.Controls.Add PropTable 0 2 tableHeight += (25 * 2) ) 2: ( VehicleTable = dotNetObject "TableLayoutPanel" VehicleTable.RowCount = 2 VehicleTable.Margin = dotNetObject "System.Windows.Forms.Padding" 2 VehicleTable.Dock = RS_dotNetPreset.DS_Fill VehicleTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) VehicleTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) VehicleTable.ColumnCount = 1 VehicleTable.ColumnStyles.add (RS_dotNetObject.columnStyleObject "percent" 100) PrepareVehicleButton = RS_DotNetUI.InitButton "Prepare Vehicle" dotNet.AddEventHandler PrepareVehicleButton "Click" PrepareVehicle VehicleTable.Controls.Add PrepareVehicleButton 0 0 NukeMaterialsButton = RS_DotNetUI.InitButton "Nuke Materials" dotNet.AddEventHandler NukeMaterialsButton "Click" NukeMaterials VehicleTable.Controls.Add CutsceneDataPrepUI.NukeMaterialsButton 0 1 CutsceneDataPrepUI.Table.Controls.Add VehicleTable 0 2 tableHeight += (25 * 2) ) 3: ( MapTable = dotNetObject "TableLayoutPanel" MapTable.RowCount = 4 MapTable.Margin = dotNetObject "System.Windows.Forms.Padding" 2 MapTable.Dock = RS_dotNetPreset.DS_Fill MapTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) MapTable.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 25) MapTable.ColumnCount = 1 MapTable.ColumnStyles.add (RS_dotNetObject.columnStyleObject "percent" 100) EnvironmentSetupButton = RS_DotNetUI.InitButton "Environment Setup" dotNet.AddEventHandler EnvironmentSetupButton "Click" SetupEnvironment MapTable.Controls.Add EnvironmentSetupButton 0 0 PrepareMapButton = RS_DotNetUI.InitButton "Prepare Map" dotNet.AddEventHandler PrepareMapButton "Click" PrepareMap MapTable.Controls.Add PrepareMapButton 0 1 NukeMaterialsButton = RS_DotNetUI.InitButton "Nuke Materials" dotNet.AddEventHandler NukeMaterialsButton "Click" NukeMaterials MapTable.Controls.Add CutsceneDataPrepUI.NukeMaterialsButton 0 2 ShowCapturesButton = RS_DotNetUI.InitButton "Display Capture Spheres" dotNet.AddEventHandler ShowCapturesButton "Click" CaptureDisplay MapTable.Controls.Add CutsceneDataPrepUI.ShowCapturesButton 0 3 CutsceneDataPrepUI.Table.Controls.Add MapTable 0 2 tableHeight += (25 * 4) ) ) CutsceneDataPrepUI.Form.Height = tableHeight ), ------------------------------------------------------------------------------------------------------------------------------------------ --UI ------------------------------------------------------------------------------------------------------------------------------------------ fn CreateUI = ( RS_dotNetPreset.Font_Main = dotNetObject "System.Drawing.Font" "Futura" 10 -- form setup Form = dotNetObject "maxCustomControls.maxForm" Form.Text = "Materials Export Manager" Form.StartPosition = (dotNetClass "System.Windows.Forms.FormStartPosition").manual Form.Location = dotNetObject "system.drawing.point" 0 80 Form.MaximumSize = dotNetObject "System.Drawing.Size" 1600 1200 Form.MinimumSize = dotNetObject "System.Drawing.Size" 100 100 Form.FormBorderStyle = RS_dotNetPreset.FB_Sizable dotNet.AddEventHandler Form "Load" FormOpen dotNet.AddEventHandler Form "Closing" FormClose --content ToolTip = dotnetobject "ToolTip" Table = dotNetObject "TableLayoutPanel" Table.Dock = RS_dotNetPreset.DS_Fill Table.RowCount = 3 Table.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 40) --banner Table.RowStyles.add (RS_dotNetObject.rowStyleObject "absolute" 30) --dropdownlist Table.RowStyles.add (RS_dotNetObject.rowStyleObject "percent" 100) --content Table.ColumnCount = 1 Table.ColumnStyles.add (RS_dotNetObject.columnStyleObject "percent" 100) Table.Margin = RS_dotNetPreset.Padding_None Form.Controls.Add Table RSBannerPanel = dotNetObject "System.Windows.Forms.Panel" RSBannerPanel.borderstyle = RS_dotNetClass.borderStyleClass.FixedSingle RSBannerPanel.dock = RS_dotNetPreset.DS.Fill --local banner = makeRsBanner dn_Panel:RSBannerPanel width:395 studio:"london" mail:"andy.davis@rockstarlondon.com" wiki:"Map_Art_Tech" local banner = makeRsBanner dn_Panel:RSBannerPanel width:395 studio:"london" filename:(getThisScriptFilename()) mail:"andy.davis@rockstarlondon.com" wiki:"Map_Art_Tech" banner.setup() Table.Controls.Add RSBannerPanel 0 0 ModeComboBox = dotNetObject "ComboBox" ModeComboBox.Dock = RS_dotNetPreset.DS.Fill ModeComboBox.DropDownStyle = ModeComboBox.DropDownStyle.DropDownList ModeComboBox.Font = dotNetObject "System.Drawing.Font" "Futura" 11 modes = #("CHARACTER", "PROP", "VEHICLE", "MAP") ModeComboBox.Items.AddRange modes (dotnetclass "System.gc").SuppressFinalize ModeComboBox (dotnetclass "System.gc").KeepAlive ModeComboBox dotNet.AddEventHandler ModeComboBox "SelectedIndexChanged" UpdateTool Table.Controls.Add ModeComboBox 0 1 ---------------------------------------------------------------------------------------------------------------------------- --CHECKBOX TABLE ---------------------------------------------------------------------------------------------------------------------------- -- CheckBoxTable = dotNetObject "TableLayoutPanel" -- CheckBoxTable.RowCount = 3 -- CheckBoxTable.Dock = RS_dotNetPreset.DS_Fill -- CheckBoxTable.RowStyles.add (RS_dotNetObject.rowStyleObject "percent" 25) -- CheckBoxTable.RowStyles.add (RS_dotNetObject.rowStyleObject "percent" 25) -- CheckBoxTable.RowStyles.add (RS_dotNetObject.rowStyleObject "percent" 25) -- CheckBoxTable.ColumnCount = 1 -- CheckBoxTable.ColumnStyles.add (RS_dotNetObject.columnStyleObject "percent" 100) -- AlphaCheckBox = RS_dotNetUI.InitCheckBox "Include Alpha Maps" -- CheckBoxTable.Controls.Add AlphaCheckBox 0 0 -- SpecularCheckBox = RS_dotNetUI.InitCheckBox "Include Specular Maps" -- CheckBoxTable.Controls.Add SpecularCheckBox 0 1 -- NormalCheckBox = RS_dotNetUI.InitCheckBox "Include Normal Maps" -- CheckBoxTable.Controls.Add NormalCheckBox 0 2 --draw form Form.ShowModeless() Form ) ) if CutsceneDataPrepUI != undefined then ( CutsceneDataPrepUI.Form.Close() ) CutsceneDataPrepUI = CutsceneDataPrepUIStruct() CutsceneDataPrepUI.CreateUI() ) else ( if theProject == "gta5" then ( filein (theWildwest+"/script/3dsMax/Cutscene/cs_ResourcePrep_WPF.ms") ) else ( messagebox (theProject+" is not a configured project for this tool.\nPlease contact techArt.") beep:true title:"WARNING!" ) )