712 lines
17 KiB
Plaintext
Executable File
712 lines
17 KiB
Plaintext
Executable File
--
|
|
-- File:: pipeline/util/radiosity.ms
|
|
-- Description:: Radiosity utilities
|
|
--
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- History
|
|
-----------------------------------------------------------------------------
|
|
--
|
|
-- 11/2/10
|
|
-- Marissa Warner-Wu <marissa.warner-wu@rockstarnorth.com>
|
|
-- 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]
|
|
)
|
|
)
|
|
)
|
|
) |