319 lines
7.3 KiB
Plaintext
Executable File
319 lines
7.3 KiB
Plaintext
Executable File
--
|
|
-- File:: collutil.ms
|
|
-- Description:: Collision utility functions
|
|
--
|
|
-----------------------------------------------------------------------------
|
|
-- HISTORY
|
|
--
|
|
-- 29/10/09
|
|
-- Author:: Marissa Warner-Wu <marissa.warner-wu@rockstarnorth.com>
|
|
-- Combined in functions from boundsexport.ms
|
|
-----------------------------------------------------------------------------
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Uses
|
|
-----------------------------------------------------------------------------
|
|
--filein "rockstar/util/material.ms" -- loaded on startup by startup.ms
|
|
filein "rockstar/util/attribute.ms"
|
|
filein "pipeline/util/boundsexport.ms"
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Globals
|
|
-----------------------------------------------------------------------------
|
|
RsFragBoundList = #()
|
|
RsTotalSurfProperty = ""
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- Functions
|
|
-----------------------------------------------------------------------------
|
|
|
|
fn RsGetCollMaterialList obj mat collmatlist idx:-1 = (
|
|
|
|
if classof mat == Multimaterial then (
|
|
|
|
matlist = #()
|
|
RsMatGetMapIdsUsedOnObject obj matlist
|
|
|
|
for i = 1 to matlist.count do (
|
|
|
|
matidx = finditem mat.materialIDList matlist[i]
|
|
|
|
if matidx != 0 then (
|
|
|
|
RsGetCollMaterialList obj mat.materiallist[matidx] collmatlist idx:i
|
|
)
|
|
)
|
|
) else if classof mat == RexBoundMtl then (
|
|
|
|
append collmatlist mat
|
|
)
|
|
)
|
|
|
|
fn RsGetCollMatList obj mat: idx:-1 matIds:#() subMats:#() =
|
|
(
|
|
if (mat == unsupplied) do
|
|
(
|
|
mat = obj.material
|
|
)
|
|
|
|
case classof mat of
|
|
(
|
|
Multimaterial:
|
|
(
|
|
local matlist = #()
|
|
RsMatGetMapIdsUsedOnObject obj matlist
|
|
|
|
for i = 1 to matlist.count do
|
|
(
|
|
local matidx = finditem mat.materialIDList matlist[i]
|
|
|
|
if matidx != 0 do
|
|
(
|
|
RsGetCollMatList obj mat:mat.materiallist[matidx] matIds:matIds subMats:subMats idx:matIdx
|
|
)
|
|
)
|
|
)
|
|
RexBoundMtl:
|
|
(
|
|
append matIds idx
|
|
append subMats mat
|
|
)
|
|
)
|
|
|
|
return subMats
|
|
)
|
|
|
|
fn RsGetCollMatListUsingFlags obj flags matIds:#() subMats:#() matchAll:false allIfUnflagged:false =
|
|
(
|
|
local getMatIds = #()
|
|
local getSubMats = RsGetCollMatList obj matIds:getMatIds
|
|
|
|
-- This options return all materials if no flags are selected:
|
|
local allMats = (allIfUnflagged and (flags == 0))
|
|
|
|
for n = 1 to getSubMats.count do
|
|
(
|
|
local mat = getSubMats[n]
|
|
|
|
local flagMatcher = bit.and (RexGetCollisionFlags mat) flags
|
|
|
|
if (allMats) or (if matchAll then (flagMatcher == flags) else (flagMatcher != 0)) do
|
|
(
|
|
append matIds getMatIds[n]
|
|
append subMats mat
|
|
)
|
|
)
|
|
|
|
return subMats
|
|
)
|
|
|
|
fn RsSetFacesUsingMatByID obj idx = (
|
|
|
|
if classof obj == Col_Mesh then (
|
|
|
|
col2mesh obj
|
|
)
|
|
|
|
select obj
|
|
|
|
facesel = #()
|
|
|
|
numFaces = getnumfaces obj
|
|
|
|
for j = 1 to numFaces do (
|
|
|
|
if classof obj == Editable_Mesh then (
|
|
|
|
matID = getfacematid obj j
|
|
) else if classof obj == Editable_Poly or classof obj == PolyMeshObject then (
|
|
|
|
matID = polyop.getfacematid obj j
|
|
)
|
|
|
|
if matID == idx then (
|
|
|
|
append facesel j
|
|
)
|
|
)
|
|
|
|
setfaceselection obj facesel
|
|
setCommandPanelTaskMode(#modify)
|
|
subobjectlevel = 3
|
|
)
|
|
|
|
fn RsSetFacesUsingMatByIDList obj idxlist = (
|
|
|
|
if classof obj == Col_Mesh do
|
|
(
|
|
hideByCategory.geometry = false
|
|
col2mesh obj
|
|
)
|
|
|
|
select obj
|
|
|
|
facesel = #()
|
|
|
|
numFaces = getnumfaces obj
|
|
|
|
for j = 1 to numFaces do (
|
|
|
|
if classof obj == Editable_Mesh then (
|
|
|
|
matID = getfacematid obj j
|
|
) else if classof obj == Editable_Poly or classof obj == PolyMeshObject then (
|
|
|
|
matID = polyop.getfacematid obj j
|
|
)
|
|
|
|
if finditem idxlist matID != 0 then (
|
|
|
|
append facesel j
|
|
)
|
|
)
|
|
|
|
setfaceselection obj facesel
|
|
setCommandPanelTaskMode(#modify)
|
|
subobjectlevel = 3
|
|
)
|
|
|
|
fn RsSetFacesByFlags obj flags matchAll:false surfType: procType: =
|
|
(
|
|
local checkSurf = (isKindOf surfType String)
|
|
local checkProc = (isKindOf procType String)
|
|
local typeFiltered = (checkSurf or checkProc)
|
|
|
|
local matIds = #()
|
|
local subMats = #()
|
|
RsGetCollMatListUsingFlags obj flags matIds:matIds subMats:subMats matchAll:matchAll allIfUnflagged:typeFiltered
|
|
|
|
-- Filter materials by surface/procedural-type:
|
|
if (typeFiltered) do
|
|
(
|
|
local matchNums = #{}
|
|
|
|
for n = 1 to subMats.count do
|
|
(
|
|
local subMat = subMats[n]
|
|
local surfMatch = True
|
|
local procMatch = True
|
|
|
|
if checkSurf do
|
|
(
|
|
local matSurfType = RexGetCollisionName subMat
|
|
surfMatch = matchPattern matSurfType pattern:surfType
|
|
)
|
|
if checkProc do
|
|
(
|
|
local matProcType = RexGetProceduralName subMat
|
|
procMatch = matchPattern matProcType pattern:procType
|
|
)
|
|
|
|
if (matchAll) then
|
|
(
|
|
matchNums[n] = (surfMatch and procMatch)
|
|
)
|
|
else
|
|
(
|
|
matchNums[n] = (checkSurf and surfMatch) or (checkProc and procMatch)
|
|
)
|
|
--format "%, %\n" surfMatch procMatch
|
|
)
|
|
|
|
matIds = for n = matchNums collect matIds[n]
|
|
)
|
|
|
|
RsSetFacesUsingMatByIDList obj matIds
|
|
)
|
|
|
|
-- Returns true if object uses any of the given flags:
|
|
fn RsDoesObjectUseFlags obj flags matchAll:false =
|
|
(
|
|
local matchFound = false
|
|
|
|
-- Check object's materials for flags:
|
|
local colMatList = RsGetCollMatList obj
|
|
|
|
-- Filter out non-material flags:
|
|
-- Flag-numbers correspond to 'RsCollisionAttrs',
|
|
-- which lists the collision-material flag-names, plus some object-only ones appended to the end
|
|
local bitMask = 0
|
|
for n = 1 to (RexGetCollisionFlagNames()).Count do
|
|
(
|
|
bitMask = bit.set bitMask n true
|
|
)
|
|
local getMatFlags = bit.and flags bitMask
|
|
|
|
fn flagMatch matchAll flags matchedFlags =
|
|
(
|
|
if matchAll then (matchedFlags == flags) else (matchedFlags != 0)
|
|
)
|
|
|
|
local matchedFlags = 0
|
|
|
|
if (getMatFlags != 0) do
|
|
(
|
|
for mat in colMatList while (not matchFound) do
|
|
(
|
|
local matFlags = RexGetCollisionFlags mat
|
|
local matMatchFlags = bit.and matFlags getMatFlags
|
|
matchedFlags = bit.or matchedFlags matMatchFlags
|
|
|
|
matchFound = flagMatch matchAll flags matchedFlags
|
|
)
|
|
)
|
|
|
|
-- Now check object-attributes for the requested flag-names:
|
|
if (not matchFound) do
|
|
(
|
|
-- Only test flags that have an associated object-attribute index:
|
|
for n = 1 to RsCollisionAttrIdxs.count where (bit.get flags n) while (not matchFound) do
|
|
(
|
|
local AttrIdx = RsCollisionAttrIdxs[n]
|
|
|
|
if (AttrIdx != undefined) and (getAttr obj RsCollisionAttrIdxs[n]) do
|
|
(
|
|
-- Save bit for matching flag:
|
|
matchedFlags = bit.set matchedFlags n true
|
|
|
|
-- Declare object as matched if requested flags have been accounted for:
|
|
matchFound = flagMatch matchAll flags matchedFlags
|
|
)
|
|
)
|
|
)
|
|
|
|
return matchFound
|
|
)
|
|
|
|
fn RsDoesCollMatHaveRooms obj = (
|
|
|
|
collmatlist = #()
|
|
RsGetCollMaterialList obj obj.material collmatlist
|
|
|
|
retval = false
|
|
|
|
for item in collmatlist do (
|
|
|
|
cobj = RexGetRoomNode item
|
|
|
|
if retval == false and cobj != undefined and (isdeleted cobj == false) then (
|
|
|
|
retval = true
|
|
)
|
|
)
|
|
|
|
retval
|
|
)
|
|
|
|
fn RsDoesObjHaveCollRooms obj = (
|
|
|
|
for childobj in obj.children do (
|
|
|
|
if classof childobj == Col_Mesh then (
|
|
|
|
if RsDoesCollMatHaveRooms childobj then return true
|
|
)
|
|
)
|
|
|
|
false
|
|
)
|