289 lines
8.2 KiB
Plaintext
Executable File
289 lines
8.2 KiB
Plaintext
Executable File
-- Scene Info Browser for optimisation
|
||
-- Rick Stirling, Rockstar North, October 2011
|
||
|
||
-- The original request from Aaron was
|
||
-- Would it be possible to quickly knowck something up that displays the selections polycount, shader count, and a bunch of attributes…
|
||
-- Lod distance
|
||
-- Txd
|
||
-- Low priority
|
||
-- Don’t add to ipl
|
||
|
||
|
||
-------------------------------------------------------------------------------------------------------------------------
|
||
-- This line loads the custom header
|
||
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
||
--sceneInfoUI = undefined -- declare the UI
|
||
|
||
|
||
|
||
-- item to check, what we are looking for, test when a string (true = good, false = bad)
|
||
abnormalDataChecks = #(
|
||
--#("TXD", "CHANGEME",false),
|
||
--#("Collision Group", "undefined",true),
|
||
#("IPL Group", "undefined",true),
|
||
#("Dont Export", true, false),
|
||
#("Level Design Object", true, false),
|
||
#("Is time object", true, false),
|
||
#("Dont Add To IPL", true, false),
|
||
#("Has Door Physics", true, false),
|
||
#("Has Anim", true, false),
|
||
#("Has UvAnim", true, false),
|
||
#("Is Cloth", true, false),
|
||
#("Dont cast shadows", true, false),
|
||
#("padding",false,false)
|
||
)
|
||
|
||
-- animation flags
|
||
--is door
|
||
--is level design object
|
||
|
||
badgeoData =#()
|
||
|
||
|
||
fn processgeo geoObj polyshaderusage = (
|
||
|
||
geoData=#()
|
||
|
||
-- Parse the geo to get the polycount and shader data
|
||
-- Create a virtual copy of the mesh as a trimesh for better stats
|
||
tempdatamesh = snapshotAsMesh geoObj as TriMesh
|
||
|
||
-- Polycount
|
||
thepolycount = getnumfaces tempdatamesh
|
||
append geoData thepolycount
|
||
|
||
|
||
objMaterials = #()
|
||
uobjMaterials = #()
|
||
|
||
materialClass = classof geoObj.material
|
||
if (materialClass == Multimaterial) then
|
||
(
|
||
for facecount = 1 to thepolycount do
|
||
(
|
||
face = getFace tempdatamesh facecount
|
||
matid = getFaceMatId tempdatamesh facecount
|
||
append objMaterials matid
|
||
appendifunique uobjMaterials matid
|
||
)
|
||
)
|
||
|
||
else
|
||
(
|
||
append objMaterials "1"
|
||
append uobjMaterials "1"
|
||
)
|
||
|
||
|
||
shadercount = uobjMaterials.count
|
||
append geoData shadercount
|
||
|
||
|
||
|
||
-- find shaders with low poly usages
|
||
lowpolyshaders=#()
|
||
for spf = 1 to uobjMaterials.count do
|
||
(
|
||
-- go through each used shader in turn
|
||
theShaderID = uobjMaterials[spf]
|
||
|
||
-- count the number of polys that use that.
|
||
mycounter = 0
|
||
for pus = 1 to objMaterials.count do
|
||
(
|
||
if objMaterials[pus] == theShaderID then mycounter+=1
|
||
)
|
||
|
||
-- Under the check amount?
|
||
if mycounter < polyshaderusage then append lowpolyshaders theShaderID
|
||
)
|
||
|
||
sort lowpolyshaders
|
||
|
||
append geodata lowpolyshaders
|
||
|
||
--return this:
|
||
geoData
|
||
)
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
-- read all geo in the scene to see if it's good
|
||
fn selectAbnormalObjects = (
|
||
|
||
badgeoData =#()
|
||
isbad = false
|
||
|
||
-- find bad shit in the scene
|
||
for selObj in geometry do
|
||
(
|
||
-- Check attributes
|
||
for abnormalcheckindex = 1 to abnormalDataChecks.count do
|
||
(
|
||
selObjAttrib = readAttribute selObj abnormalDataChecks[abnormalcheckindex][1] false
|
||
checkObjAttrib = abnormalDataChecks[abnormalcheckindex][2]
|
||
tfcheck = abnormalDataChecks[abnormalcheckindex][3]
|
||
|
||
reasondata = #(selobj, abnormalDataChecks[abnormalcheckindex][1])
|
||
|
||
if ((selObjAttrib == checkObjAttrib) and (tfcheck == false)) then appendifunique badgeoData reasondata
|
||
)
|
||
|
||
-- Check children
|
||
selKids = selobj.children
|
||
kidcount = selKids.count
|
||
for kidIndex = 1 to kidcount do
|
||
(
|
||
thekid = selKids[kidIndex]
|
||
|
||
-- is it a light?
|
||
if superclassof thekid == light then appendifunique badgeoData (#(selobj,"LIGHT CHILD"))
|
||
)
|
||
|
||
)
|
||
|
||
|
||
|
||
|
||
max unhide all
|
||
clearSelection()
|
||
for baddata in badgeoData do selectmore baddata[1]
|
||
max hide inv
|
||
clearSelection()
|
||
|
||
|
||
|
||
|
||
)
|
||
|
||
|
||
|
||
|
||
|
||
fn populateUI = (
|
||
-- is anything selected?
|
||
theSelection = getcurrentselection()
|
||
if (theSelection.count > 0) do
|
||
(
|
||
selObj = theSelection[1]
|
||
|
||
if (classof selObj == Editable_mesh) or (classof selObj == Editable_poly) then
|
||
(
|
||
|
||
--get geo data
|
||
returnedgeodata = processgeo selObj sceneInfoUI.spnPolysPerShader.value
|
||
|
||
-- Only look at the first object in the selection
|
||
sceneInfoUI.edtSelObjectName.text = selObj.name
|
||
sceneInfoUI.edtTXDName.text = (readAttribute selObj "TXD" false)
|
||
|
||
sceneInfoUI.edtSelObjectPolycount.text = (returnedgeodata[1] as string)
|
||
sceneInfoUI.edtSelObjectNumShaders.text = (returnedgeodata[2] as string)
|
||
|
||
sceneInfoUI.edtLODVal.text = ((readAttribute selObj "LOD distance" false) as string)
|
||
|
||
sceneInfoUI.edtLowPolyShaders.text = (returnedgeodata[3] as string)
|
||
|
||
sceneInfoUI.chkAddToIPL.state = (readAttribute selObj "Dont Add To IPL" false)
|
||
sceneInfoUI.chkLowPriority.state = (readAttribute selObj "Low Priority" false)
|
||
|
||
sceneInfoUI.edtAbnormalReason.text = ""
|
||
|
||
-- Try to report abnormal data here
|
||
for baddata in badgeoData do
|
||
(
|
||
if baddata[1] == selObj then (sceneInfoUI.edtAbnormalReason.text = baddata[2])
|
||
)
|
||
)
|
||
|
||
|
||
else -- not a valid geometry object
|
||
(
|
||
sceneInfoUI.edtSelObjectName.text = selObj.name
|
||
sceneInfoUI.edtTXDName.text = "NOT READABLE"
|
||
sceneInfoUI.edtSelObjectPolycount.text = "UNKNOWN"
|
||
sceneInfoUI.edtSelObjectNumShaders.text = "UNKNOWN"
|
||
)
|
||
)
|
||
)
|
||
|
||
if sceneInfoUI != undefined then
|
||
(
|
||
destroydialog sceneInfoUI
|
||
)
|
||
-------------------------------------------------------------------------------------------------------------------------
|
||
rollout sceneInfoUI "Scene Info Browser" width:220 height:360
|
||
(
|
||
|
||
--hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Scene_Info_Browser" align:#right color:(color 20 20 255) hoverColor:(color 255 255 255) visitedColor:(color 0 0 255)
|
||
--Head
|
||
button btnLogo tooltip:"Feedback" border:false align:#left offset:[0, 2] images:#("RockStarNorthLogo.bmp", "RockStarNorthLogo_Mask.bmp", 1, 1, 1, 1, 1, false) across:2
|
||
button btnHelp tooltip:"Help?" border:false align:#right offset:[0, 2] images:#("HelpIcon_32.bmp", "HelpIcon_32a.bmp", 1, 1, 1, 1, 1, false)
|
||
groupbox grpHeader width:210 height:46 pos:[4, 0]
|
||
|
||
group "Object Info"
|
||
(
|
||
edittext edtSelObjectName "Object" text:"OBJECT NAME" fieldWidth:150 labelOnTop:false readOnly:true bold:false
|
||
edittext edtTXDName " TXD" text:"TXD NAME" fieldWidth:150 labelOnTop:false readOnly:true
|
||
edittext edtSelObjectPolycount "Polycount" text:"POLYCOUNT" fieldWidth:80 labelOnTop:true across:2 readOnly:true
|
||
edittext edtSelObjectNumShaders "Shader count" text:"SHADER COUNT" fieldWidth:80 offset:[8, 0]labelOnTop:true readOnly:true
|
||
edittext edtLODVal "LOD Distance" fieldwidth:50 readOnly:true
|
||
spinner spnPolysPerShader "Poly:shader threshold" type:#integer fieldwidth:30 range:[0,500,50] align:#left
|
||
edittext edtLowPolyShaders "" text:"SHADER LIST" fieldWidth:190 labelOnTop:true readOnly:true
|
||
|
||
checkbox chkLowPriority "Low Priority" across:2
|
||
checkbox chkAddToIPL "Don't Add To IPL"
|
||
)
|
||
--button btnGReadSelected "Read Selected Geo" width:170 height:25
|
||
button btnScenStats "Launch Scene Stats" width:210 height:25
|
||
|
||
button btnSelectAbnormal "Show Abnormal Objects" width:210 height:25
|
||
edittext edtAbnormalReason "Reason" text:"" fieldWidth:160 labelOnTop:false readOnly:true
|
||
|
||
button btnCollisionReporter "Collision Mesh Reporter" width:210 height:25
|
||
|
||
|
||
|
||
on sceneInfoUI open do
|
||
(
|
||
populateUI()
|
||
)
|
||
|
||
|
||
on sceneInfoUI close do
|
||
(
|
||
callbacks.removescripts #selectionsetchanged id:#sceneinfo
|
||
)
|
||
|
||
--------------------------------------------------------------
|
||
--Launch help docs in browser
|
||
--------------------------------------------------------------
|
||
on btnHelp pressed do
|
||
(
|
||
process = dotnetobject "System.Diagnostics.Process"
|
||
process.start "https://devstar.rockstargames.com/wiki/index.php/Scene_Info_Browser"
|
||
|
||
process.dispose()
|
||
)
|
||
|
||
|
||
on btnGReadSelected pressed do populateUI()
|
||
on btnScenStats pressed do filein (theProjectToolsRoot + "/dcc/current/max2012/scripts/rockstar/helpers/scenestats.ms")
|
||
|
||
|
||
on btnSelectAbnormal pressed do selectAbnormalObjects()
|
||
|
||
on btnCollisionReporter pressed do filein (RsConfigGetWildWestDir() + "script/3dsMax/Maps/Optimization/Collision_mesh_reporter.ms")
|
||
|
||
)
|
||
|
||
|
||
|
||
callbacks.addScript #selectionSetChanged "populateUI()" id:#sceneinfo
|
||
|
||
createDialog sceneInfoUI
|