1783 lines
51 KiB
Plaintext
Executable File
1783 lines
51 KiB
Plaintext
Executable File
/**
|
|
THIS IS A MODIFICATION OF THE ORIGINAL ASSET RESOURCE TOOL TO MAKE THINGS MUCH MORE AUTOMATED.
|
|
A LOT OF THE FUNCTIONS ARE DIRECTLY COPIED OVER FORM THE OLD TOOL WITH A FEW EXTRA PARAMS ADDED TO THEM
|
|
WITH A FEW NEW PREP FUNCTIONS ADDED IN.
|
|
**/
|
|
|
|
if resourcePrep_UI != undefined then destroyDialog resourcePrep_UI
|
|
filein "rockstar/export/settings.ms" -- This is fast
|
|
|
|
-- Figure out the project
|
|
theProjectRoot = RsConfigGetProjRootDir()
|
|
theProject = RSConfigGetProjectName()
|
|
theWildWest = RsConfigGetWildWestDir()
|
|
|
|
theProjectConfig = RsConfigGetProjBinConfigDir()
|
|
|
|
toolsRoot = RsConfigGetToolsRootDir()
|
|
RSTA_LoadCommonFunction #("FN_Materials.ms")
|
|
|
|
filein (theWildWest + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
|
|
filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Perforce.ms")
|
|
|
|
filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_Rigging.ms")
|
|
|
|
filein (theWildWest + "script/3dsMax/_common_functions/FN_RSTA_UI.ms")
|
|
|
|
global resourcePrep_UIWidth = 240
|
|
global resourcePrep_UIHeight = 270
|
|
global resourcePrep_UI = undefined
|
|
rageMaterialsArray = undefined
|
|
|
|
index = undefined
|
|
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
fn RSTA_getUiPosFile =
|
|
(
|
|
--THIS HAS TO BE DECLARED FROM WITHIN THIS SCRIPT
|
|
|
|
uiPosFile = ((getThisScriptFilename()))
|
|
|
|
filePath = filterString uiPosFile "."
|
|
|
|
uiPosFile = (filePath[1]+"_UIPOSFILE.TXT")
|
|
|
|
return uiPosFile
|
|
)
|
|
|
|
fn findLodObjects =
|
|
(
|
|
lodStrings = #(
|
|
"_LOD", --end of string
|
|
"_SLOD", --end of string
|
|
"_lod_" --anywhere in string
|
|
)
|
|
lodObjects = #()
|
|
|
|
for obj in objects do
|
|
(
|
|
if superclassof obj == GeometryClass do
|
|
(
|
|
nameCount = obj.name.count
|
|
|
|
if (substring (toLower(obj.name)) (nameCount - 3) -1) == toLower(lodStrings[1]) do
|
|
(
|
|
appendIfUnique lodObjects obj
|
|
--format ("Appending "+lodStrings[1]+" "+obj.name+" to lodObjects.\n")
|
|
)
|
|
|
|
if (findString (toLower(obj.name)) (toLower(lodStrings[2]))) != undefined do
|
|
(
|
|
appendIfUnique lodObjects obj
|
|
--format ("Appending "+lodStrings[2]+" "+obj.name+" to lodObjects.\n")
|
|
)
|
|
|
|
if (findString (toLower(obj.name)) (toLower(lodStrings[3]))) != undefined do
|
|
(
|
|
appendIfUnique lodObjects obj
|
|
--format ("Appending "+lodStrings[3]+" "+obj.name+" to lodObjects.\n")
|
|
)
|
|
)
|
|
)
|
|
|
|
return lodObjects
|
|
)
|
|
-- collects all children recursively. arguments:
|
|
-- found on http://forums.cgsociety.org/showpost.php?p=4427477&postcount=2
|
|
fn CollectChildren obj &allChildren includeParent:false includeHidden:false =
|
|
(
|
|
-- check if object should be collected
|
|
if (includeHidden or not obj.isHiddenInVpt) and includeParent and finditem allChildren obj == 0 then
|
|
|
|
append allChildren obj
|
|
|
|
-- collect current object's children
|
|
for c in obj.children do CollectChildren c &allChildren includeParent:true includeHidden:includeHidden
|
|
) -- end collectChildren
|
|
|
|
-- tidy up the user defined properties by sorting it alphabetically
|
|
fn ReorderTags tagMe =
|
|
(
|
|
currentUDP = getUserPropbuffer tagMe
|
|
filterUDP = filterString currentUDP "\r\n"
|
|
alphUDP = sort filterUDP
|
|
tag = ""
|
|
|
|
for t = 1 to alphUDP.count do
|
|
(
|
|
tag = tag + alphUDP[t] + "\r\n"
|
|
setUserPropbuffer tagMe tag
|
|
)
|
|
)-- end reorderTags
|
|
|
|
|
|
-- delete any mesh info tags. this includes selection sets and meshnames
|
|
-- deleteFromThese = the meshes to delete from
|
|
fn DelFileInfoTags deleteThisMesh =
|
|
(
|
|
keepUDP = #()
|
|
currentUDP = getUserPropbuffer deleteThisMesh
|
|
filterUDP = filterString currentUDP "\r\n"
|
|
|
|
for f = 1 to filterUDP.count do
|
|
(
|
|
tempUDP = uppercase filterUDP[f]
|
|
shortUDP = substring tempUDP 1 7
|
|
|
|
if (shortUDP != "MAXFILE") then
|
|
append keepUDP tempUDP
|
|
)
|
|
|
|
tag = ""
|
|
|
|
if keepUDP.count == 0 then
|
|
setUserPropbuffer deleteThisMesh tag
|
|
else
|
|
|
|
for k = 1 to keepUDP.count do
|
|
(
|
|
tag = tag + keepUDP[k] + "\r\n"
|
|
setUserPropbuffer deleteThisMesh tag
|
|
)
|
|
|
|
ReorderTags deleteThisMesh
|
|
)-- end delFileInfoTags
|
|
|
|
-- go through all geometry and tag it with the maxscene name
|
|
fn TagFileNameInfo meshToTag =
|
|
(
|
|
tagThis = ""
|
|
tagThis = "MaxFile=" + maxfilepath + maxfilename
|
|
oldTag = getUserPropbuffer meshToTag
|
|
tagThis = oldTag+"\r\n"+tagThis
|
|
tagThis = uppercase tagThis
|
|
setUserPropbuffer meshToTag tagThis
|
|
ReorderTags meshToTag --tidy up the tags
|
|
)-- end tagFileNameInfo
|
|
|
|
|
|
|
|
fn CaptureDisplay =
|
|
(
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/Cutscene/CutsceneCaptureSphereDisplay.ms")
|
|
)
|
|
|
|
|
|
|
|
fn restoreMaterials rageMaterialsArray =
|
|
(
|
|
if rageMaterialsArray.count == 24 then
|
|
(
|
|
for i = 1 to rageMaterialsArray.count do
|
|
(
|
|
-- for tmp = 1 to rageMaterialsArray[i][1].count do
|
|
-- (
|
|
-- format ("Restoring "+(tmp as string)+" "+(rageMaterialsArray[i][1][tmp] as string)+"\n")
|
|
-- )
|
|
|
|
meditMaterials[i] = rageMaterialsArray[i][1][1]
|
|
rageMat = meditMaterials[i]
|
|
|
|
if rageMaterialsArray[i][2].count > 0 then
|
|
(
|
|
for obj = 1 to rageMaterialsArray[i][2].count do
|
|
(
|
|
thisObj = rageMaterialsArray[i][2][obj]
|
|
|
|
thisObj.material = rageMat
|
|
)
|
|
)
|
|
)
|
|
format ("Materials restored.")
|
|
)
|
|
else
|
|
(
|
|
format ("Could not find stored materials array.\n")
|
|
)
|
|
)
|
|
|
|
|
|
fn Export mode =
|
|
(
|
|
case mode of
|
|
(
|
|
#cutscene:
|
|
(
|
|
messagebox "Export #cutscene"
|
|
)
|
|
#game:
|
|
(
|
|
messagebox "Export #game"
|
|
)
|
|
)
|
|
)
|
|
|
|
-- fn PrepareProp exportAlso =
|
|
-- (
|
|
-- if selection.count == 1 then
|
|
-- (
|
|
-- thisProp = getCurrentSelection()
|
|
-- --===========================================================================================================================
|
|
-- --a section to handle gun magazine meshes - bug 808586
|
|
-- gunMag == false
|
|
-- propName = upperCase thisProp[1].name --get the prop name
|
|
-- filterPropName = filterString propName "_" --filter the name for breaks
|
|
-- shortPropName = #() --an array to hold the shortened filter data
|
|
-- for x=1 to filterPropName.count do (append shortPropName (subString filterPropName[x] 1 3))
|
|
-- magCheck = findItem shortPropName "MAG"
|
|
-- if magCheck !=0 do (if filterPropName[magCheck].count == 4 do gunMag = true)
|
|
-- --===========================================================================================================================
|
|
--
|
|
-- if ((isMeshSkinned thisProp[1]) == true) and (gunMag != true) then--if the mesh is skinned
|
|
-- (
|
|
-- print "Preparing skinned prop"
|
|
-- thisProp = getCurrentSelection()
|
|
-- SortAndSwitch thisProp
|
|
-- SkinnedProp thisProp[1] exportAlso
|
|
-- )
|
|
-- else
|
|
-- (
|
|
-- if queryBox "This appears to be an unskinned prop.\r\nI will attempt create a rig root setup for it.\r\nDo you want to continue?" beep:false title:"Materials Export Manager" do
|
|
-- (
|
|
-- print "Preparing unskinned prop"
|
|
-- thisProp = getCurrentSelection()
|
|
-- SortAndSwitch thisProp
|
|
-- UnskinnedProp thisProp[1] exportAlso
|
|
-- )
|
|
-- )
|
|
-- )
|
|
-- else (messageBox "Please run with only one object selected.")
|
|
-- )
|
|
|
|
fn PrepareVehicle=
|
|
(
|
|
print "Preparing vehicle"
|
|
|
|
if selection.count != 0 then
|
|
(
|
|
vehicleMeshes = getCurrentSelection()
|
|
-- vehicleMeshes = #()
|
|
-- appendIfUnique vehicleMeshes driver
|
|
-- for obj in skelArray do
|
|
-- (
|
|
-- appendIfUnique vehicleMeshes obj
|
|
-- )
|
|
SortAndSwitch vehicleMeshes
|
|
|
|
VehicleSetup()-- driver skelArray
|
|
)
|
|
else
|
|
(
|
|
if queryBox "Nothing selected.\r\nI will attempt to perform this on all objects in the scene.\r\nThis could take a while.\r\nDo you want to continue?" beep:false do
|
|
(
|
|
hideByCategory.none() -- unhide all by categry
|
|
max unhide all -- unhide all
|
|
max select all --select all
|
|
vehicleMeshes = getCurrentSelection()
|
|
-- vehicleMeshes = #()
|
|
-- appendIfUnique vehicleMeshes driver
|
|
-- for obj in skelArray do
|
|
-- (
|
|
-- appendIfUnique vehicleMeshes obj
|
|
-- )
|
|
|
|
clearSelection()
|
|
SortAndSwitch vehicleMeshes
|
|
VehicleSetup()
|
|
-- VehicleSetup driver skelArray
|
|
|
|
|
|
)
|
|
)
|
|
)
|
|
|
|
fn PrepareMap =
|
|
(
|
|
print "Preparing map"
|
|
|
|
if queryBox "I will attempt to delete all materials in the scene.\r\nDo you want to continue?" beep:false do
|
|
(
|
|
-- clear_all_materials()
|
|
|
|
format ("Cleared all materials...\n")
|
|
-- kill_materials()
|
|
format ("Killed all materials...\n")
|
|
CSMapExport()
|
|
format ("CS Map Exported.\n")
|
|
)
|
|
)
|
|
|
|
fn SetupEnvironment =
|
|
(
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/Cutscene/cs_enviroment_setup.ms")
|
|
|
|
)
|
|
|
|
|
|
------------------------------------------------------------------------------------------------------------------------------------------
|
|
--WORKHORSE FUNCTIONS
|
|
------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
fn CullTextures =
|
|
(
|
|
print "Cull Textures"
|
|
local shaders = getClassInstances StandardMaterial
|
|
local diffuseMaps = for item in shaders where item.diffuseMap != undefined collect item.diffuseMap
|
|
local buffer = #()
|
|
local mapKeepList = #() --array of map id's that we are going to keep
|
|
|
|
--work out which maps to keep
|
|
(
|
|
if (CutsceneDataPrepUI.AlphaCheckBox.Checked) then
|
|
append mapKeepList 6
|
|
)
|
|
|
|
clearlistener()
|
|
-- for item in diffuseMaps where item.bitmap != undefined do
|
|
for item in diffuseMaps do
|
|
(
|
|
try
|
|
(
|
|
item.bitmap
|
|
append buffer item
|
|
)
|
|
catch (print "problem with " + item as string)
|
|
)
|
|
|
|
diffuseMaps = makeUniqueArray buffer
|
|
|
|
for item in diffuseMaps do
|
|
(
|
|
print item.bitmap
|
|
)
|
|
-- print diffuseMaps
|
|
)
|
|
|
|
fn UnskinnedProp theProp exportAlso =
|
|
--theProp = a single mesh
|
|
(
|
|
convertto theProp editable_poly --convert mesh to edit poly
|
|
ResetTransform theProp --reset xforms
|
|
convertto theProp editable_poly --convert mesh to edit poly again to be sure
|
|
|
|
--move selected to 0,0,0 worldspace
|
|
in coordsys world theProp.pos = [0,0,0]
|
|
print "Prop defined and moved to center"
|
|
|
|
-- newRootSystem = BuildRigRootSystem theProp
|
|
RSTA_buildPropRoot theProp false false
|
|
|
|
-- rootObj = newRootSystem[2][1]--this should be the dummy
|
|
-- movObj = newRootSystem[2][2]--this should be the mover
|
|
|
|
rootObj = getNodeByName ("Dummy_"+theProp.name)
|
|
movObj = getNodeByName ("Mover_"+theProp.name)
|
|
|
|
local newRootSystem = #(
|
|
#(),
|
|
#()
|
|
)
|
|
|
|
newRootSystem[1] = RSTA_getAllChildren rootObj arr:newRootSystem[1]#()
|
|
|
|
if classOf rootObj == Dummy do--we are going to tag the dummy with the filename
|
|
(
|
|
DelFileInfoTags rootObj --delete the tags off the children of the export dummy
|
|
TagFileNameInfo rootObj --tag mesh information
|
|
)
|
|
|
|
for boneDel=1 to newRootSystem[1].count do
|
|
(
|
|
if newRootSystem[1][boneDel] != rootObj then
|
|
(
|
|
if newRootSystem[1][boneDel] != movObj then
|
|
(
|
|
delete newRootSystem[1][boneDel]
|
|
)
|
|
)
|
|
)
|
|
|
|
theProp.parent = movObj--parent the prop to the mover
|
|
exportMeshes = #()
|
|
CollectChildren rootObj &exportMeshes includeParent:true includeHidden:true --collect all the skeleton heirarchy
|
|
appendIfUnique exportMeshes theProp
|
|
hideByCategory.none() -- unhide all by categry
|
|
max unhide all -- unhide all
|
|
clearSelection()
|
|
select exportMeshes
|
|
max hide inv
|
|
|
|
if exportAlso == true do
|
|
(
|
|
--hacky export selected as method. needs better way.
|
|
actionMan.executeAction 0 "40373" -- File: Export Selected
|
|
)
|
|
)--end UnskinnedProp
|
|
|
|
--****************************************************************************************
|
|
fn SkinnedProp theProp exportAlso =
|
|
--theProp = a single mesh
|
|
(
|
|
exportMeshes = #(theProp)
|
|
skinningBones = #()
|
|
objectsToShow = #()
|
|
rootObj = undefined
|
|
|
|
if (isMeshSkinned theProp) == true do--if the mesh is skinned
|
|
(
|
|
skinMod = theProp.modifiers[#Skin]
|
|
modPanel.setCurrentObject skinMod
|
|
skinnedBoneCount = skinops.getNumberBones skinMod
|
|
|
|
if skinnedBoneCount > 0 do --if there are bones in the skin modifier
|
|
(
|
|
realBone = getBoneFromSkin skinMod 1 --find a real bone in the scene
|
|
rootObj = WWfindRootObject realBone --find the root of the heirarchy
|
|
CollectChildren rootObj &skinningBones includeParent:true includeHidden:true --collect all the skeleton heirarchy
|
|
)
|
|
)--if the mesh is skinned remember it
|
|
|
|
if classOf rootObj == Dummy do--we are going to tag the dummy with the filename
|
|
(
|
|
DelFileInfoTags rootObj --delete the tags off the children of the export dummy
|
|
TagFileNameInfo rootObj --tag mesh information
|
|
)
|
|
|
|
objectsToShow = exportMeshes
|
|
join objectsToShow skinningBones
|
|
selectionsets["*CS Export"] = objectsToShow --create selection set of everything
|
|
hideByCategory.none() -- unhide all by categry
|
|
max unhide all -- unhide all
|
|
clearSelection()
|
|
select objectsToShow
|
|
max hide inv
|
|
|
|
if exportAlso == true do
|
|
(
|
|
--hacky export selected as method. needs better way.
|
|
actionMan.executeAction 0 "40373" -- File: Export Selected
|
|
)
|
|
)--end SkinnedProp
|
|
|
|
--attempt to find the export dummy
|
|
fn findTheDummy =
|
|
(
|
|
characterNode = undefined
|
|
try
|
|
(
|
|
selectByWildCard "head_000" --there should always be a head mesh
|
|
if selection.count > 0 then --if we find at least 1 mesh
|
|
(
|
|
obj = selection[1]
|
|
exportDummy = WWfindRootObject obj
|
|
clearSelection()
|
|
exportDummy --pass out the export dummy
|
|
)
|
|
else
|
|
(
|
|
print "I couldn't find my head"
|
|
)
|
|
)catch()
|
|
)--end findTheDummy
|
|
|
|
|
|
|
|
fn ShowSkinningAndBones =
|
|
(
|
|
if ((progBar != undefined) and (progBar.isDisplayed)) do (destroyDialog progBar)
|
|
|
|
CreateDialog progBar width:300 Height:30
|
|
progBar.prog.color = [225, 110, 35] --green
|
|
max modify mode
|
|
exportMeshes = #()
|
|
skinningBones = #()
|
|
objectsToShow = #()
|
|
characterNode = FindTheDummy() --find the export dummy
|
|
|
|
if classOf characterNode == Dummy do--we are going to tag the dummy with the filename
|
|
(
|
|
DelFileInfoTags characterNode --delete the tags off the children of the export dummy
|
|
TagFileNameInfo characterNode --tag mesh information
|
|
)
|
|
|
|
if characterNode != undefined then
|
|
(
|
|
progBar.prog.value = 20
|
|
CollectChildren characterNode &exportMeshes includeParent:false includeHidden:true --collect all the skeleton heirarchy
|
|
|
|
if exportMeshes.count > 0 do
|
|
(
|
|
progBar.prog.value = 40
|
|
|
|
for checkMesh = 1 to exportMeshes.count while skinningBones.count == 0 do
|
|
(
|
|
if (isMeshSkinned exportMeshes[checkMesh]) == true do--if the mesh is skinned
|
|
(
|
|
progBar.prog.value = 60
|
|
skinMod = exportMeshes[checkMesh].modifiers[#Skin]
|
|
modPanel.setCurrentObject skinMod
|
|
skinnedBoneCount = skinops.getNumberBones skinMod
|
|
|
|
if skinnedBoneCount > 0 do --if there are bones in the skin modifier
|
|
(
|
|
progBar.prog.value = 80
|
|
realBone = getBoneFromSkin skinMod 1 --find a real bone in the scene
|
|
rootObj = WWfindRootObject realBone --find the root of the heirarchy
|
|
CollectChildren rootObj &skinningBones includeParent:true includeHidden:true --collect all the skeleton heirarchy
|
|
progBar.prog.value = 100
|
|
)
|
|
)--if the mesh is skinned remember it
|
|
)
|
|
)
|
|
|
|
objectsToShow = exportMeshes
|
|
join objectsToShow skinningBones
|
|
appendIfUnique objectsToShow characterNode
|
|
selectionsets["*CS Export"] = objectsToShow --create selection set of everything
|
|
hideByCategory.none() -- unhide all by categry
|
|
max unhide all -- unhide all
|
|
clearSelection()
|
|
select objectsToShow
|
|
max hide inv
|
|
(destroyDialog progBar)
|
|
)
|
|
else
|
|
(
|
|
progBar.prog.color = [255,0,0]--red
|
|
progBar.prog.value = 100
|
|
print "Couldn't find the export dummy!"
|
|
(destroyDialog progBar)
|
|
)
|
|
|
|
exportMeshes--pass out the meshes for the shader change
|
|
)--end showSkinningAndBones
|
|
|
|
fn VehicleSetup =
|
|
--copied from vehicle_export_setup.ms
|
|
(
|
|
savePath = theProjectRoot + "/art/animation/resources/vehicles/"
|
|
|
|
maxName = undefined
|
|
vehicleMesh = #()
|
|
parentDummy = undefined
|
|
vehicleSkel = #()
|
|
everything = #()
|
|
|
|
--this is a neater way of getting all children. alt method to using actionMan.executeAction 0 "40180"
|
|
fn selectHierarchy whatGeo =
|
|
(
|
|
for p in whatGeo do
|
|
(
|
|
if p.children != undefined do
|
|
(
|
|
selectmore p.children
|
|
)
|
|
)
|
|
)--end selectHierarchy
|
|
|
|
maxName = filterstring maxFileName "_" --this should get the prefix of vehicle name which is always vehiclename_skinned.max
|
|
chassisBoneName = (maxName[1]+"_Skel")
|
|
|
|
try (delete $Dummy01) catch()--try and delete a dummy mesh if it exists already
|
|
|
|
parentDummy = dummy pos:[0,0,0]
|
|
parentDummy.name = "Dummy01"
|
|
skel = getNodeByName chassisBoneName
|
|
|
|
|
|
if (skel != undefined) then
|
|
(
|
|
skel.parent = parentDummy
|
|
print (chassisBoneName+" parented to "+parentDummy.name)
|
|
hideByCategory.none()--unhide everything by category
|
|
unhide (for obj in objects where obj.ishidden collect obj) --unhide all
|
|
maxName = filterstring maxFileName "_"
|
|
meshName = maxName[1] + "_skin"
|
|
|
|
|
|
try
|
|
(
|
|
vehicleMesh = getNodeByName meshName
|
|
) catch (print ("Couldn't find " +meshName))
|
|
|
|
hideByCategory.none()--unhide everything by category
|
|
unhide (for obj in objects where obj.ishidden collect obj) --unhide all
|
|
|
|
try
|
|
(
|
|
selectHierarchy parentDummy --select the children (and children's children) of the parentdummy
|
|
-- clearSelection()
|
|
-- select skelArray
|
|
selectmore parentDummy --add the dummy to the selection
|
|
selectionsets["*vehicleSkel"] = selection --create selection set of everything
|
|
vehicleSkel = getCurrentSelection()
|
|
clearSelection()
|
|
print "vehicle skeleton found"
|
|
) catch (messagebox "Can't Find Parent Dummy" title:"Materials Export Manager") --attempt to select the export dummy
|
|
|
|
everything = vehicleSkel
|
|
appendIfUnique everything vehicleMesh
|
|
select everything
|
|
saveFile = savePath + maxName[1]
|
|
exportFile saveFile #noPrompt selectedOnly:true using:FBXEXP
|
|
messageText = maxName[1] + " exported as FBX to " + saveFile + ".fbx"
|
|
messageBox messageText title:"Materials Export Manager"
|
|
)
|
|
else
|
|
(
|
|
messageBox "Selected vehicle has no skeleton." title:"Materials Export Manager"
|
|
)
|
|
)--end vehicleSetup
|
|
|
|
--function for getting the shader/material values and storing them
|
|
fn SwitchRageToStd matID =
|
|
(
|
|
if classof mlib[MatID] == Multimaterial then --if the material is a multisub then we want to look in it
|
|
(
|
|
for SubID = 1 to mlib[MatID].numSubs do --for every multisub in this material
|
|
(
|
|
if classof mlib[matid][subid] == Rage_Shader then
|
|
(
|
|
varValue = ""--set an undefined value for the bitmap path
|
|
|
|
for x=1 to RstGetVariableCount mlib[matid][subid] do
|
|
(
|
|
--if the variable type is texmap, the map type is diffuse and the path is not undefined
|
|
if (uppercase (RstGetVariableType mlib[matid][subid] x)) == "TEXMAP" and (findstring (uppercase (RstGetVariableName mlib[matid][subid] x)) "DIFFUSE TEXTURE") != undefined and (RstGetVariable mlib[matid][subid] x) != "" do
|
|
(
|
|
varValue = RstGetVariable mlib[matid][subid] x--store the bitmap path
|
|
)
|
|
)
|
|
mlib[matid][subid] = Standardmaterial () --change it to a standard material
|
|
mlib[matid][subid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
|
|
mlib[matid][subid].showInViewport = true
|
|
)
|
|
else
|
|
(
|
|
if classof mlib[matid][subid] == Standardmaterial then
|
|
(
|
|
if mlib[matid][subid].diffusemap != undefined do
|
|
(
|
|
varValue = mlib[matid][subid].diffusemap.filename
|
|
if varValue != undefined do
|
|
(
|
|
mlib[matid][subid] = Standardmaterial () --change it to a standard material
|
|
mlib[matid][subid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
|
|
mlib[matid][subid].showInViewport = true
|
|
)
|
|
)
|
|
)
|
|
else()
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
if classof mlib[matid] == Rage_Shader then
|
|
(
|
|
varValue = ""--set an undefined value for the bitmap path
|
|
|
|
for x=1 to RstGetVariableCount mlib[matid] do
|
|
(
|
|
--if the variable type is texmap, the map type is diffuse and the path is not undefined
|
|
if (uppercase (RstGetVariableType mlib[matid] x)) == "TEXMAP" and (findstring (uppercase (RstGetVariableName mlib[matid] x)) "DIFFUSE TEXTURE") != undefined and (RstGetVariable mlib[matid] x != "") do
|
|
(
|
|
varValue = RstGetVariable mlib[matid] x--store the bitmap path
|
|
)
|
|
)
|
|
mlib[matid] = Standardmaterial () --change it to a standard material
|
|
mlib[matid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
|
|
mlib[matid].showInViewport = true
|
|
)
|
|
else
|
|
(
|
|
if classof mlib[matid] == Standardmaterial then
|
|
(
|
|
if mlib[matid].diffusemap != undefined do
|
|
(
|
|
varValue = mlib[matid].diffusemap.filename
|
|
if varValue != undefined do
|
|
(
|
|
mlib[matid] = Standardmaterial () --change it to a standard material
|
|
mlib[matid].diffusemap = Bitmaptexture fileName:varValue --set the diffuse map to the value we found in the rage shader
|
|
mlib[matid].showInViewport = true
|
|
)
|
|
)
|
|
)
|
|
else()
|
|
)
|
|
)
|
|
)--end switchRageToStd
|
|
|
|
--function to filter selection and switch materials
|
|
fn SortAndSwitch meshesToSort =
|
|
--meshesToSort = an array of objects
|
|
(
|
|
if ((progBar != undefined) and (progBar.isDisplayed)) do (destroyDialog progBar)
|
|
CreateDialog progBar width:300 Height:30
|
|
progBar.prog.color = [10,210,10] --green
|
|
|
|
meshesToChange = #()
|
|
|
|
if meshesToSort.count > 0 do
|
|
(
|
|
for allSel=1 to meshesToSort.count do
|
|
(
|
|
if superClassOf meshesToSort[allSel] == GeometryClass do append meshesToChange meshesToSort[allSel]
|
|
)
|
|
|
|
if meshesToChange.count > 0 do
|
|
(
|
|
print "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
|
|
print "Starting Texture Swtich"
|
|
startTimer = timestamp()
|
|
print ("Converting "+ (meshesToChange.count as string) + " mesh materials.")
|
|
|
|
for selMesh=1 to meshesToChange.count do
|
|
(
|
|
if meshesToChange[selMesh].material != undefined do
|
|
(
|
|
mlib[24] = meshesToChange[selMesh].material
|
|
SwitchRageToStd 24
|
|
meshesToChange[selMesh].material = mlib[24]
|
|
)
|
|
progBar.prog.value = ((100* selMesh)/meshesToChange.count)
|
|
)
|
|
endTimer = timeStamp()
|
|
|
|
print "Texture Switch Complete"
|
|
format "Time taken: %s\n" ((endTimer - startTimer) / 1000.0)
|
|
print "^^^^^^^^^^^^^^^^^^^^^^"
|
|
)
|
|
)
|
|
(destroyDialog progBar)
|
|
)--end sortAndSwitch
|
|
|
|
|
|
|
|
--function for writing out the selection sets to a text file
|
|
fn WriteSelectionSets =
|
|
(
|
|
everything = #()
|
|
outputFolder = maxfilepath --output folder is the same as the max file
|
|
outputFile = outputFolder + "SelectionSets.txt" --save the file as "SelectionSets.txt"
|
|
selectionSetFile = createFile outputFile --now we make the text file using the above settings
|
|
|
|
--fileHeadText = ("Created on " + localtime)
|
|
--print fileHeadText to: selectionSetFile --write the system time to the text file
|
|
|
|
for ss = 1 to selectionsets.count do
|
|
(
|
|
singleSelSet = #(infoText = ("Selection Set " + ss as string + " of " + selectionsets.count as string)) --some header information
|
|
selSetName = SelectionSets[ss].name --the name of the selection set
|
|
append singleSelSet selSetName
|
|
matchSS = for obj in SelectionSets[ss] collect obj.name --turn sel.set into array
|
|
append singleSelSet matchSS
|
|
append everything singleSelSet
|
|
)
|
|
|
|
print everything to: selectionSetFile
|
|
|
|
close selectionSetFile --housekeeping. this closes the txt file
|
|
)--end writeSelectionSets
|
|
|
|
--function to setup map for cs export
|
|
--copied code from cs_enviroment_setup.ms
|
|
fn CSMapExport =
|
|
(
|
|
exportOk = false
|
|
--Unhide & unfreeze the dummy01 node
|
|
max unhide all
|
|
max unfreeze all
|
|
|
|
--Select the original scene root, it can be called either Dummy01 or Dummy001
|
|
try(
|
|
select $Point01
|
|
$.name = "PointOrig"
|
|
)catch(format ("couldn't find $point01\n"))
|
|
|
|
try(
|
|
select $Point001
|
|
$.name = "PointOrig"
|
|
)catch(format ("couldn't find $point01\n"))
|
|
|
|
if $PointOrig != undefined then
|
|
(
|
|
--Copy the "Point Orig" and rename
|
|
Copy $
|
|
select $PointOrig001
|
|
$.name = "SetRoot"
|
|
|
|
--Set selection filter to select the geo and parent selection to the setroot
|
|
setSelectFilter 2
|
|
max select all
|
|
$.parent = $SetRoot
|
|
|
|
--Return Selection filter to all
|
|
SetSelectFilter 1
|
|
|
|
--Clear the selection
|
|
clearSelection()
|
|
|
|
--Create "PointZerod2"
|
|
Point pos:[0,0,0] isSelected:on
|
|
$.name = "PointZerod2"
|
|
|
|
--Align Setroot to "PointZerod2"
|
|
select $SetRoot
|
|
$.pos = $PointZerod2.pos
|
|
|
|
--Parent the "PointZerod2" & "Point Orig" to the SetRoot
|
|
select $PointZerod2
|
|
$.parent = $SetRoot
|
|
select $PointOrig
|
|
$.parent = $SetRoot
|
|
|
|
--Clear the selection
|
|
clearSelection()
|
|
|
|
--select the "PointOrig" & Get offset information
|
|
select $PointOrig
|
|
offsetposition = $PointOrig.pos
|
|
Positionfilter = (offsetposition as string)
|
|
Position_offset_values = filterstring Positionfilter "[ ]"
|
|
PointOrigangle = $PointOrig.rotation as eulerAngles
|
|
offsetrotation= PointOrigangle.Z
|
|
Rotation_offset_values = (offsetrotation as string )
|
|
|
|
--Time & user stamp
|
|
timedate = localtime
|
|
Updatedby = sysInfo.username
|
|
Filename = maxFileName as string
|
|
Setname = filterString Filename "."
|
|
|
|
format ("Attempting to output offset file...\n")
|
|
-- create an offset co-ordinate file
|
|
makeDir @"X:\gta5\art\animation\resources\sets\Offsets"
|
|
output_name = ("X:\\gta5\\art\\animation\\resources\\sets\\Offsets\\"+ Setname[1] +".log")
|
|
outputFile = createfile output_name
|
|
format (("<<<<<< " +Setname[1] +" >>>>>>" )+"\n") to:outputFile
|
|
format (("Last updated by " + Updatedby + " on the " + timedate)+"\n") to:outputFile
|
|
format (("" )+"\n") to:outputFile
|
|
format (("Position Offset = " + Position_offset_values[1] )+"\n") to:outputFile
|
|
format (("Rotation Offset = " + Rotation_offset_values )+"\n") to:outputFile
|
|
close outputFile
|
|
|
|
format (output_name+" created.\n")
|
|
exportOk = true
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Couldn't prep and export map as Point001/point01 not found. \n")
|
|
exportOk = false
|
|
)
|
|
return exportOk
|
|
)--csMapExport
|
|
|
|
fn PrepareProp exportAlso =
|
|
(
|
|
if selection.count == 1 then
|
|
(
|
|
thisProp = getCurrentSelection()
|
|
--===========================================================================================================================
|
|
--a section to handle gun magazine meshes - bug 808586
|
|
gunMag == false
|
|
propName = upperCase thisProp[1].name --get the prop name
|
|
filterPropName = filterString propName "_" --filter the name for breaks
|
|
shortPropName = #() --an array to hold the shortened filter data
|
|
for x=1 to filterPropName.count do (append shortPropName (subString filterPropName[x] 1 3))
|
|
magCheck = findItem shortPropName "MAG"
|
|
if magCheck !=0 do (if filterPropName[magCheck].count == 4 do gunMag = true)
|
|
--===========================================================================================================================
|
|
|
|
if ((isMeshSkinned thisProp[1]) == true) and (gunMag != true) then--if the mesh is skinned
|
|
(
|
|
print "Preparing skinned prop"
|
|
thisProp = getCurrentSelection()
|
|
SortAndSwitch thisProp
|
|
SkinnedProp thisProp[1] exportAlso
|
|
)
|
|
else
|
|
(
|
|
if queryBox "This appears to be an unskinned prop.\r\nI will attempt create a rig root setup for it.\r\nDo you want to continue?" beep:false title:"Materials Export Manager" do
|
|
(
|
|
print "Preparing unskinned prop"
|
|
thisProp = getCurrentSelection()
|
|
SortAndSwitch thisProp
|
|
UnskinnedProp thisProp[1] exportAlso
|
|
)
|
|
)
|
|
)
|
|
else (messageBox "Please run with only one object selected.")
|
|
)
|
|
|
|
fn PrepareCharacter =
|
|
(
|
|
print "Preparing character"
|
|
local pedMeshes = ShowSkinningAndBones()
|
|
SortAndSwitch pedMeshes
|
|
|
|
WriteSelectionSets()
|
|
|
|
-- addDummyData()
|
|
RSTA_addDummyData()
|
|
|
|
|
|
|
|
)
|
|
|
|
fn PrepareExpressions =
|
|
(
|
|
print "Preparing expressions"
|
|
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/usefulScripts/RSTA_cleanExpressionControllersForMotionBuilder.ms")
|
|
--from "X:\gta5\tools\wildwest\script\3dsMax\Characters\Rigging\riggingToolsGUI.ms" lines 154 -> 155
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/findExpressionObjects.ms")
|
|
print "Expression set Created"
|
|
exprItems = #()
|
|
selCount = getNumNamedSelSets()
|
|
|
|
for i = selCount to 1 by -1 do
|
|
(
|
|
if getNamedSelSetName i == "*expressionsToExport" then
|
|
(
|
|
setItems = getNamedSelSetItemCount i
|
|
|
|
for a = 1 to setItems do
|
|
(
|
|
thisItem = getNamedSelSetItem i a
|
|
appendIfUnique exprItems thisItem
|
|
)
|
|
)
|
|
)
|
|
|
|
select exprItems
|
|
--from "X:\gta5\tools\wildwest\script\3dsMax\Characters\Rigging\ExpressionExporter\expressionGUI.ms" lines 161 -> 164
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/ExpressionExporter/objectOutput.ms")
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/Characters/Rigging/ExpressionExporter/expressionOutputXML.ms")
|
|
print "Expressions saved"
|
|
|
|
local dummyObj = getNodeByName "Dummy01"
|
|
local exprFile = undefined
|
|
local thisPath = maxFilePath
|
|
if thisPath != undefined do
|
|
(
|
|
if maxfileName != undefined do
|
|
(
|
|
local thisMaxFile = (filterstring (maxFileName as string) ".")
|
|
thisMaxFile = thisMaxFile[1]
|
|
local output_nameXML = (thisPath+thisMaxFile+"_RSNXML.xml")
|
|
if (doesFileExist output_NameXml) == true then
|
|
(
|
|
exprFile = output_nameXML
|
|
)
|
|
)
|
|
)
|
|
|
|
if dummyObj != undefined do
|
|
(
|
|
setUserProp dummyObj "exprFile" (exprFile as string)
|
|
)
|
|
|
|
)
|
|
|
|
|
|
fn rsta_findObjectsToKeep charDummy =
|
|
(
|
|
/**
|
|
WILL FIND ALL CHILDREN OF NODES IN NODES TO KEEP AND ENSURE THAT THESE ARE PASSED THROUGH AS A SELECTION
|
|
THIS CAN THEN BE USED TO FILTER WHAT WE TEMPORARILY DELETE FROM THE SCENE.
|
|
**/
|
|
objectsToKeep = #()
|
|
nodesToTest = #(
|
|
charDummy,
|
|
"FaceFX",
|
|
"Ambient_UI",
|
|
"Dummy01",
|
|
"faceControls_OFF",
|
|
"FacialAttrGUI",
|
|
"facialRoot_C_OFF",
|
|
"TEXT_Normals",
|
|
"WRINKLES_TEXT"
|
|
)
|
|
|
|
for obj in objects do
|
|
(
|
|
if substring obj.name 1 4 == "RECT" do
|
|
(
|
|
appendIfUnique nodesToTest obj.name
|
|
)
|
|
)
|
|
|
|
for item in nodesToTest do
|
|
(
|
|
thisNode = getNodeByName item
|
|
|
|
if thisNode != undefined then
|
|
(
|
|
append objectsToKeep thisNode
|
|
objectsToKeep = RSTA_getAllChildren thisNode arr:objectsToKeep#()
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't find "+(item as string)+"\n")
|
|
)
|
|
)
|
|
|
|
return objectsToKeep
|
|
)
|
|
|
|
fn rsta_exportFbx fbxFileName fbxVer exportSelected =
|
|
(
|
|
|
|
if fbxVer == 2010 then
|
|
(
|
|
format ("Exporting as fbx 2010\n")
|
|
--think i need to call the import here
|
|
pluginManager.loadClass FBXEXP
|
|
fbxExporterSetParam "FileVersion" "FBX 201000"
|
|
exportFile fbxFileName #noPrompt selectedOnly:exportSelected using:FBXEXP
|
|
)
|
|
else
|
|
(
|
|
if fbxVer == 2012 then
|
|
(
|
|
version = 2012
|
|
format ("Exporting as fbx 2012\n")
|
|
|
|
pluginManager.loadClass FBXEXP
|
|
|
|
fbxExporterSetParam "FileVersion" "FBX201200"
|
|
exportFile fbxFileName #noPrompt selectedOnly:exportSelected using:FBXEXP
|
|
)
|
|
else
|
|
(
|
|
format ("Couldn't export fbx file as version was set to "+(fbxVer as string)+"\n")
|
|
messagebox ("Couldn't export fbx file as version was set to "+(fbxVer as string)+"\n") beep:true title:"Save Error!"
|
|
)
|
|
)
|
|
)
|
|
|
|
fn PrepAndExportCharacter =
|
|
(
|
|
start = timestamp()
|
|
local fbxFileName = undefined
|
|
undo label:"Prep and Epxort Character" on(
|
|
|
|
--first off we need to pick the name and location of the fbx file to save
|
|
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
|
|
|
|
if fbxFileName != undefined then
|
|
(
|
|
--first off remove any template heads.
|
|
filein (RsConfigGetWildWestDir() +"script\\3dsMax\\Characters\\Rigging\\ambientFacial\\removeGuideHead.ms")
|
|
|
|
--now we will delete unselected nodes
|
|
|
|
charDummy = findTheDummy()
|
|
--format ("charDummy: "+(charDummy as string)+"\n")
|
|
selArray = rsta_findObjectsToKeep charDummy.name
|
|
select selArray
|
|
|
|
objArray = objects as array
|
|
objToDelete = #()
|
|
for o = objArray.count to 1 by -1 do
|
|
(
|
|
obj = objArray[o]
|
|
fnd = finditem selArray obj
|
|
|
|
if fnd == 0 then
|
|
(
|
|
--format ("Couldn't find "+obj.name+" in selArray\n")
|
|
append objToDelete obj
|
|
)
|
|
)
|
|
|
|
delete objToDelete
|
|
|
|
PrepareCharacter()
|
|
PrepareExpressions()
|
|
|
|
rageMaterials = rsta_NukeMaterials true
|
|
|
|
--NOW WE CAN EXPORT
|
|
--now if the character has an ambient ui then it needs to be exported as fbx2010 otherwise 2012
|
|
|
|
ambientUINode = getNodeByName "Ambient_UI"
|
|
local version = undefined
|
|
if ambientUINode != undefined then
|
|
(
|
|
fbxVer = 2010
|
|
rsta_exportFbx fbxFileName fbxVer false
|
|
)
|
|
else
|
|
(
|
|
fbxVer = 2012
|
|
rsta_exportFbx fbxFileName fbxVer false
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("No valid fbx file specified.")
|
|
)
|
|
)
|
|
|
|
format ("Exporting. This can take a little while...\n")
|
|
--now we can undo everytihng.
|
|
max undo
|
|
format ("Scene reset to initial state.\n")
|
|
fndFbx = doesFileExist fbxFileName
|
|
|
|
end = timestamp()
|
|
|
|
if fndFbx == true then
|
|
(
|
|
format ("Exported to "+fbxFileName+"\n")
|
|
format "Processing Prepare & Export took % seconds\n" ((end - start) / 1000.0)
|
|
messagebox ("Exported to "+fbxFileName+"\n") beep:true title:"Success!"
|
|
|
|
)
|
|
else
|
|
(
|
|
format "Processing Prepare & Export took % seconds\n" ((end - start) / 1000.0)
|
|
messagebox ("Exporting appears to have failed. Please see the listener.") beep:true title:"WARNING!"
|
|
)
|
|
|
|
)
|
|
|
|
-- fn PrepAndExportVehicle genType =
|
|
fn PrepAndExportVehicle =
|
|
(
|
|
start = timestamp()
|
|
local fbxFileName = undefined
|
|
undo label:"Prep and Export Vehicle" on(
|
|
|
|
selectedVehicle = selectByName title:"Pick Vehicle skin mesh." showHidden:true
|
|
driver = selectedVehicle[1]
|
|
format "You selected Vehicle:'%'!\n" driver.name
|
|
|
|
-- if selection.count == 1 then
|
|
if driver != undefined then
|
|
(
|
|
select driver
|
|
format ("Exporting "+driver.name+"\n")
|
|
if driver.modifiers[#Skin] != undefined then
|
|
(
|
|
--first off we need to pick the name and location of the fbx file to save
|
|
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
|
|
if fbxFileName != undefined then
|
|
(
|
|
--now we will delete unselected nodes
|
|
local mainName = filterstring driver.name "_"
|
|
mainName = mainName[1]
|
|
|
|
-- genType = (findString (toLower(obj.name)) "_ng_")
|
|
-- local lwrName = toLower(driver.name)
|
|
-- genType = findstring lwrName "_ng_"
|
|
|
|
local selArray = #()
|
|
--format ("charDummy: "+(charDummy as string)+"\n")
|
|
-- append selArray driver
|
|
|
|
-- local skelRootNode = undefined
|
|
|
|
-- if genType == undefined then
|
|
-- (
|
|
-- format ("Prepping as last gen.\n")
|
|
skelRootNode = getNodeByName (mainName+"_"+"skel")
|
|
-- )
|
|
-- else
|
|
-- (
|
|
-- format ("Prepping as next gen.\n")
|
|
-- skelRootNode = getNodeByName (mainName+"_"+"ng")
|
|
-- )
|
|
|
|
skelArray = undefined
|
|
if skelRootNode != undefined do
|
|
(
|
|
append selArray skelRootNode
|
|
selArray = RSTA_getAllChildren skelRootNode arr:selArray#()
|
|
skelArray = deepcopy selArray
|
|
)
|
|
append selArray driver
|
|
-- select selArray
|
|
|
|
objArray = objects as array
|
|
objToDelete = #()
|
|
for o = objArray.count to 1 by -1 do
|
|
(
|
|
obj = objArray[o]
|
|
fnd = finditem selArray obj
|
|
|
|
if fnd == 0 then
|
|
(
|
|
--format ("Couldn't find "+obj.name+" in selArray\n")
|
|
append objToDelete obj
|
|
)
|
|
)
|
|
|
|
-- select objToDelete
|
|
delete objToDelete
|
|
|
|
select selArray
|
|
-- PrepareVehicle driver skelArray
|
|
local parentDummy = dummy pos:[0,0,0]
|
|
parentDummy.name = "Dummy01"
|
|
skelRootNode.parent = parentDummy
|
|
|
|
rageMaterials = rsta_NukeMaterials true true
|
|
|
|
--NOW WE CAN EXPORT
|
|
--now if the character has an ambient ui then it needs to be exported as fbx2010 otherwise 2012
|
|
|
|
fbxVer = 2012
|
|
rsta_exportFbx fbxFileName fbxVer false
|
|
|
|
format ("Exporting. This can take a little while...\n")
|
|
--now we can undo everytihng.
|
|
max undo
|
|
format ("Scene reset to initial state.\n")
|
|
fndFbx = doesFileExist fbxFileName
|
|
|
|
end = timestamp()
|
|
|
|
if fndFbx == true then
|
|
(
|
|
format ("Exported to "+fbxFileName+"\n")
|
|
format "Processing Prepare & Export took % seconds\n" ((end - start) / 1000.0)
|
|
messagebox ("Exported to "+fbxFileName+"\n") beep:true title:"Success!"
|
|
|
|
)
|
|
else
|
|
(
|
|
format "Processing Prepare & Export took % seconds\n" ((end - start) / 1000.0)
|
|
messagebox ("Exporting appears to have failed. Please see the listener.") beep:true title:"WARNING!"
|
|
)
|
|
|
|
)
|
|
else
|
|
(
|
|
format ("No valid fbx file specified.")
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("No skin modifier found on "+driver.name+"\n")
|
|
messagebox ("No skin modifier found on "+driver.name+"\n") beep:true title:"WARNING!"
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format "Please select only your vehicle mesh."
|
|
messagebox "Please select only your vehicle mesh." beep:true title:"Warning"
|
|
|
|
)
|
|
|
|
|
|
)
|
|
)
|
|
|
|
fn EnvSetupPrepMapAndExport =
|
|
(
|
|
start = timestamp()
|
|
local fbxFileName = undefined
|
|
undo label:"Prep and Export Map" on(
|
|
--first off we need to pick the name and location of the fbx file to save
|
|
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
|
|
if fbxFileName != undefined then
|
|
(
|
|
rsta_NukeMaterials true true
|
|
-- PrepareMap()
|
|
|
|
filePath = "//depot/gta5/art/animation/resources/sets/Max_Files/"
|
|
|
|
maxFile = filterString fbxFileName "."
|
|
maxFile = (maxFile[1]+".max")
|
|
|
|
if maxFile != undefined then
|
|
(
|
|
saveMaxFile maxFile
|
|
|
|
exportOk = CSMapExport()
|
|
|
|
if exportOk == true do
|
|
(
|
|
format ("Exporting as fbx 2012\n")
|
|
|
|
fbxVer = 2012
|
|
rsta_exportFbx fbxFileName fbxVer false
|
|
|
|
format ("Exporting. This can take a little while...\n")
|
|
--now we can undo everytihng.
|
|
max undo
|
|
format ("Scene reset to initial state.\n")
|
|
fndFbx = doesFileExist fbxFileName
|
|
|
|
end = timestamp()
|
|
|
|
if fndFbx == true then
|
|
(
|
|
format ("Exported to "+fbxFileName+"\n")
|
|
format "Processing Setup Prep and Export took % seconds\n" ((end - start) / 1000.0)
|
|
messagebox ("Exported to "+fbxFileName+"\n") beep:true title:"Success!"
|
|
|
|
)
|
|
else
|
|
(
|
|
format "Processing Setup Prep and Export took % seconds\n" ((end - start) / 1000.0)
|
|
messagebox ("Exporting appears to have failed. Please see the listener.") beep:true title:"WARNING!"
|
|
)
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("No max file name set")
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("No valid fbx file specified.")
|
|
)
|
|
)
|
|
)
|
|
|
|
|
|
fn ImportMapAssets interiorType =
|
|
(
|
|
success = true
|
|
undo label:"Prep Map Data" on(
|
|
|
|
viewpt = viewport.setLayout #layout_1
|
|
|
|
viewport.SetRenderLevel #wireframe
|
|
containerFileName = undefined
|
|
if interiorType == false then
|
|
(
|
|
containerFileName = getOpenFileName caption:"Container File" types:"Container File (*.MAXC)|*.maxc|All Files (*.*)|*.*|"
|
|
)
|
|
else
|
|
(
|
|
containerFileName = getOpenFileName caption:"Interior File" types:"Interior File (*.MAX)|*.max|All Files (*.*)|*.*|"
|
|
)
|
|
|
|
if containerFileName != undefined then
|
|
(
|
|
format ("Picked "+containerFileName+"...\n")
|
|
|
|
if interiorType == false then
|
|
(
|
|
cont1 = Containers.CreateInheritedContainer containerFileName
|
|
cont1.MakeUnique()
|
|
format "Made Unique\n"
|
|
--now unlink
|
|
for obj in objects do
|
|
(
|
|
obj.parent = undefined
|
|
)
|
|
|
|
delete cont1
|
|
|
|
lodObjs = findLodObjects()
|
|
delete lodObjs
|
|
|
|
objToDelete = #()
|
|
selArray = #()
|
|
for obj in objects do
|
|
(
|
|
if superclassof obj != GeometryClass do
|
|
(
|
|
append objToDelete obj
|
|
)
|
|
)
|
|
|
|
delete objToDelete
|
|
)
|
|
else
|
|
(
|
|
mergemaxFile containerFileName #prompt
|
|
objToDelete = #()
|
|
|
|
for obj in objects do
|
|
(
|
|
if superclassof obj != GeometryClass then
|
|
(
|
|
append objToDelete obj
|
|
)
|
|
)
|
|
|
|
delete objToDelete
|
|
)
|
|
|
|
for obj in objects do
|
|
(
|
|
convertTo obj Editable_Mesh
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("No container picked.\n")
|
|
)
|
|
)
|
|
|
|
if success == false do
|
|
(
|
|
max undo
|
|
)
|
|
|
|
messagebox ("Map Assets imported.") beep:true
|
|
)
|
|
|
|
fn prepareAndExportProp obj =
|
|
(
|
|
success = false
|
|
undo label:"Prep and Export prop" on(
|
|
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
|
|
if fbxFileName != undefined then
|
|
(
|
|
select obj
|
|
PrepareProp false
|
|
fbxVer = 2012
|
|
rsta_exportFbx fbxFileName fbxVer true
|
|
success = true
|
|
)
|
|
else
|
|
(
|
|
format ("No valid fbx file picked.\n")
|
|
success = false
|
|
)
|
|
)
|
|
|
|
if success == true do
|
|
(
|
|
format ("Trying to Restore scene state...\n")
|
|
max undo
|
|
)
|
|
|
|
messagebox ("Prop Prepped and exported.") beep:true
|
|
)
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
fn RSTA_resourcePrepUI =
|
|
(
|
|
--HAD TO TURN THIS INTO A FUNCTION SO WE CAN RESET IT AFTER CREATION OF EXPRESSIONS.
|
|
|
|
--//////////////////////////////////////////////////////////////////////////////////////////////
|
|
-- UI
|
|
--//////////////////////////////////////////////////////////////////////////////////////////////
|
|
if resourcePrep_UI != undefined then destroyDialog resourcePrep_UI
|
|
|
|
rollout resourcePrep_UI "Resource Prep" --this is the main rollout that contains all the tabs and sub rollouts.
|
|
(
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
-- VARIABLES
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
|
|
local tabHeight = 20
|
|
-- local tabHeight = 40 --for if iwe want double tab rows
|
|
local tabRollouts = #(::rollCharacters,::rollProp,::rollVehicles,::rollMap)
|
|
|
|
-- local expressionSubRolls = #(::subRollNodePick,::subRollExpressionType, ::subRollExpressionText, ::subRollLoadPreset, ::subRollSavePreset)
|
|
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
-- CONTROLS
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:resourcePrep_UI.width
|
|
local banner = makeRsBanner dn_Panel:rsBannerPanel wiki:"ExpressionCreate" filename:(getThisScriptFilename())
|
|
dotNetControl dnTabs "system.windows.forms.tabControl" width:resourcePrep_UI.width height:tabHeight offset:[-12, 0]
|
|
|
|
subRollout theSubRollout width:(resourcePrep_UI.width - 2) height:(resourcePrep_UI.Height - (dnTabs.height + rsBannerPanel.height))offset:[-12, 0] pos:[-1, dnTabs.pos.y + (tabHeight+ 10)]
|
|
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
-- FUNCTIONS
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
fn SetPage index =
|
|
(
|
|
if index > tabRollouts.count do messageBox "invalid tab"
|
|
|
|
for roll in theSubRollout.rollouts do
|
|
(
|
|
removeRollout roll
|
|
)
|
|
|
|
AddSubRollout theSubRollout tabRollouts[index] rolledup:false border:true
|
|
|
|
if index == 1 do --ie characters
|
|
(
|
|
-- AddSubRollout theSubRollout expressionSubRolls[1] rolledup:false border:false
|
|
)
|
|
|
|
if index == 2 do -- ie prop
|
|
(
|
|
-- AddSubRollout theSubRollout expressionSubRolls[1] rolledup:false border:false
|
|
)
|
|
|
|
if index == 3 do --ie vehicles
|
|
(
|
|
-- AddSubRollout theSubRollout expressionSubRolls[1] rolledup:false border:false
|
|
)
|
|
if index == 4 do --ie map
|
|
(
|
|
)
|
|
|
|
if index != 1 then
|
|
(
|
|
-- subRollNodePick.btnCreateDriverJoystick.enabled = false
|
|
)
|
|
else
|
|
(
|
|
-- subRollNodePick.btnCreateDriverJoystick.enabled = true
|
|
)
|
|
|
|
)
|
|
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
-- EVENTS
|
|
--//////////////////////////////////////////////////////////////////////////////
|
|
on dnTabs Click do
|
|
(
|
|
local tabNum = dnTabs.SelectedIndex + 1
|
|
-- local tabName = tabRollouts[tabNum].name
|
|
|
|
SetPage tabNum
|
|
)
|
|
|
|
on resourcePrep_UI open do
|
|
(
|
|
banner.setup()
|
|
|
|
dnTabs.multiline = true --this lets us have multiple lines of tabs
|
|
|
|
for tab in tabRollouts do dnTabs.tabPages.Add tab.title
|
|
SetPage 1
|
|
|
|
--now we need to find a previous saved position and apply that if found
|
|
uiPosFile = RSTA_getUiPosFile() --get the dialogPos file
|
|
dialogPos = RSTA_DialogPosLoad uiPosFile --get the position form the dialog pos file
|
|
format ("Attempting to set dialog pos to "+(dialogPos as string)+"\n")
|
|
SetDialogPos resourcePrep_UI dialogPos
|
|
)
|
|
|
|
on resourcePrep_UI close do
|
|
(
|
|
gc light:true
|
|
)
|
|
|
|
on resourcePrep_UI moved position do
|
|
(
|
|
uiPosFile = RSTA_getUiPosFile() --get the dialogPos file
|
|
RSTA_DialogPosRec resourcePrep_UI uiPosFile
|
|
)
|
|
)
|
|
|
|
rollout rollCharacters "Characters"
|
|
(
|
|
button btnPrepareAndExportCharacter "Prepare & Export" width:(resourcePrep_UIWidth - 20) tooltip:"Prepare meshes, expressions, shaders and then export."
|
|
button btnPrepareCharacter "Prepare Character" width:(resourcePrep_UIWidth - 20) tooltip:"Prepare meshes and shaders"
|
|
button btnPrepareExpressions "Prepare Expressions" width:(resourcePrep_UIWidth - 20)
|
|
button btnNukeMaterials "Nuke Materials" width:(resourcePrep_UIWidth - 20)
|
|
button btnRestoreMaterials "Restore Materials" width:(resourcePrep_UIWidth - 20)
|
|
|
|
on btnPrepareAndExportCharacter pressed do
|
|
(
|
|
PrepAndExportCharacter()
|
|
)
|
|
|
|
on btnPrepareCharacter pressed do
|
|
(
|
|
PrepareCharacter()
|
|
)
|
|
|
|
on btnPrepareExpressions pressed do
|
|
(
|
|
PrepareExpressions()
|
|
)
|
|
|
|
on btnNukeMaterials pressed do
|
|
(
|
|
rsta_NukeMaterials false true
|
|
)
|
|
|
|
on btnRestoreMaterials pressed do
|
|
(
|
|
if rageMaterialsArray != undefined then
|
|
(
|
|
restoreMaterials rageMaterialsArray
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Rage materials have not been stored so we cannot restore them. Sorry\n") beep:true
|
|
)
|
|
)
|
|
)
|
|
|
|
rollout rollProp "Prop"
|
|
(
|
|
button btnPrepareAndExportProp "Prepare & Export Prop" width:(resourcePrep_UIWidth - 20) tooltip:"Prepare props"
|
|
button btnPrepareProp "Prepare Prop" width:(resourcePrep_UIWidth - 20) tooltip:"Prepare props"
|
|
button btnNukeMaterials "Nuke Materials" width:(resourcePrep_UIWidth - 20)
|
|
button btnRestoreMaterials "Restore Materials" width:(resourcePrep_UIWidth - 20)
|
|
|
|
on btnPrepareAndExportProp pressed do
|
|
(
|
|
if selection.count == 1 then
|
|
(
|
|
if superclassof $ == GeometryClass then
|
|
(
|
|
prepareAndExportProp $
|
|
)
|
|
else
|
|
(
|
|
format ($.name+" is not a valid geometry.\n")
|
|
messagebox ($.name+" is not a valid geometry.\n") beep:true
|
|
)
|
|
)
|
|
else
|
|
(
|
|
format ("Please only pick the prop mesh you wish to export.\n")
|
|
messagebox ("Please only pick the prop mesh you wish to export.\n")
|
|
)
|
|
)
|
|
|
|
on btnPrepareProp pressed do
|
|
(
|
|
PrepareProp true
|
|
)
|
|
|
|
on btnNukeMaterials pressed do
|
|
(
|
|
rsta_NukeMaterials false true
|
|
)
|
|
|
|
on btnRestoreMaterials pressed do
|
|
(
|
|
if rageMaterialsArray != undefined then
|
|
(
|
|
restoreMaterials rageMaterialsArray
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Rage materials have not been stored so we cannot restore them. Sorry\n") beep:true
|
|
)
|
|
)
|
|
)
|
|
|
|
rollout rollVehicles "Vehicles"
|
|
(
|
|
button btnPrepareAndExportVechicle "Prep & Export Vehicles" width:(resourcePrep_UIWidth - 20)
|
|
button btnPrepareVechicle "Prepare Vehicles" width:(resourcePrep_UIWidth - 20)
|
|
button btnNukeMaterials "Nuke Materails" width:(resourcePrep_UIWidth - 20)
|
|
button btnRestoreMaterials "Restore Materials" width:(resourcePrep_UIWidth - 20)
|
|
|
|
on btnPrepareAndExportVechicle pressed do
|
|
(
|
|
PrepAndExportVehicle()
|
|
)
|
|
|
|
on btnPrepareVechicle pressed do
|
|
(
|
|
PrepareVehicle()
|
|
)
|
|
|
|
on btnNukeMaterials pressed do
|
|
(
|
|
rsta_NukeMaterials false true
|
|
)
|
|
|
|
on btnRestoreMaterials pressed do
|
|
(
|
|
if rageMaterialsArray != undefined then
|
|
(
|
|
restoreMaterials rageMaterialsArray
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Rage materials have not been stored so we cannot restore them. Sorry\n") beep:true
|
|
)
|
|
)
|
|
)
|
|
|
|
rollout rollMap "Map"
|
|
(
|
|
local interiorType = false
|
|
checkbox chkInterior "Interior Asset" default:false
|
|
|
|
button btnImportMapAssets "Import Map Assets" width:(resourcePrep_UIWidth - 20)
|
|
button btnEnvSetupPrepMapAndExport "Prepare & Export Map" width:(resourcePrep_UIWidth - 20)
|
|
button btnPrepareMap "Prepare Map" width:(resourcePrep_UIWidth - 20)
|
|
button btnNukeMaterials "Nuke Materials" width:(resourcePrep_UIWidth - 20)
|
|
button btnRestoreMaterials "Restore Material" width:(resourcePrep_UIWidth - 20)
|
|
button btnExportFbx "Export FBX" width:(resourcePrep_UIWidth - 20)
|
|
|
|
on chkInterior changed state do
|
|
(
|
|
interiorType = state
|
|
)
|
|
|
|
on btnImportMapAssets pressed do
|
|
(
|
|
ImportMapAssets interiorType
|
|
)
|
|
|
|
on btnEnvSetupPrepMapAndExport pressed do
|
|
(
|
|
EnvSetupPrepMapAndExport()
|
|
)
|
|
|
|
on btnPrepareMap pressed do
|
|
(
|
|
-- PrepareMap()
|
|
if maxFileName != undefined then
|
|
(
|
|
CSMapExport()
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Please save your max file and try again.\n")
|
|
)
|
|
)
|
|
|
|
on btnNukeMaterials pressed do
|
|
(
|
|
rsta_NukeMaterials false true
|
|
)
|
|
|
|
on btnRestoreMaterials pressed do
|
|
(
|
|
if rageMaterialsArray != undefined then
|
|
(
|
|
restoreMaterials rageMaterialsArray
|
|
)
|
|
else
|
|
(
|
|
messagebox ("Rage materials have not been stored so we cannot restore them. Sorry\n") beep:true
|
|
)
|
|
)
|
|
|
|
on btnExportFbx pressed do
|
|
(
|
|
fbxFileName = getSaveFileName caption:"FBX File" types:"FBX File (*.FBX)|*.fbx|All Files (*.*)|*.*|"
|
|
if fbxFileName != undefined then
|
|
(
|
|
fbxVer = 2012
|
|
rsta_exportFbx fbxFileName fbxVer
|
|
)
|
|
else
|
|
(
|
|
format ("No valid fbx file picked.\n")
|
|
)
|
|
)
|
|
)
|
|
|
|
createDialog resourcePrep_UI width:resourcePrep_UIWidth height:resourcePrep_UIHeight style:#(#style_titlebar, #style_border, #style_sysmenu)
|
|
|
|
format ("Regenerating ui...\n")
|
|
)
|
|
|
|
RSTA_resourcePrepUI() |