-- -- File:: pipeline/util/radiosity.ms -- Description:: Radiosity utilities -- ----------------------------------------------------------------------------- -- History ----------------------------------------------------------------------------- -- -- 11/2/10 -- Marissa Warner-Wu -- Combining with new Radiosity and Lighting tool. -- ----------------------------------------------------------------------------- -- Uses ----------------------------------------------------------------------------- --filein "rockstar/util/material.ms" -- loaded on startup by startup.ms ----------------------------------------------------------------------------- -- Globals ----------------------------------------------------------------------------- ErrorObjects = #() ErrorEntries = #() RsStoreHandles = #() RsStoreMaterials = #() global GtaCollAsMesh = #() global GtaParentHidden = #() global GtaSurfaceType = #() global GtaPieceType = #() global inGameLightMultiple = 1.0 radiositySetTime = "Day" global GtaEmissiveList = #( "emissive", "emissivenight", "emissivenight_alpha", "emissivestrong", "emissivestrong_alpha", "emissive_alpha", "emissive_alpha_tnt", "emissive_tnt", "glass_emissive", "glass_emissivenight", "glass_emissivenight_alpha", "glass_emissive_alpha", "normal_spec_reflect_emissive", "normal_spec_reflect_emissivenight", "normal_spec_reflect_emissivenight_alpha", "normal_spec_reflect_emissive_alpha" ) ----------------------------------------------------------------------------- -- Functions ----------------------------------------------------------------------------- fn CheckLightOn obj time isroot = ( if obj == undefined then ( return 0 ) if obj == undefined then ( return 0 ) if classof obj == ObjectSet then ( for childobj in obj do ( CheckLightOn childobj time ) ) if GetAttrClass(obj) == "Gta LightPhoto" then ( if classof(obj) == DaylightAssemblyHead then ( if isroot == false then ( isOn = false ) else ( isOn = true ) if isOn == true then ( if obj.sun != undefined then ( obj.sun.on = true ) if obj.sky != undefined then ( obj.sky.on = true ) obj.ishidden = false ) else ( obj.ishidden = true if obj.sun != undefined then ( obj.sun.on = false ) if obj.sky != undefined then ( obj.sky.on = false ) ) ) else ( if isroot == false then ( isOn = false ) else ( isOn = true ) if isOn == true then ( obj.enabled = true obj.ishidden = false if ( classof(obj) == RageLight ) do obj.lightEnabled = true ) else ( obj.enabled = false obj.ishidden = true if ( classof(obj) == RageLight ) do obj.lightEnabled = false ) ) ) if GetAttrClass(obj) == "Gta Light" then ( if classof(obj) == DaylightAssemblyHead then ( if isroot == false then ( isOn = false ) else ( isOn = true ) if isOn == true then ( if obj.sun != undefined then ( obj.sun.on = true ) if obj.sky != undefined then ( obj.sky.on = true ) obj.ishidden = false ) else ( obj.ishidden = true if obj.sun != undefined then ( obj.sun.on = false ) if obj.sky != undefined then ( obj.sky.on = false ) ) ) else ( if isroot == false then ( isOn = false ) else ( isOn = true ) if isOn == true then ( obj.enabled = true obj.ishidden = false ) else ( obj.enabled = false obj.ishidden = true ) ) ) for childobj in obj.children do ( CheckLightOn childobj time false ) ) fn LightsOn time = ( for obj in rootnode.children do ( CheckLightOn obj time true ) ) fn RestoreMaterials = ( for i = 1 to RsStoreHandles.count do ( obj = maxOps.getNodeByHandle RsStoreHandles[i] obj.material = RsStoreMaterials[i] ) RsStoreHandles = #() RsStoreMaterials = #() ) fn CheckForBogusVerts = ( kosher = true for selMesh in selection do ( badVerts = #() if classof selMesh == Editable_mesh then ( m = selMesh.baseobject nVerts = meshop.getNumVerts m for i = 1 to nVerts do ( if not bit.isFinite ((meshop.getVert m i)[1]) do ( append badVerts i print (meshop.getVert m i) ) ) if badVerts.count > 0 then ( if queryBox ("Broken verts found on " + selMesh.name + ". Do you want to remove them? Radiosity can't be processed unless you do.") == true then ( meshop.deleteVerts m badVerts print ("Starting: " + nVerts as string + " - Ending: " + (meshop.getNumVerts m) as string) ) else ( kosher = false ) ) ) else if classof selMesh == Editable_Poly then ( m = selMesh.baseobject nVerts = polyop.getNumVerts m for i = 0 to nVerts do ( if not bit.isFinite ((m.getVertex i)[1]) do ( append badVerts i print (m.getVertex i) ) ) if badVerts.count > 0 then ( if queryBox ("Broken verts found on " + selMesh.name + ". Do you want to remove them? Radiosity can't be processed unless you do.") == true then ( polyop.deleteVerts m badVerts print ("Starting: " + nVerts as string + " - Ending: " + (polyop.getNumVerts m) as string) ) else ( kosher = false ) ) ) ) kosher ) fn doCombineColour colVal = ( greyScale = (colVal.r / 255.0) * 0.3 greyScale = greyScale + ((colVal.g / 255.0) * 0.59) greyScale = greyScale + ((colVal.b / 255.0) * 0.11) greyScale = (greyScale * 255.0) as integer colVal = (color greyScale greyScale greyScale) return colVal ) fn doRadiosityForObject SrcMesh ignoreEmissive blackenIllum= ( found = false idxDontApplyRadiosity = -1 if (isInternalRef SrcMesh) do return 0 if GetAttrClass SrcMesh == "Gta Object" then ( idxDontApplyRadiosity = GetAttrIndex "Gta Object" "Dont Apply Radiosity" ) if GetAttrClass SrcMesh == "GtaAnimHierarchy" then ( idxDontApplyRadiosity = GetAttrIndex "GtaAnimHierarchy" "Dont Apply Radiosity" ) if idxDontApplyRadiosity != -1 then ( if GetAttr SrcMesh idxDontApplyRadiosity == true then ( found = true ) ) if found == true then ( return 0 ) if isRefObj SrcMesh then ( return 0 ) if (canConvertTo SrcMesh Editable_Mesh) == false then ( return 0 ) newMesh = undefined Try(ConvertToMesh SrcMesh)Catch() Try(newMesh = radiosityMeshOps.getRadiosityMesh SrcMesh)Catch() if newMesh == undefined then ( return 0 ) ignorePolys = #() ignoreVerts = #() if ignoreEmissive then ( for item in GtaEmissiveList do ( RsGetObjFacesUsingShader SrcMesh item ignorePolys ) SrcMesh.selectedfaces = ignorePolys ) numCPVVerts = getNumCPVVerts(newMesh.mesh) numOldCPVVerts = getNumCPVVerts(SrcMesh.mesh) numOldIllumVerts = getNumIVCVerts(SrcMesh.mesh) if ignoreEmissive then ( if radiositySetTime == "Day" then ( if numOldCPVVerts == 0 then ( setNumCPVVerts SrcMesh.mesh numCPVVerts buildVCFaces SrcMesh.mesh ) else if (( true == blackenIllum ) and ( 0 == numOldIllumVerts )) do ( setNumIVCVerts SrcMesh.mesh numCPVVerts buildIVFaces SrcMesh.mesh ) ) else ( if numOldIllumVerts == 0 then ( setNumIVCVerts SrcMesh.mesh numCPVVerts buildIVFaces SrcMesh.mesh ) ) newVertList = #() newFaceList = #() for i = 1 to newMesh.numfaces do ( vertA = undefined vertB = undefined vertC = undefined if finditem ignorePolys i == 0 then ( faceColour = getVCFace newMesh i vertA = getVertColor newMesh faceColour[1] vertB = getVertColor newMesh faceColour[2] vertC = getVertColor newMesh faceColour[3] ) else ( if radiositySetTime == "Day" then ( faceColour = getVCFace SrcMesh.mesh i vertA = getVertColor SrcMesh.mesh faceColour[1] vertB = getVertColor SrcMesh.mesh faceColour[2] vertC = getVertColor SrcMesh.mesh faceColour[3] ) else ( faceColour = getIVFace SrcMesh.mesh i vertA = getIllumVertColor SrcMesh.mesh faceColour[1] vertB = getIllumVertColor SrcMesh.mesh faceColour[2] vertC = getIllumVertColor SrcMesh.mesh faceColour[3] ) ) faceid = i - 1 append newVertList vertA append newVertList vertB append newVertList vertC append newFaceList [faceid * 3 + 1,faceid * 3 + 2,faceid * 3 + 3] ) if radiositySetTime == "Day" then ( setNumCPVVerts SrcMesh.mesh (newMesh.numfaces * 3) buildVCFaces SrcMesh.mesh for i = 1 to SrcMesh.numfaces do ( setVCFace SrcMesh.mesh i newFaceList[i] ) for i = 1 to newVertList.count do ( setVertColor SrcMesh.mesh i newVertList[i] ) -- Set default illum colour to black if tickbox is checked -- for bugstar:22267 if ( true == blackenIllum ) do ( setNumIVCVerts SrcMesh.mesh (newMesh.numfaces * 3) buildIVFaces SrcMesh.mesh for i = 1 to SrcMesh.numfaces do ( setIVFace SrcMesh.mesh i newFaceList[i] ) for i = 1 to newVertList.count do ( setIllumVertColor SrcMesh.mesh i (color 0 0 0) ) ) ) else ( setNumIVCVerts SrcMesh.mesh (newMesh.numfaces * 3) buildIVFaces SrcMesh.mesh for i = 1 to SrcMesh.numfaces do ( setIVFace SrcMesh.mesh i newFaceList[i] ) for i = 1 to newVertList.count do ( setIllumVertColor SrcMesh.mesh i newVertList[i] ) ) ) else ( if radiositySetTime == "Day" then ( setNumCPVVerts SrcMesh.mesh numCPVVerts buildVCFaces SrcMesh.mesh -- If checkbox is ticked, set illum channel to 0 -- rather than it defaulting to 1 - for bugstar:22267 if ( true == blackenIllum ) do ( setNumIVCVerts SrcMesh.mesh numCPVVerts buildIVFaces SrcMesh.mesh ) ) else ( setNumIVCVerts SrcMesh.mesh numCPVVerts buildIVFaces SrcMesh.mesh ) for i = 1 to numCPVVerts do ( vertColour = getVertColor newMesh i if radiositySetTime == "Day" then ( setVertColor SrcMesh.mesh i vertColour if ( true == blackenIllum ) do ( setIllumVertColor SrcMesh.mesh i (color 0 0 0) ) ) else ( setIllumVertColor SrcMesh.mesh i vertColour ) ) for i = 1 to newMesh.numfaces do ( faceColour = getVCFace newMesh i if radiositySetTime == "Day" then ( setVCFace SrcMesh.mesh i faceColour if ( true == blackenIllum ) do ( setIVFace SrcMesh.mesh i faceColour ) ) else ( setIVFace SrcMesh.mesh i faceColour ) ) ) if radiositySetTime == "Day" then ( SrcMesh.vertexcolortype = #color ) else ( SrcMesh.vertexcolortype = #illum ) SrcMesh.showVertexColors = true ) fn doRadiosityForCollObject SrcMesh = ( found = false if isRefObj SrcMesh then ( return 0 ) if (canConvertTo SrcMesh Editable_Mesh) == false then ( return 0 ) newMesh = undefined Try(ConvertToMesh SrcMesh)Catch() Try(newMesh = radiosityMeshOps.getRadiosityMesh SrcMesh)Catch() if newMesh == undefined then ( return 0 ) numCPVVerts = newMesh.numfaces numOldCPVVerts = getNumCPVVerts(SrcMesh.mesh) numOldIllumVerts = getNumIVCVerts(SrcMesh.mesh) if radiositySetTime == "Day" then ( setNumCPVVerts SrcMesh.mesh numCPVVerts buildVCFaces SrcMesh.mesh ) else ( setNumIVCVerts SrcMesh.mesh numCPVVerts buildIVFaces SrcMesh.mesh ) indexSet = 1 print newMesh.numfaces for i = 1 to newMesh.numfaces do ( faceColour = getVCFace newMesh i vertA = (getVertColor newMesh faceColour.x) / 3.0 vertB = (getVertColor newMesh faceColour.y) / 3.0 vertC = (getVertColor newMesh faceColour.z) / 3.0 setVert = doCombineColour(vertA + vertB + vertC) if radiositySetTime == "Day" then ( setVertColor SrcMesh.mesh indexSet setVert ) else ( setIllumVertColor SrcMesh.mesh indexSet setVert ) setFace = [indexSet,indexSet,indexSet] if radiositySetTime == "Day" then ( setVCFace SrcMesh.mesh i setFace ) else ( setIVFace SrcMesh.mesh i setFace ) indexSet = indexSet + 1 ) if radiositySetTime == "Day" then ( SrcMesh.vertexcolortype = #color ) else ( SrcMesh.vertexcolortype = #illum ) SrcMesh.showVertexColors = true ) ----------------------------------------------------------------------------- -- Handlers for external events ----------------------------------------------------------------------------- fn ButtonPrepareMat ignoreEmissive = ( if (RsStoreHandles.count > 0) then ( case (yesnocancelbox "You've already stored some object materials. Restore before proceeding?") of ( #cancel:(return 0) #yes:(RestoreMaterials()) ) ) fn setToMat mat ignoreEmissive = ( local ignore = false local isTransparent = false if isKindOf mat Rage_Shader then ( local shaderName = (RstGetShaderName mat) for item in #("*glass*", "*alpha*", "*decal*", "*cutout*") while not isTransparent do ( isTransparent = matchPattern shaderName pattern:item ) if ignoreEmissive do ( ignore = ((findItem GtaEmissiveList (getFilenameFile shaderName)) != 0) ) ) return case of ( (mat == undefined):undefined ignore:mat isTransparent:(StandardMaterial diffuse:(color 150.0 150.0 150.0) opacity:0.0) default:(StandardMaterial diffuse:(color 150.0 150.0 150.0)) ) ) for obj in selection do ( append RsStoreHandles obj.handle append RsStoreMaterials obj.material if (isKindOf obj.material MultiMaterial) then ( obj.material = copy obj.material for i = 1 to obj.material.materiallist.count do ( local subMat = obj.material.materiallist[i] local newMat = setToMat subMat ignoreEmissive if (subMat != newMat) do ( obj.material.materiallist[i] = newMat ) ) ) else ( local newMat = setToMat obj.material ignoreEmissive if (obj.material != newMat) do ( obj.material = newMat ) ) ) ) fn ButtonApplyRadiosity ignoreEmissive retainIllum= ( ErrorObjects = #() ErrorEntries = #() if CheckForBogusVerts() == true then ( for selMesh in selection do ( doRadiosityForObject selMesh ignoreEmissive retainIllum ) for selMesh in GtaCollAsMesh do ( doRadiosityForCollObject selMesh ) rollout GTARadiosityErrorRoll "Radiosity Set Problems" ( --UI listbox err "Errors:" height:14 items:ErrorEntries button quit "Ok" -- events on err selected item do ( if (ErrorObjects[item] != undefined) then ( select ErrorObjects[item] max zoomext sel ) ) on quit pressed do ( try DestroyDialog GTARadiosityErrorRoll catch() ) ) try DestroyDialog GTARadiosityErrorRoll catch() if ErrorEntries.count > 0 then ( GTARadiosityErrorUtil = CreateDialog GTARadiosityErrorRoll width:360 height:230 modal:false escapeEnable:false ) ) ) fn ButtonCopyVertIllum = ( for mesh = 1 to selection.count do ( SrcMesh = selection[mesh] found = false if isRefObj SrcMesh then ( continue ) if (canConvertTo SrcMesh Editable_Mesh) == false then ( continue ) Try(ConvertToMesh SrcMesh)Catch() numCPVVerts = getNumCPVVerts(SrcMesh.mesh) numIllumVerts = getNumIVCVerts(SrcMesh.mesh) CPVVerts = #() IllumVerts = #() CPVFaces = #() IllumFaces = #() for i = 1 to numCPVVerts do ( append CPVVerts (getVertColor SrcMesh.mesh i) ) for j = 1 to numIllumVerts do ( append IllumVerts (getIllumVertColor SrcMesh.mesh j) ) for k = 1 to SrcMesh.numfaces do ( if numCPVVerts > 0 then ( append CPVFaces (getVCFace SrcMesh.mesh k) ) if numIllumVerts > 0 then ( append IllumFaces (getIVFace SrcMesh.mesh k) ) ) if numCPVVerts > 0 then ( setNumIVCVerts SrcMesh.mesh numCPVVerts ) else ( setNumIVCVerts SrcMesh.mesh 1 ) buildIVFaces SrcMesh.mesh if numCPVVerts > 0 then ( for l = 1 to numCPVVerts do ( setIllumVertColor SrcMesh.mesh l CPVVerts[l] ) ) else ( setIllumVertColor SrcMesh.mesh 1 [255,255,255] ) for n = 1 to SrcMesh.numfaces do ( if numCPVVerts > 0 then ( setIVFace SrcMesh.mesh n CPVFaces[n] ) else ( setIVFace SrcMesh.mesh n [1,1,1] ) ) ) )