------------------------------------------------------------------------------------ -- -- File:: RsSceneAnalyser.ms -- Description:: Scene Analysis Tool - gets memory dump and displays info on the loaded entities (mostly texture info so far) -- -- Author:: Martin Good -- Date:: 09/04/2014 -- ------------------------------------------------------------------------------------ filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms") filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_RSTA_XML.ms") fileIn "pipeline/util/RAG_funcs.ms" filein "pipeline/util/assert.ms" global RsSceneAnalyserPos = [580,75] -- floater height and default position global RsSceneAnalyser global TextureAnalyser try (RsSceneAnalyserPos = GetDialogPos RsSceneAnalyser ; DestroyDialog RsSceneAnalyser) catch() try (DestroyDialog RsTexPreview) catch() ---- ADDITIONAL PREVIEW DIALOG WINDOWS --- rollout RsTexPreview "Texture Preview" ( local TABitmapSize = 200 bitmap TexThumb width:TABitmapSize height:TABitmapSize offset:[-2,-2] pos:[0,0] editText TexName "" width:((TABitmapSize-46) * 0.65) height:22 pos:[-4,TABitmapSize] readonly:true -- old width (TABitmapSize+8)*0.65 editText TexDims "" width:((TABitmapSize-46) * 0.35) height:22 pos:[((TABitmapSize-58) * 0.65),TABitmapSize] readonly:true button SourceSwitch "GAME" width:52 height:21 pos:[(TABitmapSize - 54), (TABitmapSize+1)] fn UpdatePreview = ( local bmDimensions = (filterstring TexDims.text "x") local bmw= try(bmDimensions[1] as float) catch(undefined) local bmh = try(bmDimensions[2] as float) catch(undefined) if ((bmw != undefined) and (bmh != undefined)) then ( local aspectRatio = bmw / bmh if (aspectRatio <= 1.0) then ( -- height is largest scaleRatio = aMin #((TexThumb.height / bmh), 1.0) ) else ( -- width largest (or equal) scaleRatio = aMin #((TexThumb.width / bmw), 1.0) ) wScaled = (bmw * scaleRatio) as integer ; hScaled = (bmh * scaleRatio) as integer --format "Image :(% x %) Aspect:(%) Dialog (% x %) Scale: % = (% x %)\n" bmw bmh aspectRatio TexThumb.width TexThumb.height scaleRatio wScaled hScaled --!!! DEBUG ) else ( wScaled = TexThumb.width ; hScaled = TexThumb.height ) local img = bitmap wScaled hScaled local rm local tm --case RsSceneAnalyser.TABitmapPath of if (RsSceneAnalyser.Tex.rollouts[1].TextureDump.selection > 0) then ( case RsSceneAnalyser.Tex.rollouts[1].FilteredTextureList[RsSceneAnalyser.Tex.rollouts[1].TextureDump.selection].sourceImage of ( "NO SOURCE IMAGE":(rm = bitmap wScaled hScaled color:[255,0,0] )--; format "NO_BMP\n") "MISSING TCS":(rm = bitmap wScaled hScaled color:[64,0,0] )--; format "BAD_TCS") default: ( try (tm = bitMapTexture bitmap:(openBitmap RsSceneAnalyser.Tex.rollouts[1].FilteredTextureList[RsSceneAnalyser.Tex.rollouts[1].TextureDump.selection].sourceImage) ; rm = renderMap tm into:img size:[wScaled,hScaled]) catch (rm = bitmap wScaled hScaled color:[255,0,0]) ) ) ) else ( rm = bitmap wScaled hScaled color:[255,0,0] ) TexThumb.bitmap = rm free img ; free tm ; free rm ) on SourceSwitch pressed do ( --SourceSwitch.text = (if SourceSwitch.text == "GAME" then "ASSET" else "GAME") SourceSwitch.text = case SourceSwitch.text of ( "GAME":("ASSET") "ASSET":("GAME") ) if (TextureAnalyser.TextureDump.selection > 0) then ( TexDims.text = case SourceSwitch.text of ( "GAME":(TextureAnalyser.FilteredTextureList[TextureAnalyser.TextureDump.selection].dims) "ASSET":(TextureAnalyser.FilteredTextureList[TextureAnalyser.TextureDump.selection].sourceRes) ) UpdatePreview() ) ) on RsTexPreview resized newSize do ( if (RsTexPreview.height < 182) then (RsTexPreview.height = 182) RsSceneAnalyser.TABitmapSize = RsTexPreview.height RsTexPreview.width = RsTexPreview.height - 22 TexThumb.width = TexThumb.height = RsTexPreview.width TexName.width = (TexThumb.width - 54) * 0.65 ; TexDims.width = (TexThumb.width - 54) * 0.35 TexName.pos = [0,TexThumb.height] TexDims.pos = [TexName.width,TexThumb.height] SourceSwitch.pos = [(TexThumb.width - 54),TexThumb.height+1] UpdatePreview() ) on RsTexPreview close do ( TextureAnalyser.ShowTexPreviewSurround.enabled = false TextureAnalyser.ShowTexPreview.enabled = true ) ) ---- TEXTURE ANALYSIS SUBROLLOUT ---- rollout TextureAnalyser "Texture Analysis" height:26 rolledUp:true ( local TArows = 26 local JAWidth = 620 local TACountWidth = 42 local TANameWidth = JAWidth - 254 - TACountWidth local TASizeWidth = 76 local SurroundColour = [40,0,0] local TAFormatWidth = 133 local TAPreviewDefaultSize = 128 local FilteredTextureList = #() progressbar DIFFSurround "" color:SurroundColour value:100 width:44 height:26 align:#left offset:[36,-2] enabled:true progressbar NORMSurround "" color:SurroundColour value:100 width:44 height:26 align:#left offset:[82,-31] enabled:true progressbar SPECSurround "" color:SurroundColour value:100 width:44 height:26 align:#left offset:[128,-31] enabled:true progressbar MISCSurround "" color:SurroundColour value:100 width:44 height:26 align:#left offset:[174,-31] enabled:true progressbar PlusHDSurround "" color:SurroundColour value:100 width:38 height:26 align:#right offset:[-108,-31] enabled:true progressbar MinusHDSurround "" color:SurroundColour value:100 width:38 height:26 align:#right offset:[-70,-31] enabled:true progressbar PlusNHSurround "" color:SurroundColour value:100 width:38 height:26 align:#right offset:[-28,-31] enabled:true progressbar MinusNHSurround "" color:SurroundColour value:100 width:38 height:26 align:#right offset:[10,-31] enabled:true spinner CountMin "" type:#integer range:[1,999,1] width:40 height:18 align:#left offset:[-10,-27] button DiffFilter "DIFF" width:36 height:18 align:#left offset:[40, -23] enabled:true -- -27 button NormFilter "NORM" width:36 height:18 align:#left offset:[86, -23] enabled:true button SpecFilter "SPEC" width:36 height:18 align:#left offset:[132, -23] enabled:true button MiscFilter "MISC" width:36 height:18 align:#left offset:[178, -23] enabled:true button PlusHD "+ HD" width:29 height:18 align:#right offset:[-112, -23] enabled:true button MinusHD "- HD" width:29 height:18 align:#right offset:[-74, -23] enabled:true button PlusNH "+ NH" width:29 height:18 align:#right offset:[-32, -23] enabled:true button MinusNH "- NH" width:29 height:18 align:#right offset:[6, -23] enabled:true progressbar TexCountSurround "" color:SurroundColour value:100 width:TACountWidth height:29 align:#left offset:[-9,2] enabled:false progressbar TexNameSurround "" color:SurroundColour value:100 width:TANameWidth height:29 align:#left offset:[(TACountWidth-9),-34] enabled:true progressbar TexSizeSurround "" color:SurroundColour value:100 width:(TASizeWidth-22) height:29 align:#right offset:[-169,-34] enabled:false progressbar TexTemplateSurround "" color:SurroundColour value:100 width:(TAFormatWidth-22) height:29 align:#right offset:[-35,-34] enabled:false button SortByTexCount "Count" width:(TACountWidth-7) offset:[-5, -30] align:#left enabled:true button SortByTexName "Texture Name" width:(TANameWidth-7) offset:[(TACountWidth-5), -26] align:#left enabled:true button SortByTexSize "Size" width:(TASizeWidth-29) align:#right offset:[-172, -26] enabled:true button SwitchTexSize "R" width:20 height:28 align:#right offset:[-149, -30] enabled:true tooltip:"Size,\nResolution,\nTotal Size" button SortByTexTemplate "Template" width:(TAFormatWidth-29) align:#right offset:[-38, -29] enabled:true button SwitchTexTemplate "F" width:20 height:28 align:#right offset:[-15,-30] enabled:true tooltip:"Template,\nFormat" button TexByteSize "KB" width:20 height:29 align:#right offset:[9,-34] enabled:true listbox TextureDump "" items:#() width:(TextureAnalyser.width-7) height:TArows offset:[-9,0] edittext SelectedTexSource "" width:((JAwidth*0.65)-2) height:16 align:#left offset:[-12,-4] enabled:true readonly:false edittext SelectedTexTemplate "" width:(JAwidth*0.48) height:16 align:#left offset:[-12,-2] enabled:true readonly:false edittext SelectedTexSourceRes "" width:(JAwidth*0.17) height:16 align:#left offset:[((JAwidth*0.48)-14),-21] enabled:true readonly:false checkbox UseTexNameFilter "" align:#left checked:true offset:[-9,-2] editText TexNameFilter "Filter" align:#left width:(JAWidth-(JAwidth*0.31)-55) height:16 offset:[16,-20] progressbar ShowTexPreviewSurround "" color:SurroundColour value:100 width:(JAwidth*0.32) height:56 align:#right offset:[9,-59] enabled:false button ShowTexPreview "TEXTURE PREVIEW" width:((JAwidth*0.32)-9) height:46 align:#right offset:[5,-56] enabled:true button TABottom "" height:1 enabled:false visible:false offset:[0,-7] ---- ANALYSER FUNCTIONS ---- fn CompareTextures tex1 tex2 = ( -- Compare Texture Stat values - used in qsort local diff = 0 case of ( (TexCountSurround.enabled):( diff = tex1.dupes.numberSet - tex2.dupes.numberSet ) (TexNameSurround.enabled):( diff = stricmp tex2.name tex1.name ) (TexSizeSurround.enabled): ( case SortByTexSize.text of ( "Res.": ( local tex1sizes = filterstring tex1.dims "x" local tex2sizes = filterstring tex2.dims "x" diff = (try( ((tex1sizes[1] as float) + (tex1sizes[2] as float)) - ((tex2sizes[1] as float) + (tex2sizes[2] as float)) ) catch(0.0)) ) "Size": ( diff = tex1.size - tex2.size ) "Total": ( diff = tex1.sizeTotal - tex2.sizeTotal ) ) ) (TexTemplateSurround.enabled): ( if SortByTexTemplate.text == "Template" then ( diff = stricmp tex2.template tex1.template ) else ( diff = stricmp tex2.form tex1.form ) ) ) case of ( (diff < 0.0): 1 (diff > 0.0): -1 default: 0 ) ) fn kbToString Val = ( if (TexByteSize.text == "KB") then (Val as string + TexByteSize.text) else ( (formattedPrint (Val / 1024.0) format:RsSceneAnalyser.FPPrecision) + TexByteSize.text ) ) fn ClearTextureSelection = ( if (classOf TextureDump) == ListBoxControl then (TextureDump.selection = 0) else (TextureDump.selection = #()) --SelectedObject.text = "" ; SelectedObjectCount.text = "" --SelectedMainTotal.text = "" ; SelectedVRAMTotal.text = "" --SelectedObjectCount.enabled = SelectedStoreTotal.enabled = SelectedMainTotal.enabled = SelectedVRAMTotal.enabled = false ) fn ClearTextureList = ( ClearTextureSelection() TextureDump.items = #() SelectedTexSource.text = SelectedTexSourceRes.text = SelectedTexTemplate.text = "" --try (DestroyDialog RsTexPreview) catch() --RsSceneAnalyser.ShowTexPreviewSurround.enabled = false --RsSceneAnalyser.ShowTexPreview.enabled = true ) fn DumpTextureList = ( -- build (filtered) texture lists (using string in TexNameFilter.text) and drop into TextureDump.items local dumpItems = #() local NameSizeCheck = SortByTexSize.pos[1] - SortByTexName.pos[1] - 24 local NamesCheck = filterstring TexNameFilter.text " " local FilteredTextures = 0 local FilteredSize = 0 local ExprText = "" FilteredTextureList = #() local NameMatch = true local ExclusionTest = false for tex in RsSceneAnalyser.TextureList do ( -- Need to double check entry against filters... NameMatch = true if UseTexNameFilter.state then ( for expr in NamesCheck do ( if (expr[1]) == "-" then ( -- Exclusive Test ExclusionTest = true ; ExprText = (trimleft expr "-") ) else ( -- Inclusive Test ExclusionTest = false ; ExprText = expr ) if (matchPattern tex.name pattern:("*"+ExprText+"*") ignorecase:true) then ExprMatch = true else ExprMatch = false if ExclusionTest then (ExprMatch = not ExprMatch) NameMatch = NameMatch and ExprMatch ) ) if NameMatch then ( local filtered = false case SortByTexName.text of ( "Texture Name": ( -- Selection is a texture case tex.type of ( "Diff":( if DIFFSurround.enabled then filtered = true ) "Norm":( if NORMSurround.enabled then filtered = true ) "Spec":( if SPECSurround.enabled then filtered = true ) default:( if MISCSurround.enabled then filtered = true ) ) ) default: ( -- Selection is a dictionary -- DIFF = BASE, NORM = +HI / SPEC = TXD, MISC = DRAW case tex.type of ( "ITD":(if SPECSurround.enabled then filtered = true) "IDR":(if MISCSurround.enabled then filtered = true) default:(filtered = true) ) if (matchpattern tex.name pattern:"*+*") then (filtered = (filtered and NORMSurround.enabled)) else (filtered = (filtered and DIFFSurround.enabled)) ) ) if filtered then ( -- Check _HD_Split is in template, and filter accordingly if (tex.template.count >= 8) then ( if (substring (toLower tex.template) (tex.template.count - 7) 8) == "hd_split" then (filtered = PlusHDSurround.enabled) else (filtered = MinusHDSurround.enabled) ) else (filtered = MinusHDSurround.enabled) ) if filtered then ( -- Check if Not_Half is set in the template and filter accordingly if ((findString (toLower tex.template) "not_half") == undefined) then (filtered = MinusNHSurround.enabled) else (filtered = PlusNHSurround.enabled) ) if filtered then ( if tex.dupes.numberset < CountMin.value then (filtered = false) ) if filtered then ( local dumpString = stringstream "" local nameString = stringstream "" local inLimit = true local CountVal = "" local SizeVal = "" local FormVal = "" for char = 1 to tex.name.count while inLimit do ( if ((GetTextExtent nameString)[1] < NameSizeCheck) then (format "%" tex.name[char] to:nameString) else (inLimit = false ; format "..." to:nameString) ) CountVal = tex.dupes.numberSet as string format "%" CountVal to:dumpString -- Pad between COUNT and NAME padLength = ((TexNameSurround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) as integer if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" (nameString as string) to:dumpString ; free nameString --SizeVal = kbToString tex.size SizeText = case SortByTexSize.text of ( "Size":( kbToString tex.size ) "Total":( kbToString tex.sizeTotal ) default:( tex.dims ) -- "Res." only other option so far ) case SortByTexTemplate.text of ( "Format":(TemplateText = tex.form) "Template": ( nameString = stringstream "" inLimit = true --tex.template for char = 1 to tex.template.count while inLimit do ( if ((GetTextExtent nameString)[1] < TAFormatWidth) then (format "%" tex.template[char] to:nameString) else (inLimit = false ; format "..." to:nameString) ) TemplateText = (nameString as string) ; free nameString ) default:(TemplateText = tex.type) -- "Type" only other option so far ) local SizePad = (TASizeWidth - ((GetTextExtent SizeText)[1]))/6 local TemplatePad = (TAFormatWidth - ((GetTextExtent TemplateText)[1]))/6 -- Pad between NAME and SIZE padLength = (((TexSizeSurround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) + SizePad) as integer if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" SizeText to:dumpString -- Pad between DIMS and FORMAT padlength = (((TexTemplateSurround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) + TemplatePad) as integer if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" TemplateText to:dumpString append dumpItems (dumpString as string) free dumpString FilteredTextures += 1 FilteredSize += tex.size free SizeVal append FilteredTextureList tex ) ) ) TextureDump.items = dumpItems ) fn ChangeButtonSet type = ( case type of ( "TEX": ( DiffFilter.text = "DIFF" NormFilter.text = "NORM" SpecFilter.text = "SPEC" MiscFilter.text = "MISC" SortByTexTemplate.text = "Template" SortByTexName.text = "Texture Name" ) "DICT": ( DiffFilter.text = "BASE" NormFilter.text = "+HI" SpecFilter.text = "TXD" MiscFilter.text = "DRAW" SortByTexTemplate.text = "Type" SortByTexName.text = "Dictionary Name" ) ) ) ---- TEXTURE ANALYSER EVENTS ---- -- FILTER TOGGLE EVENTS on UseTexNameFilter changed Arg do (TexNameFilter.enabled = Arg ; ClearTextureSelection() ; DumpTextureList()) on TexNameFilter entered ArgIgnore do (ClearTextureSelection() ; DumpTextureList()) on CountMin changed ArgIgnore do ( ClearTextureSelection() ; DumpTextureList() ) on DIFFFilter pressed do ( DIFFSurround.enabled = true ; DIFFFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on NORMFilter pressed do ( NORMSurround.enabled = true ; NORMFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on SPECFilter pressed do ( SPECSurround.enabled = true ; SPECFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on MISCFilter pressed do ( MISCSurround.enabled = true ; MISCFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on DIFFSurround clicked ArgIgnore do ( DIFFSurround.enabled = false ; DIFFFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on NORMSurround clicked ArgIgnore do ( NORMSurround.enabled = false ; NORMFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on SPECSurround clicked ArgIgnore do ( SPECSurround.enabled = false ; SPECFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on MISCSurround clicked ArgIgnore do ( MISCSurround.enabled = false ; MISCFilter.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on PlusHD pressed do (PlusHDSurround.enabled = true ; PlusHD.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on MinusHD pressed do (MinusHDSurround.enabled = true ; MinusHD.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on PlusHDSurround clicked ArgIgnore do ( PlusHDSurround.enabled = false ; PlusHD.enabled = true MinusHDSurround.enabled = true ; MinusHD.enabled = true ClearTextureSelection() ; DumpTextureList() ) on MinusHDSurround clicked ArgIgnore do ( MinusHDSurround.enabled = false ; MinusHD.enabled = true PlusHDSurround.enabled = true ; PlusHD.enabled = true ClearTextureSelection() ; DumpTextureList() ) on PlusNH pressed do (PlusNHSurround.enabled = true ; PlusNH.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on MinusNH pressed do (MinusNHSurround.enabled = true ; MinusNH.enabled = true ; ClearTextureSelection() ; DumpTextureList() ) on PlusNHSurround clicked ArgIgnore do ( PlusNHSurround.enabled = false ; PlusNH.enabled = true MinusNHSurround.enabled = true ; MinusNH.enabled = true ClearTextureSelection() ; DumpTextureList() ) on MinusNHSurround clicked ArgIgnore do ( MinusNHSurround.enabled = false ; MinusNH.enabled = true PlusNHSurround.enabled = true ; PlusNH.enabled = true ClearTextureSelection() ; DumpTextureList() ) on DIFFFilter rightclick do ( NORMSurround.enabled = SPECSurround.enabled = MISCSurround.enabled = false ; DIFFSurround.enabled = true DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on NORMFilter rightclick do ( DIFFSurround.enabled = SPECSurround.enabled = MISCSurround.enabled = false ; NORMSurround.enabled = true DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on SPECFilter rightclick do ( DIFFSurround.enabled = NORMSurround.enabled = MISCSurround.enabled = false ; SPECSurround.enabled = true DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on MISCFilter rightclick do ( DIFFSurround.enabled = NORMSurround.enabled = SPECSurround.enabled = false ; MISCSurround.enabled = true DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on DIFFSurround rightclick do ( NORMSurround.enabled = SPECSurround.enabled = MISCSurround.enabled = false DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on NORMSurround rightclick do ( DIFFSurround.enabled = SPECSurround.enabled = MISCSurround.enabled = false DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on SPECSurround rightclick do ( DIFFSurround.enabled = NORMSurround.enabled = MISCSurround.enabled = false DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on MISCSurround rightclick do ( DIFFSurround.enabled = NORMSurround.enabled = SPECSurround.enabled = false DIFFFilter.enabled = NORMFilter.enabled = SPECFilter.enabled = MISCFilter.enabled = true ClearTextureSelection() ; DumpTextureList() ) on SwitchTexSize pressed do ( case SwitchTexSize.text of ( "R":(SortByTexSize.text = "Res." ; SwitchTexSize.text ="S") "S":(SortByTexSize.text = "Size" ; SwitchTexSize.text ="T") "T":(SortByTexSize.text = "Total" ; SwitchTexSize.text ="R") ) SwitchTexSize.enabled = true DumpTextureList() ) on SwitchTexTemplate pressed do ( if SortByTexTemplate.text == "Template" then (SortByTexTemplate.text = "Format" ; SwitchTexTemplate.text ="T") else (SortByTexTemplate.text = "Template" ; SwitchTexTemplate.text ="F") SwitchTexTemplate.enabled = true DumpTextureList() ) on TexByteSize pressed do ( if TexByteSize.text == "KB" then (TexByteSize.text = "MB") else (TexByteSize.text = "KB") DumpTextureList() ) on SortByTexCount pressed do ( --if (classOf TextureDump) == ListBoxControl then (TextureDump.selection = 0) else (TextureDump.selection = #()) TexCountSurround.enabled = true TexNameSurround.enabled = TexSizeSurround.enabled = TexTemplateSurround.enabled = false --TexFormatSurround.enabled = SortByTexCount.enabled = SortByTexName.enabled = SortByTexSize.enabled = SortByTexTemplate.enabled = true --SwitchTexSize.enabled = SwitchTexTemplate.enabled = false qsort RsSceneAnalyser.TextureList CompareTextures ClearTextureSelection() ; DumpTextureList() ) on SortByTexName pressed do ( --if (classOf TextureDump) == ListBoxControl then (TextureDump.selection = 0) else (TextureDump.selection = #()) TexNameSurround.enabled = true TexCountSurround.enabled = TexSizeSurround.enabled = TexTemplateSurround.enabled = false --TexFormatSurround.enabled = SortByTexCount.enabled = SortByTexName.enabled = SortByTexSize.enabled = SortByTexTemplate.enabled = true --SwitchTexSize.enabled = SwitchTexTemplate.enabled = false qsort RsSceneAnalyser.TextureList CompareTextures ClearTextureSelection() ; DumpTextureList() ) on SortByTexSize pressed do ( --if (classOf TextureDump) == ListBoxControl then (TextureDump.selection = 0) else (TextureDump.selection = #()) TexSizeSurround.enabled = true TexNameSurround.enabled = TexCountSurround.enabled = TexTemplateSurround.enabled = false --= TexFormatSurround.enabled SortByTexCount.enabled = SortByTexName.enabled = SortByTexSize.enabled = SortByTexTemplate.enabled = true --SwitchTexSize.enabled = true ; SwitchTexTemplate.enabled = false qsort RsSceneAnalyser.TextureList CompareTextures ClearTextureSelection() ; DumpTextureList() ) on TexSizeSurround clicked ArgIgnore do ( qsort RsSceneAnalyser.TextureList CompareTextures ClearTextureSelection() ; DumpTextureList() ) on SortByTexTemplate pressed do ( --if (classOf TextureDump) == ListBoxControl then (TextureDump.selection = 0) else (TextureDump.selection = #()) TexTemplateSurround.enabled = true TexSizeSurround.enabled = TexCountSurround.enabled = TexNameSurround.enabled = false SortByTexCount.enabled = SortByTexName.enabled = SortByTexSize.enabled = SortByTexTemplate.enabled = true --SwitchTexSize.enabled = false ; SwitchTexTemplate.enabled = true qsort RsSceneAnalyser.TextureList CompareTextures ClearTextureSelection() ; DumpTextureList() ) on TexTemplateSurround clicked ArgIgnore do ( qsort RsSceneAnalyser.TextureList CompareTextures ClearTextureSelection() ; DumpTextureList() ) on TextureDump selected Arg do ( SelectedTexSource.text = FilteredTextureList[Arg].TCS --sourceImage SelectedTexSourceRes.text = FilteredTextureList[Arg].sourceRes SelectedTexTemplate.text = FilteredTextureList[Arg].template RsSceneAnalyser.SceneDump.selection = FilteredTextureList[TextureDump.selection].dupes RsSceneAnalyser.ListOnlySelected.enabled = true RsSceneAnalyser.ListOnlySelected.text = "Isolate" if RsTexPreview.open then ( RsTexPreview.TexName.text = FilteredTextureList[Arg].name RsTexPreview.TexDims.text = case RsTexPreview.SourceSwitch.text of ( "GAME":(FilteredTextureList[TextureDump.selection].dims) "ASSET":(FilteredTextureList[TextureDump.selection].sourceRes) ) RsTexPreview.UpdatePreview() ) /* if (RsSceneAnalyser.LookAtSurround.enabled) and (RsSceneAnalyser.SceneDump.selection.numberSet > 0) then ( RsSceneAnalyser.LookAtPoint RsSceneAnalyser.FilteredList[(RsSceneAnalyser.SceneDump.selection as array)[1]].attr.pos ) */ if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( if RsSceneAnalyser.TexViewerSurround.enabled then ( RemoteConnection.WriteStringWidget "Texture Viewer/Search Type" "Textures" RemoteConnection.WriteStringWidget "Texture Viewer/Search Filter" FilteredTextureList[Arg].name RemoteConnection.WriteBoolWidget "Texture Viewer/Visible" true RemoteConnection.WriteBoolWidget "Texture Viewer/Search" true RemoteConnection.WriteBoolWidget "Texture Viewer/Load Texture/Txd/Load All List Entries" true ) if RsSceneAnalyser.WireSurround.enabled then ( RemoteConnection.WriteBoolWidget "Renderer/Wireframe/Render Alpha" false RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredTextureList[Arg].name RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Shader Uses Texture ..." RemoteConnection.WriteBoolWidget "Renderer/Wireframe/Draw" true ) ) ) on TextureDump doubleclicked Arg do ( RemoteConnection.WriteBoolWidget "Texture Viewer/Load Texture/Txd/Load All List Entries" true ) on ShowTexPreview pressed do ( ShowTexPreviewSurround.enabled = true ; ShowTexPreview.enabled = true --RsSceneAnalyser.Tex.TextureAnalyser.open = true try ( DestroyDialog RsTexPreview ) catch() RsSceneAnalyser.TABitmapSize = 200 local RFPreviewPos = getDialogPos RsSceneAnalyser + RsSceneAnalyser.Tex.pos RFPreviewPos.x = aMax #(RFPreviewPos.x - (RsSceneAnalyser.TABitmapSize + 20), 20) CreateDialog RsTexPreview width:(RsSceneAnalyser.TABitmapSize) height:(RsSceneAnalyser.TABitmapSize + 22) lockWidth:true style:#(#style_titlebar, #style_border, #style_sysmenu,#style_toolwindow, #style_resizing) setDialogPos RsTexPreview RFPreviewPos if (TextureDump.selection > 0) then ( RsTexPreview.TexName.text = FilteredTextureList[TextureDump.selection].name RsTexPreview.TexDims.text = case RsTexPreview.SourceSwitch.text of ( "GAME":(FilteredTextureList[TextureDump.selection].dims) "ASSET":(FilteredTextureList[TextureDump.selection].sourceRes) ) ) else ( RsTexPreview.TexName.text = "Nothing Picked" RsTexPreview.TexDims.text = "N/A" ) RsTexPreview.UpdatePreview() ) on ShowTexPreviewSurround clicked ArgIgnore do ( ShowTexPreviewSurround.enabled = false ; ShowTexPreview.enabled = true --if (TextureDump.items.count == 0) then (RsSceneAnalyser.Tex.TextureAnalyser.open = false) try (DestroyDialog RsTexPreview) catch() ) on TextureAnalyser rolledUp Rolled do ( if Rolled then ( RsSceneAnalyser.Tex.height = (TABottom.pos.y + 42) /* RsSceneAnalyser.Tex.height = amax #((TABottom.pos.y + 42), (1022 - RsSceneAnalyser.Tex.pos.y)) TABottom.pos.y = RsSceneAnalyser.Tex.height - 42 SelectedTexSource.pos.y = TABottom.pos.y - 48 SelectedTexTemplate.pos.y = TABottom.pos.y - 30 SelectedTexSourceRes.pos.y = TABottom.pos.y - 30 UseTexNameFilter.pos.y = TABottom.pos.y - 10 TexNameFilter.pos.y = TABottom.pos.y - 12 ShowTexPreviewSurround.pos.y = TABottom.pos.y - 48 ShowTexPreview.pos.y = ShowTexPreviewSurround.pos.y + 5 RsSceneAnalyser.LoadTexturesSurround.enabled = true RsSceneAnalyser.LoadTextures.enabled = true */ ) else ( RsSceneAnalyser.Tex.height = 25 ShowTexPreviewSurround.enabled = false ; ShowTexPreview.enabled = true RsSceneAnalyser.LoadTexturesSurround.enabled = false RsSceneAnalyser.LoadTextures.enabled = true try (DestroyDialog RsTexPreview)catch() ) RsSceneAnalyser.height = aMin #((RsSceneAnalyser.Tex.pos.y + RsSceneAnalyser.Tex.height + 4), 1038) --TextureAnalyser.height = TABottom.pos.y + 14 ) ) ---- MAIN DIALOG ---- rollout RsSceneAnalyser "Scene Analyser" ( -- RAG integrated, memory-dump explorer dialog -- CONSTANTS -- local JAWidth = 620 --350 good test case... 500 looks ok to avoid problems (so far) local JAwidgets = 280 local JArowSize = 13 local JArows = 23 local JAHeight = JAwidgets+(JArowSize*JArows) local SurroundColour = [40,0,0] local ProgressFloat = 0 -- Arithmetic Type/Operator Fields local MathsNames = #(" Main memory", " VRAM", " Distance From Camera", " LOD Distance", " Poly count", " BBox XY Area", " BBox Volume", " HD Distance", " Texture Count" ) local MathsButtons = #("Main", "VRAM", "Distance", "LOD Dist", "Poly Count", "XY Area", "Volume", "HD Dist.", "Textures" ) local MathsOperators = #(" ", " +", " -", " *", " /") local FieldDefaults = #(1,2,4,5) local TABitmapSize = 200 local FPPrecision = "#.2f" local LODLevels = #("", "Orphan", "HD", "LOD", "SLOD1", "SLOD2", "SLOD3") local JATemp = "x:\SceneAnalysis\\" local MemoryDumpFileLocation = JATemp + "ModuleMemoryDump.txt" local TextureDumpFileLocation = JATemp + "TextureDump.csv" local JAAssetZipTemp = JATemp + "SAZipTemp\\" local JAEntityZipTemp = JAAssetZipTemp + "EntityTemp\\" local UnpackedAssets = #() -- P4 Integration local P4Assets = #() local P4Textures = #() -- !!!! DEBUG Flags for switching off shit local DEBUG_SPEW = false -- STRUCTS -- struct sceneEntity (name, store, main, vram, imap, imapPathArray, assetPath, depend, dependIndex, textureList, attr) struct texture (name, dupes, size, sizeTotal, dims, form, TCS, type, template, sourceImage, sourceRes, errorFlag) struct attributeList (loaded, guid, parent, children, LODLevel, LODDist, HDDist, pos, dist, polyCount, BBmin, BBmax, area, volume, mathsResult) struct IMAP (name, assetList) struct asset (name, index) -- ARRAYS -- local ObjectList = #() local FilteredList = #() local TextureList = #() local IMAPs = #() -- VARIABLES -- local FilteredCount = 0 local ActiveMain = 0 local ActiveVRAM = 0 local TotalMain = 0 local TotalVRAM = 0 dotNetControl rsBannerPanel "System.Windows.Forms.Panel" height:32 pos:[0,0] width:RsSceneAnalyser.width local banner = makeRsBanner dn_Panel:rsBannerPanel versionNum:1.0 versionName:"Scene Analyser" colourScheme:#eval filename:(getThisScriptFilename()) group "RAG Functions" ( progressbar WireSurround "" color:SurroundColour value:100 width:44 height:44 align:#right offset:[-50,-3] enabled:true button WireToggle "Wire" width:36 height:36 align:#right offset:[-54,-45] progressbar WireOpacity width:52 height:20 value:50 orient:#horizontal color:[60,60,60] align:#right offset:[3,-45] dropdownlist WireMode "" items:#("Name","TXD") selection:1 width:52 align:#right offset:[3,-4] dropdownlist LODLevel "" items:#("HD","LOD","SLOD1","SLOD2","SLOD3") width:72 align:#right offset:[-98,-48] dropdownlist LODFunction "" items:#("Draw All","Switch To","Cull Only", "Cull Other") width:72 align:#right offset:[-98,-5] progressbar OrphanSurround "" color:SurroundColour value:100 width:40 height:23 align:#right offset:[-264,-50] enabled:true button OrphanToggle "O.HD" width:32 height:14 align:#right offset:[-268,-24] progressbar HDSurround "" color:SurroundColour value:100 width:40 height:23 align:#right offset:[-264,0] enabled:true button HDToggle "L.HD" width:32 height:14 align:#right offset:[-268,-24] progressbar LODSurround "" color:SurroundColour value:100 width:46 height:23 align:#right offset:[-218,-46] enabled:true button LODToggle "LOD" width:38 height:14 align:#right offset:[-222,-24] progressbar SLOD1Surround "" color:SurroundColour value:100 width:46 height:23 align:#right offset:[-218,0] enabled:true button SLOD1Toggle "SLOD1" width:38 height:14 align:#right offset:[-222,-24] progressbar SLOD2Surround "" color:SurroundColour value:100 width:46 height:23 align:#right offset:[-172,-46] enabled:true button SLOD2Toggle "SLOD2" width:38 height:14 align:#right offset:[-176,-24] progressbar SLOD3Surround "" color:SurroundColour value:100 width:46 height:23 align:#right offset:[-172,0] enabled:true button SLOD3Toggle "SLOD3" width:38 height:14 align:#right offset:[-176,-24] progressbar MOHSurround "" color:SurroundColour value:100 width:84 height:44 align:#left offset:[-2,-45] enabled:false button MOHToggle "Map Opt" width:55 height:36 align:#left offset:[2,-45] button MOHIsolate "I" width:19 height:36 align:#left offset:[59,-41] progressbar TexViewerSurround "" color:SurroundColour value:100 width:44 height:44 align:#left offset:[86,-45] enabled:false button TexViewerToggle "TXDs" width:36 height:36 align:#left offset:[90,-45] progressbar IsoSurround "" color:SurroundColour value:100 width:50 height:44 align:#left offset:[134,-45] enabled:false button Isolation "Isolate" width:42 height:36 align:#left offset:[138,-45] progressbar OcclFlipSurround "" color:SurroundColour value:100 width:56 height:23 align:#left offset:[188,-46] enabled:false button OcclFlip "Flip Occl" width:48 height:14 align:#left offset:[192,-24] progressbar OcclOffSurround "" color:SurroundColour value:100 width:56 height:23 align:#left offset:[188,0] enabled:true button OcclOff "Occlusion" width:48 height:14 align:#left offset:[192,-24] progressbar LookAtSurround "" color:SurroundColour value:100 width:44 height:44 align:#left offset:[248,-45] button LookAtObj "Find" width:36 height:36 align:#left offset:[252,-45] editText WarpToNames "Warp To TXDs" align:#left width:(JAwidth-110) height:16 offset:[-2,4] button WarpToTXDs "WARP" align:#right width:96 height:16 offset:[3,-20] tooltip:"Warp to TXDs that match the text entered in the box to the left." button MakeRAGGroupBigger "" height:2 offset:[2,-6] visible:false -- Not used for anything other than making the group tidier ) group "Asset Loading" ( progressbar AnalyseSceneSurround "" color:SurroundColour value:100 width:((JAwidth*0.43)-16) height:45 align:#left offset:[-3,-2] enabled:false button AnalyseScene "ANALYSE CURRENT SCENE" height:35 align:#left width:((JAWidth*0.43)-26) offset:[2,-45] progressbar LoadTexturesSurround "" color:SurroundColour value:100 width:(JAwidth*0.15) height:45 align:#right offset:[((-JAwidth*0.27)-2),-45] enabled:false button LoadTextures "Load Textures" height:35 align:#right width:((JAWidth*0.15)-11) offset:[((-JAwidth*0.27)-7),-45] tooltip:"Load texture info from ZIP and game when item is picked." progressbar LoadXMLsSurround "" color:SurroundColour value:100 width:(JAwidth*0.15) height:45 align:#right offset:[((-JAwidth*0.42)-2),-45] enabled:false button LoadXMLs "Load XMLs" height:35 align:#right width:((JAWidth*0.15)-11) offset:[((-JAwidth*0.42)-7),-45] tooltip:"Load extra info from XML when item is picked.\nOff by default as XML loading is really slow." button SynchAssets "Synch Assets" width:(JAwidth*0.135) height:44 align:#right offset:[((-JAwidth*0.135)+1),-45] enabled:false tooltip:"Get latest scene asset XMLs and ZIPs." button SynchTextures "Synch Textures" width:(JAwidth*0.135) height:44 align:#right offset:[3,-49] enabled:true tooltip:"Get latest on loaded textures." ) -- Filters checkbox UseNameFilter "" align:#left checked:true offset:[-9,7] editText NameFilter "Filter" align:#left width:(JAwidth-210) height:16 offset:[16,-20] progressbar IDRSurround "" color:SurroundColour value:100 width:42 height:26 align:#right offset:[-128,-24] enabled:true progressbar IDDSurround "" color:SurroundColour value:100 width:42 height:26 align:#right offset:[-84,-31] enabled:true progressbar ITDSurround "" color:SurroundColour value:100 width:42 height:26 align:#right offset:[-40,-31] enabled:true progressbar OtherSurround "" color:SurroundColour value:100 width:47 height:26 align:#right offset:[10,-31] enabled:false button IDRFilter "IDR" width:34 height:18 align:#right offset:[-132, -27] enabled:true button IDDFilter "IDD" width:34 height:18 align:#right offset:[-88, -23] enabled:true button ITDFilter "ITD" width:34 height:18 align:#right offset:[-44, -23] enabled:true button OtherFilter "Other" width:40 height:18 align:#right offset:[7, -23] enabled:true -- Maths Business dropdownlist MValue1 "" items:MathsNames selection:FieldDefaults[1] align:#left width:((JAWidth*0.33)-60) offset:[-11,2] enabled:true dropdownlist MOperator2 "" items:MathsOperators selection:1 align:#left width:38 offset:[((JAWidth*0.33)-69),-27] enabled:false dropdownlist MValue2 "" items:MathsNames selection:FieldDefaults[2] align:#left width:((JAWidth*0.33)-60) offset:[((JAWidth*0.33)-29),-27] enabled:true dropdownlist MOperator1 "" items:MathsOperators selection:1 align:#left width:38 offset:[((JAWidth*0.66)-88),-27] enabled:true dropdownlist MValue3 "" items:MathsNames selection:FieldDefaults[3] align:#left width:((JAWidth*0.33)-60) offset:[((JAWidth*0.66)-48),-27] enabled:true dropdownlist MOperator3 "" items:MathsOperators selection:1 align:#left width:38 offset:[(JAWidth-113),-27] enabled:true spinner MConstant "" range:[0.0,1000000.0, 1.0] align:#right width:70 height:18 offset:[10,-25] enabled:false -- Sort By Type buttons progressbar StoreSurround "" color:SurroundColour value:100 width:33 height:29 align:#left offset:[-9,2] enabled:false progressbar LODLevelSurround "" color:SurroundColour value:100 width:46 height:29 align:#left offset:[25,-34] enabled:false progressbar NameSurround "" color:SurroundColour value:100 width:(JAwidth-372) height:29 align:#left offset:[72,-34] enabled:true progressbar Field1Surround "" color:SurroundColour value:100 width:67 height:29 align:#right offset:[-218,-34] enabled:false progressbar Field2Surround "" color:SurroundColour value:100 width:67 height:29 align:#right offset:[-150,-34] enabled:false progressbar Field3Surround "" color:SurroundColour value:100 width:67 height:29 align:#right offset:[-82,-34] enabled:false progressbar Field4Surround "" color:SurroundColour value:100 width:67 height:29 align:#right offset:[-14,-34] enabled:false button SortByStore "STR" width:25 align:#left offset:[-5, -30] enabled:true button SortByLODLevel "Level" width:38 align:#left offset:[29, -26] enabled:true button SortByName "Name" width:(JAwidth-380) offset:[76, -26] align:#left enabled:true button SortByField1 MathsButtons[FieldDefaults[1]] width:58 align:#right offset:[-222, -26] enabled:true -- "Main" button SortByField2 MathsButtons[FieldDefaults[2]] width:58 align:#right offset:[-154, -26] enabled:true -- "VRAM" button SortByField3 MathsButtons[FieldDefaults[3]] width:58 align:#right offset:[-86, -26] enabled:true -- "LOD Dist" button SortByField4 MathsButtons[FieldDefaults[4]] width:58 align:#right offset:[-18, -26] enabled:true -- "Distance" button ByteSize "KB" width:20 height:29 align:#right offset:[9,-30] progressbar TexLoadProgress "" color:SurroundColour value:0 width:(JAWidth+4) height:8 align:#right offset:[9,0] enabled:true -- MULTI LIST FOR THE MODULE DUMP ENTRIES... multilistbox SceneDump "" items:#() width:(JAwidth+4) height:((JAHeight-JAwidgets)/JArowSize) offset:[-9,-2] edittext SelectedObject "" width:((JAwidth-64)*0.5) height:16 align:#left offset:[-12,-5] enabled:true readonly:false edittext SelectedTXD "" width:((JAwidth-64)*0.31) height:16 align:#left offset:[(((JAwidth-64)*0.5)-14),-21] enabled:true readonly:false edittext SelectedIMAP "" width:((JAwidth-64)*0.19) height:16 align:#left offset:[(((JAwidth-64)*0.81)-16),-21] enabled:true readonly:false button ListOnlySelected "Isolate" width:75 height:16 align:#right offset:[9,-20] enabled:false -- Text boxes for totals label SelectedTotals "SELECTION" align:#left offset:[-7, -1] edittext SelectedObjectCount "" width:80 height:16 align:#left offset:[47,-20] readonly:true enabled:true edittext SelectedStoreTotal "" width:(JAwidth-284) height:16 align:#right offset:[-145, -21] readonly:true enabled:true edittext SelectedMainTotal "" width:80 height:16 align:#right offset:[-68, -21] readonly:true enabled:true edittext SelectedVRAMTotal "" width:80 height:16 align:#right offset:[9, -21] readonly:true enabled:true label FilteredTotals "FILTERED" align:#left offset:[1, -3] edittext FilteredObjectCount "" width:80 height:16 align:#left offset:[47,-20] readonly:true enabled:true edittext FilteredStoreTotal "" width:(JAwidth-284) height:16 align:#right offset:[-145, -21] readonly:true enabled:true edittext FilteredMainTotal "" width:80 height:16 align:#right offset:[-68, -21] readonly:true enabled:true edittext FilteredVRAMTotal "" width:80 height:16 align:#right offset:[9, -21] readonly:true enabled:true label ObjectTotals "TOTAL" align:#left offset:[16, -3] edittext ObjectCount "" width:80 height:16 align:#left offset:[47,-20] readonly:true enabled:true edittext StoreTotal "" width:(JAwidth-284) height:16 align:#right offset:[-145, -21] readonly:true enabled:true edittext MainTotal "" width:80 height:16 align:#right offset:[-68, -21] readonly:true enabled:true edittext VRAMTotal "" width:80 height:16 align:#right offset:[9, -21] readonly:true enabled:true subrollout Tex "Texture Analysis" height:26 width:JAWidth height:130 offset:[-7,4] rolledup:true ---- ANALYSER FUNCTIONS ---- fn CompareObjects obj1 obj2 = ( -- Compare junction Tracked Stat values - used in qsort local diff = 0 case of ( (NameSurround.enabled):( diff = stricmp obj2.name obj1.name ) (StoreSurround.enabled):( diff = stricmp obj2.store obj1.store ) (LODLevelSurround.enabled):( diff = obj2.attr.LODLevel - obj1.attr.LODLevel ) (Field1Surround.enabled):( diff = obj1.attr.mathsResult[1] - obj2.attr.mathsResult[1] ) (Field2Surround.enabled):(diff = obj1.attr.mathsResult[2] - obj2.attr.mathsResult[2] ) (Field3Surround.enabled):( diff = obj1.attr.mathsResult[3] - obj2.attr.mathsResult[3] ) (Field4Surround.enabled):( diff = obj1.attr.mathsResult[4] - obj2.attr.mathsResult[4] ) (default):( diff = obj1.attr.mathsResult[4] - obj2.attr.mathsResult[4] ) ) case of ( (diff < 0.0): 1 (diff > 0.0): -1 default: 0 ) ) fn kbToString Val = ( local result = "" if ByteSize.text == "KB" then ( if ((classOf Val) == Integer) then (result = Val as string + ByteSize.text) else (result = formattedPrint (Val format:FPPrecision) + ByteSize.text) ) else ( result = (formattedPrint (Val / 1024.0) format:FPPrecision) + ByteSize.text ) result ) fn ConvertToString NumType NumVal = ( local ByteMask = #{1,2} local FloatMask = #{3,4,6,7,8} local IntMask = #{5,9} local val = case of ( ((findItem IntMask NumType) > 0):(if NumVal != 0 then (NumVal as string) else "") ((findItem ByteMask NumType) > 0):(kbToString NumVal) ((findItem FloatMask NumType) > 0):(if NumVal != 0.0 then (formattedPrint NumVal format:FPPrecision) else "") ) if val == "0.0" then val = "" val ) fn TheUnsetValue = ( local valuesSet = #{MValue1.selection, MValue2.selection, MValue3.selection} local result = 0 case of ( ((findItem valuesSet FieldDefaults[2]) == 0):(result = FieldDefaults[2]) ((findItem valuesSet FieldDefaults[1]) == 0):(result = FieldDefaults[1]) ((findItem valuesSet FieldDefaults[3]) == 0):(result = FieldDefaults[3]) ((findItem valuesSet FieldDefaults[4]) == 0):(result = FieldDefaults[4]) ) result ) fn ClearDumpSelection = ( SceneDump.selection = #() SelectedObject.text = "" ; SelectedTXD.text = "" ; SelectedIMAP.text = "" ; SelectedObjectCount.text = "" SelectedMainTotal.text = "" ; SelectedVRAMTotal.text = "" --SelectedObjectCount.enabled = SelectedStoreTotal.enabled = SelectedMainTotal.enabled = SelectedVRAMTotal.enabled = false --TextureAnalyser.ClearTextureList() ) fn ListButtonUpdate = ( if (SceneDump.selection.isempty) then ( if (SceneDump.items.count < FilteredCount) then (ListOnlySelected.text = "List All" ; ListOnlySelected.enabled = true) else (ListOnlySelected.text = "Isolate" ; ListOnlySelected.enabled = false) ) else ( ListOnlySelected.text = "Isolate" ; ListOnlySelected.enabled = true ) ) fn FindCameraCoords = ( local camPos = point3 0.0 0.0 0.0 local camx = 0 local camy = 0 local camz = 0 if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if RemoteConnection.IsConnected() then ( RemoteConnection.WriteBoolWidget "Camera/Create camera widgets" true RemoteConnection.SendSyncCommand() camx = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position X" camy = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position Y" camz = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position Z" camPos = point3 camx camy camz if (camPos == [0.0, 0.0, 0.0]) then ( camx = RemoteConnection.ReadFloatWidget "Camera/Renderer/CamMtx/WorldMtx d X" camy = RemoteConnection.ReadFloatWidget "Camera/Renderer/CamMtx/WorldMtx d Y" camz = RemoteConnection.ReadFloatWidget "Camera/Renderer/CamMtx/WorldMtx d Z" camPos = point3 camx camy camz ) ) camPos ) fn LookAtPoint coords = ( if (not RemoteConnection.IsConnected()) then RemoteConnection.Connect() if RemoteConnection.IsConnected() then ( RemoteConnection.WriteBoolWidget "Camera/Create camera widgets" true local camX = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position X" local camY = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position Y" local camZ = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position Z" local XYVector = [coords.x,coords.y,0.0] - [camX,camY,0.0] local newOrient = acos ( dot (normalize XYVector) [0.0,1.0,0.0] ) newOrient = if (XYVector.x < 0.0) then (newOrient) else (0.0 - newOrient) RemoteConnection.WriteFloatWidget "Camera/Free camera/Orientation Z" newOrient local YZVector = [0.0,(length XYVector),(coords.z - camZ)] newOrient = acos( dot (normalize YZVector) [0,1.0,0]) newOrient = if (YZVector.z > 0.0) then (newOrient) else (0.0 - newOrient) RemoteConnection.WriteFloatWidget "Camera/Free camera/Orientation X" newOrient ) else (format "No Connection\n") ) fn SynchSceneAssets = ( if (P4Assets.count > 0) then ( gRsPerforce.sync P4Assets Force:false Silent:True ; free P4Assets ; P4Assets = #() )) fn SynchSceneTextures = ( if (P4Textures.count > 0) then (gRsPerforce.sync P4Textures Force:false Silent:True ; free P4Textures ; P4Textures = #() )) fn CalculateComplexStat objectValues = ( -- 1 = main, 2 = vram, 3 = distance, 4 = LODDist, 5 = polyCount, 6 = area, 7 = volume, 8 = HDDist local StatValue1 = objectValues[MValue1.selection] local StatValue2 = objectValues[MValue2.selection] local StatValue3 = objectValues[MValue3.selection] local result = 0 case MOperator1.selection of ( 2:(result = StatValue2 + StatValue3) 3:(result = StatValue2 - StatValue3) 4:(result = StatValue2 * StatValue3) 5:(result = if (StatValue3 == 0) then (0.0) else (StatValue2 / StatValue3)) default:(result = objectValues[TheUnsetValue()]) ) case MOperator2.selection of ( 2:(result = StatValue1 + result) 3:(result = StatValue1 - result) 4:(result = StatValue1 * result) 5:(result = if (result == 0) then (0.0) else (StatValue1 / result)) default:() ) case MOperator3.selection of ( 2:(result += MConstant.value) 3:(result -= MConstant.value) 4:(result *= MConstant.value) 5:(if (MConstant.value == 0) then (result = 0.0) else (result /= MConstant.value)) default:() ) #(StatValue1, StatValue2, StatValue3, result) ) fn DumpSceneItemList = ( -- build (filtered) object list text and drop into SceneDump.items local dumpItems = #() local NameSizeCheck = Field1Surround.pos[1] - (NameSurround.pos[1] + 24) local NamesCheck = filterstring NameFilter.text " " local FilteredMain = 0 local FilteredVRAM =0 local ExprText = "" FilteredList = #() FilteredCount = 0 local NameMatch = true local ExclusionTest = false for obj in ObjectList do ( -- Need to double check entry against filters... NameMatch = true for expr in NamesCheck do ( if (expr[1]) == "-" then ( -- Exclusive Test ExclusionTest = true ; ExprText = (trimleft expr "-") ) else ( -- Inclusive Test ExclusionTest = false ; ExprText = expr ) if (matchPattern obj.name pattern:("*"+ExprText+"*") ignorecase:true) then ExprMatch = true else ExprMatch = false if UseNameFilter.state then (if ExclusionTest then (ExprMatch = not ExprMatch)) else (ExprMatch =true) NameMatch = NameMatch and ExprMatch ) if nameMatch then ( local filtered = false case (substring obj.store 2 2) of ( "DR":( if IDRSurround.enabled then filtered = true ) "DD":( if IDDSurround.enabled then filtered = true ) "TD":( if ITDSurround.enabled then filtered = true ) default:( if OtherSurround.enabled then filtered = true ) ) case (obj.attr.LODLevel) of ( 2:(if OrphanSurround.enabled == false then filtered = false) 3:(if HDSurround.enabled == false then filtered = false) 4:(if LODSurround.enabled == false then filtered = false) 5:(if SLOD1Surround.enabled == false then filtered = false) 6:(if SLOD2Surround.enabled == false then filtered = false) 7:(if SLOD3Surround.enabled == false then filtered = false) default:() ) if filtered then ( FilteredCount += 1 FilteredMain += obj.main ; FilteredVRAM += obj.vram append FilteredList obj local ObjectValues = #(obj.main, obj.vram,obj.attr.dist,obj.attr.LODdist,obj.attr.polyCount,obj.attr.area,obj.attr.volume,obj.attr.HDDist, obj.textureList.count) obj.attr.mathsResult = CalculateComplexStat ObjectValues ) ) ) local FieldWidth = 67 qsort FilteredList CompareObjects for obj in FilteredList do ( local dumpString = stringstream "" local nameString = stringstream "" local inLimit = true local Field1Val = ConvertToString MValue1.selection obj.attr.mathsResult[1] local Field2Val = ConvertToString MValue2.selection obj.attr.mathsResult[2] local Field3Val = ConvertToString MValue3.selection obj.attr.mathsResult[3] local Field4Val = ConvertToString 5 obj.attr.mathsResult[4] -- Spaces to add between start of each column and text to centre justify (neatest looking justification) local Field1Pad = (((FieldWidth - (GetTextExtent Field1Val)[1]))/6) as integer local Field2Pad = (((FieldWidth - (GetTextExtent Field2Val)[1]))/6) as integer local Field3Pad = (((FieldWidth - (GetTextExtent Field3Val)[1]))/6) as integer local Field4Pad = (((FieldWidth - (GetTextExtent Field4Val)[1]))/6) as integer format "%" obj.store to:dumpString -- Pad between STORE and LEVEL padLength = ((LODLevelSurround.pos[1] - (GetTextExtent dumpString)[1]) / 3) as integer if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) if ((substring obj.store 2 2) != "DR") then ( case obj.attr.LODLevel of ( (1):() (2):(format "hd" to:dumpString) (3):(format "hd" to:dumpString) (4):(format "lod" to:dumpString) (5):(format "slod 1" to:dumpString) (6):(format "slod 2" to:dumpString) (7):(format "slod 3" to:dumpString) ) ) else ( format "%" LODLevels[obj.attr.LODLevel] to:dumpString ) -- Pad between LEVEL and NAME padLength = ((NameSurround.pos[1] - (GetTextExtent dumpString)[1]) / 3) as integer if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) for char = 1 to obj.name.count while inLimit do ( if ((GetTextExtent nameString)[1] < NameSizeCheck) then (format "%" obj.name[char] to:nameString) else (inLimit = false ; format "..." to:nameString) ) format "%" (nameString as string) to:dumpString ; free nameString -- Pad between NAME and MAIN padlength = (((Field1Surround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) as integer) + Field1Pad if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" Field1Val to:dumpString -- Pad between MAIN and VRAM padlength = (((Field2Surround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) as integer) + Field2Pad if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" Field2Val to:dumpString -- Pad between VRAM and LOD Dist padlength = (((Field3Surround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) as integer) + Field3Pad if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" Field3Val to:dumpString -- Pad between LODDist and Maths Result padlength = (((Field4Surround.pos[1] - (GetTextExtent dumpString)[1] - 9) / 3) as integer) + Field4Pad if (padLength > 0) then ( for space = 1 to padLength do format " " to:dumpString ) format "%" Field4Val to:dumpString append dumpItems (dumpString as string) free dumpString free Field1Val ; free Field2Val ; free Field3Val ; free Field4Val ) FilteredObjectCount.text = FilteredCount as string FilteredMainTotal.text = kbToString FilteredMain ; FilteredVRAMTotal.text = kbToString FilteredVRAM FilteredMainTotal.enabled = (FilteredMainTotal.text != MainTotal.text) FilteredVRAMTotal.enabled = (FilteredVRAMTotal.text != VRAMTotal.text) SceneDump.items = dumpItems ListButtonUpdate() ) fn ReadAssetXML IMAPIndex IMAPTick camPos = ( local containerXML = (toLower IMAPs[IMAPIndex].name) +".xml" if (doesFileExist containerXML) then ( format "Reading %\n" containerXML -- !!! DEBUG Might keep this one as it's a slow process of reading all the XMLs local xml_io = rsta_xml_io xmlFile:containerXML local xml_objects = try(rsta_xml.getChildren xml_io.root name:"objects/object/children/object" attr:"superclass" value:"geomobject") catch(#()) --attr:"name" value:FilteredList[AssetIndex].name for index = 1 to xml_objects.count do ( local obj_guid = "" local obj_nodePos = undefined local obj_lodDist = 0.0 local obj_HDDist = 0.0 local obj_distance = 0.0 local obj_parent = "" local obj_children = #() local obj_grandchildren = 0 local obj_LODLevel = 1 local obj_polycount = 0 local obj_BBmin = [0,0,0] local obj_BBmax = [0,0,0] local obj_area = 0.0 local obj_volume = 0.0 local ObjectNames = for assetEntry in IMAPs[IMAPIndex].assetList collect assetEntry.name local ObjectIndex = finditem ObjectNames (toLower (xml_objects[index].getAttribute "name")) if (ObjectIndex > 0) then ( -- !!!!! WORKING -- May require several passes... -- Get children, count children, if children == 0 then "HD" (+ if no parent then "ORPHAN") -- More complicated than it seems... and easier as well since no link to LOD container (so SLOD2 and 3 trivial) -- -- !!!! Add to field options... "texture count" + anything else that sounds half-useful... -- try(obj_guid = xml_objects[index].getAttribute "guid") catch() try(obj_LODDist = ((rsta_xml.getChildren xml_objects[index] name:"attributes/attribute" attr:"name" value:"LOD distance")[1].getAttribute "value") as float) catch() try(obj_HDDist = ((rsta_xml.getChildren xml_objects[index] name:"attributes/attribute" attr:"name" value:"HD Textures Distance")[1].getAttribute "value") as float) catch() try(obj_parent = (rsta_xml.getChildren xml_objects[index] name:"lod_hierarchy/parent")[1].getAttribute "name") catch() try ( local xml_children = rsta_xml.getChildren xml_objects[index] name:"lod_hierarchy/children/child" obj_children = (for child in xml_children collect (child.getAttribute "name")) ) catch() -- Work out LOD level local containerType = filterstring (toLower IMAPs[IMAPIndex].name) "_" if (substring containerType[containerType.count] 1 3 == "lod") then ( if (obj_children.count == 0) then (obj_LODLevel = 6) else (obj_LODLevel = 7) -- SLOD2 / SLOD3 ) else ( if (obj_children.count == 0) then ( obj_LODLevel = (if obj_parent == "" then (2) else (3)) -- ORPHAN / LODDED HD ) else ( obj_LODLevel = 4 -- LOD (OR SLOD1) try ( local xml_child1 = rsta_xml.getChildren xml_io.root name:"objects/object/children/object" attr:"name" value:obj_children[1] local obj_grandchildren = ((xml_child1[1].SelectSingleNode "lod_hierarchy/children").getAttribute "count") as integer if (obj_grandchildren > 0) then (obj_LODLevel = 5) -- SLOD1 ) catch () ) ) -- Work out distance to object try ( local xml_obj_Pos = point3 0.0 0.0 0.0 xml_obj_Pos.x = ((xml_objects[index].SelectSingleNode "transform/node/position").getAttribute "x") as float xml_obj_Pos.y = ((xml_objects[index].SelectSingleNode "transform/node/position").getAttribute "y") as float xml_obj_Pos.z = ((xml_objects[index].SelectSingleNode "transform/node/position").getAttribute "z") as float obj_nodePos = xml_obj_Pos ) catch() if (obj_nodePos != undefined) then ( if (camPos != [0,0,0]) then (obj_distance = distance obj_nodePos camPos) else (obj_distance = 0.0) ) else ( obj_nodePos = [0,0,0] ; obj_distance = 0.0 ) -- Get poly count and bounding box try (obj_polyCount = ((xml_objects[index].SelectSingleNode "polycount").getAttribute "value") as integer) catch() try ( obj_BBmin.x = ((xml_objects[index].SelectSingleNode "boundingbox3/world/min").getAttribute "x") as float obj_BBmin.y = ((xml_objects[index].SelectSingleNode "boundingbox3/world/min").getAttribute "y") as float obj_BBmin.z = ((xml_objects[index].SelectSingleNode "boundingbox3/world/min").getAttribute "z") as float obj_BBmax.x = ((xml_objects[index].SelectSingleNode "boundingbox3/world/max").getAttribute "x") as float obj_BBmax.y = ((xml_objects[index].SelectSingleNode "boundingbox3/world/max").getAttribute "y") as float obj_BBmax.z = ((xml_objects[index].SelectSingleNode "boundingbox3/world/max").getAttribute "z") as float obj_area = (obj_BBmax.x - obj_BBmin.x) * (obj_BBmax.y - obj_BBmin.y) obj_volume = obj_area * (obj_BBmax.z - obj_BBmin.z) ) catch() -- Use parent's child LOD distance if it exists. if (obj_parent != "") then ( try ( xml_parent = rsta_xml.getChildren xml_io.root name:"objects/object/children/object" attr:"name" value:obj_parent obj_LODdist = ((rsta_xml.getChildren xml_parent[1] name:"attributes/attribute" attr:"name" value:"Child LOD distance")[1].getAttribute "value") as float ) catch() ) --format "Found % : @ %\n" (xml_objects[index].getAttribute "name") obj_nodePos-- !!! DEBUG local entityIndex = IMAPs[IMAPIndex].assetList[ObjectIndex].index local dependIndex = ObjectList[entityIndex].dependIndex ObjectList[entityIndex].attr = attributeList loaded:true guid:obj_guid parent:obj_parent children:obj_children LODLevel:obj_LODLevel LODDist:obj_LODDist HDDist:obj_HDDist \ pos:obj_nodePos dist:obj_distance polyCount:obj_polyCount BBmin:obj_BBmin BBmax:obj_BBmax area:obj_area volume:obj_volume mathsResult:0.0 local ObjectValues = #(ObjectList[entityIndex].main, ObjectList[entityIndex].vram,obj_distance,obj_LODDist,obj_polyCount,obj_area,obj_volume,obj_HDDist) ObjectList[entityIndex].attr.mathsResult = CalculateComplexStat ObjectValues --local dependIndex = ObjectList[IMAPs[IMAPIndex].assetList[ObjectIndex].index].dependIndex if (dependIndex > 0) then ( ObjectList[dependIndex].attr.LODLevel = obj_LODLevel if (obj_distance < ObjectList[dependIndex].attr.dist) or (ObjectList[dependIndex].attr.dist == 0.0) then ( ObjectList[dependIndex].attr.dist = obj_distance ObjectList[dependIndex].attr.pos = obj_nodePos --format "Setting [%]%.% position to same as [%]%.% (%)\n" dependIndex ObjectList[dependIndex].name ObjectList[dependIndex].store entityIndex ObjectList[entityIndex].name ObjectList[entityIndex].store ObjectList[36].attr.pos --obj_distance -- !!! DEBUG ) local lowestDistance = amin #(obj_HDDist, obj_LODDist) if (lowestDistance > obj_distance) then ( if (lowestDistance > ObjectList[dependIndex].attr.HDDist) then (ObjectList[dependIndex].attr.hdDist = lowestDistance) ) -- Expand dependency's bounding box if (ObjectList[dependIndex].attr.area == 0.0) then ( ObjectList[dependIndex].attr.BBmin = obj_BBmin ObjectList[dependIndex].attr.BBmax = obj_BBmax ObjectList[dependIndex].attr.area = obj_area ObjectList[dependIndex].attr.volume = obj_volume ) else ( ObjectList[dependIndex].attr.BBmin.x = amin #(ObjectList[dependIndex].attr.BBmin.x, obj_BBmin.x) ObjectList[dependIndex].attr.BBmin.y = amin #(ObjectList[dependIndex].attr.BBmin.y, obj_BBmin.y) ObjectList[dependIndex].attr.BBmin.z = amin #(ObjectList[dependIndex].attr.BBmin.z, obj_BBmin.z) ObjectList[dependIndex].attr.BBmax.x = amax #(ObjectList[dependIndex].attr.BBmax.x, obj_BBmax.x) ObjectList[dependIndex].attr.BBmax.y = amax #(ObjectList[dependIndex].attr.BBmax.y, obj_BBmax.y) ObjectList[dependIndex].attr.BBmax.z = amax #(ObjectList[dependIndex].attr.BBmax.z, obj_BBmax.z) ObjectList[dependIndex].attr.area = (ObjectList[dependIndex].attr.BBmax.x - ObjectList[dependIndex].attr.BBmin.x) * (ObjectList[dependIndex].attr.BBmax.y - ObjectList[dependIndex].attr.BBmin.y) ObjectList[dependIndex].attr.volume = obj_area * (ObjectList[dependIndex].attr.BBmax.z - ObjectList[dependIndex].attr.BBmin.z) ) ObjectList[dependIndex].attr.loaded = true ) ) ProgressFloat += (100.0 / (xml_objects.count * IMAPTick)) TexLoadProgress.value = ProgressFloat --as integer ) --format "xml_object.count: %, IMAPList.count: %\n" xml_objects.count IMAPList.count free xml_io ; free xml_objects ) else (TexLoadProgress.value += (100.0 / IMAPTick)) ) fn buildSceneAssetList = ( -- build list of assets to get in P4 on SynchAssets pressed local AssetBase = ::RsConfigGetAssetsDir() + "export" for index = 1 to ObjectList.count do ( -- Build the XML/ZIP path for the each asset (and dependency index) local AssetName = stringstream "" format "%" AssetBase to:AssetName for pathPart = 1 to (ObjectList[index].imapPathArray.count - 2) do ( format "/%" ObjectList[index].imapPathArray[pathPart] to:AssetName ) local nameSplit = filterstring ObjectList[index].name "_" local assetFileName = stringstream "" format "%" nameSplit[1] to:assetFileName if nameSplit.count > 1 then ( format "_%" nameSplit[2] to:assetFileName if (nameSplit.count > 2) then (if (nameSplit[3] == "props") then (format "_props" to:assetFileName)) ) if (ObjectList[index].imapPathArray[1] == "levels") and (nameSplit.count > 1) then ( format "/%" (assetFileName as string) to:AssetName ) else ( format "/%" ObjectList[index].imapPathArray[ObjectList[index].imapPathArray.count - 1] to:AssetName ) ObjectList[index].assetPath = (AssetName as string) append P4Assets (ObjectList[index].assetPath + ".zip") append P4Assets (ObjectList[index].assetPath + ".xml") if (findstring ObjectList[index].imap "_") != undefined then ( append P4Assets (ObjectList[index].assetPath + "_props.zip") append P4Assets (ObjectList[index].assetPath + "_props.xml") ) free AssetName free assetFileName local StoreType = substring ObjectList[index].store 2 2 -- Build Lists -- IMAPs = IMAP (name, assetList #( (name,index)...(name, index) )) if (StoreType == "DR") and (substring ObjectList[index].imap 1 2 != "v_") then ( local newAsset = asset name:ObjectList[index].name index:index local IMAPNames = for IMAPEntry in IMAPs collect IMAPEntry.name local IMAPIndex = findItem IMAPNames ObjectList[index].assetPath if (IMAPIndex == 0) then ( local newIMAP = IMAP name:ObjectList[index].assetPath assetList:#(newAsset) append IMAPs newIMAP ) else ( append IMAPs[IMAPIndex].assetList newAsset ) ) /* -- !!!! Not sure why I reset this... else ( ObjectList[index].attr = attributeList loaded:false guid:"" parent:"" LODDist:0.0 HDDist:0.0 pos:[0,0,0] dist:0.0 polyCount:0 BBmin:0 BBmax:0 area:0.0 volume:0.0 mathsResult:0.0 ) */ if ObjectList[index].depend != "" then ( notFound = true for TXDindex = 1 to ObjectList.count while notFound do ( if (ObjectList[TXDindex].name == ObjectList[index].depend) and ((substring ObjectList[TXDindex].store 2 2) == "TD") then ( notFound = false ObjectList[index].dependIndex = TXDindex ) ) ) ) -- Process XMLs ProgressFloat = 0.0 TexLoadProgress.value = 0 /* -- !!!! Disabling auto asset load... too painful to accidentally load all assets... local camPos = FindCameraCoords() if LoadXMLsSurround.enabled then ( for index = 1 to IMAPs.count do ( ReadAssetXML index IMAPs.count camPos ) ) */ free AssetBase ) fn SceneAnalysis = ( -- check RAG connection, activate memdump widgets and dump to MemoryDumpFileLocation, load file into ObjectList array of sceneEntitys /* COMMENT OUT FOR TEST PURPOSES !!!! */ if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/Create Scene widgets" true RemoteConnection.WriteBoolWidget "Camera/Create camera widgets" true RemoteConnection.WriteBoolWidget "Renderer/Create Renderer widgets" true RemoteConnection.WriteBoolWidget "Streaming & Memory/Create streaming memory widgets" true RemoteConnection.SendSyncCommand() if not (doesFileExist JAEntityZipTemp) then ( makeDir JAEntityZipTemp ) deleteFile MemoryDumpFileLocation RemoteConnection.WriteBoolWidget "Streaming & Memory/Create streaming memory widgets" true RemoteConnection.WriteStringWidget "Streaming & Memory/Memory/Memory Usage/Per-Module Info/Master Module Display/Resource Search" "" RemoteConnection.WriteBoolWidget "Streaming & Memory/Memory/Memory Usage/Per-Module Info/Master Module Display/Only Scene Assets" true RemoteConnection.WriteStringWidget "Streaming & Memory/Memory/Memory Usage/Per-Module Info/Master Module Display/Sort objects by" "name" RemoteConnection.WriteBoolWidget "Streaming & Memory/Memory/Memory Usage/Per-Module Info/Master Module Display/Show Dependencies" true RemoteConnection.WriteStringWidget "Streaming & Memory/Memory/Memory Usage/Per-Module Info/Master Module Display/File to dump to (none=TTY)" MemoryDumpFileLocation RemoteConnection.WriteBoolWidget "Streaming & Memory/Memory/Memory Usage/Per-Module Info/Master Module Display/Dump Module Info" true RemoteConnection.SendSyncCommand() ) else ( local message = "Can't connect to RAG.\nMake sure game and RAG are running." messageBox message title:"No Connection" ) /* uncomment*/ -- load dump file free PAssets PAssets = #() free P4Textures P4Textures = #() free ObjectList ; free FilteredList ; free TextureList ; free IMAPs ObjectList = #() ; FilteredList = #() ; TextureList = #() ; IMAPs = #() ClearDumpSelection() TotalMain = 0 TotalVRAM = 0 local memDumpFile = openFile MemoryDumpFileLocation if (memDumpFile != undefined) then ( local header = filterString (readline memDumpFile) " " -- header[4] = object count ; header[5] = Total Main ; header[6] = Total VRAM while not (eof memDumpFile) do ( -- "object.store", "MainK", "VRAMK", "0??", "Dependency count", "Stream source", ("Immediate Dependant"), "IMap" local nextline = filterString (readline memDumpFile) " " if (nextline.count > 6) then ( -- Ignore odd case where memory modules have been expanded in RAG !!!!!! May change behaviour later if it's semi-interesting info being ignored local objectName = filterString (nextline[1]) "." local nextobject = sceneEntity name:objectName[1] store:(toUpper objectName[2]) nextobject.main = (trimright nextline[2] "K") as integer nextobject.vram = (trimright nextline[3] "K") as integer local imapIndex = nextline.count if (imapIndex == 8) then (nextobject.depend = (filterstring nextline[7] "(<.>)")[1]) else (nextobject.depend = "") nextobject.dependIndex = 0 -- Set this up in SceneAnalysis nextobject.imapPathArray = filterstring (trimleft nextline[imapIndex] "platform:" ) "/." nextobject.imap = try(nextobject.imapPathArray[(nextobject.imapPathArray.count-1)]) catch("") nextobject.textureList = #() nextobject.attr = attributeList loaded:false guid:"" parent:"" children:#() LODLevel:1 LODDist:0.0 HDDist:0.0 pos:[0,0,0] dist:0.0 polyCount:0 BBmin:[0,0,0] BBmax:[0,0,0] area:0.0 volume:0.0 mathsResult:0.0 append ObjectList nextobject TotalMain += nextobject.main ; TotalVRAM += nextobject.vram ) ) close memDumpFile ) ObjectCount.text = ObjectList.count as string MainTotal.text = kbToString TotalMain ; VRAMTotal.text = kbToString TotalVRAM buildSceneAssetList() SynchAssets.enabled = true DumpSceneItemList() ) fn ShowEntityInRAG AssetIndex Dtype = ( -- RAG Widgetry local storeType = substring FilteredList[AssetIndex].store 2 2 --format "%\n" FilteredList[findSelection] if (not RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/Create Scene widgets" true RemoteConnection.WriteBoolWidget "Renderer/Create Renderer widgets" true -- WIREFRAME DRAW INTEGRATION -- RemoteConnection.WriteFloatWidget "Renderer/Wireframe/Rendering/Opacity" (WireOPacity.value / 100.0) RemoteConnection.WriteFloatWidget "Renderer/Wireframe/Rendering/Invisible Opacity" 0.25 RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Name Is ..." RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Uses Parent Txd ..." if (storeType == "TD") then ( RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredList[AssetIndex].name RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Uses Parent Txd ..." ) else ( if (FilteredList[AssetIndex].depend == "") or (WireMode.selection == 1) or (DType == "IDR") then ( RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredList[AssetIndex].name RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Name Is ..." ) else ( RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredList[AssetIndex].depend RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Uses Parent Txd ..." ) ) if (LookAtSurround.enabled) and (FilteredList[AssetIndex].attr.pos != [0.0,0.0,0.0]) then LookAtPoint FilteredList[AssetIndex].attr.pos if WireSurround.enabled then (RemoteConnection.WriteBoolWidget "Renderer/Wireframe/Draw" true) else ( RemoteConnection.WriteBoolWidget "Renderer/Wireframe/Draw" false ) -- TEXTURE VIEWER INTEGRATIONS -- RemoteConnection.WriteStringWidget "Texture Viewer/Search Type" "Texture Dictionaries" RemoteConnection.WriteBoolWidget "Texture Viewer/Search Params/Exact Name Match" true if ( (storeType == "TD") or (FilteredList[AssetIndex].depend =="") or (DType == "IDR")) then (RemoteConnection.WriteStringWidget "Texture Viewer/Search Filter" FilteredList[AssetIndex].name) else (RemoteConnection.WriteStringWidget "Texture Viewer/Search Filter" FilteredList[AssetIndex].depend) RemoteConnection.WriteBoolWidget "Texture Viewer/Search" true RemoteConnection.WriteBoolWidget "Texture Viewer/Stretch to Fit" true if (TexViewerSurround.enabled and (not MOHSurround.enabled)) then (RemoteConnection.writeBoolWidget "Texture Viewer/Visible" true) -- MAP OPTIMISATION HELPER INTEGRATIONS -- if MOHSurround.enabled then ( RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Enable" true RemoteConnection.WriteStringWidget "Scene/Map Optimization Helper/Search txd name" FilteredList[AssetIndex].name RemoteConnection.WriteStringWidget "Scene/Map Optimization Helper/Mode" "Txd analysis" if MOHIsolate.enabled then ( MOHISolate.enabled = false ; RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Isolate selected" false) else ( MOHISolate.enabled = true ; RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Isolate selected" true ) RemoteConnection.WriteBoolWidget "Texture Viewer/Stretch to Fit" true RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Show results in Texture Viewer" TexViewerSurround.enabled RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Scan visible" true ) else ( RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Enable" false ) -- BLOCK ISOLATE INTEGRATION -- RemoteConnection.WriteStringWidget "Blocks/Block" FilteredList[AssetIndex].imap if ((IsoSurround.enabled) and (storeType != "DD")) then ( RemoteConnection.WriteBoolWidget "Blocks/Isolate Block" true ) else ( RemoteConnection.WriteBoolWidget "Blocks/Isolate Block" false ) if (not TexViewerSurround.enabled) then (RemoteConnection.writeBoolWidget "Texture Viewer/Visible" false) ) else ( local message = "Connection to RAG lost.\nCheck game and RAG are running." messageBox message title:"Connection Lost" ) ) fn LoadEntityTextureList AssetIndex = ( -- Find the ZIP file for the entity, unmaz it, build the TextureList local AssetZIPName = FilteredList[AssetIndex].assetPath + ".zip" local EntityName = stringstream "" local StoreType = substring FilteredList[AssetIndex].store 2 2 format "%.i%.zip" (toLower FilteredList[AssetIndex].name) (toLower StoreType) to:EntityName EntityName = EntityName as string local cmd = "del /Q " + JAEntityZipTemp ; HiddenDOSCommand cmd donotwait:false -- Catch cases where the temp folder hasn't cleared if ((findItem UnpackedAssets AssetZIPName) == 0) then ( if DEBUG_SPEW then (local cmd = stringstream "" ; format "Unpacking % to temporary folder %" AssetZIPName JAAssetZipTemp to:cmd ; format "%\n" (cmd as string))-- DEBUG !!! unmaz AssetZIPName JAAssetZipTemp append UnpackedAssets AssetZIPName ) if DEBUG_SPEW then (local cmd = stringstream "" ; format "Unpacking %% to %" JAAssetZipTemp EntityName JAEntityZipTemp to:cmd ; format "%\n\n" (cmd as string))-- DEBUG !!! unmaz (JAAssetZipTemp + EntityName) JAEntityZipTemp -- Old way commented out.. worked ok for non-gtxd... -- (Possibly) Re-instate but put new way in else case to catch gtxd TCLs that have no .textures file in the ZIP -- /* -- Build texture list from the unpacked asset ZIP TextureListFile = stringstream "" format "%" JAEntityZipTemp to:TextureListFile case StoreType of ( "DR":(format "entity.textures" to:TextureListFile) "TD":(format "%.textures" (toLower FilteredList[AssetIndex].name) to:TextureListFile) default:(TextureListfile = "NOT_LOADING_THESE_ONES") ) TextureListFile = TextureListFile as string if (doesFileExist TextureListFile) then ( --format "Texture List : %\n" (TextureListFile as string) -- !!! DEBUG local texFile = openFile TextureListFile while not (eof texFile) do ( local nextline = (filterString (readline texFile) " ")[1] local nextName = substring nextline ( JAEntityZipTemp.count + 1) (nextline.count - JAEntityZipTemp.count) local nexttex = texture name:nextline TCS:"UNKNOWN" size:0 dims:"UNKNOWN" form:"UNKNOWN" type:"TEX" template:"UNKNOWN" sourceImage:"UNKNOWN" sourceRes:"UNKNOWN" append FilteredList[AssetIndex].textureList nexttex ) close texFile for tex in FilteredList[AssetIndex].textureList do ( TextureTCL = JAEntityZipTemp + tex.name + ".tcl" if (doesFileExist TextureTCL) then ( try ( xml_io = rsta_xml_io xmlFile:TextureTCL TCSPath = ((rsta_xml.getChildren xml_io.root name:"parent")[1].InnerText)+".tcs" tex.TCS = substituteString TCSPath "$(assets)" (::RsConfigGetAssetsDir()) free xml_io ) catch() --format "% : %\n" tex.name tex.TCS -- !!! DEBUG ) ) ) */ local TCLFiles = getFiles (JAEntityZipTemp + "*.tcl") --format "TCLFiles : %\n" TCLFiles for TextureTCL in TCLFiles do ( local nextname = getFilenameFile TextureTCL local nexttex = texture name:nextname TCS:"UNKNOWN" size:0 dims:"UNKNOWN" form:"UNKNOWN" type:"TEX" template:"UNKNOWN" sourceImage:"NO SOURCE IMAGE" sourceRes:"UNKNOWN" try ( xml_io = rsta_xml_io xmlFile:TextureTCL local TCSPath = ((rsta_xml.getChildren xml_io.root name:"parent")[1].InnerText)+".tcs" local TCSPathBits = filterstring TCSPath ")}" if (TCSPathBits.count > 1) then (TCSPath = ((::RsConfigGetAssetsDir()) + TCSPathBits[2])) nexttex.TCS = TCSPath free xml_io ) catch() append FilteredList[AssetIndex].textureList nexttex ) local cmd = "del /Q " + JAEntityZipTemp ; HiddenDOSCommand cmd donotwait:true ) fn LoadTextureData AssetIndex = ( -- Build texture list for selected asset (function above), get appropriate TCSs, TIFs, DDSs, dump info to TextureDump.items local P4TCSs = #() local forceGet = false -- forceGet or (not doesFileExist tex.sourceImage) local progressVal = TexLoadProgress.value --0.0 TexLoadProgress.value = progressVal if (FilteredList[AssetIndex].textureList.count == 0) and (LoadTexturesSurround.enabled) then ( if LookAtSurround.enabled then ShowEntityInRAG AssetIndex "ITD"--LookAtPoint FilteredList[AssetIndex].attr.pos LoadEntityTextureList AssetIndex -- Builds Asset TextureLists -- Follow the chain of assets... TCL --> TCS --> TIF/DDS -- -- P4 GetLatest at each stage -- -- !!!!!! WORKING removing the default TCS use from here as it's confusing... -- Need to double check TCSs elsewhere to try to resolve bad data through unmaz problems... -- -- /* for tex in FilteredList[AssetIndex].textureList do ( -- Get the TCSs -- Old TCS name assembly.. shouldn't need any more, but just in case... if tex.TCS == "UNKNOWN" then ( local LocalTCSname = stringstream "" for index = 3 to (FilteredList[AssetIndex].imapPathArray.count - 1) do ( format "%/" FilteredList[AssetIndex].imapPathArray[index] to:LocalTCSname ) format "%.tcs" tex.name to:LocalTCSname --format "%.tcs" tex.name to:SharedTCSname tex.TCS = (LocalTCSname as string) ) -- format "% : %\n" tex.name tex.TCS -- !!! DEBUG --append P4TCSs (tex.TCS) -- !!!! P4 REDO progressVal += (25.0 / ((FilteredList[AssetIndex].textureList.count as float) * SceneDump.selection.numberset)) TexLoadProgress.value = progressVal as integer ) */ --if (P4TCSs.count > 0) then (gRsPerforce.sync P4Assets Force:false Silent:True) --P4TCSs = #() for tex in FilteredList[AssetIndex].textureList do ( -- Get the asset TIFs/DDSs local TCSImage = "NO SOURCE IMAGE" if (doesFileExist tex.TCS) then ( local xml_io = rsta_xml_io xmlFile:tex.TCS try ( TCSImage = ((rsta_xml.getChildren xml_io.root name:"resourceTextures/Item")[1].SelectSingleNode "pathname").InnerText ) catch () try ( local templateArray = filterstring ((rsta_xml.getChildren xml_io.root name:"parent")[1].InnerText) "/" tex.template = templateArray[templateArray.count] tex.type = case (substring (tex.template) 1 4) of ( "Defa":("Diff") "Diff":("Diff") "Norm":("Norm") "Spec":("Spec") default:("Misc") ) ) catch (tex.template = "NO TEMPLATE" ; tex.type = "Diff" ; format "[%] MISSING TEMPLATE !\n" tex.name) -- !!! DEBUG tex.SourceImage = TCSImage progressVal += (25.0 / ((FilteredList[AssetIndex].textureList.count as float) * SceneDump.selection.numberset)) TexLoadProgress.value = progressVal as integer free xml_io ) if (TCSImage == "NO SOURCE IMAGE") then ( -- Use default image location + .TIF format which will be 95% correct under current conditions (made up statistic) tex.SourceImage = ::RsConfigGetAssetsDir() + "maps/textures/" + tex.name + ".tif" ) append P4Textures tex.SourceImage --format "%\n" tex -- !!! DEBUG ) --if (P4Assets.count > 0) then (if P4SYNCH then (gRsPerforce.sync P4Assets Force:forceGet Silent:True)) else (if DEBUG_SPEW then format "No Source Images in P4 grab!\n") for tex in FilteredList[AssetIndex].textureList do ( -- Read the image Sizes, Templates, Format if (tex.sourceImage != "NO SOURCE IMAGE") then ( if (doesFileExist tex.sourceImage) then ( try ( local tempBitmap = openbitmap tex.sourceImage tex.sourceRes = (tempBitmap.width as string) + "x" + (tempBitmap.height as string) free tempBitmap ) catch (tex.sourceRes = "UNKNOWN") ) if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( -- RAG widgetry dumps texture list CSV to TextureDumpFileLocation -- Fields should be... -- Texture Name, Dictionary Name, Dictionary ID (Txd/Draw:UID), SizeKB (#.3f), Dimensions (WxH), Mips, BPP, Format, HD (Yes/No) RemoteConnection.WriteStringWidget "Texture Viewer/Search Type" "Textures" RemoteConnection.WriteStringWidget "Texture Viewer/Search Filter" tex.name RemoteConnection.WriteBoolWidget "Texture Viewer/Search" true RemoteConnection.WriteBoolWidget "Texture Viewer/Load Texture/Txd/Load All List Entries" true RemoteConnection.WriteStringWidget "Texture Viewer/Utilities/Dump List Path" TextureDumpFileLocation RemoteConnection.WriteBoolWidget "Texture Viewer/Utilities/Dump List To CSV" true RemoteConnection.SendSyncCommand() texFile = openFile TextureDumpFileLocation if (texFile != undefined) then ( tex.dupes = #{} ; tex.sizeTotal = 0 local notFound = true while (not (eof texFile)) do ( local nextline = (filterString (readline texFile) ",") if (nextline.count >= 8) then ( if (nextline[1] == (toLower tex.name)) then ( if (nextline[2] == FilteredList[AssetIndex].name) then ( tex.size = (trimright nextline[4] "KB") as float if (tex.size == undefined) then (tex.size = "UNKNOWN...") tex.dims = nextline[5] tex.form = nextline[8] notFound = false ) ) ) else ( format "Problem with Texture Viewer Output\n%\n" nextline notFound = false ) ) if notFound then format "% : Couldn't find in Texture Viewer dump !\n" tex.name ) else ( format "% : Texture Dump File missing !\n" tex.name ) ) ) --format "%\n" tex -- !!! DEBUG progressVal += (50.0 / ((FilteredList[AssetIndex].textureList.count as float) * SceneDump.selection.numberset)) TexLoadProgress.value = progressVal as integer ) ) --TextureList = FilteredList[AssetIndex].textureList --TextureList = #() for texIndex = 1 to FilteredList[AssetIndex].textureList.count do -- in RsSceneAnalyser.SceneDump.selection do -- ( local textureListNames = for listTex in TextureList collect listTex.name local textureSearch = (findItem textureListNames FilteredList[AssetIndex].textureList[texIndex].name) if (textureSearch == 0) then ( append TextureList FilteredList[AssetIndex].textureList[texIndex] TextureList[TextureList.count].dupes = #{AssetIndex} TextureList[TextureList.count].sizeTotal = FilteredList[AssetIndex].textureList[texIndex].size ) else ( append TextureList[textureSearch].dupes AssetIndex TextureList[textureSearch].sizeTotal += FilteredList[AssetIndex].textureList[texIndex].size ) ) ) ---- ANALYSER EVENTS ---- --on WarpToTXDs entered TXDString on WarpToTXDs pressed do ( fn getFilesRecursive root pattern = ( dir_array = GetDirectories (root+"/*") for d in dir_array do join dir_array (GetDirectories (d+"/*")) my_files = #() for f in dir_array do join my_files (getFiles (f + pattern)) my_files ) local TXDList = filterstring WarpToNames.text ", " local TXDBounds = #() for TXDname in TXDList do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteStringWidget "Texture Viewer/Search Type" "Texture Dictionaries" RemoteConnection.WriteBoolWidget "Texture Viewer/Search Params/Exact Name Match" true RemoteConnection.WriteStringWidget "Texture Viewer/Search Filter" TXDname RemoteConnection.WriteBoolWidget "Texture Viewer/Search" true ) -- find XML from name, open, find objects with TXD name, increase bounding box local TXDParse = filterstring TXDname "_" if (TXDParse.count > 1) then ( local XMLname = TXDParse[1]+"_"+TXDParse[2]+".xml" local XMLfiles = getFilesRecursive (::RsConfigGetAssetsDir()) XMLname if (XMLfiles.count > 0) then ( format "Searching in %\n" XMLfiles[1] local bounds = #([0,0,0], [0,0,0]) local xml_io = rsta_xml_io xmlFile:XMLfiles[1] local xml_objects = try(rsta_xml.getChildren xml_io.root name:"objects/object/children/object" attr:"superclass" value:"geomobject") catch(#()) for obj in xml_objects do ( local obj_TXD = try((rsta_xml.getChildren obj name:"attributes/attribute" attr:"name" value:"TXD")[1].getAttribute "value") catch("") --if ((toLower obj_TXD) == (toLower TXDname)) then if ((findstring (toLower obj_TXD) (toLower TXDname)) != undefined) then ( local obj_BBmin = [0,0,0] local obj_BBmax = [0,0,0] try ( obj_BBmin.x = ((obj.SelectSingleNode "boundingbox3/world/min").getAttribute "x") as float obj_BBmin.y = ((obj.SelectSingleNode "boundingbox3/world/min").getAttribute "y") as float obj_BBmin.z = ((obj.SelectSingleNode "boundingbox3/world/min").getAttribute "z") as float obj_BBmax.x = ((obj.SelectSingleNode "boundingbox3/world/max").getAttribute "x") as float obj_BBmax.y = ((obj.SelectSingleNode "boundingbox3/world/max").getAttribute "y") as float obj_BBmax.z = ((obj.SelectSingleNode "boundingbox3/world/max").getAttribute "z") as float ) catch() if (bounds[1]==[0,0,0]) and (bounds[2]==[0,0,0]) then ( bounds[1] = obj_BBmin ; bounds[2] = obj_BBmax ) else ( bounds[2].x = amax #(bounds[2].x, obj_BBmax.x) bounds[2].y = amax #(bounds[2].y, obj_BBmax.y) bounds[2].z = amax #(bounds[2].z, obj_BBmax.z) bounds[1].x = amin #(bounds[1].x, obj_BBmin.x) bounds[1].y = amin #(bounds[1].y, obj_BBmin.y) --bounds[1].z = amin #(bounds[1].z, obj_BBmin.z) bounds[1].z = bounds[2].z ) ) ) append TXDBounds bounds ) ) ) --format "%\n" TXDBounds -- !!!! WORKING -- Maybe add an auto Analyse option... if (TXDBounds.count > 0) then ( local WarpPoint = [0,0,0] for TXDbbox in TXDBounds do ( WarpPoint += (TXDbbox[1] + TXDbbox[2])/2 ) if (WarpPoint != [0,0,0]) then ( WarpPoint /= TXDBounds.count if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Camera/Create camera widgets" true RemoteConnection.SendSyncCommand() RemoteConnection.WriteFloatWidget "Camera/Free camera/Position X" WarpPoint.x RemoteConnection.WriteFloatWidget "Camera/Free camera/Position Y" WarpPoint.y RemoteConnection.WriteFloatWidget "Camera/Free camera/Position Z" WarpPoint.z format "Warping debug camera to %\n" WarpPoint ) ) ) ) on AnalyseScene pressed do ( ClearDumpSelection() ; SceneAnalysis() ) on LoadTextures pressed do (LoadTexturesSurround.enabled = true ; LoadTextures.enabled = true ; RsSceneAnalyser.Tex.TextureAnalyser.open = true) on LoadTexturesSurround clicked ArgIgnore do (LoadTexturesSurround.enabled = false ; LoadTextures.enabled = true ; RsSceneAnalyser.Tex.TextureAnalyser.open = false) on LoadXMLs pressed do (LoadXMLsSurround.enabled = true ; LoadXMLs.enabled = true ) on LoadXMLsSurround clicked ArgIgnore do (LoadXMLsSurround.enabled = false ; LoadXMLs.enabled = true ) on SynchAssets pressed do (SynchSceneAssets()) on SynchTextures pressed do (SynchSceneTextures()) on ByteSize pressed do ( if ByteSize.text == "KB" then (ByteSize.text = "MB") else (ByteSize.text = "KB") MainTotal.text = KbToString TotalMain ; VRAMTotal.text = KbToString TotalVRAM SelectedMainTotal.text = KbToString ActiveMain ; SelectedVRAMTotal.text = KbToString ActiveVRAM DumpSceneItemList() ) on SelectedObject entered SearchString do ( local NameMatch = true local NamesCheck = filterstring SearchString " " local ExclusionTest = false local NewSelection = #{} ActiveMain = 0 ; ActiveVRAM = 0 for index = 1 to FilteredList.count do ( NameMatch = true for expr in NamesCheck do ( if (expr[1]) == "-" then ( -- Exclusive Test ExclusionTest = true ; ExprText = (trimleft expr "-") ) else ( -- Inclusive Test ExclusionTest = false ; ExprText = expr ) if (matchPattern FilteredList[index].name pattern:("*"+ExprText+"*") ignorecase:true) then ExprMatch = true else ExprMatch = false if ExclusionTest then (ExprMatch = not ExprMatch) NameMatch = NameMatch and ExprMatch ) NewSelection[index] = NameMatch if NameMatch then (ActiveMain += FilteredList[index].main ; ActiveVRAM = FilteredList[index].vram ) -- format "% %\n" SceneDump.items[index] NewSelection) ) SceneDump.selection = NewSelection if (SceneDump.selection.numberSet > 0) then ( SelectedObjectCount.text = SceneDump.selection.numberSet as string SelectedMainTotal.text = kbToString ActiveMain ; SelectedVRAMTotal.text = kbToString ActiveVRAM ) ListButtonUpdate() TextureAnalyser.ClearTextureList() ) on SelectedIMAP entered SearchString do ( local NameMatch = true local NamesCheck = filterstring SearchString " " local ExclusionTest = false local NewSelection = #{} ActiveMain = 0 ; ActiveVRAM = 0 for index = 1 to FilteredList.count do ( NameMatch = true for expr in NamesCheck do ( if (expr[1]) == "-" then ( -- Exclusive Test ExclusionTest = true ; ExprText = (trimleft expr "-") ) else ( -- Inclusive Test ExclusionTest = false ; ExprText = expr ) if (matchPattern FilteredList[index].imap pattern:("*"+ExprText+"*") ignorecase:true) then ExprMatch = true else ExprMatch = false if ExclusionTest then (ExprMatch = not ExprMatch) NameMatch = NameMatch and ExprMatch ) NewSelection[index] = NameMatch if NameMatch then (ActiveMain += FilteredList[index].main ; ActiveVRAM = FilteredList[index].vram)-- ; format "% %\n" SceneDump.items[index] NewSelection) ) SceneDump.selection = NewSelection if (SceneDump.selection.numberSet > 0) then ( SelectedObjectCount.text = SceneDump.selection.numberSet as string SelectedMainTotal.text = kbToString ActiveMain ; SelectedVRAMTotal.text = kbToString ActiveVRAM ) ListButtonUpdate() TextureAnalyser.ClearTextureList() ) on SelectedTXD entered SearchString do ( local NameMatch = true local NamesCheck = filterstring SearchString " " local ExclusionTest = false local NewSelection = #{} ActiveMain = 0 ; ActiveVRAM = 0 for index = 1 to FilteredList.count do ( NameMatch = true for expr in NamesCheck do ( if (expr[1]) == "-" then ( -- Exclusive Test ExclusionTest = true ; ExprText = (trimleft expr "-") ) else ( -- Inclusive Test ExclusionTest = false ; ExprText = expr ) --local TXDName = (if ( (( substring FilteredList[index].store 2 2) != "TD") and (FilteredList[index].depend !="") ) then (FilteredList[index].depend) else (FilteredList[index].name)) local TXDName = (if (FilteredList[index].depend !="") then (FilteredList[index].depend) else (FilteredList[index].name)) if (matchPattern TXDName pattern:("*"+ExprText+"*") ignorecase:true) then ExprMatch = true else ExprMatch = false if ExclusionTest then (ExprMatch = not ExprMatch) NameMatch = NameMatch and ExprMatch ) NewSelection[index] = NameMatch if NameMatch then (ActiveMain += FilteredList[index].main ; ActiveVRAM = FilteredList[index].vram)-- ; format "% %\n" SceneDump.items[index] NewSelection) ) SceneDump.selection = NewSelection if (SceneDump.selection.numberSet > 0) then ( SelectedObjectCount.text = SceneDump.selection.numberSet as string SelectedMainTotal.text = kbToString ActiveMain ; SelectedVRAMTotal.text = kbToString ActiveVRAM ) ListButtonUpdate() TextureAnalyser.ClearTextureList() ) on ListOnlySelected pressed do ( if (ListOnlySelected.text == "Isolate") then ( if (SceneDump.selection.isEmpty != true) then ( local newItems = #() local newSelection = #() for index in SceneDump.selection do ( append newItems SceneDump.items[index] append newSelection FilteredList[index] ) SceneDump.selection = #{} SceneDump.items = newItems FilteredList = newSelection FilteredObjectCount.text = SelectedObjectCount.text FilteredMainTotal.text = SelectedMainTotal.text FilteredVRAMTotal.text = SelectedVRAMTotal.text SelectedObjectCount.text = "0" SelectedMainTotal.text = kbToString 0 ; SelectedVRAMTotal.text = kbToString 0 ) ) else ( ClearDumpSelection() ; DumpSceneItemList() ) ListButtonUpdate() ) on SceneDump selectionEnd do ( ActiveMain = ActiveVRAM = 0 if LoadXMLsSurround.enabled then ( local IMAPsToLoad = #() for index in SceneDump.selection do ( --if ((substring FilteredList[index].store 2 2) == "DR") and (FilteredList[index].attr.guid == "") then if (FilteredList[index].attr.loaded == false) then ( appendIfUnique IMAPsToLoad FilteredList[index].assetPath --FilteredList[index].attr.guid = "-" -- Fail check next time if it fails to find the object in the asset file... FilteredList[index].attr.loaded = true -- Fail check next time if object fails to load from asset file... ) ) if IMAPsToLoad.count > 0 then ( if (Field1Surround.enabled or Field2Surround.enabled or Field3Surround.enabled or Field4Surround.enabled or LODLevelSurround.enabled) then ( ClearDumpSelection() ) local IMAPNames = for IMAPEntry in IMAPs collect IMAPEntry.name local camPos = FindCameraCoords() format "CamPos = %\n" camPos -- !!! DEBUG for nextIMAP in IMAPsToLoad do ( IMAPIndex = (findItem IMAPNames nextIMAP) if (IMAPIndex > 0) then (ReadAssetXML IMAPIndex IMAPsToLoad.count camPos) ) DumpSceneItemList() ) ) TextureList = #() TexLoadProgress.value = 0 for index in SceneDump.selection do ( ActiveMain += FilteredList[index].main ; ActiveVRAM += FilteredList[index].vram if LoadTexturesSurround.enabled then ( LoadTextureData index ) if (FilteredList[index].dependIndex > 0) then ( ObjectList[FilteredList[index].dependIndex].attr.LODLevel = FilteredList[index].attr.LODLevel ) ) TexLoadProgress.value = 100 qsort TextureList TextureAnalyser.CompareTextures TextureAnalyser.ClearTextureSelection() ; TextureAnalyser.DumpTextureList() if (SceneDump.selection.isEmpty) then ( SelectedObject.text = "" SelectedTXD.text = "" SelectedIMAP.text = "" TextureAnalyser.ClearTextureList() ) else ( local ActiveEntity = (SceneDump.selection as array)[1] SelectedObject.text = FilteredList[ActiveEntity].name SelectedTXD.text = FilteredList[ActiveEntity].depend SelectedIMAP.text = FilteredList[ActiveEntity].imap ShowEntityInRAG ActiveEntity "ITD" -- !!! Don't need this arg passed... ) ListButtonUpdate() SelectedObjectCount.text = SceneDump.selection.numberSet as string --DumpSceneItemList() SelectedMainTotal.text = kbToString ActiveMain ; SelectedVRAMTotal.text = kbToString ActiveVRAM ) on MValue1 selected Arg do ( SortByField1.text = MathsButtons[Arg] if (MOperator1.selection == 1) then (SortByField4.text = MathsButtons[TheUnsetValue()]) ClearDumpSelection() ; DumpSceneItemList() ) on MValue2 selected Arg do ( SortByField2.text = MathsButtons[Arg] if (MOperator1.selection == 1) then (SortByField4.text = MathsButtons[TheUnsetValue()]) ClearDumpSelection() ; DumpSceneItemList() ) on MValue3 selected Arg do ( SortByField3.text = MathsButtons[Arg] if (MOperator1.selection == 1) then (SortByField4.text = MathsButtons[TheUnsetValue()]) ClearDumpSelection() ; DumpSceneItemList() ) on MOperator1 selected Arg do ( if (Arg == 1) then ( MOperator2.selection = 1 ; MOperator2.enabled = false SortByField4.text = MathsButtons[TheUnsetValue()] ) else ( SortByField4.text = "Result" ; MOperator2.enabled = true ) ClearDumpSelection() ; DumpSceneItemList() ) on MOperator2 selected Arg do ( ClearDumpSelection() ; DumpSceneItemList() ) on MOperator3 selected Arg do ( if (Arg == 1) then (MConstant.enabled = false) else (MConstant.enabled = true) ClearDumpSelection() ; DumpSceneItemList() ) on MConstant changed Arg do ( ClearDumpSelection() ; DumpSceneItemList() ) -- FILTER TOGGLE EVENTS on UseNameFilter changed Arg do (NameFilter.enabled = Arg ; ClearDumpSelection() ; DumpSceneItemList()) on NameFilter entered ArgIgnore do (ClearDumpSelection() ; DumpSceneItemList()) on IDRFilter pressed do ( IDRSurround.enabled = true ; IDRFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on IDDFilter pressed do ( IDDSurround.enabled = true ; IDDFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on ITDFilter pressed do ( ITDSurround.enabled = true ; ITDFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on OtherFilter pressed do ( OtherSurround.enabled = true ; OtherFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on IDRSurround clicked ArgIgnore do ( IDRSurround.enabled = false ; IDRFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on IDDSurround clicked ArgIgnore do ( IDDSurround.enabled = false ; IDDFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on ITDSurround clicked ArgIgnore do ( ITDSurround.enabled = false ; ITDFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on OtherSurround clicked ArgIgnore do ( OtherSurround.enabled = false ; OtherFilter.enabled = true ; ClearDumpSelection() ; DumpSceneItemList() ) on IDRFilter rightclick do ( ITDSurround.enabled = IDDSurround.enabled = OtherSurround.enabled = false ; IDRSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on IDDFilter rightclick do ( IDRSurround.enabled = ITDSurround.enabled = OtherSurround.enabled = false ; IDDSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on ITDFilter rightclick do ( IDRSurround.enabled = IDDSurround.enabled = OtherSurround.enabled = false ; ITDSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on OtherFilter rightclick do ( IDRSurround.enabled = IDDSurround.enabled = ITDSurround.enabled = false ; OtherSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on IDRSurround rightclick do ( ITDSurround.enabled = IDDSurround.enabled = OtherSurround.enabled = false ; IDRSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on IDDSurround rightclick do ( IDRSurround.enabled = ITDSurround.enabled = OtherSurround.enabled = false ; IDDSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on ITDSurround rightclick do ( IDRSurround.enabled = IDDSurround.enabled = OtherSurround.enabled = false ; ITDSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on OtherSurround rightclick do ( IDRSurround.enabled = IDDSurround.enabled = ITDSurround.enabled = false ; OtherSurround.enabled = true IDRFilter.enabled = IDDFilter.enabled = ITDFilter.enabled = OtherFilter.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) ---- SORT EVENTS ---- on SortByName pressed do ( SceneDump.selection = #() NameSurround.enabled = true StoreSurround.enabled = LODLevelSurround.enabled = Field1Surround.enabled = Field2Surround.enabled = Field3Surround.enabled = Field4Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField2.enabled = SortByField3.enabled = SortByField4.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SortByStore pressed do ( SceneDump.selection = #() StoreSurround.enabled = true NameSurround.enabled = LODLevelSurround.enabled = Field1Surround.enabled = Field2Surround.enabled = Field3Surround.enabled = Field4Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField2.enabled = SortByField3.enabled = SortByField4.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SortByLODLevel pressed do ( SceneDump.selection = #() LODLevelSurround.enabled = true NameSurround.enabled = StoreSurround.enabled = Field1Surround.enabled = Field2Surround.enabled = Field3Surround.enabled = Field4Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField2.enabled = SortByField3.enabled = SortByField4.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SortByField1 pressed do ( SceneDump.selection = #() Field1Surround.enabled = true StoreSurround.enabled = LODLevelSurround.enabled = NameSurround.enabled = Field2Surround.enabled = Field3Surround.enabled = Field4Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField2.enabled = SortByField3.enabled = SortByField4.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SortByField2 pressed do ( SceneDump.selection = #() Field2Surround.enabled = true StoreSurround.enabled = LODLevelSurround.enabled = Field1Surround.enabled = NameSurround.enabled = Field3Surround.enabled = Field4Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField2.enabled = SortByField3.enabled = SortByField4.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SortByField3 pressed do ( SceneDump.selection = #() Field3Surround.enabled = true StoreSurround.enabled = LODLevelSurround.enabled = NameSurround.enabled = Field1Surround.enabled = Field2Surround.enabled = Field4Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField2.enabled = SortByField4.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SortByField4 pressed do ( SceneDump.selection = #() Field4Surround.enabled = true StoreSurround.enabled = LODLevelSurround.enabled = Field1Surround.enabled = Field2Surround.enabled = NameSurround.enabled = Field3Surround.enabled = false SortByName.enabled = SortByStore.enabled = SortByLODLevel.enabled = SortByField1.enabled = SortByField4.enabled = SortByField2.enabled = SortByField3.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) ---- RAG WIDGET CONTROL EVENTS ---- on MOHToggle pressed do ( local prevState = MOHIsolate.enabled MOHSurround.enabled = true ; MOHToggle.enabled = true ; MOHIsolate.enabled = prevState if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Enable" true ) on MOHSurround clicked Side do ( if (Side < 75) then ( local prevState = MOHIsolate.enabled MOHSurround.enabled = false ; MOHToggle.enabled = true ; MOHIsolate.enabled = prevState if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Enable" false RemoteConnection.WriteBoolWidget "Texture Viewer/Visible" false ) else ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if MOHIsolate.enabled then ( MOHISolate.enabled = false ; RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Isolate selected" false) else ( MOHISolate.enabled = true ; RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Isolate selected" true ) ) ) on MOHIsolate pressed do ( MOHIsolate.enabled = not MOHIsolate.enabled if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Scene/Map Optimization Helper/Isolate selected" MOHISolate.enabled ) on TexViewerToggle pressed do ( if (not MOHSurround.enabled) then ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Texture Viewer/Visible" true ) TexViewerSurround.enabled = true ; TexViewerToggle.enabled = true ) on TexViewerSurround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Texture Viewer/Visible" false TexViewerSurround.enabled = false ; TexViewerToggle.enabled = true ) on Isolation pressed do ( IsoSurround.enabled = true ; Isolation.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Blocks/Isolate Block" true ) on IsoSurround clicked ArgIgnore do ( IsoSurround.enabled = false if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Blocks/Isolate Block" false ) on OcclFlip pressed do ( OcclFlipSurround.enabled = true ; OcclFlip.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Renderer/Occlusion/Flip Result" true ) on OcclFlipSurround clicked ArgIgnore do ( OcclFlipSurround.enabled = false ; OcclFlip.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Renderer/Occlusion/Flip Result" false ) on OcclOff pressed do ( OcclOffSurround.enabled = true ; OcclOff.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Renderer/Occlusion/Force Disable Occlusion" false ) on OcclOffSurround clicked ArgIgnore do ( OcclOffSurround.enabled = false ; OcclOff.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Renderer/Occlusion/Force Disable Occlusion" true ) on LookAtObj pressed do ( LookAtSurround.enabled = true ; LookAtObj.enabled = true if (not SceneDump.selection.isEmpty) then (LookAtPoint FilteredList[(SceneDump.selection as array)[1]].attr.pos) ) on LookAtSurround clicked ArgIgnore do ( LookAtSurround.enabled = false ; LookAtObj.enabled = true) on LODLevel selected Arg do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteStringWidget "Scene/PostScan/Lod Level" LODLevel.selected ) ) on LODFunction selected Arg do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Switch to level" (Arg == 2) RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull only level" (Arg == 3) RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull all except level" (Arg == 4) ) ) on OrphanToggle pressed do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull orphan HD" false ) OrphanSurround.enabled = true ; OrphanToggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on HDToggle pressed do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull lodded HD" false ) HDSurround.enabled = true ; HDToggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on LODToggle pressed do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull LOD" false ) LODSurround.enabled = true ; LODToggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SLOD1Toggle pressed do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull SLOD1" false ) SLOD1Surround.enabled = true ; SLOD1Toggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SLOD2Toggle pressed do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull SLOD2" false ) SLOD2Surround.enabled = true ; SLOD2Toggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SLOD3Toggle pressed do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull SLOD3" false ) SLOD3Surround.enabled = true ; SLOD3Toggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on OrphanSurround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull orphan HD" true ) OrphanSurround.enabled = false ; OrphanToggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on HDSurround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull lodded HD" true ) HDSurround.enabled = false ; HDToggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on LODSurround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull LOD" true ) LODSurround.enabled = false ; LODToggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SLOD1Surround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull SLOD1" true ) SLOD1Surround.enabled = false ; SLOD1Toggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SLOD2Surround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull SLOD2" true ) SLOD2Surround.enabled = false ; SLOD2Toggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on SLOD3Surround clicked ArgIgnore do ( if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/PostScan/Cull SLOD3" true ) SLOD3Surround.enabled = false ; SLOD3Toggle.enabled = true ClearDumpSelection() ; DumpSceneItemList() ) on WireMode selected Arg do ( local findSelection = (SceneDump.selection as array)[1] -- !!! Can do this better... if findSelection != undefined then ( local storeType = substring FilteredList[findSelection].store 2 2 if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.IsConnected()) then ( if (storeType == "TD") then ( RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredList[findSelection].name RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Uses Parent Txd ..." ) else ( if (FilteredList[findSelection].depend == "") or (Arg == 1) then ( RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredList[findSelection].name RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Name Is ..." ) else ( RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode Params/Filter" FilteredList[findSelection].depend RemoteConnection.WriteStringWidget "Renderer/Wireframe/Mode" "Model Uses Parent Txd ..." ) ) ) ) ) on WireToggle pressed do ( WireSurround.enabled = true ; WireToggle.enabled = WireOpacity.enabled = WireMode.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Renderer/Wireframe/Draw" true ) on WireSurround clicked ArgIgnore do ( WireSurround.enabled = WireOpacity.enabled = WireMode.enabled = false ; WireToggle.enabled = true if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() RemoteConnection.WriteBoolWidget "Renderer/Wireframe/Draw" false ) on WireOpacity clicked Val do ( WireOpacity.value = Val ; if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if (RemoteConnection.isConnected()) then ( RemoteConnection.WriteFloatWidget "Renderer/Wireframe/Rendering/Opacity" (Val / 100.0) if (val > 50) then (RemoteConnection.WriteFloatWidget "Renderer/Wireframe/Rendering/Fill Opacity" ((val/400.0)+0.25)) else (RemoteConnection.WriteFloatWidget "Renderer/Wireframe/Rendering/Fill Opacity" 0.0) RemoteConnection.WriteFloatWidget "Renderer/Wireframe/Rendering/Invisible Opacity" ((100 - val)/350.0) ) ) ---- ROLLOUT OPEN/RESIZE EVENTS ---- on RsSceneAnalyser open do ( banner.setup() ) on RsSceneAnalyser resized newSize do ( -- Scale object list and move totals so they stay visible unless it goes below 5 lines of module list local NewSceneDumpHeight = (newSize[2] - (SceneDump.pos.y + RsSceneAnalyser.Tex.height + RsSceneAnalyser.Tex.pos.y - SelectedObject.pos.y) - 5 ) as integer if ((NewSceneDumpHeight + 5) > (JArowSize * 5)) then ( SceneDump.height = NewSceneDumpHeight local newPos = SceneDump.pos.y + SceneDump.height + 1 SelectedObject.pos.y = newPos SelectedTXD.pos.y = newPos SelectedIMAP.pos.y = newPos ListOnlySelected.pos.y = newPos + 1 newPos += 20 SelectedTotals.pos.y = newPos + 2 SelectedObjectCount.pos.y = newPos SelectedStoreTotal.pos.y = newPos SelectedMainTotal.pos.y = newPos SelectedVRAMTotal.pos.y = newPos newPos += 16 FilteredTotals.pos.y = newPos + 2 FilteredObjectCount.pos.y = newPos FilteredStoreTotal.pos.y = newPos FilteredMainTotal.pos.y = newPos FilteredVRAMTotal.pos.y = newPos newPos += 16 ObjectTotals.pos.y = newPos + 2 ObjectCount.pos.y = newPos StoreTotal.pos.y = newPos MainTotal.pos.y = newPos VRAMTotal.pos.y = newPos newPos += 26 Tex.pos.y = newPos ) ) on RsSceneAnalyser close do ( -- Remove temporary ZIP files, kill the Texture Preview dialog local cmd = "del /Q " + JAAssetZipTemp + "*.zip" ; HiddenDOSCommand cmd donotwait:true try ( DestroyDialog RsTexPreview ) catch() if RemoteConnection.IsConnected() then RemoteConnection.Disconnect() free RsSceneAnalyserPos free ObjectList free FilteredList free TextureList free IMAPs free P4Assets free P4Textures free TextureAnalyser free RsSceneAnalyser ) ) if not (RemoteConnection.IsConnected()) then RemoteConnection.Connect() if RemoteConnection.IsConnected() then ( RemoteConnection.WriteBoolWidget "Scene/Create Scene widgets" true RemoteConnection.WriteBoolWidget "Camera/Create camera widgets" true RemoteConnection.WriteBoolWidget "Renderer/Create Renderer widgets" true RemoteConnection.WriteBoolWidget "Streaming & Memory/Create streaming memory widgets" true ) CreateDialog RsSceneAnalyser width:(RsSceneAnalyser.JAwidth+12) lockWidth:true style:#(#style_titlebar, #style_border, #style_sysmenu,#style_toolwindow, #style_resizing) --476 AddSubRollout RsSceneAnalyser.Tex TextureAnalyser setDialogPos RsSceneAnalyser RsSceneAnalyserPos