404 lines
12 KiB
Plaintext
Executable File
404 lines
12 KiB
Plaintext
Executable File
--TexTXD
|
|
-- url:bugstar:313343
|
|
--Neil Gregory
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Uses
|
|
-----------------------------------------------------------------------------
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
filein "rockstar/util/material.ms" -- loaded on startup by startup.ms
|
|
|
|
-- .Net ListView Control
|
|
--filein ( (getdir #maxroot) + "stdplugs/stdscripts/NET_ListViewWrapper.ms" )
|
|
-----------------------------------------------------------------------------
|
|
-- .Net Initialisation
|
|
-----------------------------------------------------------------------------
|
|
dotNet.loadAssembly "System.Windows.Forms.dll"
|
|
dotNet.loadassembly "MaxCustomControls.dll"
|
|
RS_CustomDataGrid()
|
|
|
|
struct TextureObject
|
|
(
|
|
name, --bare name
|
|
path, --file path
|
|
width, --pixels
|
|
height, --pixels
|
|
size, --KB
|
|
txdList = #(), --TXDs belongs to
|
|
|
|
fn getArea =
|
|
(
|
|
return (width * height)
|
|
)
|
|
)
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Rollout
|
|
-----------------------------------------------------------------------------
|
|
try (DestroyDialog TXDSpy_UI)catch()
|
|
rollout TXDSpy_UI "Texture Map TXD Statistics"
|
|
(
|
|
|
|
-----------------------------------------------------------------------------------------
|
|
-- Script-scope Variables
|
|
-----------------------------------------------------------------------------------------
|
|
local appTitle = "Texture Map TXD Statistics"
|
|
local sceneTXDTextures = #()
|
|
local objectTextures = #() --#(name: val:#(tdxlist), memory, area )
|
|
local txdList = RsGetSceneTxdList()
|
|
local txdAttrIdx = getattrindex "Gta Object" "TXD"
|
|
local pieHeaders = #(#("ID", 30), #("Object", 100), #("Texture Name", 150), #("Mem Share", 150))
|
|
local affinityHeaders = #(#("ID", 30), #("Texture Name", 150))
|
|
|
|
local DNcolour = dotNetClass "System.Drawing.Color"
|
|
local textCol = (colorMan.getColor #windowText) * 255
|
|
local windowCol = (colorMan.getColor #window) * 255
|
|
local textColour = DNcolour.FromArgb textCol[1] textCol[2] textCol[3]
|
|
local backColour = DNcolour.FromArgb windowCol[1] windowCol[2] windowCol[3]
|
|
local altBackColour = DNcolour.FromArgb (windowCol[1]-10) (windowCol[2]-10) (windowCol[3]-10)
|
|
|
|
-----------------------------------------------------------------------------------------
|
|
-- UI Widgets and Layout
|
|
-----------------------------------------------------------------------------------------
|
|
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:TXDSpy_UI.width
|
|
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"TextureTXDUsage" filename:(getThisScriptFilename())
|
|
|
|
--button btnUpdate "Update" align:#left width:100 across:3
|
|
group ""
|
|
(
|
|
dropdownlist ddl_TXDList "SceneTXDs:" items:txdList tooltip:"Scene TXD selector"
|
|
checkButton btnAffinity "Object Texture Affinity" align:#left tooltip:"Textures common amongst object selection"
|
|
)
|
|
--hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Texture_TXD_Stats" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255)
|
|
--dotNetControl lstView "System.Windows.Forms.DataGridView" height:(300-65)
|
|
dotNetControl lstView "RsCustomDataGridView" width:595 height:(300-65) offset:[-10, 0]
|
|
progressbar barProgress
|
|
--button btnClose "Close" align:#right width:100
|
|
|
|
-----------------------------------------------------------------------------------------
|
|
-- Functions
|
|
-----------------------------------------------------------------------------------------
|
|
fn buildSceneTextureObjects =
|
|
(
|
|
--lets build the textureObjects for those in the sscene TXDs
|
|
for txd in txdList do
|
|
(
|
|
texmaplist = #()
|
|
RsGetTexMapsByTxdNameNoStrip texmaplist #() #() #() txd
|
|
|
|
for tex in texmaplist do
|
|
(
|
|
tex = (filterString tex "+")[1] --in case of a double texture take the first bitmap path
|
|
texName = getFileNameFile tex
|
|
--print texName
|
|
|
|
--add to dict
|
|
texExists = (for tex in sceneTXDTextures where tex.name == texName collect tex)[1]
|
|
|
|
--format "texExists: % \n" texExists
|
|
if texExists == undefined then
|
|
(
|
|
txObj = TextureObject()
|
|
txObj.name = texName
|
|
txObj.path = tex
|
|
texBmp = if doesFileExist tex then openBitmap tex
|
|
if texBmp != undefined then
|
|
(
|
|
txObj.width = texBmp.width
|
|
txObj.height = texBmp.height
|
|
)
|
|
txObj.size = (getfilesize tex) / 1024
|
|
free texBmp
|
|
txObj.txdList = append txObj.txdList txd
|
|
|
|
append sceneTXDTextures (DataPair name:texName obj:txObj)
|
|
)
|
|
else --this texture object already exists, update its txd list
|
|
(
|
|
append texExists.obj.txdList txd
|
|
)
|
|
--get the file path
|
|
--RsGetTexMapTextures tex
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
fn TXDSpy =
|
|
(
|
|
if btnAffinity.checked == true then
|
|
(
|
|
TXDSpy_UI.columnHeaders "affinity"
|
|
TXDSpy_UI.sharedTextures()
|
|
return true
|
|
)
|
|
|
|
TXDSpy_UI.columnHeaders "pie"
|
|
--lstView.ListViewItemSorter = dotNetObject "GenericEditor.cListViewColumnNullSorter"
|
|
lstView.rows.Clear()
|
|
textureData = #()
|
|
|
|
txdList = RsGetSceneTxdList()
|
|
|
|
--Now match the selection with the built array/dict to determine usage and efficiency
|
|
--get the textures on the selection and match against the sceneTXDs
|
|
for obj in $selection do
|
|
(
|
|
objectTextures = #()
|
|
objTex = #()
|
|
RsGetTexMapsFromMaterial obj obj.material objTex #() #()
|
|
--RsGetTexMapListForMat $.material objectTex matIdList:matIDs
|
|
|
|
--TXDTextures = #()
|
|
|
|
--give the number of matches and % of memory for each texture on the selected object
|
|
TXDMatches = #()
|
|
memCompare = #()
|
|
areaCompare = undefined
|
|
for tex in objTex do
|
|
(
|
|
tex = (filterString tex "+")[1] --in case of a double texture take the first bitmap path
|
|
|
|
--Texture properties
|
|
--see if the object texture exists already in sceneTXDTextures and retrieve its propertes from there
|
|
texArea = undefined
|
|
texMemory = undefined
|
|
|
|
texObj = (for texItem in sceneTXDTextures where texItem.obj.name == tex collect texItem.obj)[1]
|
|
if texObj == undefined then continue
|
|
|
|
texArea = texObj.getArea()
|
|
texMemory = texObj.size
|
|
|
|
--now collect up all the texture area and memory for each TXD the texture is used in and compare to its own properties
|
|
TXDareaShare = 0
|
|
TXDmemShare = 0
|
|
|
|
--format "tex: % texObj: % \n" tex texObj.txdList
|
|
--get the txd match
|
|
objectTXD = tolower (getAttr obj txdAttrIdx)
|
|
UITXD = ddl_TXDList.selected
|
|
TXD = (for txd in texObj.txdList where UITXD == txd collect txd)[1]
|
|
--format "TXD: % \n" TXD
|
|
if TXD != undefined then --for txd in texObj.txdList where (getAttr obj txdAttrIdx) == txd do
|
|
(
|
|
texTXDTotalArea = 0
|
|
texTXDTotalMem = 0
|
|
|
|
--get the txd textures
|
|
TXDTextures = #()
|
|
RsGetTexMapsByTxdName TXDTextures #() #() #() TXD srcobjlist:#(obj)
|
|
|
|
--get the textureObjects for those textures
|
|
TXDTextureObjs = #()
|
|
for tex in TXDTextures do
|
|
(
|
|
--find the object
|
|
texObj = (for texItem in sceneTXDTextures where texItem.obj.name == tex collect texItem.obj)[1]
|
|
if texObj != undefined then
|
|
(
|
|
texTXDTotalArea += texObj.getArea()
|
|
texTXDTotalMem += texObj.size
|
|
)
|
|
)
|
|
--TXDareaShare = (texArea * (100.0 / texTXDTotalArea))
|
|
TXDmemShare = (texMemory * (100.0 / texTXDTotalMem))
|
|
if TXDmemShare < 0 or TXDmemShare > 100 then TXDmemShare = "--"
|
|
)
|
|
append objectTextures (DataPair name:obj.name props:#(tex, TXD, "TXDareaShare", TXDmemShare))
|
|
)
|
|
|
|
append textureData objectTextures
|
|
--TXDMatches = makeUniqueArray TXDMatches
|
|
--format "TXDMatches: %\n" TXDMatches
|
|
--format "objectTextures: %\n" objectTextures
|
|
|
|
)
|
|
|
|
count = 0
|
|
for objTx in textureData do
|
|
(
|
|
--random
|
|
--lstView.RowsDefaultCellStyle.backColor = DNcolour.FromArgb (random (windowCol[1]-30) windowCol[1]) (random (windowCol[2]-30) windowCol[2]) (random (windowCol[3]-30) windowCol[3])
|
|
objRowCol = DNcolour.FromArgb (random (windowCol[1]-40) windowCol[1]) (random (windowCol[2]-40) windowCol[2]) (random (windowCol[3]-40) windowCol[3])
|
|
for tex in objTx do
|
|
(
|
|
rowID = lstView.rows.Add #( count, tex.name, tex.props[1], tex.props[4] as Integer)
|
|
lstView.rows.item[rowId].DefaultCellStyle.backColor = objRowCol
|
|
count += 1
|
|
)
|
|
)
|
|
--print the number (and if expanded the names) of the shared textures used between any random selection of objects.
|
|
)
|
|
|
|
fn sharedTextures =
|
|
(
|
|
--clear the decks
|
|
lstView.rows.Clear()
|
|
|
|
if $selection.count < 2 then return false
|
|
|
|
commonTextures = #()
|
|
textureLib = #()
|
|
--get the textures from each object
|
|
for obj in $selection where isKindOf obj GeometryClass do
|
|
(
|
|
objectTextures = #()
|
|
objTex = #()
|
|
RsGetTexMapsFromMaterial obj obj.material objTex #() #()
|
|
print objTex
|
|
append textureLib (DataPair obj:obj textures:objTex)
|
|
)
|
|
|
|
--now boil em up to extract the common textures.
|
|
--texture centric obj arrays
|
|
for lib in textureLib do
|
|
(
|
|
--print lib
|
|
for tex in lib.textures do
|
|
(
|
|
for sibling in textureLib where sibling != lib do
|
|
(
|
|
for sibTex in sibling.textures where tex == sibTex do
|
|
(
|
|
append commonTextures tex
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
commonTextures = makeUniqueArray commonTextures
|
|
|
|
--format "common Textures: % \n" commonTextures
|
|
--format "count: % \n" commonTextures.count
|
|
count = 0
|
|
for tex in commonTextures do
|
|
(
|
|
lstView.rows.Add #( count, tex)
|
|
count += 1
|
|
)
|
|
)
|
|
|
|
fn columnHeaders mode =
|
|
(
|
|
--lvops.ClearColumns lstView
|
|
lstView.columns.Clear()
|
|
|
|
case mode of
|
|
(
|
|
"pie":
|
|
(
|
|
for item in pieHeaders do
|
|
(
|
|
num = lstView.columns.Add item[1] item[1]
|
|
lstView.columns.Item[num].minimumWidth = item[2]
|
|
lstView.columns.Item[num].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
|
|
)
|
|
)
|
|
|
|
"affinity":
|
|
(
|
|
for item in affinityHeaders do
|
|
(
|
|
num = lstView.columns.Add item[1] item[1]
|
|
lstView.columns.Item[num].minimumWidth = item[2]
|
|
lstView.columns.Item[num].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
|
|
)
|
|
)
|
|
|
|
default:
|
|
(
|
|
for item in pieHeaders do
|
|
(
|
|
num = lstView.columns.Add item[1] item[1]
|
|
lstView.columns.Item[num].minimumWidth = item[2]
|
|
lstView.columns.Item[num].autoSizeMode = (dotNetClass "System.Windows.Forms.DataGridViewAutoSizeColumnMode").AllCellsExceptHeader
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
fn init =
|
|
(
|
|
format "listView: % \n" lstView
|
|
|
|
lstView.AllowUserToAddRows = false
|
|
lstView.AllowUserToDeleteRows = false
|
|
lstView.AllowUserToOrderColumns = true
|
|
lstView.AllowUserToResizeRows = false
|
|
lstView.AllowUserToResizeColumns = false
|
|
lstView.AllowDrop = false
|
|
lstView.MultiSelect = true
|
|
lstView.ReadOnly = true
|
|
lstView.AutoSizeColumnsMode = (dotNetClass "DataGridViewAutoSizeColumnsMode").Fill
|
|
|
|
lstView.dock = lstView.dock.fill
|
|
lstView.DefaultCellStyle.backColor = backColour
|
|
lstView.DefaultCellStyle.foreColor = textColour
|
|
|
|
lstView.SelectionMode = (dotNetClass "DataGridViewSelectionMode").FullRowSelect
|
|
--lstView.AlternatingRowsDefaultCellStyle.BackColor = altBackColour
|
|
|
|
)
|
|
|
|
-----------------------------------------------------------------------------------------
|
|
-- Events dear boy
|
|
-----------------------------------------------------------------------------------------
|
|
on btnUpdate pressed do
|
|
(
|
|
columnHeaders "pie"
|
|
TXDSpy()
|
|
)
|
|
|
|
on btnAffinity changed arg do
|
|
(
|
|
if arg then
|
|
(
|
|
columnHeaders "affinity"
|
|
sharedTextures()
|
|
)
|
|
else
|
|
(
|
|
columnHeaders "pie"
|
|
TXDSpy()
|
|
)
|
|
)
|
|
|
|
fn ddlSelector item =
|
|
(
|
|
columnHeaders "pie"
|
|
TXDSpy()
|
|
)
|
|
|
|
on ddl_TXDList selected item do ddlSelector item
|
|
|
|
/*
|
|
on lstView ColumnClick args do
|
|
(
|
|
sorting = dotNetClass "System.Windows.Forms.SortOrder"
|
|
lstView.Sorting = sorting.Ascending
|
|
|
|
lstView.ListViewItemSorter = dotNetObject "GenericEditor.cListViewColumnIntSorter" args.Column
|
|
lstView.Sort()
|
|
)
|
|
*/
|
|
|
|
on TXDSpy_UI open do
|
|
(
|
|
banner.setup()
|
|
init()
|
|
columnHeaders "pie"
|
|
buildSceneTextureObjects()
|
|
|
|
callbacks.removeScripts id:#TexTXD
|
|
callbacks.addScript #SelectionSetChanged "TXDSpy_UI.TXDSpy()" id:#TexTXD
|
|
TXDSpy()
|
|
)
|
|
|
|
on TXDSpy_UI close do
|
|
(
|
|
callbacks.removeScripts id:#TexTXD
|
|
)
|
|
)
|
|
CreateDialog TXDSpy_UI width:600 height:400 \
|
|
--TXDSpy() |