273 lines
6.7 KiB
Plaintext
Executable File
273 lines
6.7 KiB
Plaintext
Executable File
/*
|
|
RSN_CleanMesh
|
|
|
|
|
|
Stores map channel data then exports an FBX of the mesh
|
|
Then re-imports the FBX and restores the map channel data
|
|
|
|
Neil.Gregory@RockstarNorth.com
|
|
|
|
12/2011
|
|
*/
|
|
|
|
|
|
struct meshData
|
|
(
|
|
name = undefined,
|
|
attrs = #(),
|
|
material = undefined,
|
|
parent = undefined,
|
|
children = undefined
|
|
|
|
)--END OF STRUCT
|
|
|
|
struct meshCPVData
|
|
(
|
|
vtxPositionsExport = #(), --unique mesh vertex positions as Point3 array
|
|
vtxPositionsImport = #(),
|
|
channels = #(), --#("name", channelindex, #(vtxPositionsIndex, mapVtxIndex, colour),#(vtxPositionsIndex, mapVtxIndex, colour), #(vtxPositionsIndex, mapVtxIndex, colour),.....)
|
|
channelNames = #("Alpha", "Illum", "Colour", "UV", "MaskUV", \
|
|
"NULL", "NULL", "NULL", "NULL", "NULL", \
|
|
"NULL", "Terrain", "NULL", "MicroMovement", "NULL", \
|
|
"Tint", "PedEnv", "PedFat"),
|
|
|
|
fn storeMapChannels obj =
|
|
(
|
|
--flush channels #()
|
|
channels = #()
|
|
|
|
--get all vert positions and stuff into vtxPositions
|
|
vtxPositionsExport = for v = 1 to (getNumVerts obj) collect getvert obj v
|
|
|
|
numMaps = meshop.getNumMaps obj
|
|
|
|
--interface speedup
|
|
meshOpGetMapFace = meshop.getMapFace
|
|
meshOpGetVert = meshop.getvert
|
|
meshOpGetMapVert = meshop.getMapVert
|
|
|
|
--find all the channels with data in
|
|
for chn = 2 to (numMaps - 1) do
|
|
(
|
|
--update progress
|
|
progressUpdate (100.0 *(chn+3) / numMaps)
|
|
|
|
local channelArray = #()
|
|
|
|
if (meshop.getMapSupport obj chn) == true then
|
|
(
|
|
--print chn
|
|
--channel name id
|
|
append channelArray channelNames[chn+3]
|
|
--index
|
|
append channelArray chn
|
|
|
|
for mapFace = 1 to (meshop.getNumMapFaces obj chn) do
|
|
(
|
|
mapFaceVerts = meshOpGetMapFace obj chn mapFace
|
|
mapFaceVerts = #(mapFaceVerts.x as Integer, mapFaceVerts.y as Integer, mapFaceVerts.z as Integer)
|
|
|
|
faceVerts = getFace $ mapFace
|
|
faceVerts = #(faceVerts.x as Integer, faceVerts.y as Integer, faceVerts.z as Integer)
|
|
--format "mapFaceVerts: % faceVerts: % \n" mapFaceVerts faceVerts
|
|
|
|
for mv = 1 to 3 do
|
|
(
|
|
mapVertIdx = mapFaceVerts[mv]
|
|
--using index get the vertex from the array and grab its pos
|
|
vPos = meshOpGetVert obj faceVerts[mv]
|
|
--now find the same position in the vtxPositions array
|
|
vtxPosIdx = findItem vtxPositionsExport vPos
|
|
|
|
--map vert value
|
|
mapVertVal = meshOpGetMapVert obj chn mapVertIdx
|
|
|
|
channelArray[mapVertIdx+2] = #(vtxPosIdx, mapFace, mv, mapVertVal)
|
|
)
|
|
)
|
|
)
|
|
|
|
--add to the channels
|
|
append channels channelArray
|
|
)
|
|
|
|
--set the number of map channels to 0 so FBX doesnt save any
|
|
meshop.setNumMaps obj 0
|
|
),
|
|
|
|
|
|
fn restoreMapChannels obj =
|
|
(
|
|
--check we have some channel data
|
|
if channels.count == 0 then return false
|
|
|
|
meshop.setNumMaps obj (channels.count + 1)
|
|
|
|
vtxPositionsImport = for v = 1 to (getNumVerts obj) collect getvert obj v
|
|
|
|
--iterate channels stored and re-apply to the the obj
|
|
for chan = 1 to channels.count do
|
|
(
|
|
if channels[chan].count != 0 then
|
|
(
|
|
--array
|
|
|
|
--get the idx
|
|
channelIdx = channels[chan][2]
|
|
--print channelIdx
|
|
if channels[chan][1] != undefined then ChannelInfo.NameChannel obj 3 channelIdx channels[chan][1]
|
|
|
|
--setup map channel
|
|
meshop.setMapSupport obj channelIdx true
|
|
|
|
--iterate miss first 2 as they are channel meta data
|
|
for vtx = 3 to channels[chan].count do
|
|
(
|
|
--get the map face idx
|
|
mapFace = channels[chan][vtx][2]
|
|
--get the mapvert in the face
|
|
mapFaceVerts = meshop.getMapFace obj channelIdx mapFace
|
|
--the mapvert we want to set
|
|
mapVertIdx = mapFaceVerts[channels[chan][vtx][3]]
|
|
|
|
--now set the value on it
|
|
meshop.setMapVert obj channelIdx mapVertIdx channels[chan][vtx][4]
|
|
|
|
)
|
|
|
|
)
|
|
else --just add an empty channel
|
|
(
|
|
channelCount = meshop.getNumMaps obj
|
|
-- +1
|
|
if chan > 1 then meshop.setNumMaps obj (channelCount + 1)
|
|
)
|
|
)
|
|
)
|
|
|
|
)--END OF STRUCT
|
|
|
|
fn cleanMesh =
|
|
(
|
|
--timing
|
|
start = timestamp()
|
|
|
|
--mesh data inst
|
|
mData = meshData()
|
|
|
|
--selection
|
|
obj = $selection as array
|
|
if obj.count == 0 then
|
|
(
|
|
messagebox "Nothing selected!" title:"Error"
|
|
return false
|
|
)
|
|
|
|
--setup a progressbar
|
|
progressStart "Clean Mesh:"
|
|
|
|
obj = obj[1]
|
|
--store the name
|
|
mData.name = obj.name
|
|
--print mData.name
|
|
--break()
|
|
|
|
--store the attrs
|
|
local attrClass = GetAttrClass obj
|
|
local attrCount = GetNumAttr attrClass
|
|
|
|
mData.attrs = for i = 1 to attrCount collect GetAttr obj i
|
|
|
|
--store the material
|
|
mData.material = obj.material
|
|
|
|
--
|
|
--store the cpv data
|
|
--
|
|
--turn it to a mesh, it will come back in as one anyway
|
|
addModifier obj (turn_to_mesh())
|
|
collapseStack obj
|
|
|
|
--create a meshCPVData instance
|
|
cpvData = meshCPVData()
|
|
cpvData.storeMapChannels obj
|
|
|
|
|
|
--meshop.getMapSupport obj chn
|
|
--meshop.getNumMapVerts <Mesh mesh> <Integer mapChannel>
|
|
|
|
--iterate verts getting position, looking up index in vtxPositions, store that with vertex colour
|
|
|
|
--store the parent in heirarchy if any
|
|
mData.parent = obj.parent
|
|
mData.children = (readvalue (("$"+obj.name+"/*") as stringstream)) as Array
|
|
|
|
--export as fbx
|
|
exportSuccess = exportFile (GetDir #export + "/cleanMesh.fbx" ) #noPrompt selectedOnly:true
|
|
|
|
--delete obj
|
|
obj.name = (obj.name + "_OLD")
|
|
--print obj.name
|
|
delSuccess = delete obj
|
|
--delSuccess = 1
|
|
|
|
|
|
if delSuccess == 1 then
|
|
(
|
|
--reimport from fbx
|
|
if exportSuccess then
|
|
(
|
|
--delete old object
|
|
|
|
--break()
|
|
FbxImporterSetParam "Mode" "merge"
|
|
importSuccess = importFile (GetDir #export + "/cleanMesh.fbx" ) #noPrompt
|
|
if not importSuccess then
|
|
(
|
|
messagebox "Failed to import" title:"Error.."
|
|
return false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
messageBox "Failed to export" title:"Error.."
|
|
return false
|
|
)
|
|
|
|
newObj = getNodeByName mData.name
|
|
|
|
--restore attrs to imported object
|
|
for i = 1 to mData.attrs.count do setAttr newObj i mData.attrs[i]
|
|
|
|
--restore material to imported object
|
|
newObj.material = mData.material
|
|
|
|
--restore the map channels
|
|
cpvData.restoreMapChannels newObj
|
|
|
|
--restore imported object into heirarchy
|
|
if mData.parent != undefined then newObj.parent = mData.parent
|
|
if mData.children != undefined then
|
|
(
|
|
for child in mData.children do
|
|
(
|
|
child.parent = newObj
|
|
)
|
|
)
|
|
|
|
--display
|
|
newObj.displayByLayer = false
|
|
newObj.showVertexColors = on
|
|
newObj.vertexColorType = 0
|
|
|
|
|
|
--clean up
|
|
mData = undefined
|
|
)
|
|
|
|
end = timeStamp()
|
|
|
|
format "Processing took % seconds\n" ((end - start) / 1000.0)
|
|
)
|
|
|
|
cleanMesh() |