--setup scene geo for lighting --url:bugstar:446769 filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") filein (RsConfigGetToolsDir()+"dcc/current/max2012/scripts/rockstar/util/scenebaker/nightLightUtils.ms") try( DestroyDialog mapBakeGeoSetup_UI)catch() rollout mapBakeGeoSetup_UI "Map Bake Block Setup" ( --///////////////////////////////////////////////////////////////// -- VARS --///////////////////////////////////////////////////////////////// local blockNeighboursCSV = RsConfigGetToolsDir() + "etc/config/generic/Block_Neighbours_for_lighting.csv" local regex = dotnetclass "System.Text.RegularExpressions.Regex" local re_IgnoreCase = (dotnetclass "System.Text.RegularExpressions.RegexOptions").IgnoreCase local blockNeighbours = dotNetObject "RSG.MaxUtils.MaxDictionary" local mapContainers = (RsConfigGetArtDir() + "Models") local standardMat = StandardMaterial() local lightingModelLayer = LayerManager.getLayerFromName "LightingModel" --///////////////////////////////////////////////////////////////// -- UI CONTROLS --///////////////////////////////////////////////////////////////// button btn_doSetup "Setup" width:475 listbox lst_Process width:475 height:15 progressbar prg_Process color:green --///////////////////////////////////////////////////////////////// -- FUNCTIONS --///////////////////////////////////////////////////////////////// fn notifyProcess inText = ( --get the text array theText = lst_Process.items --append the new item append theText inText --stuff back into the control lst_Process.items = theText --select last item lst_Process.selection = theText.count windows.processPostedMessages() ) fn getPrimaryContainerName = ( --get scene containers loadedContainers = for obj in $objects where classOf obj == container collect obj if loadedContainers.count == 0 then ( messagebox "No containers in the scene, exiting" title:"Error" return false ) if loadedContainers.count > 1 then ( messageBox "There is more than 1 container present" title:"huh?" return false ) loadedContainers[1].name ) fn mapBakeGeoSetup = ( --create a lightingmodel layer if it doesnt exist notifyProcess "Creating lighting model layer" if LayerManager.getLayerFromName "LightingModel" == undefined then ( lightingModelLayer = LayerManager.newLayerFromName "LightingModel" ) --load each container and process the relevant contents files = getDepotFiles mapContainers wildcard:"*.maxc" walk:true if files.count == 0 then ( messageBox "Cant retrieve filenames from p4" title:"ERROR" try( DestroyDialog mapBakeGeoSetup_UI)catch() return false ) --The current scene container rootBlockName = getPrimaryContainerName() if rootBlockName == false then return false lightingModelName = rootBlockName + "_Lighting_Model" primaryContainer = getNodeByName rootBlockName --open the container --primaryContainer.setOpen true --delete any old lighting model try( delete (getNodeByname lightingModelName))catch() --retrieve the neighbours blockNeighbours.TryGetValue rootBlockName &neighbours format "neighbours: %\n" neighbours --reset progress prg_Process.value = 0 prgStep = 100.0 / neighbours.count --print files lightingMeshes = #() roadPropHitList = #() roadPropContainers = #() step = 1 notifyProcess "Processing neighbouring blocks.." for blockName in neighbours do ( notifyProcess blockName --find the container path containerPath = (for item in files where (getFileNameFile item.depotFile) == blockName collect item.depotFile)[1] if containerPath != undefined then ( --if this is a road container then we need to load the prop file for it to get the lights setup for the nightbake isRoad = false if regex.isMatch blockName "rd|fwy?" re_IgnoreCase != false then --we have a road container, find the prop files for it ( isRoad = true notifyProcess "This is a road container.." --match against files in the same folder containerDir = (dotnetclass "System.IO.Path").getDirectoryName containerPath containerDir = substituteString containerDir "\\" "/" areaFiles = getDepotFiles containerDir wildcard:".maxc" walk:true areaContainers = for f in areaFiles collect f.depotfile for item in areaContainers where regex.isMatch item "(rd([0-9])?_props.maxc)|(fwy_0[0-9]_props.maxc)" re_IgnoreCase != false do ( notifyProcess ("Load road prop file:" + item) --check if its already been hit if finditem roadPropHitList item == 0 then ( append roadPropHitList item format "roadProps: % \n" item --propTainer = roadMatches.item[r].value --getPropLights item --sync the container gRsPerforce.p4.run "sync" #(item) localPath = substituteString item "//depot" "x:" roadPropContainer = Containers.CreateInheritedContainer localPath roadPropContainer.makeUnique() --add to list append roadPropContainers roadPropContainer ) ) ) --also we want the LOD from the road not the SLOD --------------------------------------- --sync the file and on we go gRsPerforce.p4.run "sync" #(containerPath) --get local path adjBlockLocalPath = substituteString containerPath "//depot" "x:" --check we did get the file locally if doesFileExist adjBlockLocalPath == false then continue print containerPath --load the container notifyProcess "Loading container" theContainer = Containers.CreateInheritedContainer adjBlockLocalPath theContainer.MakeUnique() --id the LODS notifyProcess "Extracting LODS" LODS = undefined if isRoad then ( LODS = for obj in theContainer.children where matchPattern obj.name pattern:"*_LOD*" == true collect obj ) else ( LODS = for obj in theContainer.children where matchPattern obj.name pattern:"*_SLOD*" == true collect obj ) --print SLODS --apply to SLODS and detach from parent container --merge the meshes -- for obj in LODS do ( obj.material = standardMat obj.parent = undefined ) --add to the list join lightingMeshes LODS --delete the container delete theContainer --update progress prg_Process.value = step * prgStep step += 1 ) ) --print lightingMeshes --merge all the lighting meshes together notifyProcess "Process resulting light model" combinedMesh = convertToPoly lightingMeshes[1] for i = 2 to lightingMeshes.count do ( attachee = convertToPoly lightingMeshes[i] polyop.attach lightingMeshes[1] attachee ) --rename the object combinedMesh.name = lightingModelName --set to not export attrID = getAttrIndex "Gta Object" "Dont Export" setAttr combinedMesh attrID false --add to lighting layer theLayer = LayerManager.getLayerFromName "LightingModel" theLayer.addNode combinedMesh --add to the primary container --primaryContainer.setOpen true primaryContainer.AddNodeToContent combinedMesh --primaryContainer.setOpen false --create the lights notifyProcess "Creating lights" RsRefFuncs.loadRSrefData() print "create nightlights" nightLightUtils.loadLightConfig() nightLightUtils.generatePhotoLights() --add them to the lighting layer for nightLight in nightLightUtils.createdLights do ( theLayer.addNode nightLight primaryContainer.AddNodeToContent nightLight ) --break() for cont in roadPropContainers do ( format "Deleting roadPropContainer: % \n" cont delete cont ) --delete roadPropContainer --reset progress bar prg_Process.value = 0 notifyProcess "Finished!" ) fn processBlockNeighboursCSV row = ( bits = (dotNetObject "System.String" row).split "," --check first item is a valid block name --if it doesnt have an underscore in the name matches = regex.matches bits[1] "\w\w[0-9]+_.+" re_IgnoreCase if matches.count != 0 then ( containerName = matches.item[0].value if containerName != undefined then ( neighbours = for item = 2 to bits.count where bits[item] != "" collect bits[item] --set dict key = trimright bits[1] blockNeighbours.add key neighbours ) ) ) --///////////////////////////////////////////////////////////////// -- EVENTS dear boy --///////////////////////////////////////////////////////////////// on btn_doSetup pressed do ( primaryContainerName = getPrimaryContainerName() if primaryContainerName == false then return false lightingModelName = primaryContainerName + "_Lighting_Model" --check for existing mesh and prompt to replace it if it exists lightingModelLayer = LayerManager.getLayerFromName "LightingModel" if lightingModelLayer != undefined then ( success = lightingModelLayer.nodes &layerNodes lightingModel = undefined if success then ( lightingModel = for obj in layerNodes where obj.name == lightingModelName collect obj.name ) if lightingModel.count != 0 then ( decision = queryBox "Do you want to regenerate the lighting model for this container?" title:"Regenerate?" if decision == true then ( --generate lighting model mapBakeGeoSetup() ) ) else ( mapBakeGeoSetup() ) ) else --starting with a clean scene ( mapBakeGeoSetup() ) ) on mapBakeGeoSetup_UI open do ( --parse block neighbour file and generate map csv = CSVReader() csv.csvFile = blockNeighboursCSV csv.processingFn = processBlockNeighboursCSV csv.open() csv.close() --print blockNeighbours.keys ) ) createDialog mapBakeGeoSetup_UI width:500 height:275 style:#(#style_titlebar, #style_border, #style_sysmenu, #style_minimizebox)