-- Gta Scene Statistics -- Greg Smith -- Luke Openshaw -- 31/1/2007 filein "rockstar/util/material.ms" filein "rockstar/util/string.ms" filein "rockstar/util/lod.ms" filein "rockstar/export/settings.ms" filein "rockstar/export/mapsetup.ms" filein (RsConfigGetWildWestDir()+"/script/max/rockstar_london/pipeline/RSL_LevelConfig.ms") ideFileNames = #() ideLoaded = #() ideObjectNames = #() ideObjectTXDs = #() struct objInfo (name, textures, polys, collpolys, loddistance, size, txd, txdsize, txdtextures, volume, polydensity, modelgroup, islod, isxref, isprop, isinterior, memdensity, txdpercent, instances, totalsize) RsObjList = #() struct objTexInfo (name, polys, width, height, size, matid, texmap, objects, objectfaces) RsTexInfoList = #() fn showProps obj= ( clearListener() format "Properties:\n" showProperties obj format "\nMethods:\n" showMethods obj format "\nEvents:\n" showEvents obj ) try (DestroyDialog RsSceneStatsRoll) catch() rollout RsSceneStatsRoll "Scene Stats" ( --//////////////////////////////////////////////////////////// -- interface --//////////////////////////////////////////////////////////// checkbox chkIncludeXrefs "Include Xrefs" checkbox chkIncludeStnd "Include Standard" offset:[90,-20] checked:true checkbox chkIncludeDyn "Include Dynamic" offset:[190,-20] checked:true checkbox chkFragmentChildren "Frag Children" offset:[300,-20] button cmdUpdate "Update" align:#left width:100 offset:[410,-20] button cmdSaveCurrent "Save To File" align:#left width:100 offset:[520,-26] button cmdSaveReport "Save Report" align:#left width:100 offset:[630,-26] progressbar barLoad width:300 offset:[750,-20] label lblObjects "Objects:" align:#left dropdownlist lstObjectOrder "" offset:[100,-16] width:200 items:#("Name","Textures","Polys","Coll Polys","LOD Distance","Size","TXD","TXD Size","TXD Textures","Volume","PolyDensity","MemDensity","TXD Percent","Instances","Total Size") dotNetControl axObjectList "System.Windows.Forms.ListView" height:(((RsSettingsReadInteger "rsstatsroll" "height" 500) - 100) / 2) align:#center label lblTextures "Selected Object's Textures:" align:#left dropdownlist lstTextureOrder "" offset:[150,-16] width:200 items:#("Name","Polys","Width","Height","Size","Material ID") dotNetControl axTextureList "System.Windows.Forms.ListView" height:(((RsSettingsReadInteger "rsstatsroll" "height" 500) - 100) / 2) width:500 align:#left bitmap bmpTex offset:[200,-210] width:200 height:200 button cmdSelect "Select Faces" align:#right width:100 offset:[0,-200] button cmdSelectObj "Select Object" align:#right width:100 offset:[0,0] button cmdEdit "Edit" align:#right width:100 offset:[0,0] --//////////////////////////////////////////////////////////// -- methods --//////////////////////////////////////////////////////////// fn LoadIDEFileNamesRec dir = ( filelist = getFiles ( dir + "/*.ide" ) for file in filelist do ( append ideFileNames file append ideLoaded false ) local dirlist = getDirectories ( dir + "/*" ) for dir in dirlist do ( LoadIDEFileNamesRec dir ) ) fn LoadIDEFileNames = ( local indDir = RsConfigGetIndDir() local dirlist = getDirectories ( indDir + "/*" ) for dir in dirlist do ( LoadIDEFileNamesRec dir ) ) fn LoadIDEInfo mapName = ( ideFilename = RsLowercase(mapName + ".ide") idxFound = 0 for i = 1 to ideFileNames.count do ( if findstring ideFileNames[i] ideFilename != undefined then ( idxFound = i exit ) ) if idxFound != 0 then ( if ideLoaded[idxFound] == false then ( ideLoaded[idxFound] = true ideFile = openfile ideFileNames[idxFound] mode:"r" if ideFile != undefined then ( readState = #none while eof ideFile == false do ( ideFileLine = readline ideFile if readState == #none then ( if ideFileLine == "objs" then ( readState = #readingObjs ) ) else ( if ideFileLine == "end" then ( readState = #none exit ) else ( lineTokens = filterstring ideFileLine ", " objName = RsUpperCase lineTokens[1] objTXD = RsUpperCase lineTokens[2] if finditem ideObjectNames objName == 0 then ( append ideObjectNames objName append ideObjectTXDs objTXD ) ) ) ) close ideFile ) ) ) ideFileNames[idxFound] ) fn UpdateObjectInfo objlist includeXrefs includeStnd includeDyn updateProgress:true = ( objNameList = #() objFlagList = #() if includeDyn == false then ( doscommand(RsConfigGetBinDir() + "/" + RsConfigGetRagebuilder() + " " + RsConfigGetProjRootDir() + "/bin/general/utility/createflagsformaxstats.rbs") tempfilename = RsConfigGetBinDir() + "/temp.txt" tempfile = openfile tempfilename mode:"r" while eof tempfile == false do ( tempfileline = readline tempfile tempfiletokens = filterstring tempfileline "," append objNameList (RsUppercase tempfiletokens[1]) append objFlagList (tempfiletokens[2] as integer) ) close tempfile ) idxTXD = getattrindex "Gta Object" "TXD" idxLODDistance = getattrindex "Gta Object" "LOD distance" idxModelGroup = getattrindex "Gta Object" "Model Group" RsObjList = #() txdNames = #() txdTextureCounts = #() txdSizes = #() xrefObjectNames = #() xrefObjectLine = #() if (filterstring maxfilename ".")[1] == undefined then return 0 for i = 1 to objlist.count do ( obj = objlist[i] if updateProgress then barLoad.value = ((i as float) / selection.count) * 100.0 if obj.parent != undefined then ( if classof obj.parent != Gta_MILO and classof obj.parent != GtaMloRoom and chkFragmentChildren.checked == false then continue ) if ((classof obj == Editable_Mesh or classof obj == Editable_Poly) and includeStnd == true) or (classof obj == XRefObject and includeXrefs == true) then ( objName = "" isLod = false isXref = false isProp = false isInterior = false instanceCount = 1 if RsIsAnyLOD obj then ( isLod = true ) if getattrclass obj != "Gta Object" then ( continue ) if classof obj == XRefObject then ( isXref = true objName = RsUpperCase obj.objectName idxFound = finditem xrefObjectNames objName if idxFound == 0 then ( append xrefObjectNames objName append xrefObjectLine (RsObjList.count + 1) ) else ( if RsObjList[xrefObjectLine[idxFound]] != undefined then ( RsObjList[xrefObjectLine[idxFound]].instances = RsObjList[xrefObjectLine[idxFound]].instances + 1 ) continue ) ) else ( objName = RsUpperCase obj.name ) idxFlagFound = finditem objNameList objName if idxFlagFound != 0 then ( if (bit.and objFlagList[idxFlagFound] 131072) != 0 then ( continue ) ) valTXD = "" valLODDistance = "" valTXD = RsUpperCase(getattr obj idxTXD) valLODDistance = (getattr obj idxLODDistance) as string idxFound = finditem txdNames valTXD currentTexCount = "" currentTxdSize = "" if idxFound == 0 then ( -- Try network ITD file first... filename = RsConfigGetNetworkDir() + "maps/" + (filterString maxfilename ".")[1] + "/" + valTXD + ".itd" txdSize = getFileSize filename -- If file size was zero, try local ITD file... if ( 0 == txdSize ) then ( filename = RsConfigGetMapStreamDir() + "maps/" + (filterstring maxfilename ".")[1] + "/" + valTXD + ".itd" txdSize = getFileSize filename ) -- file size is still zero, try genstreamdir if txdSize == 0 then ( filename = RsConfigInfos[RsCurrentConfig].genstreamdir + "maps/" + (filterstring maxfilename ".")[1] + "/" + valTXD + ".itd" txdSize = getFileSize filename ) if txdSize == 0 then ( txdSize = "unknown" ) else ( txdSize = (txdSize / 1024) as string ) texmaplist = #() maxsizelist = #() isbumplist = #() usagelist = #() RsGetTexMapsByTxdNameNoStrip texmaplist maxsizelist isbumplist usagelist valTXD currentTexCount = texmaplist.count as string currentTxdSize = txdSize append txdNames valTXD append txdTextureCounts currentTexCount append txdSizes currentTxdSize ) else ( currentTexCount = txdTextureCounts[idxFound] currentTxdSize = txdSizes[idxFound] ) -- texture list texmaplist = #() maxsizelist = #() isbumplist = #() RsGetTexMapsFromMaterial obj obj.material texmaplist maxsizelist isbumplist -- number of faces numFaces = 0 try ( numFaces = obj.numfaces ) catch ( ) -- collision polys collPolys = 0 for subobj in obj.children do ( if classof subobj == Col_Mesh do ( collPolys = collPolys + getcollpolycount subobj ) ) -- volume dimensions = obj.max - obj.min volume = dimensions.x * dimensions.y * dimensions.z -- poly density polyDensity = 0 if numFaces != 0 then polyDensity = (numFaces as float) / volume -- size of file modelSize = "unknown" valModelGroup = getattr obj idxModelGroup filename = "" if classof obj == XRefObject then ( srcMapFile = RsRemovePathAndExtension(obj.fileName) ideFileName = LoadIDEInfo srcMapFile if findstring ideFileName "props" != undefined then ( isProp = true ) if getattrclass obj == "Gta MILOTri" then ( isInterior = true ) modelSize = getFileSize (RsConfigInfos[RsCurrentConfig].genstreamdir + "maps/" + srcMapFile + "/" + obj.objectName + ".idr") if modelSize == 0 then ( modelSize = getFileSize (RsConfigInfos[RsCurrentConfig].genstreamdir + "maps/" + srcMapFile + "/" + obj.objectName + ".ift") ) idxFound = finditem ideObjectNames (RsUpperCase obj.objectName) if idxFound != 0 then ( valTXD = RsUpperCase(ideObjectTXDs[idxFound]) if valTXD == undefined or valTXD == "NULL" then ( valTXD = "none" currentTxdSize = "0" ) else ( currentTxdSize = getFileSize (RsConfigInfos[RsCurrentConfig].genstreamdir + "maps/" + srcMapFile + "/" + valTXD + ".itd") if currentTxdSize == 0 then ( currentTxdSize = "unknown" ) else ( currentTxdSize = (currentTxdSize / 1024) as string ) ) ) ) else ( -- Try network ITD file first... basefilename = RsConfigGetNetworkDir() + "maps/" + (filterString maxfilename ".")[1] -- Get model file suffix if valModelGroup == "null" or valModelGroup == "" then ( filemodel = "/" + obj.name + ".idr" ) else ( filemodel = "/" + valModelGroup + ".idd" ) filename = basefilename + filemodel modelSize = getFileSize filename if ( 0 == modelSize ) then ( basefilename = RsConfigGetMapStreamDir() filename = basefilename + filemodel modelSize = getFileSize filename if modelSize == 0 then ( modelSize = getFileSize (RsConfigInfos[RsCurrentConfig].genstreamdir + "maps/" + (filterstring maxfilename ".")[1] + "/" + obj.name + ".idr") if modelSize == 0 then ( objName = RsGetNonFragmentName obj.name modelSize = getFileSize (RsConfigInfos[RsCurrentConfig].genstreamdir + "maps/" + (filterstring maxfilename ".")[1] + "/" + objName + ".ift") ) ) ) ) memDensity = 0.0 if modelSize == 0 then ( modelSize = "unknown" memDensity = 0.0 ) else ( modelSize = (modelSize / 1024) as string memDensity = (modelSize as float) / volume ) -- texmap count texMapCount = (texmaplist.count as string) -- if classof obj == XRefObject then ( objName = "{" + objName + "}" texMapCount = "NA" collPolys = "NA" valLODDistance = "NA" currentTexCount = "NA" ) else ( txdpercent = 100.0 * ((texMapCount as float) / (currentTexCount as float)) ) -- totalsize if ( "unknown" == modelSize or undefined == modelSize ) or ( "unknown" == currentTxdSize or undefined == currentTxdSize ) then totalSize = "unknown" else totalsize = ( ( modelSize as number ) + ( currentTxdSize as number ) ) as string append RsObjList (objInfo objName texMapCount (numFaces as string) (collPolys as string) valLODDistance modelSize valTXD currentTxdSize currentTexCount (volume as string) (polyDensity as string) valModelGroup isLod isXref isProp isInterior (memDensity as string) (txdpercent as string) instanceCount totalsize ) ) ) ) fn cbCompareTextures v1 v2 = ( retval = case(lstTextureOrder.selection) of ( 1:(stricmp v1.name v2.name) 2:(v1.polys - v2.polys) 3:(v1.width - v2.width) 4:(v1.height - v2.height) 5:(v1.size - v2.size) 6: ( valA = v1.matid as number valB = v2.matid as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) ) retval ) fn cbCompareObjects v1 v2 = ( retval = case(lstObjectOrder.selection) of ( 1:(stricmp v1.name v2.name) 2: ( valA = v1.textures as number valB = v2.textures as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 3: ( valA = v1.polys as number valB = v2.polys as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 4:( valA = v1.collpolys as number valB = v2.collpolys as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 5:( valA = v1.loddistance as number valB = v2.loddistance as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 6:( valA = v1.size as number valB = v2.size as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 7:(stricmp v1.txd v2.txd) 8:( valA = v1.txdsize as number valB = v2.txdsize as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 9:( valA = v1.txdtextures as number valB = v2.txdtextures as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 10:( valA = v1.volume as float valB = v2.volume as float if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 11:( valA = v1.polydensity as float valB = v2.polydensity as float if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 12:( valA = v1.memdensity as float valB = v2.memdensity as float if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 13:( valA = v1.txdpercent as float valB = v2.txdpercent as float if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 14:( valA = v1.instances valB = v2.instances if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) 15:( valA = v1.totalsize as number valB = v2.totalsize as number if valA == undefined and valB == undefined then ( 0 ) else if valA == undefined then ( -1 ) else if valB == undefined then ( 1 ) else ( (valA - valB) ) ) ) retval ) fn RefreshSelectedObjects = ( qsort RsObjList cbCompareObjects axObjectList.Items.Clear() theRange = #() --array to collect the list items for i = 1 to RsObjList.count do ( --First we create a ListViewItem object with the object's name: newItem = dotNetObject "System.Windows.Forms.ListViewItem" RsObjList[i].name --Then we add all the sub-items with the desired string values: sub_li = newItem.SubItems.add RsObjList[i].textures sub_li = newItem.SubItems.add RsObjList[i].polys sub_li = newItem.SubItems.add RsObjList[i].collpolys sub_li = newItem.SubItems.add RsObjList[i].loddistance sub_li = newItem.SubItems.add RsObjList[i].size sub_li = newItem.SubItems.add RsObjList[i].txd sub_li = newItem.SubItems.add RsObjList[i].txdsize sub_li = newItem.SubItems.add RsObjList[i].txdtextures sub_li = newItem.SubItems.add RsObjList[i].volume sub_li = newItem.SubItems.add RsObjList[i].polydensity sub_li = newItem.SubItems.add RsObjList[i].memdensity sub_li = newItem.SubItems.add RsObjList[i].txdpercent sub_li = newItem.SubItems.add (RsObjList[i].instances as string) sub_li = newItem.SubItems.add RsObjList[i].totalsize append theRange newItem --we add the list item to the array ) axObjectList.Items.AddRange theRange --when done, we populate the ListView axObjectList.MultiSelect = true -- axObjectList.Sorted = false ) fn UpdateSelectedObjects = ( UpdateObjectInfo selection chkIncludeXrefs.checked chkIncludeStnd.checked chkIncludeDyn.checked RefreshSelectedObjects() ) fn RefreshSelectedTextures = ( qsort RsTexInfoList cbCompareTextures axTextureList.Items.Clear() theRange = #() --array to collect the list items for i = 1 to RsTexInfoList.count do ( --First we create a ListViewItem object with the object's name: newItem = dotNetObject "System.Windows.Forms.ListViewItem" RsTexInfoList[i].name --Then we add all the sub-items with the desired string values: sub_li = newItem.SubItems.add (RsTexInfoList[i].polys as string) sub_li = newItem.SubItems.add (RsTexInfoList[i].width as string) sub_li = newItem.SubItems.add (RsTexInfoList[i].height as string) sub_li = newItem.SubItems.add (RsTexInfoList[i].size as string) sub_li = newItem.SubItems.add (RsTexInfoList[i].matID as string) append theRange newItem --we add the list item to the array ) axTextureList.Items.AddRange theRange --when done, we populate the ListView ) fn UpdateSelectedTextures = ( objlist = #() -- clearListener() for i = 0 to (axObjectList.SelectedItems.Count - 1) do ( foundObj = getNodeByName axObjectList.SelectedItems.Item[i].Text exact:true if foundObj != undefined then ( append objlist foundObj ) ) RsTexInfoList = #() texmaplist = #() objPolys = #() objWidth = #() objHeight = #() objSize = #() objMatID = #() objTexMaps = #() objObjects = #() objObjectFaces = #() for obj in objlist do ( RsGetTexMapsInfoFromMaterial obj obj.material texmaplist objPolys objWidth objHeight objSize objMatID objTexMaps objObjects objObjectFaces ) for i = 1 to texmaplist.count do ( matID = objMatID[i] if objObjects[i].count > 1 then ( matID = "multiple" ) else ( matID = matID as string ) append RsTexInfoList (objTexInfo texmaplist[i] objPolys[i] (objWidth[i] / 2) (objHeight[i] / 2) objSize[i] matID objTexMaps[i] objObjects[i] objObjectFaces[i]) ) RefreshSelectedTextures() ) --//////////////////////////////////////////////////////////// -- events --//////////////////////////////////////////////////////////// on lstObjectOrder selected arg do ( RefreshSelectedObjects() ) on lstTextureOrder selected arg do ( RefreshSelectedTextures() ) on cmdSaveReport pressed do ( saveFilename = getsavefilename caption:"Save report to:" filename:"out.csv" types:"Comma Seperated (*.csv)|*.csv" if saveFilename == undefined then return 0 saveFile = openfile saveFilename mode:"wb" if saveFile == undefined then return 0 allobj = #() RsGetMapObjectsWithXrefs rootnode.children allobj RsSetupBlocks true -- create blocks BlockNames = #() SelectionSets = #() BlockAreas = #() BlockObjects = #() idxBlockID = getattrindex "Gta Object" "BlockID" idxBlockIDMilo = getattrindex "Gta MILOTri" "BlockID" for obj in allobj do ( blockName = "" if getattrclass obj == "Gta Object" then ( blockName = RsLowercase(getattr obj idxBlockID) ) else if getattrclass obj == "Gta MILOTri" then ( blockName = RsLowercase(getattr obj idxBlockIDMilo) ) if blockName == "" then blockName = "unassigned" idxFound = finditem BlockNames blockName if idxFound == 0 then ( objFoundList = getnodebyname blockName exact:true all:true objValid = #() areaValue = 0.0 for objFound in objFoundList do ( if classof objFound == GtaBlock then ( append objValid objFound areaValue = objFound.plane.length * objFound.plane.width ) ) append BlockNames blockName append SelectionSets #(obj) append BlockAreas areaValue append BlockObjects objValid ) else ( append SelectionSets[idxFound] obj ) ) blockTotalPolys = #() blockTotalCollPolys = #() blockTotalModelSize = #() blockTotalTXDSize = #() blockTotalTXDCount = #() blockTotalLodSize = #() blockTotalInteriorSize = #() blockTotalPropSize = #() blockTotalXrefSize = #() for i = 1 to BlockNames.count do ( blockName = BlockNames[i] UpdateObjectInfo SelectionSets[i] true true true updateProgress:false barLoad.value = ((i as float) / BlockNames.count) * 100.0 format ("Block: " + blockName + "\n\n") to:saveFile format ("Name" + ",") to:saveFile format ("Textures" + ",") to:saveFile format ("Polys" + ",") to:saveFile format ("Collision Polys" + ",") to:saveFile format ("LOD Distance" + ",") to:saveFile format ("Size (k)" + ",") to:saveFile format ("TXD" + ",") to:saveFile format ("TXD Size (k)" + ",") to:saveFile format ("TXD Textures" + ",") to:saveFile format ("Volume" + ",") to:saveFile format ("Poly Density" + ",") to:saveFile format ("Mem Density" + ",") to:saveFile format ("TXD Percent" + ",") to:saveFile format ("Is Lod" + ",") to:saveFile format ("Is Xref" + ",") to:saveFile format ("Is Prop" + ",") to:saveFile format ("Is Interior" + "\n") to:saveFile currTotalPolys = 0 currTotalCollPolys = 0 currTotalModelSize = 0 currTotalTXDSize = 0 currTotalLodSize = 0 currTotalInteriorSize = 0 currTotalPropSize = 0 currTotalXrefSize = 0 blockTxds = #() for j = 1 to RsObjList.count do ( thisTotalPolys = RsObjList[j].polys as number thisTotalCollPolys = RsObjList[j].collpolys as number thisTotalModelSize = RsObjList[j].size as number thisTotalTXDSize = RsObjList[j].txdsize as number if thisTotalPolys != undefined then currTotalPolys = currTotalPolys + thisTotalPolys if thisTotalCollPolys != undefined then currTotalCollPolys = currTotalCollPolys + thisTotalCollPolys if thisTotalModelSize != undefined then ( currTotalModelSize = currTotalModelSize + thisTotalModelSize if RsObjList[j].islod then currTotalLodSize = currTotalLodSize + thisTotalModelSize if RsObjList[j].isxref then currTotalXrefSize = currTotalXrefSize + thisTotalModelSize if RsObjList[j].isprop then currTotalPropSize = currTotalPropSize + thisTotalModelSize if RsObjList[j].isinterior then currTotalInteriorSize = currTotalInteriorSize + thisTotalModelSize ) if finditem blockTxds RsObjList[j].txd == 0 then ( append blockTxds RsObjList[j].txd if thisTotalTXDSize != undefined then ( currTotalTXDSize = currTotalTXDSize + thisTotalTXDSize if RsObjList[j].islod then currTotalLodSize = currTotalLodSize + thisTotalTXDSize if RsObjList[j].isxref then currTotalXrefSize = currTotalXrefSize + thisTotalTXDSize if RsObjList[j].isprop then currTotalPropSize = currTotalPropSize + thisTotalTXDSize if RsObjList[j].isinterior then currTotalInteriorSize = currTotalInteriorSize + thisTotalTXDSize ) ) format (RsObjList[j].name + ",") to:saveFile format (RsObjList[j].textures + ",") to:saveFile format (RsObjList[j].polys + ",") to:saveFile format (RsObjList[j].collpolys + ",") to:saveFile format (RsObjList[j].loddistance + ",") to:saveFile format (RsObjList[j].size + ",") to:saveFile format (RsObjList[j].txd + ",") to:saveFile format (RsObjList[j].txdsize + ",") to:saveFile format (RsObjList[j].txdtextures + ",") to:saveFile format (RsObjList[j].volume + ",") to:saveFile format (RsObjList[j].polydensity + ",") to:saveFile format (RsObjList[j].memdensity + ",") to:saveFile format (RsObjList[j].txdpercent + ",") to:saveFile format ((RsObjList[j].islod as string) + ",") to:saveFile format ((RsObjList[j].isxref as string) + ",") to:saveFile format ((RsObjList[j].isprop as string) + ",") to:saveFile format ((RsObjList[j].isinterior as string) + "\n") to:saveFile ) append blockTotalPolys currTotalPolys append blockTotalCollPolys currTotalCollPolys append blockTotalModelSize currTotalModelSize append blockTotalTXDSize currTotalTXDSize append blockTotalLodSize currTotalLodSize append blockTotalXrefSize currTotalXrefSize append blockTotalPropSize currTotalPropSize append blockTotalInteriorSize currTotalInteriorSize append blockTotalTXDCount blockTxds.count format ("\n\n") to:saveFile ) format ("Block Summary\n\n") to:saveFile format ("Name" + ",") to:saveFile format ("Object Count" + ",") to:saveFile format ("TXD Count" + ",") to:saveFile format ("Total Poly Count" + ",") to:saveFile format ("Total Collision Poly Count" + ",") to:saveFile format ("Total Model Size (k)" + ",") to:saveFile format ("Total TXD Size (k)" + ",") to:saveFile format ("Total (k)" + ",") to:saveFile format ("Lod Size (k),") to:saveFile format ("Xref Size (k),") to:saveFile format ("Prop Size (k),") to:saveFile format ("Interior Size (k),") to:saveFile format ("Volume (m2)" + ",") to:saveFile format ("Polys/m2" + ",") to:saveFile format ("Coll Polys/m2" + ",") to:saveFile format ("Memory/m2" + "\n") to:saveFile totalObjectCount = 0 totalTXDCount = 0 totalPolyCount = 0 totalCollPolyCount = 0 totalModelSize = 0 totalTXDSize = 0 totalVolume = 0 totalLodSize = 0 totalXrefSize = 0 totalPropSize = 0 totalInteriorSize = 0 for i = 1 to BlockNames.count do ( if BlockAreas[i] != -1.0 then ( totalObjectCount = totalObjectCount + SelectionSets[i].count totalTXDCount = totalTXDCount + blockTotalTXDCount[i] totalPolyCount = totalPolyCount + blockTotalPolys[i] totalCollPolyCount = totalCollPolyCount + blockTotalCollPolys[i] totalModelSize = totalModelSize + blockTotalModelSize[i] totalTXDSize = totalTXDSize + blockTotalTXDSize[i] totalVolume = totalVolume + BlockAreas[i] totalLodSize = totalLodSize + blockTotalLodSize[i] totalXrefSize = totalXrefSize + blockTotalXrefSize[i] totalPropSize = totalPropSize + blockTotalPropSize[i] totalInteriorSize = totalInteriorSize + blockTotalInteriorSize[i] ) format (BlockNames[i] + ",") to:saveFile format ((SelectionSets[i].count as string) + ",") to:saveFile format ((blockTotalTXDCount[i] as string) + ",") to:saveFile format ((blockTotalPolys[i] as string) + ",") to:saveFile format ((blockTotalCollPolys[i] as string) + ",") to:saveFile format ((blockTotalModelSize[i] as string) + ",") to:saveFile format ((blockTotalTXDSize[i] as string) + ",") to:saveFile format (((blockTotalTXDSize[i] + blockTotalModelSize[i]) as string) + ",") to:saveFile format ((blockTotalLodSize[i] as string) + ",") to:saveFile format ((blockTotalXrefSize[i] as string) + ",") to:saveFile format ((blockTotalPropSize[i] as string) + ",") to:saveFile format ((blockTotalInteriorSize[i] as string) + ",") to:saveFile format ((BlockAreas[i] as string) + ",") to:saveFile if BlockAreas[i] != -1.0 then ( format ((((float)blockTotalPolys[i] / BlockAreas[i]) as string) + ",") to:saveFile format ((((float)blockTotalCollPolys[i] / BlockAreas[i]) as string) + ",") to:saveFile format ((((float)(blockTotalTXDSize[i] + blockTotalModelSize[i]) / BlockAreas[i]) as string) + "\n") to:saveFile ) else ( format ("0,0,0\n") to:saveFile ) ) format ("TOTAL (without unasssigned),") to:saveFile format ((totalObjectCount as string) + ",") to:saveFile format ((totalTXDCount as string) + ",") to:saveFile format ((totalPolyCount as string) + ",") to:saveFile format ((totalCollPolyCount as string) + ",") to:saveFile format ((totalModelSize as string) + ",") to:saveFile format ((totalTXDSize as string) + ",") to:saveFile format (((totalModelSize + totalTXDSize) as string) + ",") to:saveFile format ((totalLodSize as string) + ",") to:saveFile format ((totalXrefSize as string) + ",") to:saveFile format ((totalPropSize as string) + ",") to:saveFile format ((totalInteriorSize as string) + ",") to:saveFile format ((totalVolume as string) + ",") to:saveFile format ((((float)totalPolyCount / totalVolume) as string) + ",") to:saveFile format ((((float)totalCollPolyCount / totalVolume) as string) + ",") to:saveFile format ((((float)(totalModelSize + totalTXDSize) / totalVolume) as string) + "\n") to:saveFile close saveFile mapName = (filterstring maxfilename ".")[1] RsCopyFilename = RsConfigInfos[RsCurrentConfig].genstreamdir + "mapstats_details/" + mapName + ".csv" RsMakeSurePathExists RsCopyFilename copyfile saveFilename RsCopyFilename RsTotalFilename = RsConfigInfos[RsCurrentConfig].genstreamdir + "mapstats/" + mapName + ".csv" saveFile = openfile RsTotalFilename mode:"w" if saveFile != undefined then ( format ("Name" + ",") to:saveFile format ("Object Count" + ",") to:saveFile format ("TXD Count" + ",") to:saveFile format ("Total Poly Count" + ",") to:saveFile format ("Total Collision Poly Count" + ",") to:saveFile format ("Total Model Size (k)" + ",") to:saveFile format ("Total TXD Size (k)" + ",") to:saveFile format ("Total (k)" + ",") to:saveFile format ("Lod Size (k),") to:saveFile format ("Xref Size (k),") to:saveFile format ("Prop Size (k),") to:saveFile format ("Interior Size (k),") to:saveFile format ("Volume (m2)" + ",") to:saveFile format ("Polys/m2" + ",") to:saveFile format ("Coll Polys/m2" + ",") to:saveFile format ("Memory/m2" + "\n") to:saveFile for i = 1 to BlockNames.count do ( format (BlockNames[i] + ",") to:saveFile format ((SelectionSets[i].count as string) + ",") to:saveFile format ((blockTotalTXDCount[i] as string) + ",") to:saveFile format ((blockTotalPolys[i] as string) + ",") to:saveFile format ((blockTotalCollPolys[i] as string) + ",") to:saveFile format ((blockTotalModelSize[i] as string) + ",") to:saveFile format ((blockTotalTXDSize[i] as string) + ",") to:saveFile format (((blockTotalTXDSize[i] + blockTotalModelSize[i]) as string) + ",") to:saveFile format ((blockTotalLodSize[i] as string) + ",") to:saveFile format ((blockTotalXrefSize[i] as string) + ",") to:saveFile format ((blockTotalPropSize[i] as string) + ",") to:saveFile format ((blockTotalInteriorSize[i] as string) + ",") to:saveFile format ((BlockAreas[i] as string) + ",") to:saveFile if BlockAreas[i] != -1.0 then ( format ((((float)blockTotalPolys[i] / BlockAreas[i]) as string) + ",") to:saveFile format ((((float)blockTotalCollPolys[i] / BlockAreas[i]) as string) + ",") to:saveFile format ((((float)(blockTotalTXDSize[i] + blockTotalModelSize[i]) / BlockAreas[i]) as string) + "\n") to:saveFile ) else ( format ("0,0,0\n") to:saveFile ) ) close saveFile ) RsTotalFilename = RsConfigInfos[RsCurrentConfig].genstreamdir + "mapstats/blockmap/" + mapName + ".csv" RsMakeSurePathExists RsTotalFilename saveFile = openfile RsTotalFilename mode:"w" if saveFile != undefined then ( format ("VER2\n") to:saveFile for i = 1 to BlockNames.count do ( if BlockNames[i] == "unassigned" then continue format (BlockNames[i] + ",") to:saveFile format ((BlockObjects[i].count as string) + ",") to:saveFile for blockObj in BlockObjects[i] do ( format ((blockObj.pos.x as string) + ",") to:saveFile format ((blockObj.pos.y as string) + ",") to:saveFile format (((blockObj.rotation as eulerangles).z as string) + ",") to:saveFile format ((blockObj.plane.length as string) + ",") to:saveFile format ((blockObj.plane.width as string) + ",") to:saveFile ) format ((SelectionSets[i].count as string) + ",") to:saveFile format ((blockTotalTXDCount[i] as string) + ",") to:saveFile format ((blockTotalPolys[i] as string) + ",") to:saveFile format ((blockTotalCollPolys[i] as string) + ",") to:saveFile format ((blockTotalModelSize[i] as string) + ",") to:saveFile format ((blockTotalTXDSize[i] as string) + ",") to:saveFile format (((blockTotalTXDSize[i] + blockTotalModelSize[i]) as string) + ",") to:saveFile format ((blockTotalLodSize[i] as string) + ",") to:saveFile format ((blockTotalXrefSize[i] as string) + ",") to:saveFile format ((blockTotalPropSize[i] as string) + ",") to:saveFile format ((blockTotalInteriorSize[i] as string) + ",") to:saveFile format ((BlockAreas[i] as string) + ",") to:saveFile if BlockAreas[i] != -1.0 then ( format ((((float)blockTotalPolys[i] / BlockAreas[i]) as string) + ",") to:saveFile format ((((float)blockTotalCollPolys[i] / BlockAreas[i]) as string) + ",") to:saveFile format ((((float)(blockTotalTXDSize[i] + blockTotalModelSize[i]) / BlockAreas[i]) as string) + "\n") to:saveFile ) else ( format ("0,0,0\n") to:saveFile ) ) close saveFile ) UpdateSelectedObjects() ) on cmdSaveCurrent pressed do ( saveFilename = getsavefilename caption:"Save report to:" filename:"out.csv" types:"Comma Seperated (*.csv)|*.csv" if saveFilename == undefined then return 0 saveFile = openfile saveFilename mode:"wb" if saveFile == undefined then return 0 format ("Name" + ",") to:saveFile format ("Textures" + ",") to:saveFile format ("Polys" + ",") to:saveFile format ("Collision Polys" + ",") to:saveFile format ("LOD Distance" + ",") to:saveFile format ("Size (k)" + ",") to:saveFile format ("TXD" + ",") to:saveFile format ("TXD Size (k)" + ",") to:saveFile format ("TXD Textures" + ",") to:saveFile format ("Volume" + ",") to:saveFile format ("Poly Density" + ",") to:saveFile format ("Mem Density" + "\n") to:saveFile for i = 0 to (axObjectList.Items.Count - 1) do ( -- format (axObjectList.Items.Item[i].Text + ",") to:saveFile for j = 0 to 10 do ( format (axObjectList.Items.Item[i].SubItems.Item[j].Text + ",") to:saveFile ) format (axObjectList.Items.Item[i].SubItems.Item[11].Text + "\n") to:saveFile ) close saveFile ) on cmdUpdate pressed do ( UpdateSelectedObjects() ) on axTextureList ItemSelectionChanged args do ( if (axTextureList.SelectedItems.Count == 0) then ( return 0 ) img = bitmap 200 200 rm = rendermap RsTexInfoList[args.ItemIndex + 1].texmap into:img size:[200,200] bmpTex.bitmap = img close rm ) on axObjectList DoubleClick do ( objFound = getnodebyname axObjectList.SelectedItems.Item[0].Text exact:true if objfound != undefined do ( select objfound max zoomext sel ) ) on cmdEdit pressed do ( shelllaunch (getDir #maxroot + "Photoshp.exe.lnk") RsTexInfoList[axTextureList.SelectedItems.Item[0].Index + 1].texmap.filename ) fn RecSelectByName name rootobj outList = ( if rootobj != rootnode and getattrclass rootobj == "Gta Object" then ( objName = RsLowercase(rootobj.name) if classof rootobj == XRefObject then ( objName = RsLowercase(rootobj.objectname) ) if objName == name then ( append outList rootobj ) ) for childobj in rootobj.children do ( RecSelectByName name childobj outList ) ) on cmdSelectObj pressed do ( if axObjectList.SelectedItems.Count < 1 then return false objName = RsLowercase(axObjectList.SelectedItems.Item[0].Text) if objName[1] == "{" then ( objName = substring objName 2 (objName.count - 2) ) objList = #() print objName RecSelectByName objName rootnode objList select objList ) on cmdSelect pressed do ( subobjectlevel = 0 if axTextureList.SelectedItems.Count < 1 then ( return 0 ) idxFound = (axTextureList.SelectedItems.Item[0].Index + 1) if RsTexInfoList[idxFound].objects.count == 1 then ( objFound = RsTexInfoList[idxFound].objects[1] select objfound max zoomext sel if idxFound != 0 and idxObject != 0 then ( faceSel = #{} faceSel.count = objFound.numfaces for item in RsTexInfoList[idxFound].objectfaces[1] do ( faceSel[item] = true ) if classof objFound == Editable_Mesh then ( setFaceSelection objFound faceSel ) else ( polyOp.setFaceSelection objFound faceSel ) setCommandPanelTaskMode(#modify) subobjectlevel = 4 ) ) else ( selObjs = #() for i = 1 to RsTexInfoList[idxFound].objects.count do ( objFound = RsTexInfoList[idxFound].objects[i] append selObjs objFound if idxFound != 0 and idxObject != 0 then ( faceSel = #{} faceSel.count = objFound.numfaces for item in RsTexInfoList[idxFound].objectfaces[1] do ( faceSel[item] = true ) if classof objFound == Editable_Mesh then ( setFaceSelection objFound faceSel ) else ( polyOp.setFaceSelection objFound faceSel ) ) ) select selObjs max zoomext sel messagebox "multiple objects selected" ) ) on axObjectList MouseUp Button Shift x y do ( print("axObjectList MouseUp") UpdateSelectedTextures() ) on cmdOK pressed do ( DestroyDialog RsSceneStatsRoll ) on RsSceneStatsRoll open do ( LoadIDEFilenames() --showevents axObjectList --showproperties axObjectList axObjectList.FullRowSelect = true axObjectList.Columns.add "Name" 120 axObjectList.Columns.add "Textures" 56 axObjectList.Columns.add "Poly" 56 axObjectList.Columns.add "Coll Polys" 60 axObjectList.Columns.add "LOD Distance" 60 axObjectList.Columns.add "Size (k)" 60 axObjectList.Columns.add "TXD" 60 axObjectList.Columns.add "TXD Size (k)" 80 axObjectList.Columns.add "TXD Textures" 80 axObjectList.Columns.add "Volume" 76 axObjectList.Columns.add "Poly Density" 76 axObjectList.Columns.add "Mem Density" 76 axObjectList.Columns.add "TXD Percent" 76 axObjectList.Columns.add "Instances" 80 axObjectList.Columns.add "Total Size (k)" axObjectList.View = (dotNetClass "System.Windows.Forms.View").Details axTextureList.Columns.add "Name" 160 axTextureList.Columns.add "Polys" 60 axTextureList.Columns.add "Width" 60 axTextureList.Columns.add "Height" 60 axTextureList.Columns.add "Size (k)" 60 axTextureList.Columns.add "Material ID" 80 axTextureList.View = (dotNetClass "System.Windows.Forms.View").Details ) on RsSceneStatsRoll close do ( RsObjList = #() RsTexInfoList = #() ) /* Disabled this as this is extremely anoying when you resize and loose all the stats. on RsSceneStatsRoll resized pntSize do ( currPos = GetDialogPos RsSceneStatsRoll RsSettingWrite "rsstatsroll" "width" (pntSize[1]) RsSettingWrite "rsstatsroll" "height" (pntSize[2]) DestroyDialog RsSceneStatsRoll CreateDialog RsSceneStatsRoll pos:currPos modal:false width:pntSize[1] height:pntSize[2] style:#(#style_resizing, #style_titlebar, #style_border, #style_sysmenu ) RefreshSelectedObjects() RefreshSelectedTextures() ) */ ) CreateDialog RsSceneStatsRoll modal:false width:1100 height:(RsSettingsReadInteger "rsstatsroll" "height" 500) style:#( #style_titlebar, #style_border, #style_sysmenu )