501 lines
14 KiB
Plaintext
Executable File
501 lines
14 KiB
Plaintext
Executable File
global idxExportGeometryGtaObj = getattrindex "Gta Object" "Export Geometry"
|
|
global idxFragProxyGtaObj = getattrindex "Gta Object" "Is FragProxy"
|
|
global idxAnimProxyGtaObj = getattrindex "Gta Object" "Is AnimProxy"
|
|
global idxDontExportGtaObj = getattrindex "Gta Object" "Dont Export"
|
|
global idxDontExportLightPhoto = getattrindex "Gta LightPhoto" "Dont Export"
|
|
global idxDontAddToIplGtaObj = getattrindex "Gta Object" "Dont Add To IPL"
|
|
global idxIsOcclusionGtaObj = ( GetAttrIndex "Gta Object" "Is Occlusion" )
|
|
global idxIsNewDLCGtaObj = ( GetAttrIndex "Gta Object" "New DLC" )
|
|
global LinkType_LOD = 0
|
|
--------------------------------------------------------------
|
|
-- Is this an RSref object?
|
|
--------------------------------------------------------------
|
|
fn isRSref obj includeDelegates:false =
|
|
(
|
|
(isValidNode obj) and
|
|
(
|
|
(isKindOf obj.baseObject ::RSrefObject) or
|
|
(
|
|
-- isRsRef can optionally show/hide Rsref-based object-types:
|
|
includeDelegates and
|
|
(
|
|
isKindOf obj.baseObject ::RsContainerLodRef
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Is this an RsInternalRef?
|
|
--------------------------------------------------------------
|
|
fn isRsInternalRef obj =
|
|
(
|
|
(isValidNode obj) and
|
|
(
|
|
(isKindOf obj.baseObject ::RsInternalRef)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Is this any kind of InternalRef?
|
|
--------------------------------------------------------------
|
|
fn isInternalRef obj =
|
|
(
|
|
(isKindOf obj InternalRef) or (isRsInternalRef obj)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Is this any kind of InternalRef?
|
|
--------------------------------------------------------------
|
|
fn getIRefSource obj =
|
|
(
|
|
case of
|
|
(
|
|
(isKindOf obj InternalRef):(ixref_gettarget obj)
|
|
(isRsInternalRef obj):(obj.getSourceObj())
|
|
default:undefined
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Is this an RSref-based object-class?
|
|
--------------------------------------------------------------
|
|
fn isRSrefSuperClass obj =
|
|
(
|
|
(isValidNode obj) and
|
|
(
|
|
local baseObj = obj.baseObject
|
|
|
|
(isKindOf baseObj ::RSrefObject) or
|
|
(
|
|
(isProperty baseObj #delegate) and (isKindOf baseObj.delegate ::RSrefObject)
|
|
)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Is it an RSref/Xref?
|
|
--------------------------------------------------------------
|
|
fn isRefObj obj includeDelegates:true =
|
|
(
|
|
(isRSref obj includeDelegates:includeDelegates) or (isKindOf obj XRefObject)
|
|
)
|
|
|
|
--
|
|
-- name: RsMapIsOcclusion
|
|
-- desc: Return whether this object is an occlusion object.
|
|
--
|
|
fn RsMapIsOcclusion obj =
|
|
(
|
|
(isKindOf obj RsOcclusionBox) or ( ("Gta Object" == GetAttrClass obj) and ( true == GetAttr obj idxIsOcclusionGtaObj ) )
|
|
)
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- returns true if the passed in object is a valid map-export object
|
|
-----------------------------------------------------------------------------
|
|
fn IsMapObject obj CheckParent:True =
|
|
(
|
|
if (not isValidNode obj) do return False
|
|
|
|
local retval = true
|
|
|
|
local objClass = getattrclass obj
|
|
|
|
case objClass of
|
|
(
|
|
"Gta Object":
|
|
(
|
|
if (getAttr obj idxDontExportGtaObj) then
|
|
(
|
|
setattr obj idxDontAddToIplGtaObj true
|
|
retval = false
|
|
)
|
|
else
|
|
(
|
|
if (getAttr obj idxFragProxyGtaObj) or (getAttr obj idxAnimProxyGtaObj ) do (
|
|
|
|
retval = false
|
|
)
|
|
)
|
|
)
|
|
-- AJM: These Photometric lights aren't to be exported. The serialiser also checks and stops them being output
|
|
-- but doing it here in maxscript too just incase. Whether removing photometric lights from the map.objects list
|
|
-- will cause problems, we'll soon find out...
|
|
"Gta LightPhoto":
|
|
(
|
|
if (isKindOf obj mr_Sky_Portal) or (isKindOf obj Target_light) or (isKindOf obj Free_Light) do
|
|
(
|
|
setattr obj idxDontExportLightPhoto true
|
|
retval = false
|
|
)
|
|
)
|
|
)
|
|
|
|
if (not retVal) do return False
|
|
|
|
-- Test object/parent classes:
|
|
retval = case of
|
|
(
|
|
(isDeleted obj):(False)
|
|
(isRefObj obj):(False)
|
|
(isKindOf obj InternalRef):(False)
|
|
(isKindOf obj Gta_MILO):(True)
|
|
(isKindOf obj GtaMloRoom):(True)
|
|
(isKindOf obj Container):(True)
|
|
(objClass != "Gta Object"):(False)
|
|
(RsMapIsOcclusion obj):(False)
|
|
((CheckParent) and (obj.parent != undefined)):
|
|
(
|
|
-- Test parent-class:
|
|
case ClassOf Obj.Parent of
|
|
(
|
|
Gta_MILO:(True)
|
|
GtaMloRoom:(True)
|
|
Container:(True)
|
|
Default:(False)
|
|
)
|
|
)
|
|
Default:True
|
|
)
|
|
|
|
return retval
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- returns true if the passed in object is a valid map export object
|
|
--------------------------------------------------------------
|
|
fn IsMapObjectWithXref obj ignoreExportFlags:false =
|
|
(
|
|
local retVal = true
|
|
local attrClass
|
|
|
|
case of
|
|
(
|
|
(isDeleted obj):false
|
|
|
|
(
|
|
case (classOf obj.parent) of
|
|
(
|
|
UndefinedClass:false
|
|
Gta_MILO:false
|
|
GtaMloRoom:false
|
|
Container:false
|
|
Default:true
|
|
)
|
|
):false
|
|
|
|
(isKindOf obj Gta_MILO):true
|
|
|
|
(isKindOf obj GtaMloRoom):true
|
|
|
|
(
|
|
attrClass = getattrclass obj
|
|
|
|
(attrClass != "Gta Object") and (attrClass != "Gta MILOTri")
|
|
):false
|
|
|
|
((not isRefObj obj) and (attrClass == "Gta Object") and (not ignoreExportFlags)):
|
|
(
|
|
case of
|
|
(
|
|
--valFragProxy:
|
|
(getattr obj idxFragProxyGtaObj):false
|
|
|
|
-- isAnimProxy:
|
|
(getattr obj idxAnimProxyGtaObj ):false
|
|
|
|
--valDontExport:
|
|
(getattr obj idxDontExportGtaObj):false
|
|
|
|
default:true
|
|
)
|
|
)
|
|
|
|
default:true
|
|
)
|
|
)
|
|
|
|
|
|
fn RsGetMapObjectsFromRoom source target childobj =
|
|
(
|
|
for actualobj in childobj.children do
|
|
(
|
|
if IsMapObject actualobj then
|
|
(
|
|
appendIfUnique target actualobj
|
|
)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Turn all objects in the input list into valid export objects
|
|
--------------------------------------------------------------
|
|
global RsMapObjectSourceCache = #()
|
|
global RsMapObjectCache = #()
|
|
global RsMapMiloCache = #()
|
|
fn RsGetMapObjects source target isCutsceneObject:false miloHelpers:#() =
|
|
(
|
|
-- See if the cached source-list matches the new one; if so, we can reuse the output:
|
|
local cacheMatched = (source.count == RsMapObjectSourceCache.count)
|
|
for obj in source while cacheMatched do
|
|
(
|
|
if (findItem RsMapObjectSourceCache obj == 0) do (cacheMatched = false)
|
|
)
|
|
|
|
if cacheMatched and (isCutsceneObject == false) then
|
|
(
|
|
for item in RsMapObjectCache where isValidNode item do
|
|
(
|
|
appendIfUnique target item
|
|
)
|
|
|
|
for item in RsMapMiloCache where isValidNode item do
|
|
(
|
|
appendIfUnique miloHelpers item
|
|
)
|
|
)
|
|
else
|
|
(
|
|
for obj in source do (
|
|
|
|
if IsMapObject obj then (
|
|
|
|
if classof obj == Gta_MILO then (
|
|
appendIfUnique miloHelpers obj
|
|
lodobj = RsSceneLink.getparent LinkType_LOD obj
|
|
|
|
if lodobj != undefined then (
|
|
appendIfUnique target lodobj
|
|
lod2obj = RsSceneLink.getparent LinkType_LOD lodobj
|
|
if lod2obj != undefined then append target lod2obj
|
|
)
|
|
|
|
for childobj in obj.children do (
|
|
|
|
if classof childobj == GtaMloRoom then (
|
|
|
|
RsGetMapObjectsFromRoom source target childobj
|
|
) else (
|
|
|
|
if IsMapObject childobj then (
|
|
|
|
appendIfUnique target childobj
|
|
)
|
|
)
|
|
)
|
|
|
|
) else if classof obj == GtaMloRoom then (
|
|
|
|
RsGetMapObjectsFromRoom source target obj
|
|
) else if classof obj == Container then (
|
|
|
|
appendIfUnique target obj
|
|
|
|
-- Recurse into the Container.
|
|
for childobj in obj.children do (
|
|
|
|
if IsMapObject childobj then (
|
|
|
|
appendIfUnique target childobj
|
|
)
|
|
)
|
|
|
|
) else if isdeleted obj == false then (
|
|
|
|
addObject = true
|
|
|
|
if getattrclass obj == "Gta Object" then (
|
|
|
|
addObject = getattr obj idxExportGeometryGtaObj
|
|
)
|
|
|
|
if addObject then (
|
|
|
|
appendIfUnique target obj
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
RsMapObjectSourceCache = #() + source
|
|
RsMapObjectCache = #() + target
|
|
RsMapMiloCache = #() + miloHelpers
|
|
)
|
|
|
|
return target
|
|
)
|
|
|
|
fn RsGetMapObjectsFromRoomWithXref source target childobj = (
|
|
|
|
for actualobj in childobj.children do (
|
|
|
|
if IsMapObjectWithXref actualobj then (
|
|
|
|
append target actualobj
|
|
)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Turn all objects in the input list into valid export objects
|
|
--------------------------------------------------------------
|
|
fn RsGetMapObjectsWithXrefs source target ignoreExportFlags:false = (
|
|
|
|
for obj in source do (
|
|
|
|
if IsMapObjectWithXref obj ignoreExportFlags:ignoreExportFlags then (
|
|
|
|
if classof obj == Gta_MILO then (
|
|
|
|
for childobj in obj.children do (
|
|
|
|
if classof childobj == GtaMloRoom then (
|
|
|
|
RsGetMapObjectsFromRoomWithXref source target childobj
|
|
) else (
|
|
|
|
if IsMapObject childobj then (
|
|
|
|
append target childobj
|
|
)
|
|
)
|
|
)
|
|
|
|
) else if classof obj == GtaMloRoom then (
|
|
|
|
RsGetMapObjectsFromRoomWithXref source target obj
|
|
) else (
|
|
|
|
append target obj
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Get the root container for the specified object
|
|
--------------------------------------------------------------
|
|
fn RsGetObjContainer obj =
|
|
(
|
|
if (isKindOf obj Container) then obj else (Containers.IsInContainer obj)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Returns false if any objs are in different containers
|
|
--------------------------------------------------------------
|
|
fn RsObjsInSameContainer objs =
|
|
(
|
|
local objConts = #()
|
|
|
|
for obj in objs while (objConts.count < 2) do
|
|
(
|
|
appendIfUnique objConts (RsGetObjContainer obj)
|
|
)
|
|
|
|
return (objConts.count < 2)
|
|
)
|
|
|
|
--------------------------------------------------------------
|
|
-- Checks object for transforms on its pivot
|
|
--------------------------------------------------------------
|
|
fn RsObjHasXformedPivot obj badXforms:#{} =
|
|
(
|
|
local notRef = not ((isRefObj obj) or (isInternalRef obj))
|
|
|
|
badXforms[1] = ((distance obj.objectOffsetPos [0,0,0]) > 0.000001)
|
|
badXforms[2]= (obj.objectOffsetRot != quat 0 0 0 1) or (notRef and (obj.rotation != quat 0 0 0 1))
|
|
badXforms[3] = (obj.objectOffsetScale != [1,1,1]) or (notRef and (obj.scale != [1,1,1]))
|
|
|
|
(badXforms.numberSet != 0)
|
|
)
|
|
|
|
---------------------------------------------------------------------------------------
|
|
-- Returns True if 'obj' is the topmost object in a given scene-link hierarchy
|
|
-- (i.e. if it's the main map-object)
|
|
-- 'linkType' enums can be found in 'RsSceneLinkInit.ms'
|
|
---------------------------------------------------------------------------------------
|
|
fn RsIsTopSceneLink linkType obj =
|
|
(
|
|
-- LOD-links have lower-detail models as parent (mapObjIsChild = True)
|
|
-- but other link-types may have reversed priority:
|
|
local mapObjIsChild = ::gRsSceneLinkTypeData[linkType + 1].mapObjIsChild
|
|
|
|
local linkedObj
|
|
|
|
if mapObjIsChild then
|
|
(
|
|
-- If map-object is child for this linktype:
|
|
local children = #()
|
|
RsSceneLink.getChildren linkType obj &children
|
|
higherObj = children[1]
|
|
)
|
|
else
|
|
(
|
|
higherObj = RsSceneLink.getParent linkType obj
|
|
)
|
|
|
|
return (not isValidNode higherObj)
|
|
)
|
|
|
|
---------------------------------------------------------------------------------------------
|
|
-- Returns list of mesh-objects that'll be packed with map-object 'obj' on export
|
|
-- Returns empty list if object is non-exportable
|
|
-- or if it isn't top object (if 'CheckParent' is true)
|
|
---------------------------------------------------------------------------------------------
|
|
fn RsGetPackedObjs obj CheckParent:True =
|
|
(
|
|
if (getAttrClass obj != "Gta Object") or (not IsMapObject obj CheckParent:CheckParent) do return #()
|
|
|
|
-- Return empty list if this isn't the topmost mapobject for its drawable/reflect-proxy/cloth links:
|
|
local isTopObj = True
|
|
for linkType in ::RsObjPackedLinktypes while isTopObj do
|
|
(
|
|
isTopObj = RsIsTopSceneLink linkType obj
|
|
)
|
|
if (not isTopObj) do return #()
|
|
|
|
local objs = #(obj)
|
|
|
|
-- Add objects, which will be queued for their own child-adding:
|
|
local objNum = 0
|
|
while (objNum < objs.count) do
|
|
(
|
|
objNum += 1
|
|
local thisObj = objs[objNum]
|
|
|
|
-- Add linked objects: Drawable-lod, Cloth, Shadow/Reflection proxy:
|
|
for linkType in RsObjPackedLinktypes do
|
|
(
|
|
-- Which direction does this link-type's priority go?
|
|
local mapObjIsChild = ::gRsSceneLinkTypeData[linkType + 1].mapObjIsChild
|
|
|
|
local linkedObjs = #()
|
|
|
|
if mapObjIsChild then
|
|
(
|
|
-- If map-object is child for this linktype, get its parent:
|
|
linkedObjs = #(RsSceneLink.getParent linkType thisObj)
|
|
)
|
|
else
|
|
(
|
|
-- If map-object is parent for this linktype, get its children:
|
|
local linkedObjs = #()
|
|
RsSceneLink.getChildren linkType thisObj &children
|
|
)
|
|
|
|
for linkedObj in linkedObjs where (getAttrClass linkedObj == "Gta Object") and not (getAttr linkedObj idxDontExportGtaObj) do
|
|
(
|
|
-- Don't add more than once, to avoid falling into loops:
|
|
appendIfUnique objs linkedObj
|
|
)
|
|
)
|
|
|
|
-- Add child-objects to to-process list:
|
|
-- (i.e. frag-components)
|
|
local addChildren = for childObj in thisObj.children where (getAttrClass childObj == "Gta Object") and not (getAttr childObj idxDontExportGtaObj) collect childObj
|
|
join objs addChildren
|
|
)
|
|
|
|
return objs
|
|
)
|