358 lines
8.4 KiB
Plaintext
Executable File
358 lines
8.4 KiB
Plaintext
Executable File
-- 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()
|