Files
2025-09-29 00:52:08 +02:00

4139 lines
111 KiB
Plaintext
Executable File

-- Rockstar Material Utilities
-- Rockstar North
-- 14/3/2005
-- by Greg Smith
-- by Luke Openshaw
-- if you get add any functions to get texture maps
-- make sure they come out lower case. lots of comparisons
-- assume this. RsMakeSafeTextureName will return a lowercase
-- name
-----------------------------------------------------------------------------
-- Uses
-----------------------------------------------------------------------------
--filein "pipeline/util/file.ms" -- loaded on startup by startup.ms
--filein "pipeline/util/string.ms" -- loaded on startup by startup.ms
--filein "rockstar/util/mapobj.ms" -- loaded on startup by startup.ms
--filein "rockstar/export/settings.ms" -- loaded on startup by startup.ms
filein "pipeline/util/drawablelod.ms"
filein "rockstar/util/lod.ms"
filein "pipeline/util/ExcludedTextures.ms"
filein "rockstar/util/material_funcs.ms"
-----------------------------------------------------------------------------
-- Globals
-----------------------------------------------------------------------------
-- Set by RsGetShaderList:
global RSshaderList = undefined
global RsDiffuseTexMaxSize = 1024
global RsOtherTexMaxSize = 1024
global idxTexOptimised = (getAttrIndex "Gta Texture" "optimised")
global gRsCallCountRsGetTexMapsFromObjNoStrip = 0
-----------------------------------------------------------------------------
-- Functions
-----------------------------------------------------------------------------
--------------------------------------------------------------
-- Returns a list of objs without packed textured objects
--------------------------------------------------------------
fn RsGetInputObjectList inputObjList outputObjList =
(
local idxPackTextures = getattrindex "Gta Object" "Pack Textures"
local collectObjs = for obj in inputObjList where (getAttrClass obj != "Gta Object") or (getAttr obj idxPackTextures == False) collect obj
join outputObjList collectObjs
return outputObjList
)
----------------------------------------------------------------------------------------
-- Is this a Diffuse map-slot name?
----------------------------------------------------------------------------------------
fn RsIsDiffuseMap slotName =
(
local retval = case of
(
(not isKindOf slotName String):False
((matchPattern slotName pattern:"Diffuse*") and (not matchPattern slotName pattern:"*Palette*")):True
(matchPattern slotName pattern:"Color Texture*"):True
Default:False
)
return retval
)
----------------------------------------------------------------------------------------
-- Is this a Palette map-slot name?
----------------------------------------------------------------------------------------
fn RsIsPaletteMap slotName =
(
local retval = false
if (isKindOf slotName String) do
(
retval = (matchPattern slotName pattern:"*Palette*")
)
retval
)
----------------------------------------------------------------------------------------
-- Is this a Specular map-slot name?
----------------------------------------------------------------------------------------
fn RsIsSpecMap slotName =
(
local retval = false
if (isKindOf slotName String) do
(
retval = (matchPattern slotName pattern:"*Specular*")
)
retval
)
----------------------------------------------------------------------------------------
-- Is this a Bump map-slot name?
----------------------------------------------------------------------------------------
fn RsIsBumpMap slotName =
(
local retval = false
if (isKindOf slotName String) do
(
retval = (matchPattern slotName pattern:"*Bump*") or (matchPattern slotName pattern:"Normal Map*")
)
retval
)
----------------------------------------------------------------------------------------
-- Is this a cable-shader?
----------------------------------------------------------------------------------------
fn RsIsCableTexture objMat =
(
local retval = false
if (isKindOf objMat Rage_Shader) do
(
retval = (matchPattern (RstGetShaderName objMat) pattern:"*cable*")
)
return retval
)
----------------------------------------------------------------------------------------
-- Is this a Distance Map map-slot?
----------------------------------------------------------------------------------------
fn RsIsDistanceMap slotName =
(
slotName == "Distance Map"
)
----------------------------------------------------------------------------------------
-- Is this a Tint Palette map-slot?
----------------------------------------------------------------------------------------
fn RsIsTintPalette slotName =
(
slotName == "Tint Palette"
)
----------------------------------------------------------------------------------------
-- Is this a Terrain Blend map-slot?
----------------------------------------------------------------------------------------
fn RsIsTerrainBlendMap slotName =
(
local retval = false
if (isKindOf slotName String) do
(
retval = (matchPattern slotName pattern:"*Blend Texture *")
)
return retval
)
----------------------------------------------------------------------------------------
-- Is this texturemap export-exempt?
----------------------------------------------------------------------------------------
fn RsIsExportExempt mapname =
(
(mapname != undefined) and
(
RsExcludedTextures.CheckName(mapname)
)
)
-----------------------------------------------------------------------------
-- Global flags used to control texturemap-collection functions:
-----------------------------------------------------------------------------
struct RsIncTexmaps
(
incDefault = true,
incDiffuse = true,
incSpec = true,
incNormal = true,
incExempt = false,
incPalette = true,
-- Set global flags:
fn setFlags inDefault diff: spec: normal: palette: =
(
incDefault = inDefault
if (diff != unsupplied) do (incDiffuse = diff)
if (spec != unsupplied) do (incSpec = spec)
if (normal != unsupplied) do (incNormal = normal)
if (palette != unsupplied) do (incPalette = palette)
return OK
),
-- Does a given texturemap match the current include-flags?
fn isIncluded texmapName texmapType =
(
local incMap = incDefault
if RsIsDiffuseMap texmaptype do (incMap = incDiffuse)
if RsIsPaletteMap texmaptype do (incMap = incPalette)
if RsIsTerrainBlendMap texmaptype do (incMap = incDiffuse)
if RsIsSpecMap texmaptype do (incMap = incSpec)
if RsIsBumpMap texmaptype do (incMap = incNormal)
if RsIsExportExempt texmapname do (incMap = incExempt)
return incMap
)
)
gRsIncTexmaps = RsIncTexmaps()
RsSetMapsFlags = gRsIncTexmaps.setFlags
----------------------------------------------------------------------------------------
-- Gets texturemap data from an object's lights:
----------------------------------------------------------------------------------------
fn RsCheckForLighttextures obj texmaplist maxsizelist:#() isbumplist:#() exemptionList:#() texmapobjlist:#() maptypelist:#() texturetemplatelist:#() matIdList:#() =
(
if (not isValidNode obj) do return False
for childobj in obj.children do
(
local lightShadowMap = undefined
case of
(
(isproperty childobj "shadowprojectormap"):
(
lightShadowMap = childobj.shadowprojectormap
)
(isKindof childobj RageLight):
(
local underlyingLight = childobj
while isProperty underlyingLight "delegate" do
underlyingLight = underlyingLight.delegate
if isproperty underlyingLight "shadowprojectormap" then
(
underlyingLight.shadowprojectormap = childobj.lightShadowMap
lightShadowMap = childobj.delegate.shadowprojectormap
)
)
)
if (lightShadowMap != undefined) and (lightShadowMap.filename != "") do
(
if (appendIfUnique texmaplist (toLower lightShadowMap.filename)) do
(
append maptypelist "LightMap"
append texmapobjlist lightShadowMap
append maxsizelist 1024
append isbumplist false
append exemptionList false
append texturetemplatelist "Diffuse"
append matIdList -1 -- Default no-matid value
if (not doesFileExist lightShadowMap.filename) do
(
gRsUlog.LogWarning ("Texture "+ lightShadowMap.filename +" on light "+childobj.name+" couldn't be found!") context:childobj
)
)
)
)
return texmaplist
)
fn RsHasLightTxd obj =
(
local txList = #()
RsCheckForLighttextures obj txList
local HasLightTx = (txList.count > 0)
for child in obj.children while (not HasLightTx) do
(
HasLightTx = RsHasLightTxd child
)
return HasLightTx
)
-----------------------------------------------------------------
-- Build a list of a material's submaterials of a particular class
-----------------------------------------------------------------
fn RSgetMatClassSubMats mat getClass matList:#() =
(
case (classOf mat) of
(
MultiMaterial:
(
for subMat in mat.materiallist do
(
RSgetMatClassSubMats subMat getClass matList:matList
)
)
getClass:
(
appendIfUnique matList mat
)
)
matList
)
fn RsIsResizeExempt map maptypename objMat =
(
local retval = (not getAttr map idxTexOptimised) or (RsIsTintPalette maptypename) or (RsIsDistanceMap maptypename) or (RsIsCableTexture objMat)
return retval
)
fn RsGetDistanceAlphaMapResultMap distAlphaMap =
(
-- Make my name safe:
distAlphaMap.name = substituteString distAlphaMap.name " " "_"
distAlphaMap.name = substituteString distAlphaMap.name "#" ""
-- Make sure result is not downscaled:
setAttr distAlphaMap idxTexOptimised False
local resultmap = undefined
if (distAlphaMap.resultmap != undefined) do
(
resultmap = distAlphaMap.resultmap
)
-- Check whether it's a valid file path; if not, export it:
if (resultmap == undefined) or (resultmap.filename == "") or ((getFileSize resultmap.filename) == 0) do -- Rebuild if necessary
(
local diffuseMapPath = "C:\\"
if (distAlphaMap.diffusemap != undefined) do
(
diffuseMapPath = getFilenamePath distAlphaMap.diffuseMap
)
if (distAlphaMap.Create False diffuseMapPath) do
(
resultmap = distAlphaMap.resultmap
)
format "Building new Distance map to %\n" resultmap.filename
--doublecheck whether it worked
if (resultmap == "") then
(
local msg=stringstream ""
format "Result for distanceAlphaMap % could not be created!" distAlphaMap.name to:msg
messagebox msg
)
)
return resultmap
)
----------------------------------------------------------------------------------------
-- Makes list of texturemaps used on object, the number of
-- polys they use, and the faces they use
----------------------------------------------------------------------------------------
fn RsMatGetMapIdsUsedOnObjectWithCount obj mapList mat: polycount: faceidlists: maxMatId: =
(
if (mat == unsupplied) do
(
mat = obj.material
)
if (isKindOf obj col_mesh) do (obj = getColMesh obj)
local isMesh = (isKindOf obj Editable_Mesh) or (isKindOf obj TriMesh)
local doPolyCount = (polycount != unsupplied)
local doFaceIDlists = (faceidlists != unsupplied)
local limitMatIds = (maxMatId != unsupplied)
if
(
(
isMesh or
isKindOf obj Editable_Poly or
isKindOf obj PolyMeshObject
) and
(mat != undefined) and (hasProperty mat "materialList")
)
then
(
local objGetFaceMatId = if isMesh then getfacematid else polyop.getfacematid
for i = 1 to (getnumfaces obj) do
(
local matID = objGetFaceMatId obj i
if matID != undefined do
(
if limitMatIds do
(
if (matID > maxMatId) do
(
matID = (mod matID maxMatId) as integer
if (matID == 0) do (matID = maxMatId)
)
)
local idxFound = finditem mapList matID
if idxFound == 0 then
(
append mapList matID
if doPolyCount do (append polycount 1)
if doFaceIDlists do (append faceidlists #(i))
)
else
(
if doPolyCount do (polycount[idxFound] += 1)
if doFaceIDlists do (append faceidlists[idxFound] i)
)
)
)
)
else
(
append mapList -1
if doPolyCount do (append polycount 0)
)
return mapList
)
----------------------------------------------------------------------------------------
-- Makes list of texturemaps used on object
----------------------------------------------------------------------------------------
fn RsMatGetMapIdsUsedOnObject obj mapList mat: maxMatId: =
(
RsMatGetMapIdsUsedOnObjectWithCount obj mapList mat:mat maxMatId:maxMatId
sort mapList
return mapList
)
----------------------------------------------------------------------------------------
-- returns the nth texmap name in the rage shader
----------------------------------------------------------------------------------------
fn RsGetTexMapNameFromRsShader mat texmapidx =
(
local retval = undefined
local texmapidx = (texmapidx - 1)
local numVars = RstGetVariableCount mat
local texmapCount = -1
if (numVars != undefined) and (numVars >= 1) do
(
for i = 1 to numVars where (RstGetVariableType mat i == "texmap") while (retval == undefined) do
(
texmapCount += 1
if (texmapCount == texmapidx) do
(
retval = (RstGetVariableName mat i)
)
)
)
retval
)
----------------------------------------------------------------------------------------
-- Returns var-index for a given texmap-slot id:
----------------------------------------------------------------------------------------
fn RsGetTexMapIdForRstMtl mat texmapidx =
(
texmapidx = texmapidx - 1
numVars = RstGetVariableCount mat
texmapCount = -1
retval = undefined
if numVars != undefined and numVars >= 1 do
(
for i = 1 to numVars
where (RstGetVariableType mat i == "texmap") and (retval == undefined)
do
(
texmapCount += 1
if texmapCount == texmapidx do (retval = i)
)
)
retval
)
----------------------------------------------------------------------------------------
-- removes spaces from texture file names
----------------------------------------------------------------------------------------
fn RsMakeSafeTextureName namein =
(
toLower (RsMakeSafeSlashes namein)
)
----------------------------------------------------------------------------------------
-- Removes paths from texpath-string
-- (which can include multiple paths in one string)
-- Returned string will -not- include '+' and '>' tokens
----------------------------------------------------------------------------------------
fn RsStripTexturePath texpath =
(
local retval = ""
if (texpath != undefined) and (texpath != "") do
(
local PathTokens = filterstring texpath "+>"
for SubPath in PathTokens do
(
local TexName = GetFilenameFile SubPath
if (TexName != undefined) do
(
retval += TexName
)
)
)
return retval
)
----------------------------------------------------------------------------------------
-- Returns a material's variable-index for a given texmap slot 'texmapIdx'
----------------------------------------------------------------------------------------
fn RsGetTexMapVariableIndex mat texmapIdx: byVarName: =
(
local result = 0
if (texmapidx == unsupplied) and (byVarName == unsupplied) do return result
local texmapCount = 0
local varCount = RstGetVariableCount mat
local doByVarName = (byVarName != unsupplied)
for i = 1 to varCount while (result == 0) do
(
if (RstGetVariableType mat i == "texmap") do
(
texmapCount += 1
if doByVarName then
(
if ((RstGetVariableName mat i) == byVarName) do
(
result = i
)
)
else
(
if (texmapCount == texmapIdx) do
(
result = i
)
)
)
)
return result
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsGetProceduralFaces obj mat facesout = (
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined then (
if classof mat == MultiMaterial then (
for i = 1 to mat.materialIDList.count do (
if classof mat.materiallist[i] == RexBoundMtl then (
if RexGetProceduralName mat.materiallist[i] != "" then (
numFaces = getnumfaces obj
for j = 1 to numFaces do (
if classof obj == Editable_Mesh then (
matID = getfacematid obj j
) else if classof obj == Editable_Poly or classof obj == PolyMeshObject then (
matID = polyop.getfacematid obj j
)
if matID == mat.materialIDList[i] then (
append facesout j
)
)
)
)
)
) else if classof mat == RexBoundMtl then (
if RexGetProceduralName mat != "" then (
numFaces = getnumfaces obj
for j = 1 to numFaces do (
append facesout j
)
)
)
)
return false
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsGetDoesObjUseProcedurals obj mat = (
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined then (
if classof mat == MultiMaterial then (
matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do (
matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 then (
if RsGetDoesObjUseProcedurals obj mat.materiallist[matidx] == true then (
return true
)
)
)
) else if classof mat == RexBoundMtl then (
if RexGetProceduralName mat != "" then (
return true
)
)
)
return false
)
fn RsSpecularMapHack obj mat = (
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined do
(
case classof mat of
(
MultiMaterial:
(
matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do (
if id == matlist[i] then (
matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 then (
RsSpecularMapHack obj mat.materiallist[matidx]
)
)
)
)
Rage_Shader:
(
numVars = RstGetVariableCount mat
for i = 1 to numVars do
(
nameVar = RstGetVariableName mat i
if nameVar == "Specular Falloff" then
(
specVar = RstGetVariable mat i
if specVar > 199.0 and specVar < 201.0 then (
RstSetVariable mat i 201.5
)
)
)
)
)
)
)
-- Returns True if shaderName is on the shader-list:
fn RsShaderExists shaderName =
(
(findItem (::RsGetShaderList()) shaderName) != 0
)
-- Set all shaders in a material to use appropriate Default versions:
fn RsSetMaterialToAllDefault mat isPed:false quiet:true =
(
case classof mat of
(
MultiMaterial:
(
for childmat in mat.materiallist do (RsSetMaterialToAllDefault childmat isPed:isPed)
)
Rage_Shader:
(
local oldName = toLower (getFilenameFile (RstGetShaderName mat))
local defPattern = if isPed then "ped_default*" else "default*"
if not matchPattern oldName pattern:defPattern do
(
local newName = oldName
if isPed and matchPattern oldName pattern:"ped_*" do
(
newName = substring oldname 5 -1
)
-- This shader's Default version will just have the first name-token:
local nameTokens = filterString newName "_"
local newName = nameTokens[1]
-- Special-case shader-mappings:
case of
(
(findItem #("decal", "alpha") newName != 0):
(
newName = "cutout"
)
)
newName = "default_" + newname
if isPed do
(
newName = "ped_" + newName
)
-- If this new defaulty-name isn't on the shader-list, then use the default defaulty-name:
if not RsShaderExists newName do
(
newName = if isPed then "ped_default" else "default"
)
if (oldName != newName) do
(
local logMsg = stringStream ""
format "Changing shader to Default version: % to %\n" oldName newName to:logMsg
gRsUlog.LogMessage (logMsg as string) context:"RsSetMaterialToAllDefault" quiet:quiet
RstSetShaderName mat newName
)
)
)
Array:
(
for childmat in mat do(
RsSetMaterialToAllDefault childmat isPed:isPed quiet:quiet
)
)
)
)
fn RsSetMaterialTexturesToLod mat SLOD:false =
(
-- CHANGE TEXTUREMAPS TO LOD VERSIONS: (if found)
-- Set texturemaps to use LOD/SLOD versions if available:
local mainTexLodDir = RsProjectGetArtDir() + "/textures/lod/"
local findSuffixes = if SLOD then #("_slod.*", "_slod1.*") else #("_lod.*")
local matchSuffixes = for suffix in findSuffixes collect ("*" + suffix)
local numTexMap = getNumSubTexmaps mat
for n = 1 to numTexMap do
(
local subTexMap = getSubTexmap mat n
local newTexfile
if (subTexMap != undefined) and (subTexMap.filename != "") do
(
local texFilename = subTexMap.filename
-- Skip files that already have a matching suffix:
local doFile = true
for suffixPattern in matchSuffixes while doFile do
(
if matchPattern texFilename pattern:suffixPattern do
(
doFile = false
)
)
if doFile do
(
local filenameName = toLower (getFilenameFile texFilename)
local lodSuffixStart = case of
(
(not SLOD and (matchPattern filenameName pattern:"*slod")):(findString filenameName "slod")
(SLOD and (matchPattern filenameName pattern:"*lod")):(findString filenameName "lod")
default:0
)
local baseFilename = filenameName
-- Strip _/s/lod suffix:
if (lodSuffixStart != 0) do
(
lodSuffixStart -= 1
if filenameName[lodSuffixStart] == "_" do
(
lodSuffixStart -= 1
)
baseFilename = subString filenameName 1 lodSuffixStart
)
-- Look for matching _lod texture in same folder, lod subfolder, or main lod-texture folder:
local fileDir = getFilenamePath texFilename
-- Move up from Lod subdirectory, if that's what this is:
if matchPattern (pathConfig.stripPathToLeaf fileDir) pattern:"lod*" do
(
fileDir = (pathConfig.removePathLeaf fileDir) + "/"
)
for findSuffix in findSuffixes while (newTexfile == undefined) do
(
local findName = baseFilename + findSuffix
local lodFile = #()
for checkDir in #(fileDir, fileDir + "lods/", fileDir + "lod/", mainTexLodDir) while (lodFile.count == 0) do
(
lodFile = getFiles (checkDir + findName)
)
if (lodFile.count != 0) then
(
newTexfile = lodFile[1]
)
)
)
if (newTexfile != undefined) then
(
--format "Changing texture to %LOD version: % to %\n" (if SLOD then "S" else "") texFilename newTexfile
subTexMap.filename = newTexfile
)
else --flag it up as a missing lod texture
(
--format "Missing LOD texture\n"
--messageBox ("There is a missing LOD texture for:\n" + (getFilenameFile texFilename)) title:"Missing LOD Texture"
gRsULog.LogWarning "Missing lod texture paths\n" files:texFilename
)
)
)
)
----------------------------------------------------------------------------------------
-- Gets list of texmaps used by a material
-- 'typeList' and 'matIdList' can be used to return matching lists of texmap-types and matIds
----------------------------------------------------------------------------------------
fn RsGetTexMapListForMat mat texmaplist texmaptypelist:#() matIdList:#() matId:1 =
(
case of
(
(mat == undefined):()
(isKindOf mat MultiMaterial):
(
for i = 1 to mat.materiallist.count do
(
RsGetTexMapListForMat mat.materiallist[i] texmaplist texmaptypelist:texmaptypelist matIdList:matIdList matId:i
)
)
Default:
(
isAlphaShader = false
numTexMaps = getNumSubTexmaps mat
if (RstGetIsAlphaShader mat) do
(
isAlphaShader = true
numTexMaps = numTexMaps / 2
numTexMaps = numTexMaps + 1
)
numValidTexMaps = 0
for i = 1 to numTexMaps do
(
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if classOf subTexMap == CompositeTexturemap then
(
for t=1 to getNumSubTexmaps subTexMap by 2 do
(
local thisSubMap = getSubTexmap subTexMap t
if thisSubMap.filename != "" then numValidTexMaps = numValidTexMaps + 1
)
)
if (isKindOf subTexMap Bitmaptexture) and (subTexMap.filename != "") do
(
numValidTexMaps += 1
)
)
for i = 1 to numTexMaps do
(
local subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap CompositeTexturemap) do
(
for t=1 to getNumSubTexmaps subTexMap by 2 do
(
local thisSubMap = getSubTexmap subTexMap t
if (thisSubMap.filename != "") do
(
if (isKindOf mat Rage_Shader) then
(
texmapType = RsGetTexMapNameFromRsShader mat i
append texmaptypelist texmapType
)
else
(
append texmaptypelist undefined
)
append texmaplist thisSubMap
append matIdList matId
)
)
)
if (isKindOf subTexMap Bitmaptexture) do
(
if (subTexMap.filename != "") do
(
if (isKindOf mat Rage_Shader) then
(
texmapType = RsGetTexMapNameFromRsShader mat i
append texmaptypelist texmapType
)
else
(
append texmaptypelist undefined
)
append texmaplist subTexMap
append matIdList matId
)
)
)
)
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the main texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetTexMapList obj mat texmaplist shaderlist matidlist slotlist withIsScaleUv:true shaderid:1 matid:1 = (
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined then (
if classof mat == MultiMaterial then (
matlist = #()
RsMatGetMapIdsUsedOnObjectWithCount obj matlist
for i = 1 to matlist.count do
(
matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 do
(
RsGetTexMapList obj mat.materiallist[matidx] texmaplist shaderlist matidlist slotlist shaderid:i matid:matidx
)
)
)
else if classof mat == XRef_Material then (
RsGetTexMapList obj (mat.getsrcitem()) texmaplist
)
else (
isAlphaShader = false
numTexMaps = getNumSubTexmaps mat
if RstGetIsAlphaShader mat then (
isAlphaShader = true
numTexMaps = numTexMaps / 2
numTexMaps = numTexMaps + 1
)
local slotIdx = 1
for i = 1 to numTexMaps do
(
local subTexMap = getSubTexmap mat i
local isAlpha = false
if (isKindOf mat Standardmaterial) and (i == 7) then
(
isAlpha = true
)
else
(
if isAlphaShader and (i == numTexMaps) do
(
isAlpha = true
)
)
if (isKindOf subTexMap DistanceAlphaMap) do
(
--print "validation check 2"
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) do
(
if (subTexMap.filename != "") do
(
append texmaplist subTexMap
append shaderlist shaderid
append matidlist matid
if isAlpha then
(
append slotlist (-1)
)
else
(
append slotlist slotIdx
)
)
if (not isAlpha) do
(
slotIdx += 1
)
)
)
)
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the main texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetMainTexMapsFromMaterial obj mat texmaplist firstpass:true = (
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined then (
if classof mat == MultiMaterial then (
matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do (
matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 then (
RsGetMainTexMapsFromMaterial obj mat.materiallist[matidx] texmaplist firstpass:false
)
)
)
else if classof mat == XRef_Material then (
RsGetMainTexMapsFromMaterial obj (mat.getsrcitem()) texmaplist
)
else if classof mat == Standardmaterial then (
diffuseName = ""
subTexMap = getSubTexmap mat 2
append texmaplist subTexMap
) else if classof mat == Rage_Shader then (
numTexMap = getNumSubTexmaps mat
if numTexMap > 0 then (
subTexMap = getSubTexmap mat 1
append texmaplist subTexMap
)
)
else if classof mat == DirectX_9_Shader then (
numTexMap = getNumSubTexmaps mat
if numTexMap > 0 then (
subTexMap = getSubTexmap mat 1
append texmaplist subTexMap
)
)
if firstpass then (
for childobj in obj.children do (
RsGetMainTexMapsFromMaterial childobj childobj.material texmaplist
)
)
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the main texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetMainTexMapsFromMaterialByID obj mat id texmaplist = (
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined then (
if classof mat == MultiMaterial then (
matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do (
if id == matlist[i] then (
matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 then (
RsGetMainTexMapsFromMaterial obj mat.materiallist[matidx] texmaplist
)
)
)
)
else if classof mat == XRef_Material then (
RsGetMainTexMapsFromMaterial obj (mat.getsrcitem()) texmaplist
)
else if classof mat == Standardmaterial then (
diffuseName = ""
subTexMap = getSubTexmap mat 2
append texmaplist subTexMap
) else if classof mat == Rage_Shader then (
numTexMap = getNumSubTexmaps mat
if numTexMap > 1 then (
subTexMap = getSubTexmap mat 1
append texmaplist subTexMap
)
)
)
)
fn RsGetEmptyTexMaps obj mat slotlist objnamelist texmapnamelist currentslot:-1 =
(
if obj != undefined and (not isRefObj obj) and (not isInternalRef obj) and mat != undefined then
(
if classof mat == MultiMaterial then
(
local matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do
(
local matidx = finditem mat.materialIDList matlist[i]
if (matidx != 0) do
(
RsGetEmptyTexMaps obj mat.materiallist[matidx] slotlist objnamelist texmapnamelist currentslot:matlist[i]
)
)
)
else if classof mat == Rage_Shader then
(
varCount = RstGetVariableCount mat
texmapCount = 0
if (varCount != undefined) and (varCount >= 1) do
(
for i = 1 to varCount do
(
if retval == undefined and RstGetVariableType mat i == "texmap" then
(
texmapCount = texmapCount + 1
if ( getNumSubTexmaps mat < texmapCount ) then
continue
varName = RstGetVariableName mat i
varSubMap = getSubTexmap mat texmapCount
if (isKindOf varSubMap DistanceAlphaMap) do
(
varSubMap = varSubMap.resultmap
)
if (not isKindOf varSubMap CompositeTexturemap) do
(
local varFilename = ""
if (isKindOf varSubMap Bitmaptexture) and (varSubMap.filename != undefined) and (varSubMap.filename != "") do
(
varFilename = RsMakeSafeTextureName(RsStripTexturePath(varSubMap.filename))
)
if varFilename == "" and varName != "Diffuse Texture" do
(
append objnamelist obj.name
append slotlist currentslot
append texmapnamelist varName
)
)
)
)
)
)
)
)
----------------------------------------------------------------------------------------
-- Returns bitArray of matIds used on an object's mesh,
-- with no special processing (also works on TriMeshes)
----------------------------------------------------------------------------------------
fn RsGetMatIdsUsedByObj obj =
(
local objGetFaceMatID = RsGetFaceMatIDFunc obj
local retVal = #{}
for faceNum = 1 to (getNumFaces obj) do
(
local faceMatId = objGetFaceMatID obj faceNum
if (faceMatId != undefined) do
(
retVal[faceMatId] = true
)
)
return retVal
)
----------------------------------------------------------------------------------------
-- Returns a list of texture-paths used by a material.
-- 'matIds' can be used to limit the multimaterial ids used.
----------------------------------------------------------------------------------------
fn RsGetTexPathsFromMat mat matIds:#{} texList:#() =
(
case classOf mat of
(
MultiMaterial:
(
local allMatIds = (matIds.numberSet == 0)
local matIdList = #()
for matIdx = 1 to mat.materialIDList.count do
(
local matId = mat.materialIDList[matIdx]
if allMatIds or matIds[matId] do
(
RsGetTexPathsFromMat mat.materialList[matIdx] matIds:matIds texList:texList
)
)
)
XRef_Material:
(
RsGetTexPathsFromMat mat.getsrcitem() matIds:matIds texList:texList
)
CompositeTexturemap: -- That's a Texturemap, not material
(
local subTexMap = mat
local numMaps = getNumSubTexMaps subTexMap
for j = 1 to numMaps do
(
local subSubTexMap = getSubTexmap mat j
RsGetTexPathsFromMat subSubTexMap matIds:matIds texList:texList
)
)
UndefinedClass:()
default:
(
if (isKindOf mat textureMap) then
(
local subTexMap = mat
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) and (subTexMap.filename != "") then
(
local texmapname = (RsMakeSafeTextureName subTexMap.filename)
appendIfUnique texList texmapname
)
)
else
(
local numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do
(
local subTexMap = getSubTexmap mat i
RsGetTexPathsFromMat subTexMap matIds:matIds texList:texList
)
)
)
)
return texList
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromMaterialWithMap obj mat texmaplist bitmaplist maptypelist:#() matIdList:#() matId:1 incID:-1 =
(
RsCheckForLighttextures obj texmaplist texmapobjlist:bitmaplist maptypelist:maptypelist matIdList:matIdList
if (obj != undefined) and (not isRefObj obj) and (not isInternalRef obj) and (mat != undefined) do
(
if classof mat == MultiMaterial then
(
local objMatIds = #()
RsMatGetMapIdsUsedOnObject obj objMatIds maxMatId:mat.numSubs
for i = 1 to objMatIds.count do
(
local matId = objMatIds[i]
if (incID == -1) or (incID == matId) then
(
local matidx = finditem mat.materialIDList matId
if (matidx != 0) do
(
RsGetTexMapsFromMaterialWithMap obj mat.materiallist[matidx] texmaplist bitmaplist maptypelist:maptypelist matIdList:matIdList matId:matId incID:incID
)
)
)
)
else if classof mat == XRef_Material then
(
RsGetTexMapsFromMaterialWithMap obj (mat.getsrcitem()) texmaplist bitmaplist maptypelist:maptypelist matIdList:matIdList matId:matId incID:incID
)
else if classof mat == Standardmaterial then
(
diffuseName = ""
subTexMap = getSubTexmap mat 2
subTexMapMain = getSubTexmap mat 2
if (isKindOf subTexMap DistanceAlphaMap) do
(
--print "validation check 4"
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) do
(
if (subTexMap.filename != "") do
(
texmapname = toLower(subTexMap.filename)
diffuseName = texmapname
)
subTexMap = getSubTexmap mat 7
if (isKindOf subTexMap Bitmaptexture) and (subTexMap.filename != "") do
(
texmapname = toLower(subTexMap.filename)
diffuseName = diffuseName + "+" + texmapname
)
)
if diffuseName != "" do
(
diffuseName = RsMakeSafeTextureName(RsStripTexturePath diffuseName)
if finditem texmaplist diffuseName == 0 do
(
append texmaplist diffuseName
append bitmaplist subTexMapMain
append maptypelist "Diffuse"
append matIdList matId
)
)
numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do
(
if (i != 2) and (i != 7) do
(
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) and (subTexMap.filename != "") do
(
texmapname = RsMakeSafeTextureName(RsStripTexturePath (subTexMap.filename))
if (finditem texmaplist texmapname == 0) do
(
local maptype = case i of
(
4:"Specular"
9:"Bump"
Default:"Default"
)
append texmaplist texmapname
append bitmaplist subTexMap
append maptypelist maptype
append matIdList matId
)
)
)
)
) else if classof mat == Rage_Shader then (
numTexMap = getNumSubTexmaps mat
if RstGetIsAlphaShader mat then (
numTexMap = numTexMap / 2
)
for i = 1 to numTexMap do (
texmapname = ""
subTexMap = getSubTexmap mat i
if classof subTexMap == DistanceAlphaMap then
(
--print "validation check 6"
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if classof subTexMap == Bitmaptexture then (
if subTexMap.filename != "" then (
texmapname = RsMakeSafeTextureName(RsStripTexturePath(subTexMap.filename))
)
if RstGetIsAlphaShader mat then (
local alphaTexMap = getSubTexmap mat (i + numTexMap)
if classof alphaTexMap == Bitmaptexture then (
if alphaTexMap.filename != "" then (
texmapname += "+" + RsMakeSafeTextureName(RsStripTexturePath (alphaTexMap.filename))
)
)
)
)
else if classof subTexMap == CompositeTexturemap then (
numMaps = getnumsubtexmaps subTexMap
for j = 1 to numMaps do (
subsubTexMap = getSubTexmap subTexMap j
if classof subsubTexMap == Bitmaptexture then (
if subsubTexMap.filename != "" then (
if j != 1 then (
texmapname += ">"
)
texmapname += RsMakeSafeTextureName(RsStripTexturePath(subsubTexMap.filename))
)
)
)
)
if texmapname != "" then
(
if (finditem texmaplist texmapname == 0) do
(
local texmaptype = RsGetTexMapNameFromRsShader mat i
local addMap = gRsIncTexmaps.isIncluded texmapName texmapType
if addMap do
(
append texmaplist texmapname
append bitmaplist subTexMap
append maptypelist texmaptype
append matIdList matId
)
)
)
)
) else if classof mat == DirectX_9_Shader then (
numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do (
texmapname = ""
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) then
(
if (subTexMap.filename != "") do
(
texmapname = RsMakeSafeTextureName(RsStripTexturePath(subTexMap.filename))
)
if (RstGetIsAlphaShader mat) do
(
local alphaTexMap = getSubTexmap mat (i + numTexMap)
if (isKindOf alphaTexMap Bitmaptexture) and (alphaTexMap.filename != "") do
(
texmapname += "+" + RsMakeSafeTextureName(RsStripTexturePath (alphaTexMap.filename))
)
)
)
if (texmapname != "") do
(
if (finditem texmaplist texmapname == 0) do
(
append texmaplist texmapname
append bitmaplist subTexMap
)
)
)
)
else
(
numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do
(
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) and (subTexMap.filename != "") do
(
texmapname = RsMakeSafeTextureName(RsStripTexturePath (subTexMap.filename))
if (finditem texmaplist texmapname == 0) do
(
append texmaplist texmapname
append bitmaplist subTexMap
append maptypelist "Default"
append matIdList matId
)
)
)
)
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by a material
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromMaterial obj mat texmaplist maxsizelist isbumplist =
(
RsCheckForLighttextures obj texmaplist maxsizelist:maxsizelist isbumplist:isbumplist
if (obj != undefined) and (not isRefObj obj) and (not isInternalRef obj) and (mat != undefined) do
(
if classof mat == MultiMaterial then (
--print "multi"
matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do
(
local matidx = finditem mat.materialIDList matlist[i]
if (matidx != 0) do
(
RsGetTexMapsFromMaterial obj mat.materiallist[matidx] texmaplist maxsizelist isbumplist
)
)
)
else if classof mat == XRef_Material then (
RsGetTexMapsFromMaterial obj (mat.getsrcitem()) texmaplist maxsizelist isbumplist
)
else if classof mat == Standardmaterial then (
--print "standard"
diffuseName = ""
doAlpha = false
subTexMap = getSubTexmap mat 1
if subTexMap == undefined then (
doAlpha = true
subTexMap = getSubTexmap mat 2
)
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) do
(
if ( ( undefined != subTexMap.filename ) and ( "" != subTexMap.filename ) ) do
(
texmapname = toLower(subTexMap.filename)
diffuseName = texmapname
)
if doAlpha do
(
subTexMap = getSubTexmap mat 7
if (isKindOf subTexMap Bitmaptexture) do
(
if ( ( undefined != subTexMap.filename ) and ( "" != subTexMap.filename ) ) do
(
texmapname = toLower(subTexMap.filename)
diffuseName = diffuseName + "+" + texmapname
)
)
)
)
if (diffuseName != "") do
(
diffuseName = RsMakeSafeTextureName(RsStripTexturePath diffuseName)
if finditem texmaplist diffuseName == 0 then (
--print diffuseName
--print RsDiffuseTexMaxSize
append texmaplist diffuseName
append maxsizelist RsDiffuseTexMaxSize
append isbumplist false
)
)
numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do (
if (i != 2) and (i != 7) then (
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) and ( undefined != subTexMap.filename ) and ( "" != subTexMap.filename ) do
(
texmapname = RsMakeSafeTextureName(RsStripTexturePath (subTexMap.filename))
if (finditem texmaplist texmapname == 0) then
(
append texmaplist texmapname
append maxsizelist RsOtherTexMaxSize
if (i == 9) then
(
append isbumplist true
)
else
(
append isbumplist false
)
)
)
)
)
) else if classof mat == Rage_Shader then (
--print "rage"
numTexMap = getNumSubTexmaps mat
if RstGetIsAlphaShader mat then (
numTexMap = numTexMap / 2
)
for i = 1 to numTexMap do (
texmapname = ""
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) then
(
if ( ( undefined != subTexMap.filename ) and ( "" != subTexMap.filename ) ) then (
texmapname = RsMakeSafeTextureName(RsStripTexturePath(subTexMap.filename))
)
if RstGetIsAlphaShader mat then (
local alphaTexMap = getSubTexmap mat (i + numTexMap)
if classof alphaTexMap == Bitmaptexture then (
if ( undefined != alphaTexMap.filename and "" != alphaTexMap.filename ) then (
texmapname += "+" + RsMakeSafeTextureName(RsStripTexturePath (alphaTexMap.filename))
)
)
)
)
else if (isKindOf subTexMap CompositeTexturemap) then
(
numMaps = getnumsubtexmaps subTexMap
for j = 1 to numMaps do (
subsubTexMap = getSubTexmap subTexMap j
if (isKindOf subsubTexMap Bitmaptexture) and ( undefined != subsubTexMap.filename ) and ( "" != subsubTexMap.filename ) do
(
if (j != 1) do
(
texmapname += ">"
)
texmapname += RsMakeSafeTextureName(RsStripTexturePath(subsubTexMap.filename))
)
)
)
if ( ( undefined != texmapname ) and ( "" != texmapname ) ) do
(
if (finditem texmaplist texmapname == 0) do
(
local texmaptype = RsGetTexMapNameFromRsShader mat i
local addMap = gRsIncTexmaps.isIncluded texmapname texmapType
if addMap do
(
--print texmapname
append texmaplist texmapname
if RsIsBumpMap texmaptype then (
append isbumplist true
) else (
append isbumplist false
)
if RsIsDiffuseMap texmaptype then (
--print RsDiffuseTexMaxSize
append maxsizelist RsDiffuseTexMaxSize
) else (
--print RsOtherTexMaxSize
append maxsizelist RsOtherTexMaxSize
)
)
)
)
)
)
else
(
numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do (
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (classof subTexMap == Bitmaptexture) and (subTexMap.filename != "") do
(
texmapname = RsMakeSafeTextureName(RsStripTexturePath (subTexMap.filename))
if (finditem texmaplist texmapname == 0) do
(
append texmaplist texmapname
append isbumplist false
texmapname = RsGetTexMapNameFromRsShader mat i
if RsIsDiffuseMap texmapname then
(
append maxsizelist RsDiffuseTexMaxSize
)
else
(
append maxsizelist RsOtherTexMaxSize
)
)
)
)
)
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by a material
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromMaterialNoStrip obj mat texmaplist maxsizelist isbumplist exemptionList:#() texmapobjlist:#() maptypelist:#() texturetemplatelist:#() materialpresetlist:#() =
(
if (isKindOf obj Col_Mesh) do return False
RsCheckForLighttextures obj texmaplist maxsizelist:maxsizelist isbumplist:isbumplist exemptionList:exemptionList texmapobjlist:texmapobjlist maptypelist:maptypelist texturetemplatelist:texturetemplatelist
if (not isRefObj obj) and (not isInternalRef obj) and (mat != undefined) do
(
case (classof mat) of
(
MultiMaterial:
(
matlist = #()
RsMatGetMapIdsUsedOnObject obj matlist
for i = 1 to matlist.count do
(
local matidx = finditem mat.materialIDList matlist[i]
if matidx != 0 do
(
RsGetTexMapsFromMaterialNoStrip obj mat.materiallist[matidx] texmaplist maxsizelist isbumplist exemptionList:exemptionList texmapobjlist:texmapobjlist maptypelist:maptypelist texturetemplatelist:texturetemplatelist materialpresetlist:materialpresetlist
)
)
)
XRef_Material:
(
RsGetTexMapsFromMaterialNoStrip obj (mat.getsrcitem()) texmaplist maxsizelist isbumplist exemptionList:exemptionList texmapobjlist:texmapobjlist maptypelist:maptypelist texturetemplatelist:texturetemplatelist materialpresetlist:materialpresetlist
)
Standardmaterial:
(
local diffuseName = ""
local doAlpha = false
local subTexMap = getSubTexmap mat 1
if (subTexMap == undefined) do
(
doAlpha = true
subTexMap = getSubTexmap mat 2
)
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) do
(
if ( ( undefined != subTexMap.filename ) and ( "" != subTexMap.filename ) ) do
(
texmapname = toLower(subTexMap.filename)
diffuseName = texmapname
)
if doAlpha do
(
local alphaTexMap = getSubTexmap mat 7
if (isKindOf alphaTexMap Bitmaptexture) do
(
if ( ( undefined != alphaTexMap.filename ) and ( "" != alphaTexMap.filename ) ) do
(
texmapname = toLower(alphaTexMap.filename)
diffuseName = diffuseName + "+" + texmapname
)
)
)
)
if (diffuseName != "") do
(
diffuseName = RsMakeSafeTextureName(diffuseName)
if (findItem texmaplist diffuseName == 0) do
(
-- format "Texture map: %\n" diffuseName
--print RsDiffuseTexMaxSize
append texmaplist diffuseName
append maptypelist "Diffuse"
append texmapobjlist subTexMap
append maxsizelist RsDiffuseTexMaxSize
append isbumplist false
append exemptionList false
append texturetemplatelist "Default"
)
)
local numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do
(
if (i != 2) and (i != 7) do
(
subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) do
(
if (undefined != subTexMap.filename) and ("" != subTexMap.filename) do
(
texmapname = RsMakeSafeTextureName(subTexMap.filename)
if finditem texmaplist texmapname == 0 then (
append texmaplist texmapname
append texmapobjlist subTexMap
append maxsizelist RsOtherTexMaxSize
append exemptionList false
if i == 9 then (
append maptypelist "Bump Texture"
append isbumplist true
append texturetemplatelist "NormalMap"
) else (
append maptypelist "Default"
append isbumplist false
append texturetemplatelist "Default"
)
)
)
)
)
)
)
Rage_Shader:
(
numTexMap = getNumSubTexmaps mat
if RstGetIsAlphaShader mat do
(
numTexMap /=2
)
local materialPresetPath = RstGetMaterialPresetPath mat
if (materialPresetPath != undefined) do
(
materialPresetPath = (toLower materialPresetPath)
)
for i = 1 to numTexMap do
(
texmapname = ""
subTexMap = getSubTexmap mat i
local alphaTexMap = undefined
if RstGetIsAlphaShader mat then
alphaTexMap = getSubTexmap mat (i + numTexMap)
if (isKindOf subTexMap DistanceAlphaMap) do
(
if (RstGetIsAlphaShader mat) and (undefined!=alphaTexMap) do
(
local requestshader = yesNoCancelBox "Distance map can NOT be used in shaders with separate alpha textures, since it creates its own one. Use another shader or leave alpha slot empty.\nYes: Auto fix by deleting alpha texture of shader.\nNo: Put shader in slot 24 and fix yourself."
if #yes==requestshader then
(
setSubTexmap mat (i + numTexMap) undefined
alphaTexMap = undefined
)
else if #no==requestshader then
meditmaterials[24] = mat
)
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) then (
if ( ( undefined != subTexMap.filename ) and ( "" != subTexMap.filename ) ) then (
texmapname = RsMakeSafeTextureName(subTexMap.filename)
)
if RstGetIsAlphaShader mat then (
if classof alphaTexMap == Bitmaptexture then (
if ( ( undefined != alphaTexMap.filename ) and ( "" != alphaTexMap.filename ) ) then (
texmapname += ("+" + RsMakeSafeTextureName(alphaTexMap.filename))
)
)
)
)
else if (isKindOf subTexMap CompositeTexturemap) do (
numMaps = getnumsubtexmaps subTexMap
for j = 1 to numMaps do (
subsubTexMap = getSubTexmap subTexMap j
if classof subsubTexMap == Bitmaptexture then (
if ( ( undefined != subsubTexMap.filename ) and ( "" != subsubTexMap.filename ) ) then (
if j != 1 then (
texmapname += ">"
)
texmapname += RsMakeSafeTextureName(subsubTexMap.filename)
)
)
)
)
if texmapname != "" then (
idxTexMapName = finditem texmaplist texmapname
textureTemplateOrder = #( "Diffuse", "Normal", "Specular" )
alreadyInList = false
if idxTexMapName != 0 then alreadyInList = true
texmaptype = RsGetTexMapNameFromRsShader mat i
idxTex = RsGetTexMapIdForRstMtl mat i
-- This is nasty but is the only way to deal with materials that have had their
-- .fxc files deleted.
if idxTex == undefined then (
texturetemplate = "Default"
)
else (
texturetemplate = RstGetTextureTemplate mat idxTex
)
if texturetemplate == "" then texturetemplate = RstGetTextureTemplateRelative mat idxTex
local addMap = gRsIncTexmaps.isIncluded texmapName texmapType
if addMap then (
if ( not alreadyInList ) then
(
append texmaplist texmapname
append maptypelist texmaptype
append texmapobjlist subtexmap
if (materialPresetPath != undefined) do
(
append materialpresetlist materialPresetPath
)
--print ("ADDING : " + texturetemplate + " for :" + texmapname)
append texturetemplatelist texturetemplate
if RsIsBumpMap texmaptype then (
append isbumplist true
) else (
append isbumplist false
)
if RsIsResizeExempt subTexMap texmaptype mat then (
append exemptionList true
) else (
append exemptionList false
)
if RsIsDiffuseMap texmaptype then (
append maxsizelist RsDiffuseTexMaxSize
) else (
append maxsizelist RsOtherTexMaxSize
)
)
-- Already in list so check if the priority of this type is higher
-- than the value already in the list, and replace if so
else
(
-- Template already in list
idxCurrentTemplate = findItem textureTemplateOrder texturetemplatelist[idxTexMapName]
-- Template being checked
idxThisTemplate = findItem textureTemplateOrder texturetemplate
--format "Current: %\tThis: %\n" texturetemplatelist[idxTexMapName] texturetemplate
--format "idxCurrent: %\t idxThis: %\n" idxCurrentTemplate idxThisTemplate
-- If this template isn't found in the list then it'll be 0, but is really
-- lowest priority
if ( idxThisTemplate != 0 and (idxThisTemplate < idxCurrentTemplate) ) then
(
texmaplist[idxTexMapName] = texmapname
maptypelist[idxTexMapName] = texmaptype
texmapobjlist[idxTexMapName] = subtexmap
--print ("CHANGING to : " + texturetemplate + " for :" + texmapname)
texturetemplatelist[idxTexMapName] = texturetemplate
if RsIsDiffuseMap texmaptype then (
maxsizelist[idxTexMapName] = RsDiffuseTexMaxSize
) else (
maxsizelist[idxTexMapName] = RsOtherTexMaxSize
)
)
)
)
)
)
)
Default:
(
local numTexMap = getNumSubTexmaps mat
for i = 1 to numTexMap do
(
local subTexMap = getSubTexmap mat i
if (isKindOf subTexMap DistanceAlphaMap) do
(
--print "validation check 0"
subTexMap = RsGetDistanceAlphaMapResultMap subTexMap
)
if (isKindOf subTexMap Bitmaptexture) and (subTexMap.filename != "") do
(
texmapname = RsMakeSafeTextureName(subTexMap.filename)
if (finditem texmaplist texmapname == 0) do
(
--print texmapname
append texmaplist texmapname
append texmapobjlist subtexmap
append isbumplist false
append exemptionList false
if (materialPresetPath != undefined) do
(
append materialpresetlist materialPresetPath
)
idxTex = RsGetTexMapIdForRstMtl mat i
texmaptype = RsGetTexMapNameFromRsShader mat i
texturetemplate = RstGetTextureTemplate mat idxTex
if texturetemplate == "" then texturetemplate = RstGetTextureTemplateRelative mat idxTex
append maptypelist texmaptype
append texturetemplatelist texturetemplate
if RsIsDiffuseMap texmaptype then
(
--print RsDiffuseTexMaxSize
append maxsizelist RsDiffuseTexMaxSize
)
else
(
--print RsOtherTexMaxSize
append maxsizelist RsOtherTexMaxSize
)
)
)
)
)
)
)
return True
)
----------------------------------------------------------------------------------------
-- takes a texmaplist and strips the paths in it
----------------------------------------------------------------------------------------
fn RsStripPaths texNameList =
(
for i = 1 to texNameList.count do
(
texNameList[i] = RsStripTexturePath texNameList[i]
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromObjWithMapsRec obj texmaplist bitmaplist incID:-1 =
(
if (obj == undefined) do return #()
RsGetTexMapsFromMaterialWithMap obj obj.material texmaplist bitmaplist incID:incID
for childobj in obj.children do (
RsGetTexMapsFromObjWithMapsRec childobj texmaplist bitmaplist incID:incID
)
if ( RsLodDrawable_HasLowerDetailModel obj ) then
(
local ldobj = ( RsLodDrawable_GetLowerDetailModel obj )
-- format "LD Model: RsGetTexMapsFromObjWithMapsRec %\n" ldobj
RsGetTexMapsFromObjWithMapsRec ldobj texmaplist bitmaplist incID:incID
)
return texmaplist
)
----------------------------------------------------------------------------------------
-- Fills texmaplist with the texture maps used by an object
-- If 'id' is used, only texmaps with that matId are returned
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromObjWithMaps obj texmaplist bitmaplist id:-1 =
(
RsGetTexMapsFromObjWithMapsRec obj texmaplist bitmaplist incID:id
RsStripPaths texmaplist
return texmaplist
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromObjRec obj texmaplist maxsizelist isbumplist = (
if obj != undefined then (
RsGetTexMapsFromMaterial obj obj.material texmaplist maxsizelist isbumplist
for childobj in obj.children do (
RsGetTexMapsFromObjRec childobj texmaplist maxsizelist isbumplist
)
if ( RsLodDrawable_HasLowerDetailModel obj ) then
(
local ldobj = ( RsLodDrawable_GetLowerDetailModel obj )
--format "LD Model: RsGetTexMapsFromObjRec %\n" ldobj
RsGetTexMapsFromObjRec ldobj texmaplist maxsizelist isbumplist
)
)
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromObj obj texmaplist maxsizelist isbumplist = (
RsGetTexMapsFromObjRec obj texmaplist maxsizelist isbumplist
RsStripPaths texmaplist
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by an object
----------------------------------------------------------------------------------------
fn RsGetTexMapsFromObjNoStrip obj texmaplist maxsizelist isbumplist exemptionList:#() texmapobjlist:#() maptypelist:#() texturetemplatelist:#() materialpresetlist:#() =
(
gRsCallCountRsGetTexMapsFromObjNoStrip += 1
RsGetTexMapsFromMaterialNoStrip obj obj.material texmaplist maxsizelist isbumplist exemptionList:exemptionList texmapobjlist:texmapobjlist maptypelist:maptypelist texturetemplatelist:texturetemplatelist materialpresetlist:materialpresetlist
for childobj in obj.children do
(
RsGetTexMapsFromObjNoStrip childobj texmaplist maxsizelist isbumplist exemptionList:exemptionList texmapobjlist:texmapobjlist maptypelist:maptypelist texturetemplatelist:texturetemplatelist materialpresetlist:materialpresetlist
)
if ( RsLodDrawable_HasLowerDetailModel obj ) then
(
local ldobj = ( RsLodDrawable_GetLowerDetailModel obj )
--format "LD Model: RsGetTexMapsFromObjNoStrip %\n" ldobj
RsGetTexMapsFromObjNoStrip ldobj texmaplist maxsizelist isbumplist exemptionList:exemptionList texmapobjlist:texmapobjlist maptypelist:maptypelist texturetemplatelist:texturetemplatelist materialpresetlist:materialpresetlist
)
return texmaplist
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsMergeTextureUsage texmaplist texmaptypelist texturetemplatelist maxsizelist isbumplist usagelist exemptionlist objtexmaplist objtexmaptypelist objmaxsizelist objisbumplist infiniteusage objexemptionlist objtexturetemplatelist =
(
for i = 1 to objtexmaplist.count do
(
objtexmap = objtexmaplist[i]
isTintPalette = RsIsTintPalette objtexmaptypelist[i] -- B* 990857 - tint palettes are never considered 'infinite usage'
idxFound = finditem texmaplist objtexmap
if (idxFound == 0) then
(
append texmaplist objtexmap
append texmaptypelist objtexmaptypelist[i]
append maxsizelist objmaxsizelist[i]
append isbumplist objisbumplist[i]
append exemptionlist objexemptionlist[i]
append texturetemplatelist objtexturetemplatelist[i]
if (infiniteusage and (not isTintPalette)) then
(
append usagelist -1
)
else
(
append usagelist 1
)
)
else
(
if ( (infiniteusage and (not isTintPalette)) or usagelist[idxFound] == -1 ) then
(
usagelist[idxFound] = -1
)
else
(
-- Tint palettes are never to go in TXDs.
if (not isTintPalette) then
(
usagelist[idxFound] = usagelist[idxFound] + 1
)
else
(
usagelist[idxFound] = 1
)
)
)
)
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsIsTXDUsedOnLod txdname srcobjlist:rootnode.children =
(
local idxTXD = getAttrIndex "Gta Object" "TXD"
local allObjs = #()
RsGetMapObjects srcObjList allObjs
local retVal = False
for obj in allObjs while (not retVal) do
(
if (getattrclass obj == "Gta Object") and (not isRefObj obj) and (not isInternalRef obj) do
(
retVal = ((matchPattern (getattr obj idxTXD) pattern:txdname) and (::RsIsAnyLOD obj))
)
)
return retVal
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by all objects with specified txd
----------------------------------------------------------------------------------------
fn RsGetTexMapsByTxdNameNoStrip texmaplist maxsizelist isbumplist usagelist txdname srcobjlist: isCutsceneObject:false exemptionlist:#() texmaptypelist:#() texturetemplatelist:#() materialpresetlist:#() heavy_texture_logging:False =
(
txdname = toLower txdname
idxTXD = getattrindex "Gta Object" "TXD"
if (srcObjList == unsupplied) do
(
srcObjList = #()
join srcObjList rootnode.children
)
local allobjs = #()
RsGetMapObjects srcobjlist allobjs isCutsceneObject:isCutsceneObject
local usedCount = 0
for obj in allobjs do
(
if (isKindOf obj Gta_MILO) then
(
for childobj in obj.children do
(
if (not isRefObj childobj) and (not isInternalRef childobj) and (getattrclass childobj == "Gta Object") do
(
if (matchPattern (getattr childobj idxTXD) pattern:txdname) do
(
local objtexmaplist = #()
local objmaxsizelist = #()
local objisbumplist = #()
local objexemptionlist = #()
local objmaptypelist = #()
local objtexturetemplatelist = #()
RsGetTexMapsFromObjNoStrip childobj objtexmaplist objmaxsizelist objisbumplist exemptionlist:objexemptionlist maptypelist:objmaptypelist texturetemplatelist:objtexturetemplatelist materialpresetlist:materialpresetlist
RsMergeTextureUsage texmaplist texmaptypelist texturetemplatelist maxsizelist isbumplist usagelist exemptionlist objtexmaplist objmaptypelist objmaxsizelist objisbumplist false objexemptionlist objtexturetemplatelist
)
)
)
)
else
(
if (not isRefObj obj) and (not isInternalRef obj) and (getattrclass obj == "Gta Object") do
(
if (matchPattern (getattr obj idxTXD) pattern:txdname) do
(
local objtexmaplist = #()
local objmaxsizelist = #()
local objisbumplist = #()
local objexemptionlist = #()
local objmaptypelist = #()
local objtexturetemplatelist = #()
infiniteUsage = false
if ( RsIsAnyLOD obj == true ) then infiniteUsage = true
RsGetTexMapsFromObjNoStrip obj objtexmaplist objmaxsizelist objisbumplist exemptionlist:objexemptionlist maptypelist:objmaptypelist texturetemplatelist:objtexturetemplatelist materialpresetlist:materialpresetlist
if (heavy_texture_logging) do
(
format "************************************\n"
format "* after RsGetTexMapsFromObjNoStrip\n"
format "************************************\n"
format "obj.name: %\n" obj.name
format "infiniteUsage: %\n" infiniteUsage
format "objtexmaplist.count: %\n" objtexmaplist.count
for item in objtexmaplist do format " item: %\n" item
format "objmaxsizelist.count: %\n" objmaxsizelist.count
for item in objmaxsizelist do format " item: %\n" item
format "objisbumplist.count: %\n" objisbumplist.count
for item in objisbumplist do format " item: %\n" item
format "objexemptionlist.count: %\n" objexemptionlist.count
for item in objexemptionlist do format " item: %\n" item
format "objmaptypelist.count: %\n" objmaptypelist.count
for item in objmaptypelist do format " item: %\n" item
format "objtexturetemplatelist.count: %\n" objtexturetemplatelist.count
for item in objtexturetemplatelist do format " item: %\n" item
format "************************************\n"
)
RsMergeTextureUsage texmaplist texmaptypelist texturetemplatelist maxsizelist isbumplist usagelist exemptionlist objtexmaplist objmaptypelist objmaxsizelist objisbumplist infiniteUsage objexemptionlist objtexturetemplatelist
if (heavy_texture_logging) do
(
format "************************************\n"
format "* after RsMergeTextureUsage\n"
format "************************************\n"
format "texmaplist.count: %\n" texmaplist.count
for item in texmaplist do format " item: %\n" item
format "texmaptypelist.count: %\n" texmaptypelist.count
for item in texmaptypelist do format " item: %\n" item
format "texturetemplatelist.count: %\n" texturetemplatelist.count
for item in texturetemplatelist do format " item: %\n" item
format "maxsizelist.count: %\n" maxsizelist.count
for item in maxsizelist do format " item: %\n" item
format "isbumplist.count: %\n" isbumplist.count
for item in isbumplist do format " item: %\n" item
format "usagelist.count: %\n" usagelist.count
for item in usagelist do format " item: %\n" item
format "exemptionlist.count: %\n" exemptionlist.count
for item in exemptionlist do format " item: %\n" item
format "************************************\n"
)
)
)
)
-- Get texmaps for root-bone (if obj has one) to collect light-textures for a skinned object:
local skelObj = rexGetSkinRootBone obj
if (skelObj != undefined) do
(
local skel_texmaplist = #()
local skel_maxsizelist = #()
local skel_isbumplist = #()
local skel_exemptionlist = #()
local skel_maptypelist = #()
local skel_texturetemplatelist = #()
RsGetTexMapsFromObjNoStrip skelObj \
skel_texmaplist skel_maxsizelist skel_isbumplist exemptionlist:skel_exemptionlist maptypelist:skel_maptypelist texturetemplatelist:skel_texturetemplatelist materialpresetlist:materialpresetlist
RsMergeTextureUsage \
texmaplist texmaptypelist texturetemplatelist maxsizelist isbumplist usagelist exemptionlist \
skel_texmaplist skel_maptypelist skel_maxsizelist skel_isbumplist false skel_exemptionlist skel_texturetemplatelist
)
)
return texmaplist
)
----------------------------------------------------------------------------------------
-- fills texmaplist with the texture maps used by all objects with specified txd
----------------------------------------------------------------------------------------
fn RsGetTexMapsByTxdName texmaplist maxsizelist isbumplist usagelist txdname srcobjlist:rootnode.children isCutsceneObject:false resizeexemptionlist:#() texmaptypelist:#() texturetemplatelist:#() texmaplistnostrip:#() = (
newtexmaplist = #()
newtexmaptypelist = #()
newmaxsizelist = #()
newisbumplist = #()
newusagelist = #()
newresizeexemptionlist = #()
newtexturetemplatelist = #()
RsGetTexMapsByTxdNameNoStrip newtexmaplist newmaxsizelist newisbumplist newusagelist txdname srcobjlist:srcobjlist isCutsceneObject:isCutsceneObject exemptionlist:newresizeexemptionlist texmaptypelist:newtexmaptypelist texturetemplatelist:newtexturetemplatelist
newtexmaplistnostrip = copy newtexmaplist #nomap
RsStripPaths newtexmaplist
-- we need to do this because there will be multiple entries if the same texture name
-- has been used from a different path or extension
for i = 1 to newtexmaplist.count do (
texmap = newtexmaplist[i]
idxFound = finditem texmaplist texmap
if idxFound == 0 then (
append texmaplist newtexmaplist[i]
append texmaptypelist newtexmaptypelist[i]
append maxsizelist newmaxsizelist[i]
append isbumplist newisbumplist[i]
append usagelist newusagelist[i]
append resizeexemptionlist newresizeexemptionlist[i]
append texturetemplatelist newtexturetemplatelist[i]
append texmaplistnostrip newtexmaplistnostrip[i]
) else if usagelist[idxFound] != -1 and newusagelist[i] != -1 then (
usagelist[idxFound] = usagelist[idxFound] + newusagelist[i]
) else if newusagelist[i] == -1 then (
usagelist[idxFound] = -1
)
)
return texmaplist
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsGetTxdFromObject obj txdList: txdObjList: includeRefs:false
idxGroupTXD:(getattrindex "Gta Group" "TXD")
idxTXD:(getattrindex "Gta Object" "TXD")
idxDontExport:(GetAttrIndex "Gta Object" "Dont Export") =
(
local txd = unsupplied
case of
(
(includeRefs and (isRSref obj includeDelegates:true)):
(
txd = if (obj.refDef == undefined) then
(
"null"
)
else
(
if (obj.refDef.txd == undefined) do
(
RsRefFuncs.loadTxds #(obj.refDef)
)
toLower obj.refDef.txd
)
)
(includeRefs and isInternalRef obj):
(
local srcObj = getIRefSource obj
if (getattrclass srcObj == "Gta Object") do
(
txd = toLower (getattr srcObj idxTXD)
)
)
((not isInternalRef obj) and (not isRefObj obj) and (getattrclass obj == "Gta Object")):
(
valDontExport = getattr obj idxDontExport
if valDontExport == false do
(
txd = toLower (getattr obj idxTXD)
)
)
(isKindOf obj Container):
(
-- Iterate through container's children.
for child in obj.children do
(
RsGetTxdFromObject child txdList:txdList txdObjList:txdObjList includeRefs:includeRefs idxGroupTXD:idxGroupTXD idxTXD:idxTXD idxDontExport:idxDontExport
)
)
(isKindOf obj GtaGroup):
(
txd = toLower (getattr obj idxGroupTXD)
)
)
-- Don't add to lists if they're not being used:
if (txd == unsupplied) then
(
txd = undefined
)
else if (txdList != unsupplied) do
(
local idxTxd = finditem txdList txd
if (idxTxd == 0) do
(
append txdList txd
append txdObjList #()
idxTxd = txdList.count
)
append txdObjList[idxTxd] obj
)
return txd
)
----------------------------------------------------------------------------------------
-- get all the txd names for objList
----------------------------------------------------------------------------------------
fn RsGetTxdList objList txdList txdObjList includeRefs:false sorted:false
idxGroupTXD:(getattrindex "Gta Group" "TXD")
idxTXD:(getattrindex "Gta Object" "TXD")
idxDontExport:(GetAttrIndex "Gta Object" "Dont Export") =
(
local RsGetTxdListMsg = ("RsGetTxdList count:(" + (objList.count as string) + ")")
gRsUlog.ProfileStart RsGetTxdListMsg
-- Pre-load RsRef txd-data:
if includeRefs do
(
-- Flatten obj-list:
local flatObjsList = for obj in objList collect obj
local objNum = 0
while objNum < flatObjsList.count do
(
objNum += 1
join flatObjsList flatObjsList[objNum].children
)
local refDefs = for obj in flatObjsList where (isRSref obj includeDelegates:true) and (obj.refDef != undefined) collect obj.refDef
RsRefFuncs.loadTxds (makeUniqueArray refDefs)
)
for obj in objlist do
(
case classof obj of
(
Gta_MILO:
(
for childObj in obj.children do
(
if classof childobj == GtaMloRoom then
(
for actualObj in childobj.children do
(
RsGetTxdFromObject actualObj txdList:txdList txdObjList:txdObjList includeRefs:includeRefs idxGroupTXD:idxGroupTXD idxTXD:idxTXD idxDontExport:idxDontExport
)
)
else
(
RsGetTxdFromObject childObj txdList:txdList txdObjList:txdObjList includeRefs:includeRefs idxGroupTXD:idxGroupTXD idxTXD:idxTXD idxDontExport:idxDontExport
)
)
)
Default:
(
RsGetTxdFromObject obj txdList:txdList txdObjList:txdObjList includeRefs:includeRefs idxGroupTXD:idxGroupTXD idxTXD:idxTXD idxDontExport:idxDontExport
)
)
)
local nulltxdsmsg = "Removing Null TXDs"
gRsUlog.ProfileStart nulltxdsmsg
-- Remove any null txds:
local foundNull = true
while foundNull do
(
foundNull = false
local idxItem = finditem txdList "null"
if idxItem != 0 then
(
foundNull = true
deleteItem txdList idxItem
deleteItem txdObjList idxItem
)
)
gRsUlog.ProfileEnd context:nulltxdsmsg
local sortTxdsMsg = "Sorting Txds"
gRsUlog.ProfileStart sortTxdsMsg
-- Sort txds/objs alphabetically:
if sorted do
(
-- Staple object-lists to txds:
local sortList = for n = 1 to txdList.count collect (dataPair txd:txdList[n] objs:txdObjList[n])
-- Sort list:
fn txdSorter v1 v2 = (striCmp v1.txd v2.txd)
qsort sortList txdSorter
-- Replace previous list-contents with sorted items:
txdList.count = 0
txdObjList.count = 0
join txdList (for item in sortList collect item.txd)
join txdObjList (for item in sortList collect item.objs)
)
gRsUlog.ProfileEnd context:sortTxdsMsg
gRsUlog.ProfileEnd context:RsGetTxdListMsg
return txdList
)
----------------------------------------------------------------------------------------
-- get all the txd names in the scene
----------------------------------------------------------------------------------------
fn RsGetSceneTxdList includeRefs:false =
(
local txdList = #()
RsGetTxdList rootnode.children txdlist #() includeRefs:includeRefs
return txdList
)
----------------------------------------------------------------------------------------
-- get all the txd names in the scene
----------------------------------------------------------------------------------------
fn RsGetSortedTxdList objlist txdlist includeRefs:false = (
txdobjlist = #()
RsGetTxdList objlist txdlist txdobjlist includeRefs:includeRefs
sort txdlist
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsStdMatIsMapUsedByObject obj mapidx = (
retval = false
objmat = obj.material
if objmat != undefined then (
if classof objmat == XRef_Material then (
objmat = objmat.getsrcitem()
)
if classof objmat == Standardmaterial then (
if objmat.mapEnables[mapidx] == true then (
retval = true
)
)
else if classof objmat == Multimaterial then (
mapList = #()
RsMatGetMapIdsUsedOnObject obj mapList
for i = 1 to objmat.materialList.count do (
id = objmat.materialIDList[i]
if retval == false and finditem mapList id != 0 then (
mat = objmat.materialList[i]
if classof mat == Standardmaterial then (
if mat.mapEnables[mapidx] == true then (
retval = true
)
)
)
)
)
)
retval
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsDoesObjUseShader obj shaderName = (
retval = false
if classof obj == Editable_Mesh or classof obj == Editable_Poly then (
objmat = obj.material
if objmat != undefined then (
if classof objmat == XRef_Material then (
objmat = objmat.getsrcitem()
)
)
if objmat != undefined then (
if classof objmat == Multimaterial then (
mapList = #()
RsMatGetMapIdsUsedOnObject obj mapList
--print "MapList: " + (mapList as string)
for i = 1 to objmat.materialList.count do (
if retval == false then (
id = objmat.materialIDList[i]
if finditem mapList id != 0 then (
mat = objmat.materialList[i]
if classof mat == Rage_Shader then (
if (RsRemoveExtension(RstGetShaderName mat)) == shaderName then (
retval = true
)
)
)
)
)
)
if classof objmat == Rage_Shader then (
if (RsRemoveExtension(RstGetShaderName objmat)) == shaderName then (
retval = true
)
)
)
)
retval
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsGetObjFacesUsingShader obj shaderName faceidlistout = (
retval = false
if classof obj == Editable_Mesh or classof obj == Editable_Poly then (
objmat = obj.material
if objmat != undefined then (
if classof objmat == XRef_Material then (
objmat = objmat.getsrcitem()
)
)
if objmat != undefined then (
if classof objmat == Multimaterial then (
mapList = #()
polyCountList = #()
faceIDLists = #()
RsMatGetMapIdsUsedOnObjectWithCount obj mapList polycount:polyCountList faceidlists:faceIDLists
-- QUICKER WITH OUT THESE LINES
--format "mapList: % \n" (mapList as string)
--format "polyCountList: %\n" (polyCountList as string)
--format "faceidlists: %\n" (faceIDLists as string)
for i = 1 to objmat.materialList.count do (
id = objmat.materialIDList[i]
idxFound = finditem mapList id
if idxFound != 0 then (
mat = objmat.materialList[i]
if classof mat == Rage_Shader then (
if (RsRemoveExtension(RstGetShaderName mat)) == shaderName then (
for item in faceIDLists[idxFound] do
(
append faceidlistout item
)
retval = true
)
)
)
)
)
if classof objmat == Rage_Shader then (
if (RsRemoveExtension(RstGetShaderName objmat)) == shaderName then (
for face in obj.faces do append faceidlistout face.index
retval = true
)
)
)
)
retval
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsCheckIsAlphad obj = (
isAlpha = false
if classof obj == Editable_Mesh or classof obj == Editable_Poly then (
objmat = obj.material
if objmat != undefined then (
if classof objmat == XRef_Material then (
objmat = objmat.getsrcitem()
)
)
if objmat != undefined then (
if classof objmat == Multimaterial then (
mapList = #()
RsMatGetMapIdsUsedOnObject obj mapList
for i = 1 to objmat.materialList.count do (
id = objmat.materialIDList[i]
if finditem mapList id != 0 then (
mat = objmat.materialList[i]
if rexHasAlpha obj mat then (
isAlpha = true
)
)
)
)
else (
if rexHasAlpha obj objmat then (
isAlpha = true
)
)
)
)
isAlpha
)
----------------------------------------------------------------------------------------
--
----------------------------------------------------------------------------------------
fn RsDoesObjUseGlassShader obj =
(
local retVal = false
local shadersUsed = ::RsGetShaderListForObjects obj
for shaderName in shadersUsed while not retVal do
(
retVal = matchPattern shaderName pattern:"*_glass*"
)
retVal
)
fn GetCompositeFileName fileNameIn =
(
-- Sort Wierdness in SpeedTreeCad where sometimes
-- the compositefilename stored in the .spt file
-- will not have the ".tga" extension amd sometimes it will
strExt = substring fileNameIn (fileNameIn.count - 3) 4
if strExt == ".tga" then (
fileNameOut = fileNameIn
)
else (
fileNameOut = fileNameIn + ".tga"
)
return fileNameOut
)
---------------------------------------------------------------------------------
-- Return whether the specified object uses the specified shader
--
-- This is an enhanced version of the RsDoesObjUseShader2 above as it also
-- considers Standard materials that can be converted to shaders.
--
-- [return] true iff object uses shader, false otherwise
---------------------------------------------------------------------------------
fn RsDoesObjUseShader2 obj shaderName = (
retval = false
if classof obj == Editable_Mesh or classof obj == Editable_Poly then (
objmat = obj.material
if objmat != undefined then (
if classof objmat == XRef_Material then (
objmat = objmat.getsrcitem()
)
)
if objmat != undefined then (
if classof objmat == Multimaterial then (
mapList = #()
RsMatGetMapIdsUsedOnObject obj mapList
for i = 1 to objmat.materialList.count do (
if retval == false then (
id = objmat.materialIDList[i]
if finditem mapList id != 0 then (
mat = objmat.materialList[i]
if classof mat == Rage_Shader then (
if (RsRemoveExtension(RstGetShaderName mat)) == shaderName then (
retval = true
)
)
else if classof mat == Standardmaterial then (
-- Check materials shader equivalent (if available)
matShaderName = ( rexStdMatShaderName mat )
if ( String != classof matShaderName ) then
continue
if ( RsRemoveExtension( matShaderName ) == shaderName ) then (
retval = true
)
)
)
)
)
)
if classof objmat == Rage_Shader then (
if (RsRemoveExtension(RstGetShaderName objmat)) == shaderName then (
retval = true
)
)
else if classof objmat == Standardmaterial then (
-- Check materials shader equivalent (if available)
matShaderName = ( rexStdMatShaderName objmat )
if ( String != classof matShaderName ) then
continue
if ( RsRemoveExtension( matShaderName ) == shaderName ) then (
retval = true
)
)
)
)
retval
)
---------------------------------------------------------------------------------
-- Return number of Rage Shader and Standard materials (and submaterials)
-- only Standard materials that can be converted to Rage Shaders are included.
--
-- [return] Number of Rage Shader supported materials in the scene
---------------------------------------------------------------------------------
fn RsGetMaterialCount &numRageShaderMaterials &numShaderStandardMaterials &numStandardMaterials = (
numRageShaderMaterials = 0
numShaderStandardMaterials = 0
numStandardMaterials = 0
for mat in sceneMaterials do
(
if ( Rage_Shader == classof mat ) then
numRageShaderMaterials += 1
else if ( Standard == classof mat ) then
(
shaderName = ( rexStdMatShaderName mat )
if ( String == classof shaderName ) then
numShaderStandardMaterials += 1
else
numStandardMaterials += 1
)
else if ( Multimaterial == classof mat ) then
(
for submat in mat.materialList do
(
if ( Rage_Shader == classof submat ) then
numRageShaderMaterials += 1
else if ( Standard == classof mat ) then
(
shaderName = ( rexStdMatShaderName mat )
if ( String == classof shaderName ) then
numShaderStandardMaterials += 1
else
numStandardMaterials += 1
)
)
)
)
true
)
-- Return list of shaders used by material:
fn RsGetShaderListForMat mat shaderList:#() =
(
case (classof mat) of
(
Rage_Shader:
(
appendIfUnique shaderList (RstGetShaderName mat)
)
Multimaterial:
(
for subMat in mat.materialList do
(
RsGetShaderListForMat subMat shaderList:shaderList
)
)
)
shaderList
)
---------------------------------------------------------------------------------
-- Returns list of available shaders
-- (lower-case, with path/extension removed)
---------------------------------------------------------------------------------
fn RsGetShaderList =
(
if (RSshaderList == undefined) do
(
local ShaderPaths = RsFindFilesRecursive ((RsConfigGetCommonDir core:true) + "shaders/db/") #("*.sps", "*.mpt", "*.mps")
RSshaderList = for Filename in ShaderPaths collect (toLower (getFilenameFile Filename))
)
return RSshaderList
)
---------------------------------------------------------------------------------
-- Return list of shaders in current scene
--
-- [return] Array of shader name strings (path and extension removed)
---------------------------------------------------------------------------------
fn RsGetSceneShaderList =
(
shaderList = #()
for mat in sceneMaterials do
(
RsGetShaderListForMat mat shaderList:shaderList
)
sort shaderList
shaderList
)
-- Return list of shaders for a set of objects:
fn RsGetShaderListForObjects objs =
(
local shaderList = #()
for obj in objs do
(
local ObjMats = ::RsGetMaterialsOnObjFaces Obj
for Mat in ObjMats do
(
RsGetShaderListForMat Mat shaderList:shaderList
)
)
shaderList
)
---------------------------------------------------------------------------------
-- Return list of Standard Materials for a set of objects
--
-- [in] objs List of objects to get list of Standard Materials for
-- [out] matList List of Standard Materials used by objs
-- [out[ parentList List of material's in matList's parents (per mat)
---------------------------------------------------------------------------------
fn RsGetStdMatListForObjects objs &nameList &matList &parentList =
(
nameList = #()
matList = #()
parentList = #()
for o in objs do
(
if ( undefined == o.material ) then
continue
if ( StandardMaterial == classof o.material ) then
(
if ( 0 == findItem matList o.material ) then
(
append nameList o.name
append matList o.material
append parentList undefined
)
)
else if ( Multimaterial == classof o.material ) then
(
for subMat in o.material.materialList do
(
if ( StandardMaterial == classof subMat ) then
(
if ( 0 == findItem matList subMat ) then
(
append nameList o.name
append matList subMat
append parentList o.material
)
)
)
)
)
)
---------------------------------------------------------------------------------
-- Return list of Rage Shader Materials for a set of objects
--
-- [in] objs List of objects to get list of Rage Shader Materials for
-- [out] matList List of Rage Shader Materials used by objs
-- [out] parentList List of material's in matList's parents (per mat)
-- [out] objectList Allows us to retrieve source object per mat
---------------------------------------------------------------------------------
fn RsGetRageShaderMatListForObjects objs &matList &parentList objectList:#() =
(
matList = #()
parentList = #()
for o in objs do
(
if ( undefined == o.material ) then
continue
if ( Rage_Shader == classof o.material ) then
(
if ( 0 == findItem matList o.material ) then
(
append matList o.material
append parentList undefined
append objectList o
)
)
else if ( Multimaterial == classof o.material ) then
(
for subMat in o.material.materialList do
(
if ( Rage_Shader == classof subMat ) then
(
if ( 0 == findItem matList subMat ) then
(
append matList subMat
append parentList o.material
append objectList o
)
)
)
)
)
)
---------------------------------------------------------------------------------
-- Return list of Rage Nitro Shader Materials for a set of objects
--
-- [in] objs List of objects to get list of Rage Shader Materials for
-- [out] matList List of Rage Shader Materials used by objs
-- [out] parentList List of material's in matList's parents (per mat)
-- [out] objectList Allows us to retrieve source object per mat
---------------------------------------------------------------------------------
fn RsGetRageNitroShaderMatListForObjects objs &matList &parentList objectList:#() =
(
matList = #()
parentList = #()
for o in objs do
(
if ( undefined == o.material ) then
continue
if ( Rage_Nitro == classof o.material ) then
(
if ( 0 == findItem matList o.material ) then
(
append matList o.material
append parentList undefined
append objectList o
)
)
else if ( Multimaterial == classof o.material ) then
(
for subMat in o.material.materialList do
(
if ( Rage_Nitro == classof subMat ) then
(
if ( 0 == findItem matList subMat ) then
(
append matList subMat
append parentList o.material
append objectList o
)
)
)
)
)
)
---------------------------------------------------------------------------------
-- Return object shader usage counts for object list and shader list
--
-- [in] objs List of objects to get usage information for
-- [in] shaders List of shaders to get usage information for
---------------------------------------------------------------------------------
fn RsGetObjectShaderCounts objs shaders =
(
shaderObjectCounts = #()
local shaderCount = shaders.count
-- Initialise shaderObjectCount entries
for sh in shaders do
append shaderObjectCounts 0
for i = 1 to shaderCount do
(
for o in objs do
(
if ( RsDoesObjUseShader2 o shaders[i] ) then
(
shaderObjectCounts[i] += 1
)
)
)
shaderObjectCounts
)
---------------------------------------------------------------------------------
-- Fetches object shader usage counts and object, materials lists using each shader
--
-- [in] objs List of objects to get usage information for
-- [in] shaders List of shaders to get usage information for
-- [out] shaderObjectLists Array of array of object references per shader
---------------------------------------------------------------------------------
fn RsGetObjectShaderUsageData objs shaders &shaderObjectLists &shaderMaterialLists =
(
-- Initialise parameter reference data
shaderObjectLists = #()
local shaderCount = shaders.count
-- Now iterate through shaders and objects to collect our usage data
for i = 1 to shaderCount do
(
shaderObjectList = #()
shaderMaterialList = #()
for o in objs do
(
if ( RsDoesObjUseShader2 o shaders[i] ) then
(
append shaderObjectList o
if ( Multimaterial == classof o.material ) then
(
for mat in o.material.materialList do
(
if ( Standard == classof mat ) then
(
shaderName = ( rexStdMatShaderName mat )
if ( ( undefined == shaderName ) or ( classof shaderName != String ) ) then
continue
if ( (RsRemoveExtension(shaderName)) == shaders[i] ) then
if ( 0 == findItem shaderMaterialList mat ) then
append shaderMaterialList mat
)
else if ( Rage_Shader == classof mat ) then
(
shaderName = ( RstGetShaderName mat )
if ( (RsRemoveExtension(shaderName)) == shaders[i] ) then
if ( 0 == findItem shaderMaterialList mat ) then
append shaderMaterialList mat
)
)
)
else if ( Standard == classof o.material ) then
(
shaderName = ( rexStdMatShaderName o.material )
if ( ( undefined == shaderName ) or ( classof shaderName != String ) ) then
continue
if ( (RsRemoveExtension(shaderName)) == shaders[i] ) then
if ( 0 == findItem shaderMaterialList o.material ) then
append shaderMaterialList o.material
)
else if ( Rage_Shader == classof o.material ) then
(
shaderName = ( RstGetShaderName o.material )
if ( (RsRemoveExtension(shaderName)) == shaders[i] ) then
if ( 0 == findItem shaderMaterialList o.material ) then
append shaderMaterialList o.material
)
)
)
append shaderObjectLists shaderObjectList
append shaderMaterialLists shaderMaterialList
)
true
)
---------------------------------------------------------------------------------------------------
-- Is this a tree-billboard material?
---------------------------------------------------------------------------------------------------
fn RsIsBillboardMat mtl =
(
(isKindOf mtl Rage_Shader) and
(
local shadername = RstGetShaderName mtl
matchPattern shaderName pattern:"trees_lod2*"
)
)
-- True if obj has any billboard shaders:
fn RsFindTreeShader obj mtl treeShaderList: =
(
local retVal = False
case of
(
(isKindOf mtl MultiMaterial):
(
local matList = ::RsGetMaterialsOnObjFaces obj material:mtl
for subMat in matList do
(
local isTreeShader = RsFindTreeShader obj subMat treeShaderList:treeShaderList
if isTreeShader then
retVal = true
)
)
(RsIsBillboardMat mtl):
(
if unsupplied!=treeShaderList then
appendIfUnique treeShaderList mtl
retVal = True
)
)
return retVal
)
--
-- name: RsIsTreeBillboard
-- desc: Determine is the object is a tree-billboard (based on shader name).
--
fn RsIsTreeBillboard obj mat =
(
return RsFindTreeShader obj mat
)
---------------------------------------------------------------------------------------------------
-- Swaps two materials
---------------------------------------------------------------------------------------------------
fn RsMatSwapSubMats multiSub mat1Idx mat2Idx =
(
if (isKindOf multiSub Multimaterial) then
(
-- Get positions of matIDs on material-list, just in case it's been reordered or has non-contigious ID-numbers:
local listPos1 = findItem multiSub.materialIDList mat1Idx
local listPos2 = findItem multiSub.materialIDList mat2Idx
-- Swap submaterials:
local tmp = multiSub.materialList[mat1Idx]
multiSub.materialList[mat1Idx] = multiSub.materialList[mat2Idx]
multiSub.materialList[mat2Idx] = tmp
-- Swap material-enableds:
local mat1Enabled = multiSub.mapEnabled[listPos1]
local mat2Enabled = multiSub.mapEnabled[listPos2]
multiSub.mapEnabled[mat1Idx] = mat2Enabled
multiSub.mapEnabled[mat2Idx] = mat1Enabled
-- Swap submaterial-labels: (not the actual materials' names)
local mat1Name = multiSub.names[listPos1]
local mat2Name = multiSub.names[listPos2]
multiSub.names[mat1Idx] = mat2Name
multiSub.names[mat2Idx] = mat1Name
for obj in geometry where (obj.mat == multiSub) do
(
local objClass = classOf obj
local objGetFaceMatID = case objClass of
(
Editable_Mesh:getFaceMatID
Editable_Poly:polyOp.getFaceMatID
)
local objSetFaceMatID = case objClass of
(
Editable_Mesh:setFaceMatID
Editable_Poly:polyOp.setFaceMatID
)
if (objGetFaceMatID != undefined) do
(
for faceNum = 1 to obj.numfaces do
(
case (objGetFaceMatID obj faceNum) of
(
mat1Idx:(objSetFaceMatID obj faceNum mat2Idx)
mat2Idx:(objSetFaceMatID obj faceNum mat1Idx)
)
)
)
)
true
)
else false
)
---------------------------------------------------------------------------------------------------
-- Inserts new submaterial into multiSub
---------------------------------------------------------------------------------------------------
fn RsMatInsertSubMat multiSub newMatId newMat: =
(
if (isKindOf multiSub Multimaterial) then
(
if (newMat == unsupplied) do
(
local matClass = classOf multiSub.materialList[1]
newMat = createInstance matClass
)
-- Find the matID closest to newMatId, so that we can insert just before that
-- (I'm going through this rigmarole because the multimat may have been reordered or have non-contigious ID-numbers)
local insertAt = 1
local insertBeforeID = multiSub.numSubs
local getID
for n = 1 to multiSub.materialIDList.count do
(
getID = multiSub.materialIDList[n]
if (getID >= newMatId) do
(
if (getID < insertBeforeID) do
(
insertBeforeID = getID
insertAt = n
)
-- Bump up any IDs over newMatId:
multiSub.materialIDList[n] += 1
)
)
-- Insert the new material:
local newMatList = multiSub.materialList as array
local newMatIDList = multiSub.materialIDList as array
insertItem newMat newMatList insertAt
insertItem newMatId newMatIDList insertAt
multiSub.materialList = newMatList
multiSub.materialIDList = newMatIDList
-- Shuffle the submat enabled-values down the list:
for n = multiSub.materialList.count to (insertAt + 1) by -1 do
(
multiSub.mapEnabled[n] = multiSub.mapEnabled[n - 1]
)
local matObjs = for obj in geometry where (obj.mat == multiSub) collect obj
local curMatID
for obj in matObjs do
(
local objClass = classOf obj
local objGetFaceMatID = case objClass of
(
Editable_Mesh:getFaceMatID
Editable_Poly:polyOp.getFaceMatID
)
local objSetFaceMatID = case objClass of
(
Editable_Mesh:setFaceMatID
Editable_Poly:polyOp.setFaceMatID
)
if (objGetFaceMatID != undefined) do
(
for faceNum = 1 to obj.numfaces do
(
curMatID = objGetFaceMatID obj faceNum
if (curMatID >= newMatId) do
(
objSetFaceMatID obj faceNum (curMatID + 1)
)
)
)
)
true
)
else false
)
-- Returns list of defined texmaps for a given object/material/texmap:
fn RsGetMaterialTexMaps item texMaps:#() =
(
-- Recurse through given objects' materials and lightmaps:
if (isValidNode item) do
(
-- Get materials from object:
if (isProperty item #material) do
(
RsGetMaterialTexMaps item.material texMaps:texMaps
)
-- Get lightmap from light:
(
local lightShadowMap = undefined
if (isProperty item #delegate) do
(
item = item.delegate
)
if (isProperty item #shadowProjectorMap) do
(
lightShadowMap = item.shadowProjectorMap
)
if (lightShadowMap != undefined) do
(
RsGetMaterialTexMaps lightShadowMap texMaps:texMaps
)
)
return texMaps
)
-- Recurse through all sub-materials/textures:
case (classOf item) of
(
-- Materials:
MultiMaterial:
(
-- Recurse through submaterials:
for subMat in item.materialList do
(
RsGetMaterialTexMaps subMat texMaps:texMaps
)
)
CompositeMaterial:
(
-- Recurse through submaterials:
for subMat in item.materialList do
(
RsGetMaterialTexMaps subMat texMaps:texMaps
)
)
XRef_Material:
(
-- Recurse to reffed material:
RsGetMaterialTexMaps (item.getsrcitem()) texMaps:texMaps
)
Blend:
(
RsGetMaterialTexMaps item.map1 texMaps:texMaps
RsGetMaterialTexMaps item.map2 texMaps:texMaps
)
DoubleSided:
(
RsGetMaterialTexMaps item.material1 texMaps:texMaps
RsGetMaterialTexMaps item.material2 texMaps:texMaps
)
Shellac:
(
RsGetMaterialTexMaps item.shellacmtl1 texMaps:texMaps
RsGetMaterialTexMaps item.shellacmtl2 texMaps:texMaps
)
TopBottom:
(
RsGetMaterialTexMaps item.topMaterial texMaps:texMaps
RsGetMaterialTexMaps item.bottomMaterial texMaps:texMaps
)
-- Texturemaps:
Bitmaptexture:
(
-------------------------------------------------------------------------
-- Here's where the texturemaps are actually collected: --
-------------------------------------------------------------------------
if (item.filename != undefined) and (item.filename != "") do
(
append texMaps item
)
)
CompositeTexturemap:
(
-- Recurse through sub-texmaps:
for n = 1 to (getNumSubTexmaps item) do
(
local texMap = getSubTexmap item n
RsGetMaterialTexMaps texMap texMaps:texMaps
)
)
DistanceAlphaMap:
(
-- Get proper texmap for DistanceAlphaMap:
local texMap = RsGetDistanceAlphaMapResultMap item
RsGetMaterialTexMaps texMap texMaps:texMaps
)
-- Ignore undefined materials/textureMaps
UndefinedClass:()
Default:
(
if (isKindOf item material) do
(
-- Recurse through material's texturemaps:
for n = 1 to (getNumSubTexmaps item) do
(
local texMap = getSubTexmap item n
RsGetMaterialTexMaps texMap texMaps:texMaps
)
)
)
)
return texMaps
)
-- Lists all texture-paths used by material/texturemap/object 'item'
fn RsGetMaterialTextures item textureList:#() =
(
local texMaps = RsGetMaterialTexMaps item
-- Make texMaps list only contain unique texmaps:
local texMaps = (makeUniqueArray texMaps)
-- Set textureList to unique array of non-undefined paths:
local newTexPaths = for texMap in texMaps collect texMap.filename
newTexPaths = for filename in newTexPaths where (filename != "") and (filename != undefined) collect (toLower filename)
-- Don't edit/uniquify textureList if we're not adding anything:
if (newTexPaths.count != 0) do
(
join textureList newTexPaths
newTexPaths = makeUniqueArray textureList
-- Replace textureList with ammended version of list:
textureList.count = 0
join textureList newTexPaths
)
return textureList
)
-- Get unique textureMap items used in scene:
fn RsGetSceneTexMaps =
(
local texMaps = #()
-- Get lightmaps from light-objects:
for obj in lights do
(
RsGetMaterialTexMaps obj texMaps:texMaps
)
-- Get texmaps from sceneMaterials:
local sceneMats = makeUniqueArray (for mat in sceneMaterials collect mat)
for mat in sceneMats do
(
RsGetMaterialTexMaps mat texMaps:texMaps
)
-- Make unique array:
texMaps = makeUniqueArray texMaps
return texMaps
)
-- Lists all texture-paths used on materials used in the scene.
-- (Materials don't have to actually be applied to objects)
fn RsGetSceneTextures =
(
local texMaps = RsGetSceneTexMaps()
local textureList = for texMap in texMaps collect (toLower texMap.filename)
textureList = makeUniqueArray textureList
return textureList
)
-- Perforce-syncs files in textureList to latest versions on Perforce, if they're under the texture-root:
fn RsP4syncTextures textureList =
(
-- Sync scene-textures if they're in Perforce. Force-syncs if they still don't exist locally after that sync.
::gRsPerforce.syncWithRetry textureList showProgress:true progressTitle:"P4 Sync Textures:" silent:true
)
-- Perforce-syncs all textures used in the scene:
fn RsP4syncSceneTextures =
(
RsP4syncTextures (RsGetSceneTextures())
)
-- Returns all materials actually used on an object, and optionally can pass those materials' face-lists by reference
fn RsGetMaterialsOnObjFaces obj material: materials:#() faceLists: mtlIdList:#() =
(
local objMat = if (material == unsupplied) then obj.material else material
if (classof objMat == XRef_Material) or isRefObj obj then
return materials
local getMesh = true
local doFaceLists = (isKindOf faceLists Array)
case of
(
((isKindOf obj editable_mesh) or (isKindOf obj trimesh)):
(
getMesh = false
)
(isKindOf obj col_mesh):
(
obj = getColMesh obj
getMesh = false
)
(isKindOf obj Editable_Poly):
(
if ((polyop.GetHasDeadStructs obj) > 0 ) do
(
polyOp.collapseDeadStructs obj
)
getMesh = false
)
)
if getMesh do
(
if (isProperty obj #mesh) AND (classof obj != Targetobject) then
(
obj = copy obj.mesh
)
else
(
return #()
)
)
if(obj == undefined) then return #()
local objGetFaceMatID = RsGetFaceMatIDFunc obj
local numFaces = getNumFaces obj
local objSubMatIndex = #()
local isMultiMat = isKindOf objMat Multimaterial
local matCount = if isMultiMat then objMat.numSubs else 1
-- collect list of the object's faces' matIDs, corrected
if isMultiMat then
(
local foundMatIds = #()
for faceNum = 1 to numFaces do
(
local matNum = objGetFaceMatID obj faceNum
-- Deal with matIDs that are higher than the material-count:
if (matNum > matCount) do
(
matNum = (mod matNum matCount) as integer
if (matNum == 0) do (matNum = matCount)
)
local findNum = foundMatIds[matNum]
if (findNum == undefined) do
(
local matIdNum = findItem objMat.materialIDList matNum
local newMat = if (matIdNum == 0) then undefined else objMat.materialList[matIdNum]
findNum = findItem materials newMat
if (findNum == 0) do
(
append materials newMat
if doFaceLists do
(
append faceLists #{}
)
append mtlIdList matNum
findNum = materials.count
)
)
if doFaceLists do
(
faceLists[findNum][faceNum] = true
)
)
)
else
(
-- Single-material objects are simpler to process
append materials objMat
if doFaceLists do
(
append faceLists #{1..obj.numFaces}
)
append mtlIdList 1
)
return materials
)
-- Return the submaterial that will be applied to an face with a particular matId
-- (taking into account non-multimaterials and out-of-range material values)
fn RsGetSubmatByMatId mat matId =
(
if (isKindOf mat MultiMaterial) then
(
-- Deal with out-of-range values:
local numSubs = mat.numSubs
matId = (mod matId numSubs) as integer
if (matId == 0) do matId = numSubs
local matIdx = findItem mat.materialIDList matId
if (matIdx == 0) then return undefined else mat.materialList[matIdx]
)
else
(
return mat
)
)
-- Returns the texturemap paths for materials used on objects in given map-containers:
fn RsGetMapTextures maps =
(
local textureList = #()
local checkObjs = #()
for map in maps do
(
local mapObjs = for obj in map.objects where (getattrclass obj == "Gta Object") collect obj
local refNames = #()
local uniqueObjs = #()
for obj in mapObjs do
(
case of
(
-- Only count one of each ref:
(isRSref obj includeDelegates:true):
(
if (appendIfUnique refNames obj.objectName) do
(
append uniqueObjs obj
)
)
-- Don't include internalrefs, as their parent-object should already be used:
(isRsInternalRef obj):()
default:
(
append uniqueObjs obj
)
)
)
join checkObjs uniqueObjs
)
-- Filter out further instances of objects:
checkObjs = ::RsGetInstGroupLeaders checkObjs
if (checkObjs.count != 0) do
(
pushPrompt "Collecting texture-paths..."
format "Collecting texture-paths...\n"
local timeStart = timestamp()
local matsUsed = #()
for obj in checkObjs do
(
local objMats = RsGetMaterialsOnObjFaces obj
join matsUsed objMats
)
for mat in (makeUniqueArray matsUsed) do
(
RsGetMaterialTextures mat textureList:textureList
)
popPrompt()
format "Time taken: %s\n" ((timestamp() - timeStart) / 1000.0)
)
return textureList
)
--RsGetMapTextures(RsMapGetMapContainers())
-- End of script