filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/fn_vertexpaint.ms") struct LightSampleStruct ( pos, intensity ) struct StreetBakeDownStruct ( someVar = undefined, bakeSLODs = #(), bakeChannel = -1, sampleBomb = false, loColCutoff = 0.5, blend_LowThresh = 0.01, blend_HighThresh = 0.95, blend_DiffThresh = 0.6, blend_Power = 5.0, lightCloud = #(), sampleRadius = 1.0, --m blendGamma = 0.1, UIHandle = undefined, --///////////////////////////////////////// -- --///////////////////////////////////////// fn colourSampleFn samples = ( local result = [0, 0, 0] local sampCount = 0 for val in samples do ( if (distance [0, 0, 0] val) > loColCutoff do ( result += val sampCount += 1 ) ) --average based on the samples used result /= sampCount ), --///////////////////////////////////////// -- --///////////////////////////////////////// fn harvestLightCloud objList:selection = ( for obj in objList do ( local objMesh = snapshotAsMesh obj meshop.deleteIsoMapVertsAll objMesh --get the vert colours for vtx in objMesh.verts do ( --position local vtxPos = meshop.getVert objmesh vtx.index --light value meshop.getmapVert objMesh -1 vtx.index local geoFaces = meshop.getFacesUsingVert objMesh vtx.index local mapVerts = #() for face = geoFaces do ( local geoFaceVerts = (meshop.getVertsUsingFace objMesh face) as Array local mapFaceVerts = meshop.getMapFace objMesh -1 face --format "%\n" mapFaceVerts --local mapVert = (for gv=1 to geoFaceVerts.count where (geoFaceVerts[gv] == vtx.index) collect mapFaceVerts[gv])[1] local mapVert = case of ( (geoFaceVerts[1] == vtx.index): mapFaceVerts.x (geoFaceVerts[2] == vtx.index): mapFaceVerts.y (geoFaceVerts[3] == vtx.index): mapFaceVerts.z ) append mapVerts mapVert ) --save a lightSample local lightSample = LightSampleStruct() lightSample.pos = vtxPos local lightval = [0,0,0] local skipMapVert = false try ( lightval = (meshop.getMapVert objMesh -1 mapVerts[1]) as Point3 format "lightVal: % \n" lightVal ) catch ( print "." skipMapVert = true ) if not skipMapVert do ( lightSample.intensity = lightVal append lightCloud lightSample ) ) ) --print lightCloud.count ), --///////////////////////////////////////// -- --///////////////////////////////////////// fn compareIntensity v1 v2 = ( case of ( ((length v1) > (length v2)):-1 ((length v1) < (length v2)):1 default:0 ) ), --///////////////////////////////////////// -- --///////////////////////////////////////// fn blendLocality objList:selection = ( blendGamma = 1.0 / UIHandle.spnSampleGamma.value UIHandle.prgBar.value = 1 local counter = 1 for obj in objList do ( local objOp = RsMeshPolyOp obj for vtx in obj.verts do ( local vertPos = objOp.getvert obj vtx.index local currentIntensity = [0,0,0] local lightSamples = #() for sample in lightCloud do ( local dist = distance vertPos sample.pos if dist < 0.00001 do currentIntensity = sample.intensity if (not (dist < 0.00001)) and (not (dist > sampleRadius)) then ( --Append the lightsample scaled by inverse square distance append lightSamples (sample.intensity * (1.0 / (dist * dist))) ) ) --format "lightSamples count:% \n" lightSamples.count local sampleDiff = 0 if lightSamples.count > 0 do ( --sort the samples qsort lightSamples compareIntensity --if the difference between the highest and lowest value are greater than blend_DiffThresh then average the values sampleDiff = length(lightSamples[lightSamples.count] - lightSamples[1]) ) --blend local lightVal = currentIntensity local sampleCount = 0 for s=1 to lightSamples.count do ( --print lightSamples[s] if (lightSamples[s].x > blend_LowThresh) do ( lightVal += [(lightSamples[s].x ^ blendGamma), (lightSamples[s].y ^ blendGamma), (lightSamples[s].z ^ blendGamma)] sampleCount += 1 ) ) if (sampleDiff > blend_DiffThresh) do ( lightVal /= sampleCount ) --lightVal = lightVal / sampleCount --Cap intensity at 1.0 if (length lightVal) > 1.73205 then lightVal = [1.0, 1.0, 1.0] --set the colour objOp.setVertColor obj -1 vtx.index (([lightVal.x, lightVal.x, lightVal.x] as Point4) as Color) ) update obj counter += 1 UIHandle.prgBar.value = (100.0 * (counter / (objList.count as float))) ) UIHandle.prgBar.value = 0 ), --///////////////////////////////////////// -- --///////////////////////////////////////// fn blendUp objIn = ( local obj = snapshotasmesh objIn local objOp = RsMeshPolyOp objIn local newMap = #() for vtx in obj.verts do ( local geoFaces = meshop.getFacesUsingVert obj vtx.index local mapVerts = #() for face = geoFaces do ( local geoFaceVerts = (meshop.getVertsUsingFace obj face) as Array local mapFaceVerts = meshop.getMapFace obj -1 face --format "%\n" mapFaceVerts --local mapVert = (for gv=1 to geoFaceVerts.count where (geoFaceVerts[gv] == vtx.index) collect mapFaceVerts[gv])[1] local mapVert = case of ( (geoFaceVerts[1] == vtx.index): mapFaceVerts.x (geoFaceVerts[2] == vtx.index): mapFaceVerts.y (geoFaceVerts[3] == vtx.index): mapFaceVerts.z ) append mapVerts mapVert ) --print mapVerts --find the brightest coloursample and set all the local colourSamples = #() for mv in mapVerts do ( appendIfUnique colourSamples (meshop.getMapVert obj -1 mv) ) --sort them qsort colourSamples compareIntensity --break() local hiColour = if(colourSamples.count != 0) then colourSamples[1] else [0,0,0] --set it to the brightest sample to begin with /* local sampleWeight = 0 local notFinished = true --ignore any blacks --weight brighter ones based on how bright they are so we drive up the intensity. local sampleCount = 0 for sample in colourSamples while notFinished do ( if (sample.x > blend_LowThresh) do ( hiColour += [(sample.x ^ blend_Power), (sample.y ^ blend_Power), (sample.z ^ blend_Power)] --hiColour += sample sampleWeight += (1.0 - sample.x) --weights[sampleCount] = sample.x ) ) hiColour /= sampleWeight if (length hiColour) > 1.73205 then hiColour = [1.0, 1.0, 1.0] */ newMap[vtx.index] = ([hiColour.x, hiColour.x, hiColour.x, 0]) as Color --collect for lightCloud --save a lightSample local lightSample = LightSampleStruct() lightSample.pos = objOp.getVert objIn vtx.index lightSample.intensity = hiColour append lightCloud lightSample ) for vtx in objIn.verts do ( objOp.setVertColor objIn -1 vtx.index newMap[vtx.index] ) update objIn ), --///////////////////////////////////////// -- --///////////////////////////////////////// fn bakeDown = ( UIHandle.prgBar.value = 1 local counter = 1 for SLOD in bakeSLODs do ( --find the target LODs local LODS = #() RsSceneLink.GetChildren 0 SLOD &LODS if (LODS.count != 0) do ( local childLOD = snapshot LODS[1] childLOD.material = copy LODS[1].material --Merge the LODS together into a temporary object to bake from them if LODS.count > 1 then ( --childLOD = snapshot LODS[1] for l=2 to LODS.count do ( attach childLOD (snapshotasmesh LODS[l]) ) ) --Projects the data RsProjectFaceMap childLOD SLOD SRCchannel:bakeChannel TGTchannel:bakeChannel sampleBomb:sampleBomb bombSamples:2 --samplingFn:colourSampleFn --blend the vert illumination values within SLOD blendUp SLOD --delete the childLOD temporary mesh delete childLOD counter += 1 UIHandle.prgBar.value = (100.0 * (counter / (bakeSLODs.count as float))) ) ) UIHandle.prgBar.value = 0 --harvestLightCloud() --blendLocality() ) ) --///////////////////////////////////////// -- UI --///////////////////////////////////////// try(destroyDialog StreetBakeDownUI)catch() rollout StreetBakeDownUI "Street BakeDown" width:250 height:220 ( --///////////////////////////////////////// -- VARIABLES --///////////////////////////////////////// local streetBakeDown = StreetBakeDownStruct() --///////////////////////////////////////// -- CONTROLS --///////////////////////////////////////// dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:StreetBakeDownUI.width local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"CHANGEME" filename:(getThisScriptFilename()) versionNum:1.0 versionName:"Luxurient Burn" group "Samples" ( checkbox chkSampleBomb "SampleBomb" across:2 spinner spnSamples "Samples:" range:[1, 10, 2] type:#integer ) group "" ( button btnBake "BakeDown" width:(StreetBakeDownUI.width - 20) offset:[0, -8] progressBar prgBar ) group "Locality Blend" ( spinner spnSampleRad "Sample Radius" range:[1.0, 25.0, 5.0] type:#float offset:[10,0] across:2 spinner spnSampleGamma "Gamma" range:[0.1, 4.0, 1.0] type:#float button btnBlendLocal "Blend" width:(StreetBakeDownUI.width - 20) ) --///////////////////////////////////////// -- FUNCTIONS --///////////////////////////////////////// --///////////////////////////////////////// -- EVENTS --///////////////////////////////////////// on spnSampleGamma changed val do ( streetBakeDown.blendGamma = val ) --///////////////////////////////////////// -- --///////////////////////////////////////// on spnSampleRad changed val do ( streetBakeDown.sampleRadius = val ) --///////////////////////////////////////// -- --///////////////////////////////////////// on btnBlendLocal pressed do ( streetBakeDown.blendLocality() ) --///////////////////////////////////////// -- --///////////////////////////////////////// on chkSampleBomb changed state do ( streetBakeDown.sampleBomb = state ) --///////////////////////////////////////// -- --///////////////////////////////////////// on btnBake pressed do ( --check selection is valid if selection.count == 0 do ( messagebox "Nothing selected for baking" title:"No Selection" return false ) streetBakeDown.bakeSLODs = selection streetBakeDown.bakeDown() ) --///////////////////////////////////////// -- --///////////////////////////////////////// on StreetBakeDownUI open do ( banner.setup() streetBakeDown.UIHandle = StreetBakeDownUI ) ) createDialog StreetBakeDownUI