-- Rockstar Lod Utils -- Rockstar North -- 12/10/2005 -- by Greg Smith global idxLodDistance = getattrindex "Gta Object" "LOD distance" global idxChildLodDistance = getattrindex "Gta Object" "Child LOD distance" global idxInstLodDistance = getattrindex "Gta Object" "Instance LOD distance" global idxIsMiloLod = getattrindex "Gta Object" "Is MLO LOD" fn RsGetObjLodDistance obj = ( if getattrclass obj != "Gta Object" then return 0.0 valLodDistance = getattr obj idxLodDistance valLodDistanceInst = getattr obj idxInstLodDistance if (isInternalRef obj) and (valLodDistanceInst == false) do ( linkobj = getIRefSource obj if getattrclass obj == "Gta Object" do ( valLodDistance = getattr obj idxLodDistance ) ) valLodDistance ) -------------------------------------------------------------- -- -------------------------------------------------------------- fn RsGetRootMostLodObject lobj = ( parentobj = RsSceneLink.getparent LinkType_LOD lobj while parentobj != undefined do ( lobj = parentobj parentobj = RsSceneLink.getparent LinkType_LOD lobj ) lobj ) -------------------------------------------------------------- -- get all the lod children of a passed in object -------------------------------------------------------------- fn RsGetLODChildren lodparent = ( childObjs = #() RsSceneLink.getchildren LinkType_LOD lodparent &childObjs return childObjs ) -------------------------------------------------------------- -- -------------------------------------------------------------- fn RsGetAllLODChildren lodobj output = ( lodchildren = RsGetLODChildren lodobj for lobj in lodchildren do ( append output lobj ) for lobj in lodchildren do ( RsGetAllLODChildren lobj output ) ) -------------------------------------------------------------------- -- True if obj is a Container LOD, or Container LOD Proxy -------------------------------------------------------------------- fn RsIsContainerLod obj = ( (isValidNode obj) and (isKindOf obj RsContainerLodRef) ) fn RsIsAnyLOD obj skipClassCheck:false = ( (skipClassCheck or (getattrclass obj == "Gta Object")) and ( ((RsGetLODChildren obj).count > 0) or (RsIsContainerLod obj) ) ) -------------------------------------------------------------- -- Returns true if the object is an oprhan (not part of any LOD hierarchies) -------------------------------------------------------------- fn RsIsOrphan obj = ( if getattrclass obj == "Gta Object" do ( lodObjRoot = RsGetRootMostLodObject obj if( lodObjRoot == obj ) then ( return true ) else ( return false ) ) return false ) -------------------------------------------------------------- -- -------------------------------------------------------------- fn RsIsLOD lobj = ( local retval = false if getattrclass lobj == "Gta Object" do ( local lodChildren = RsGetLODChildren lobj if (lodChildren.count > 0) and (getattr lobj idxIsMiloLod) == false do ( retval = true for childobj in lodChildren while retval do ( local childlodChildren = RsGetLODChildren childobj if childlodChildren.count > 0 then ( retval = false ) ) ) ) retval ) -------------------------------------------------------------------------------- -- Returns True if object has lod-children with their own lod-children -------------------------------------------------------------------------------- fn RsIsSuperLOD lobj skipClassCheck:true = ( local isSuperLod = false if (skipClassCheck or (getattrclass lobj == "Gta Object")) do ( local lodChildren = RsGetLODChildren lobj local lodParent = RsSceneLink.getparent LinkType_LOD lobj if ((lodChildren.count > 0) and ((getattr lobj idxIsMiloLod) == false)) do ( for childobj in lodChildren while not isSuperLod do ( local lodChildrenChildren = RsGetLODChildren childobj if lodChildrenChildren.count > 0 then ( isSuperLod = true ) ) ) ) return isSuperLod ) -------------------------------------------------------------------------------- -- Returns list of objects per Lod-level: -------------------------------------------------------------------------------- fn RsGetLodLevelObjs = ( local gtaObjs = for checkObj in objects where (getattrclass checkObj == "Gta Object") collect checkObj local lodLevelObjLists = for n = 1 to 4 collect #() -- Get initial known lod-levels: for n = 1 to gtaObjs.count do ( local checkObj = gtaObjs[n] local setLevel = case of ( -- Is this not a LOD object? (not RsIsAnyLOD checkObj skipClassCheck:true):1 -- Is this a Container LOD, or Container LOD Proxy? (RsIsContainerLod checkObj):4 -- We don't know what LOD-level this has, yet: default:0 ) -- Add known-level objects to respective lod-level lists: if (setLevel != 0) do ( append lodLevelObjLists[setLevel] checkObj ) ) -- Work out Lod-levels for lod-parents: local levelNum = 0 local lastNonEmpty = 0 while levelNum < (lodLevelObjLists.count) do ( levelNum += 1 local lodLevelObjs = lodLevelObjLists[levelNum] if (lodLevelObjs.count != 0) do ( lastNonEmpty = levelNum -- Set up next-level list, if undefined: if (lodLevelObjLists[levelNum + 1] == undefined) do ( append lodLevelObjLists #() ) local nextLevelList = lodLevelObjLists[levelNum + 1] -- Put object-parents into next lod-level list: for checkObj in lodLevelObjs do ( local lodParent = RsSceneLink.getparent LinkType_LOD checkObj if (lodParent != undefined) do ( if (not RsIsContainerLod lodParent) do ( append nextLevelList lodParent ) ) ) lodLevelObjLists[levelNum + 1] = makeUniqueArray nextLevelList ) ) -- Don't return empty lists: lodLevelObjLists.count = lastNonEmpty return lodLevelObjLists ) -------------------------------------------------------------- -- Show objects with a specific LOD-level, -- and hide ones from other levels -------------------------------------------------------------- fn RsShowLodLevel levels = ( local hideLevels = #{1..5} if (isKindOf levels bitArray) then ( hideLevels -= levels ) else ( local levelIdx = if (isKindOf levels integer) then levels else ( case levels of ( #high:1 #lod:2 #slod1:3 #slod2:4 #slod3:5 ) ) hideLevels[levelIdx] = false ) local checkObjs = #() join checkObjs rootnode.children for obj in rootnode.children where isKindOf obj Container do (join checkObjs obj.children) local showObjs = #() -- Get objects in each lod-level: local lodLevelObjLists = RsGetLodLevelObjs() -- Set hidden-flags: for n = 1 to lodLevelObjLists.count do ( local hideLod = hideLevels[n] lodLevelObjLists[n].isHidden = hideLod if not hideLod do ( join showObjs lodLevelObjLists[n] ) ) -- Include Shadow mesh objects with the LOD visablity level of their children for obj in showObjs do ( -- hide if not in this lod level local childArray = #() RsSceneLink.GetChildren 6 obj &childArray if (childArray.count != 0) do ( if ((finditem showObjs childArray[1]) == 0) do ( obj.isHidden = true ) ) -- show hidden shadowMesh parents local shadowParent = RsSceneLink.GetParent 6 obj if (shadowParent != undefined) do ( shadowParent.isHidden = false ) ) completeRedraw() return showObjs ) -------------------------------------------------------------- -- Tool to show only objects with specific LOD-levels: -------------------------------------------------------------- try (destroyDialog RsShowLodSlider) catch () rollout RsShowLodSlider "" width:100 ( multiListBox lstLodLevels "Show LOD Levels:" items:#("High Detail","LOD","SuperLOD 1","SuperLOD 2","SuperLOD 3") height:5 width:90 offset:[-8,0] button btnSelect "Select Objects" on lstLodLevels selectionEnd do ( RsShowLodLevel lstLodLevels.selection ) on btnSelect pressed do ( undo "select LOD level" on ( clearSelection() select (RsShowLodLevel lstLodLevels.selection) completeRedraw() ) ) fn create = ( destroyDialog RsShowLodSlider createDialog RsShowLodSlider ) ) --RsShowLodSlider.create()