334 lines
10 KiB
Plaintext
Executable File
334 lines
10 KiB
Plaintext
Executable File
--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) |