filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") --wildwest header filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_VertexPaint.ms") filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms") struct RsVeh_ChanBlueBakeStruct ( id, name, channels ) --///////////////////////////////////////// -- UI --///////////////////////////////////////// try(destroyDialog VehicleBlueBakeUI)catch() rollout VehicleBlueBakeUI "Vehicle Burn Bake" width:200 height:350 ( --///////////////////////////////////////// -- VARIABLES --///////////////////////////////////////// local cascade = true local ng = false local mapChannelList = #((RsVeh_ChanBlueBakeStruct id:-2 name:"Alpha" channels:"all"), (RsVeh_ChanBlueBakeStruct id:-1 name:"Illum" channels:"all"), (RsVeh_ChanBlueBakeStruct id:0 name:"Color" channels:"all"), (RsVeh_ChanBlueBakeStruct id:0 name:"Burn" channels:"b")) local burnChannel = 0 local channels = "b" local selectedChannel = mapChannelList[3] --///////////////////////////////////////// -- CONTROLS --///////////////////////////////////////// dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:VehicleBlueBakeUI.width local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"CHANGEME" versionNum:1.22 versionName:"Suede Blues" filename:(getThisScriptFilename()) group "HD -> NG" ( listbox lstChannel "Channel" height:4 items:(for item in mapChannelList collect item.name) checkbox chkAllChannels "All" button btnCopyMapData "Copy Map Data" width:155 edittext edtProcess text:"Ready" enabled:False ) group "" ( spinner spnSRCChannel "Source Channel" range:[-2, 99, 14] type:#integer width:65 align:#left checkbox chkMultisample "Multi Sample" checked:true --checkbox chkCascadeLOD "LOD Cascade" checked:true ) button btnRestoreBlue "Restore Blue" width:165 button btnPushVCBlue "Push to VC Blue" width:165 progressBar prgProcess color:green --///////////////////////////////////////// -- FUNCTIONS --///////////////////////////////////////// --///////////////////////////////////////// -- --///////////////////////////////////////// fn updateProcessText msg = ( edtProcess.text = msg windows.processPostedMessages() ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn getVeh_Meshes theNode = ( local selKids = RSTA_GetAllChildren theNode (for item in selKids where GetAttrClass item == "Gta Object" collect item) ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn checkSelection = ( local theNode = selection[1] if theNode == undefined then return undefined --check selection is valid, should be a helper with chassis child object if theNode.children.count == 0 then ( Messagebox "Please pick the vehicle hierarchy root helper" title:"Bad Selection" return undefined ) if matchpattern theNode.children[1].name pattern:"chassis*" == false then ( Messagebox "Please pick the vehicle hierarchy root helper" title:"Bad Selection" return undefined ) --is it a nextgen asset if ( matchpattern theNode.name pattern:"*_ng" ) do ng = true theNode ) ----------------------------------------------------------------------------------------------------------------------------------- mapped fn CpvFlushChannel obj mapChannel: colour:[1,1,1] = ( if(mapChannel == unsupplied) then ( return false ) local setMapVert = meshop.setMapVert convertToMesh obj if (not (meshop.getMapSupport obj mapChannel)) then ( meshop.setMapSupport obj mapChannel true ) for mv=1 to (meshop.getNumMapVerts obj mapChannel) do ( setMapVert obj mapChannel mv colour ) return true ) /*** ***/ fn checkMapChannelSupport targetMesh mapChannel enableSupport:True = ( local GetMapSupport local GetNumMaps local SetNumMaps local SetMapSupport if (classOf targetMesh == Editable_Poly) or (classOf targetMesh == PolyMeshObject) then ( GetMapSupport = polyop.getMapSupport GetNumMaps = polyop.getNumMaps SetNumMaps = polyop.setNumMaps SetMapSupport = polyop.setMapSupport ) if (classOf targetMesh == Editable_Mesh) then ( GetMapSupport = meshop.getMapSupport GetNumMaps = meshop.getNumMaps SetNumMaps = meshop.setNumMaps SetMapSupport = meshop.setMapSupport ) if (GetMapSupport targetMesh mapChannel == false) then ( --print "missing map channel" local numChannels = GetNumMaps targetMesh if numChannels < (mapChannel + 1) then ( SetNumMaps targetMesh (mapChannel + 1) ) SetMapSupport targetMesh mapChannel true ) ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn combineLODPieces pieces = ( local materialCopy = copy pieces[1].material copies = for obj in pieces collect copy obj for obj in copies do ( convertToMesh obj obj.material = materialCopy ) for v=2 to copies.count do attach copies[1] copies[v] copies[1].material = originalMaterial copies[1] ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn buildObjectList theNode &veh_LODChain = ( --build object lists for each lod level append veh_LODChain (getVeh_Meshes theNode) local LODLevels = undefined if ng then ( local theNodeName = (filterString theNode.name "_")[1] if (theNodeName != undefined) do ( LODLevels = execute ("$" + theNodeName + "*") --append veh_LODChain (getVeh_Meshes theNode) local HDNode = getNodeByName theNodeName if (HDNode != undefined) do ( append veh_LODChain (getVeh_Meshes HDNode) for i=1 to LODLevels.count do ( local LODNodeName = getNodeByName (theNodeName + "_l" + (i as String)) if LODNodeName != undefined then append veh_LODChain (getVeh_Meshes LODNodeName) ) ) ) ) else ( LODLevels = execute ("$" + theNode.name + "*") for i=1 to LODLevels.count do ( local theNodeName = getNodeByName (theNode.name + "_l" + (i as String)) if theNodeName != undefined then append veh_LODChain (getVeh_Meshes theNodeName) ) ) ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn restoreBlue = ( local theNode = checkSelection() if ( theNode == undefined ) then ( return false ) --build object lists for each lod level local veh_LODChain = #() buildObjectList theNode &veh_LODChain /* append veh_LODChain (getVeh_Meshes theNode) local LODLevels = execute ("$" + theNode.name + "*") for i=1 to LODLevels.count do ( local theNodeName = getNodeByName (theNode.name + "_l" + (i as String)) if theNodeName != undefined then append veh_LODChain (getVeh_Meshes theNodeName) ) */ --Go to the start frame (for skinning information) Max Time Start --Save any skinning information SkinnedObjList = #() for sub_LODChain in veh_LODChain do ( for obj in sub_LODChain do ( if( isMeshSkinned obj ) then ( --record object and type append SkinnedObjList (datapair Obj:obj Class:(classof obj.BaseObject)) --Output skinned data ::boneList = #() outputSkinningData obj --Collapse object down collapseStack obj ) ) ) prgProcess.value = 0 for l=1 to veh_LODChain.count do ( for obj in veh_LODChain[l] do ( ChannelInfo.copySubChannel obj 3 0 0 --red channel ChannelInfo.pasteSubChannel obj 3 0 2 --blue channel collapseStack obj ) prgProcess.value = (100.0 * (l as float / veh_LODChain.count)) ) --Push skinning information back for SkinnedObj in SkinnedObjList do ( if( classof SkinnedObj.Obj != SkinnedObj.Class ) then ( convertTo SkinnedObj.Obj SkinnedObj.Class ) --Write data back skinned data InputSkinningData SkinnedObj.Obj ) prgProcess.value = 0 ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn blueBakeProcess = ( local theNode = checkSelection() if ( theNode == undefined ) then ( return false ) prgProcess.value = 0 --build object lists for each lod level local veh_LODChain = #() append veh_LODChain (getVeh_Meshes theNode) local HDCount = veh_LODChain.count local LODLevels = execute ("$" + theNode.name + "*") for i=1 to (LODLevels.count - 1) do ( local theNodeName = getNodeByName (theNode.name + "_l" + (i as String)) if (theNodeName != undefined) then ( append veh_LODChain (getVeh_Meshes theNodeName) ) ) local justHD = false if(veh_LODChain.count == HDCount) then --we have no lods so just transfer to itself ( justHD = true ) local veh_Name = theNode.name local veh_LOD = 0 local UI_SRCChannel = spnSRCChannel.value --local cascade = chkCascadeLOD.state --Go to the start frame (for skinning information) Max Time Start --Save any skinning information SkinnedObjList = #() for sub_LODChain in veh_LODChain do ( for obj in sub_LODChain do ( if( isMeshSkinned obj ) then ( --record object and type append SkinnedObjList (datapair Obj:obj Class:(classof obj.BaseObject)) --Output skinned data ::boneList = #() outputSkinningData obj --Collapse object down collapseStack obj ) ) ) --If justHD then we're just transferrring channel data between itself if justHD then ( for item in veh_LODChain[1] do ( RsProjectVertexMap item item SRCchannel:UI_SRCChannel TGTchannel:burnChannel subChannels:channels sampleBomb:false preserveMods:false --pushVal:0.01 ) ) else --Projecting to LOD chanin levels ( local penultimateLOD = (veh_LODChain.count - 1) for v=1 to penultimateLOD do ( prgProcess.value = (100.0 * (v as float / penultimateLOD)) local veh_Meshes = veh_LODChain[v] if (v == penultimateLOD) then ( --copy the lod geo copyLOD = combineLODPieces veh_LODChain[v] --move it to the lastLOD pos copyLOD.pos = veh_LODChain[v+1][1].pos --do the bake down for item in veh_LODChain[v+1] where (GetAttrClass item == "Gta Object") do ( CpvFlushChannel item mapChannel:burnChannel RsProjectVertexMap copyLOD item SRCchannel:UI_SRCChannel TGTchannel:burnChannel subChannels:channels sampleBomb:chkMultisample.checked preserveMods:false pushVal:0.01 ) --delete the copy delete copyLOD ) else ( for item in veh_Meshes where (GetAttrClass item == "Gta Object") do ( local nextLODList = veh_LODChain[v+1] local LODIdx if v == 1 then ( LODIdx = for idx=1 to nextLODList.count where (MatchPattern nextLODList[idx].name pattern:(item.name+"_l1") == true) collect idx ) else ( local itemName = substring item.name 1 (item.name.count - 3) LODIdx = for idx=1 to nextLODList.count where (MatchPattern nextLODList[idx].name pattern:(itemName+"_l"+(v as String)) == true) collect idx ) if LODIdx.count > 1 then print LODIdx if LODIdx.count == 0 then ( continue ) LODIdx = LODIdx[1] LODNode = veh_LODChain[v+1][LODIdx] format "source:% lod:%\n" item.name LODNode.name --get the node and check it exists if (not isValidNode LODNode) then ( print "bad node" continue ) --move the next lower LOD mesh for this into the same position local originalLODPos = LODNode.pos LODNode.pos = item.pos --do the bake down local success if (v == 1) then ( checkMapChannelSupport item burnChannel --CpvFlushChannel LODNode mapChannel:burnChannel RsProjectVertexMap item item SRCchannel:UI_SRCChannel TGTchannel:burnChannel subChannels:channels sampleBomb:false preserveMods:false showMessages:false success = RsProjectVertexMap item LODNode SRCchannel:UI_SRCChannel TGTchannel:burnChannel subChannels:channels sampleBomb:chkMultisample.checked pushVal:0.01 preserveMods:false ) else --copy cpv across ( --CpvFlushChannel LODNode mapChannel:burnChannel success = RsProjectVertexMap item LODNode SRCchannel:burnChannel TGTchannel:burnChannel subChannels:channels sampleBomb:chkMultisample.checked pushVal:0.01 preserveMods:false ) if success != ok then ( print (item.name + " missing map channel " + UI_SRCChannel as String) --LODNode.pos = originalLODPos --return false ) LODNode.pos = originalLODPos ) ) windows.processPostedMessages() ) ) --Push skinning information back for SkinnedObj in SkinnedObjList do ( if( classof SkinnedObj.Obj != SkinnedObj.Class ) then ( convertTo SkinnedObj.Obj SkinnedObj.Class ) --Write data back skinned data InputSkinningData SkinnedObj.Obj ) prgProcess.value = 0 ) --///////////////////////////////////////// -- --///////////////////////////////////////// fn blueBakeProcessNG = ( local theNode = checkSelection() if ( theNode == undefined ) then ( return false ) prgProcess.value = 0 --build object lists for each lod level local veh_LODChain = #() buildObjectList theNode &veh_LODChain local veh_Name = theNode.name local veh_LOD = 0 local UI_SRCChannel = spnSRCChannel.value --local cascade = chkCascadeLOD.state --Go to the start frame (for skinning information) Max Time Start --Save any skinning information SkinnedObjList = #() for sub_LODChain in veh_LODChain do ( for obj in sub_LODChain do ( if( isMeshSkinned obj ) then ( --record object and type append SkinnedObjList (datapair Obj:obj Class:(classof obj.BaseObject)) --Output skinned data ::boneList = #() outputSkinningData obj --Collapse object down collapseStack obj ) ) ) format "veh_LODChain: % \n" veh_LODChain if(veh_LODChain.count == 1) then --just transfer onto itself ( for item in veh_LODChain[1] do ( RsProjectVertexMap item item SRCchannel:UI_SRCChannel TGTchannel:burnChannel subChannels:channels sampleBomb:false preserveMods:false --pushVal:0.01 ) ) else ( --First copy from burn channels specified in the UI to vertexcolour channel specified by channels for item in veh_LODChain[1] do ( RsProjectVertexMap item item SRCchannel:UI_SRCChannel TGTchannel:burnChannel subChannels:channels sampleBomb:false preserveMods:false --pushVal:0.01 ) local penultimateLOD = (veh_LODChain.count - 1) for v=1 to penultimateLOD do ( prgProcess.value = (100.0 * (v as float / penultimateLOD)) local veh_Meshes = veh_LODChain[v] --copy the lod geo copyLOD = combineLODPieces veh_LODChain[v] --move it to the lastLOD pos copyLOD.pos = veh_LODChain[v+1][1].pos --do the bake down for item in veh_LODChain[v+1] where GetAttrClass item == "Gta Object" do ( RsProjectVertexMap copyLOD item SRCchannel:burnChannel TGTchannel:burnChannel subChannels:channels sampleBomb:chkMultisample.checked pushVal:0.01 preserveMods:false ) --delete the copy delete copyLOD ) ) --Push skinning information back for SkinnedObj in SkinnedObjList do ( if( classof SkinnedObj.Obj != SkinnedObj.Class ) then ( convertTo SkinnedObj.Obj SkinnedObj.Class ) --Write data back skinned data InputSkinningData SkinnedObj.Obj ) prgProcess.value = 0 ) /*** Copy the map channel data between HD and NG vehicle hierarchies ***/ fn TakeMaxSample samples = ( fn compare v1 v2 = ( local l1 = length v1 local l2 = length v2 case of ( (l1 > l2): 1 (l1 < l2): -1 default:0 ) ) qsort samples compare samples[1] ) fn copyHDtoNG source fromMapChannel:0 toMapChannel:0 subChannels:"all" = ( --get the HD objects local HDMeshes = getVeh_Meshes source --get the NG objects local NGRoot = getNodeByName (source.name + "_ng") local NGMeshes = getVeh_Meshes NGRoot local NGMeshNames = for item in NGMeshes collect item.name --move the HD vehicle to the NG vehicle pos local originalPos = NGRoot.pos NGRoot.pos = source.pos if (HDMeshes.count != NGMeshes.count) then ( print "HD NG mesh count mismatch!" ) --Process the meshes updateProcessText ("Processing channel: " + (fromMapChannel as String)) mainProgress = RSProgressWindow Title:"Copy Channel ....." StartStep:1 EndStep:HDMeshes.count mainProgress.Start() try ( cui.commandPanelOpen = false prgProcess.value = 10 for i = 1 to HDMeshes.count do ( local NGMeshName = (HDMeshes[i].name + "_ng") local NGMeshIndex = findItem NGMeshNames NGMeshName if (NGMeshIndex == 0) then ( format "Woah! cant find a valid index into NGMeshes" messageBox ("Cant find: " + NGMeshName) title:"Error: Missing Mesh" NGRoot.pos = originalPos --prgProcess.value = 0 mainProgress.End() updateProcessText "Ready" return false ) --check for any skin modifiers local NGMeshHasSkin = false if (NGMeshes[NGMeshIndex].modifiers.count == 1) and (isKindOf NGMeshes[NGMeshIndex].modifiers[1] Skin) then ( NGMeshHasSkin = true RSTA_outputSkinWeightData NGMeshes[NGMeshIndex] deleteModifier NGMeshes[NGMeshIndex] 1 ) --flush the channel CpvFlushChannel NGMeshes[NGMeshIndex] mapChannel:toMapChannel --project verts -- print HDMeshes[i].name RsProjectVertexMap HDMeshes[i] NGMeshes[NGMeshIndex] SRCchannel:fromMapChannel TGTchannel:toMapChannel subChannels:subChannels sampleBomb:true pushVal:0.01 preserveMods:false --samplingFn:TakeMaxSample if NGMeshHasSkin then ( addModifier NGMeshes[NGMeshIndex] (Skin()) RSTA_inputSkinData NGMeshes[NGMeshIndex] NGMeshHasSkin = false ) --prgProcess.value = (100.0 * (i / (HDMeshes.count as float))) mainProgress.PostProgressStep() windows.processPostedMessages() ) cui.commandPanelOpen = true ) catch ( print "there was a crash" cui.commandPanelOpen = true mainProgress.End() -- --restore position -- print "***************Catch Error!*****************" NGRoot.pos = originalPos -- prgProcess.value = 0 -- updateProcessText "Ready" ) --reset progress --prgProcess.value = 0 mainProgress.End() updateProcessText "Ready" --restore position NGRoot.pos = originalPos redrawViews() ) --///////////////////////////////////////// -- EVENTS --///////////////////////////////////////// --///////////////////////////////////////// -- --///////////////////////////////////////// on btnCopyMapData pressed do ( --check selection local selectedNode = checkSelection() --print selectedNode if (selectedNode == undefined) do ( return false ) if ((MatchPattern selectedNode.name pattern:"*_ng") == true) do ( messageBox "Choose the HD vehicle root" title:"Bad Selection" return false ) --do the deed updateProcessText "Working.." if chkAllChannels.state then ( for item in mapChannelList do ( local channelIdx = item.id copyHDtoNG selectedNode fromMapChannel:channelIdx toMapChannel:channelIdx subChannels:item.channels ) ) else ( copyHDtoNG selectedNode fromMapChannel:selectedChannel.id toMapChannel:selectedChannel.id subChannels:selectedChannel.channels ) updateProcessText "Ready" ) --///////////////////////////////////////// -- Restore blue channel event --///////////////////////////////////////// on btnRestoreBlue pressed do ( restoreBlue() ) --///////////////////////////////////////// -- --///////////////////////////////////////// on btnPushVCBlue pressed do ( checkSelection() if ng then ( blueBakeProcessNG() ) else ( blueBakeProcess() ) ) on lstChannel selected item do ( selectedChannel = mapChannelList[item] print mapChannelList[item].id ) --///////////////////////////////////////// -- --///////////////////////////////////////// on VehicleBlueBakeUI open do ( banner.setup() lstChannel.selection = 3 ) ) createDialog VehicleBlueBakeUI RsGetLodChildren $