Files
gtav-src/tools_ng/dcc/current/max2012/scripts/pipeline/util/MeshUtil.ms
T
2025-09-29 00:52:08 +02:00

183 lines
4.4 KiB
Plaintext
Executable File

--
-- File:: pipeline/util/MeshUtil.ms
-- Description:: Set of functions for interacting with meshes
--
-- 23/6/2004
-- by Greg Smith <greg.smith@rockstarnorth.com>
--
-----------------------------------------------------------------------------
-- Returns lowest vert (in world-space) in obj:
fn RsGetLowestVert obj =
(
local copiedMesh = not isKindOf obj EditableMesh
local objMesh = if copiedMesh then (copy obj.mesh) else obj.mesh
local minZ
local minVert = dataPair idx:undefined pos:undefined
for n = 1 to getNumVerts objMesh do
(
local vertPos = getVert objMesh n
if copiedMesh do
(
vertPos *= obj.transform
)
if (minZ == undefined) or (vertPos.z < minZ) do
(
minZ = vertPos.z
minVert.pos = vertPos
minVert.idx = n
)
)
return minVert
)
mapped fn RSmoveToGround objA objB percentMin percentMax =
(
if (not isProperty objA "mesh") or (not isProperty objB "mesh") do (return False)
local objAMesh = if (isKindOf objA EditableMesh) then objA.mesh else (copy objA.mesh)
local objBMesh = if (isKindOf objB EditableMesh) then objB.mesh else (copy objB.mesh)
local lowestVert = RsGetLowestVert objA
local testRay = ray lowestVert.pos [0,0,-1]
local intersect = intersectRay objB testRay
if (intersect != undefined) do
(
local rand_offset = random percentMin percentMax
local startRot = objA.rotation
local objRotZ = (startRot as eulerangles).z
-- MATCH THE DIRECTION
local directionOffset = intersect.dir - objA.dir
-- PERCENT OF ANGLE MATCH * GROUND ANGLE
objA.dir = intersect.dir - (directionOffset * ((100-rand_offset)/100.0))
local newRot = objA.rotation as eulerangles
newRot.z = objRotZ
objA.rotation = newRot
-- Update lowest-vert pos to rotated position:
lowestVert.pos = (getVert objA.mesh lowestVert.idx) * objA.transform
local moveVec = intersect.pos - lowestVert.pos
local setPos = objA.pos + moveVec
objA.pos = setPos
)
)
--
--fn: RSFindFacesWithZeroArea
--desc: Finds any faces on a editable mesh or poly with 0 area
-- and deletes them (which deletes the verts)
--
-- returns true if the faces are deleted, or the array of faces
-- with zero area if deleteFaces is false.
--
fn RSFindFacesWithZeroArea obj deleteFaces:false = (
facesToDelete = #()
if ( Editable_Mesh == classof obj ) then
(
for f = ( meshop.getNumFaces obj ) to 1 by -1 do
(
if ( meshop.getFaceArea obj f == 0 ) do
(
append facesToDelete f
)
)
if ( true == deleteFaces) then
(
meshop.deleteFaces obj facesToDelete
true
)
else
(
facesToDelete
)
)
else if ( Editable_Poly == classof obj ) do
(
for f = ( polyop.getNumFaces obj ) to 1 by -1 do
(
if ( polyop.getFaceArea obj f == 0 ) do
(
append facesToDelete f
)
)
if ( true == deleteFaces) then
(
polyop.deleteFaces obj facesToDelete
true
)
else
(
facesToDelete
)
)
)
fn RsTestFaceForVertIndex face index =
(
case index of
(
(face[1]):1
(face[2]):2
(face[3]):3
default:0
)
)
fn RsGetColourAverageForMeshVertIndex theMesh theChannel meshVertIndex =
(
local faces = (meshop.getFacesUsingVert theMesh #{meshVertIndex}) as array
local indeces = #()
local mapindeces = #()
local averagedValue = [0,0,0]
for f in faces do
(
append indeces (getFace theMesh f)
append mapindeces (meshop.getMapFace theMesh theChannel f)
)
for index=1 to 3 do
(
-- local vertindex = indeces[1][index]
local meshVertIndeces = #()
local isShared = true
for indexVectorIndex=1 to indeces.count do
(
local indexVector = indeces[indexVectorIndex]
local sharedvertFaceIndex = RsTestFaceForVertIndex indexVector meshVertIndex
append meshVertIndeces sharedvertFaceIndex
if 0 == sharedvertFaceIndex then
isShared = false
)
-- We found the shared index in the faces
-- Now take face indeces and get map verteces with those
if isShared then
(
for indexVectorIndex=1 to mapindeces.count do
(
local sharedvertindex = meshVertIndeces[indexVectorIndex]
local index = mapindeces[indexVectorIndex][sharedvertindex]
local vertValue = meshop.getMapVert theMesh theChannel index
averagedValue = averagedValue + vertValue
)
averagedValue /= mapindeces.count
exit
)
)
return averagedValue
)