360 lines
13 KiB
Plaintext
Executable File
360 lines
13 KiB
Plaintext
Executable File
filein (RsConfigGetWildWestDir() + "script/3dsMax/_config_files/Wildwest_header.ms")
|
|
filein (RsConfigGetWildWestDir() + "script/3dsMax/_common_functions/FN_RSTA_XML.ms")
|
|
|
|
struct RsObj
|
|
(
|
|
fn MakeXMLNodeWithInnerText name parent innnerText =
|
|
(
|
|
local xn_node = rsta_xml.makeNode name parent
|
|
xn_node.innerText = innnerText
|
|
return xn_node
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn OptimizeFloat value toString:true =
|
|
(
|
|
local value = if ((mod value 1) == 0) then value as integer else value
|
|
return (if toString then (value as string) else value)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn point3_to_string p3 endSpace:true =
|
|
(
|
|
local pX = OptimizeFloat p3.x
|
|
local pY = OptimizeFloat p3.y
|
|
local pZ = OptimizeFloat p3.z
|
|
return (pX + "," + pY + "," + pZ) + (if endSpace then " " else "")
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn string_to_point3 s =
|
|
(
|
|
local bits = FilterString s ","
|
|
return [bits[1] as float, bits[2] as float, bits[3] as float ]
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn string_to_bool s =
|
|
(
|
|
if (s == "1") do return true
|
|
if (s == "true") do return true
|
|
return false
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn transform_to_string Trans =
|
|
(
|
|
return (point3_to_string Trans.row1) + (point3_to_string Trans.row2) + (point3_to_string Trans.row3) + (point3_to_string Trans.row4 endSpace:false)
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn string_to_transform s =
|
|
(
|
|
local bits = filterstring s " "
|
|
return (matrix3 (string_to_point3 bits[1]) (string_to_point3 bits[2]) (string_to_point3 bits[3]) (string_to_point3 bits[4]))
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn colour_to_string col =
|
|
(
|
|
return ((OptimizeFloat col.r) + " " + (OptimizeFloat col.g) + " " + (OptimizeFloat col.b))
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn string_to_colour s =
|
|
(
|
|
local bits = FilterString s " "
|
|
return (color (bits[1] as integer) (bits[2] as integer) (bits[3] as integer))
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn InnerText_To_Array xml_node =
|
|
(
|
|
if (xml_node != undefined) do return FilterString xml_node.innerText " "
|
|
return #()
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn xmlList_to_xmlArray xml_list =
|
|
(
|
|
return for i=0 to xml_list.count-1 collect xml_list.item[i]
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn material_to_xml mat parent mapID: =
|
|
(
|
|
local xn_mat = rsta_xml.makeNode "Material" parent
|
|
local shaderClass = classof mat
|
|
xn_mat.setAttribute "type" (shaderClass as string)
|
|
|
|
if (mapID != unsupplied) do xn_mat.setAttribute "mapID" (mapID as string)
|
|
|
|
if (shaderClass == Multimaterial) do
|
|
(
|
|
for i=1 to mat.materialList.count do material_to_xml (mat.materialList[i]) xn_mat mapID:(mat.materialIDList[i])
|
|
)
|
|
|
|
if (shaderClass == Rage_Shader) do
|
|
(
|
|
MakeXMLNodeWithInnerText "RagePreset" xn_mat (RstGetShaderName mat)
|
|
for n=1 to (RstGetVariableCount mat) do
|
|
(
|
|
local xn_rageAttr = rsta_xml.makeNode "RageAttr" xn_mat
|
|
xn_rageAttr.setAttribute "name" (RstGetVariableName mat n)
|
|
xn_rageAttr.setAttribute "type" (RstGetVariableType mat n)
|
|
xn_rageAttr.innertext = (RstGetVariable mat n) as string
|
|
)
|
|
)
|
|
return xn_subMat
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn xml_to_material xml_node =
|
|
(
|
|
local mat = undefined
|
|
case (xml_node.getAttribute "type") of
|
|
(
|
|
"Multimaterial" :
|
|
(
|
|
mat = Multimaterial()
|
|
xn_subMats = xml_node.SelectNodes "Material"
|
|
for i=0 to xn_subMats.count-1 do
|
|
(
|
|
local xn_submat = xn_subMats.item[i]
|
|
local subMat = xml_to_material xn_submat
|
|
mat.materialList[i+1] = subMat
|
|
mat.materialIDList[i+1] = (xn_submat.getAttribute "mapID") as integer
|
|
)
|
|
)
|
|
|
|
"Rage_Shader" :
|
|
(
|
|
mat = Rage_Shader()
|
|
RstSetShaderName mat (xml_node.selectSingleNode "RagePreset").innerText
|
|
local xn_rageAttrs = xml_node.selectNodes "RageAttr"
|
|
for i=0 to xn_rageAttrs.count - 1 do
|
|
(
|
|
local xn_rageAttr = xn_rageAttrs.item[i]
|
|
local v = xn_rageAttr.innertext
|
|
|
|
case (xn_rageAttr.getAttribute "type") of
|
|
(
|
|
"float" : v = v as float
|
|
"vector3" : string_to_point3 vA
|
|
)
|
|
|
|
RstSetVariable mat (i+1) v
|
|
)
|
|
)
|
|
)
|
|
return mat
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn ExportObjects objs xmlFile: =
|
|
(
|
|
if (xmlFile == unsupplied) do
|
|
(
|
|
xmlFile = getSaveFileName caption:"Pick export location ..." types:"RsObj File|*.xml"
|
|
)
|
|
|
|
local xml_io = rsta_xml_io()
|
|
xml_io.new "RsObj"
|
|
local xn_objects = rsta_xml.makeNode "Objects" xml_io.Root
|
|
local materials = #()
|
|
|
|
for obj in objs do
|
|
(
|
|
local objMesh = obj.mesh
|
|
local xn_obj = rsta_xml.makeNode "Object" xn_objects
|
|
xn_obj.SetAttribute "name" obj.name
|
|
xn_obj.SetAttribute "transform" (transform_to_string obj.transform)
|
|
|
|
local xn_maxObj = rsta_xml.makeNode "MaxObject" xn_obj
|
|
|
|
MakeXMLNodeWithInnerText "WireColour" xn_maxObj (colour_to_string obj.wirecolor)
|
|
|
|
local xn_geo = rsta_xml.makeNode "Geometry" xn_obj
|
|
|
|
-- VERTS ------------------------------------------------------
|
|
local string_verts = ""
|
|
for i=1 to objMesh.numverts do string_verts += point3_to_string (getVert objMesh i)
|
|
MakeXMLNodeWithInnerText "Verts" xn_geo string_verts
|
|
|
|
-- FACES ------------------------------------------------------
|
|
local string_faces = ""
|
|
local string_edgeVis = ""
|
|
local string_smoothGroup = ""
|
|
local string_faceIDs = ""
|
|
|
|
for i=1 to objMesh.numfaces do
|
|
(
|
|
string_faces += point3_to_string (getFace objMesh i)
|
|
string_smoothGroup += (getFaceSmoothGroup objMesh i) as string + " "
|
|
string_faceIDs += (getFaceMatID objMesh i) as string + " "
|
|
|
|
string_edgeVis += (if (getEdgeVis objMesh i 1) then "1" else "0") + ","
|
|
string_edgeVis += (if (getEdgeVis objMesh i 2) then "1" else "0") + ","
|
|
string_edgeVis += (if (getEdgeVis objMesh i 3) then "1" else "0") + " "
|
|
)
|
|
|
|
MakeXMLNodeWithInnerText "Faces" xn_geo string_faces
|
|
MakeXMLNodeWithInnerText "EdgeVis" xn_geo string_edgeVis
|
|
MakeXMLNodeWithInnerText "SmoothingGroups" xn_geo string_smoothGroup
|
|
MakeXMLNodeWithInnerText "FaceIDs" xn_geo string_faceIDs
|
|
|
|
-- MAP CHANNEL ------------------------------------------
|
|
local xn_mapChannels = rsta_xml.makeNode "MapChannels" xn_obj
|
|
local mapChannelCount = meshop.getNumMaps objMesh
|
|
xn_mapChannels.setAttribute "count" (mapChannelCount as string)
|
|
|
|
for mapCh=-2 to mapChannelCount do
|
|
(
|
|
if (meshop.getMapSupport objMesh mapCh) do
|
|
(
|
|
local xn_mapChannel = rsta_xml.makeNode "MapChannel" xn_mapChannels
|
|
xn_mapChannel.setAttribute "channel" (mapCh as string)
|
|
|
|
local mapVertsString = ""
|
|
for vert=1 to (meshop.getNumMapVerts objMesh mapCh) do mapVertsString += point3_to_string (meshop.getMapVert objMesh mapCh vert)
|
|
MakeXMLNodeWithInnerText "Verts" xn_mapChannel mapVertsString
|
|
|
|
local mapFacesString = ""
|
|
for face=1 to (meshop.getNumMapFaces objMesh mapCh) do mapFacesString += point3_to_string (meshop.getMapFace objMesh mapCh face)
|
|
MakeXMLNodeWithInnerText "Faces" xn_mapChannel mapFacesString
|
|
)
|
|
)
|
|
|
|
local matIndex = findItem materials obj.mat
|
|
if (matIndex == 0) do
|
|
(
|
|
append materials obj.mat
|
|
matIndex = materials.count
|
|
)
|
|
|
|
xn_obj.setAttribute "MaterialIndex" (matIndex as string)
|
|
|
|
-- ATTRIBUTES --------------------------------------
|
|
local xn_attrs = rsta_xml.makeNode "RsAttrs" xn_obj
|
|
|
|
for i=1 to (GetNumAttr (GetAttrClass obj)) do
|
|
(
|
|
local value = GetAttr obj i
|
|
|
|
if (value != (GetAttrDefault (GetAttrClass obj) i)) do
|
|
(
|
|
local xn_attr = rsta_xml.makeNode "Attr" xn_attrs
|
|
xn_attr.setattribute "name" (GetAttrName (GetAttrClass obj) i)
|
|
xn_attr.setattribute "type" (GetAttrType (GetAttrClass obj) i)
|
|
xn_attr.innerText = value as string
|
|
)
|
|
)
|
|
)
|
|
|
|
-- MATERIAL ------------------------------------------------------------
|
|
local xn_mats = rsta_xml.makeNode "Materials" xml_io.root
|
|
for mat in materials do material_to_xml mat xn_mats
|
|
|
|
xml_io.xmlFile = xmlFile
|
|
xml_io.save saveWarning:false
|
|
),
|
|
---------------------------------------------------------------------------
|
|
fn ImportObjects xmlFile: objNames: transforms:true =
|
|
(
|
|
local newObjects = #()
|
|
|
|
if (xmlFile == unsupplied) do
|
|
(
|
|
xmlFile = getOpenFileName caption:"Pick file to import..." types:"RsObj File|*.xml"
|
|
)
|
|
|
|
if (doesFileExist xmlFile) do
|
|
(
|
|
local xml_io = rsta_xml_io xmlFile:xmlFile
|
|
local xn_objects = xmlList_to_xmlArray (xml_io.root.SelectNodes "Objects/Object")
|
|
|
|
-- FILTER BY NAME
|
|
if (objNames != unsupplied) do
|
|
(
|
|
objNames = for n in objNames collect toLower n
|
|
xn_objects = for xn_obj in xn_objects where ((findItem objNames (toLower (xn_obj.getattribute "name"))) != 0) collect xn_obj
|
|
)
|
|
|
|
for xn_obj in xn_objects do
|
|
(
|
|
objMesh = mesh()
|
|
append newObjects objMesh
|
|
objMesh.name = uniqueName (xn_obj.getAttribute "name")
|
|
if (transforms) do objMesh.transform = string_to_transform (xn_obj.getAttribute "transform")
|
|
|
|
objMesh.wirecolor = string_to_colour (xn_obj.selectsinglenode "MaxObject/WireColour").InnerText
|
|
|
|
local xn_geo = xn_obj.selectSingleNode "Geometry"
|
|
|
|
-- VERTS ----------------------------------------------
|
|
local xn_verts = xn_geo.SelectSingleNode "Verts"
|
|
local verts = for vert in (FilterString xn_verts.innerText " ") collect (string_to_point3 vert)
|
|
|
|
-- FACES ----------------------------------------------
|
|
local xn_faces = xn_geo.SelectSingleNode "Faces"
|
|
local faces = for face in (FilterString xn_faces.innerText " ") collect (string_to_point3 face)
|
|
|
|
setmesh objMesh vertices:verts faces:faces
|
|
|
|
-- EDGES -----------------------------------------------
|
|
local xn_edges = xn_geo.SelectSingleNode "EdgeVis"
|
|
local face_array = FilterString xn_edges.innerText " "
|
|
for f=1 to face_array.count do
|
|
(
|
|
local eP = FilterString (face_array[f]) ","
|
|
for i=1 to 3 do setEdgeVis objMesh f i (string_to_bool ep[i])
|
|
)
|
|
|
|
-- SMOOTHING GROUPS --------------------------
|
|
local smooth_array = InnerText_To_Array (xn_geo.SelectSingleNode "SmoothingGroups")
|
|
for i=1 to smooth_array.count do setFaceSmoothGroup objMesh i (smooth_array[i] as integer)
|
|
|
|
-- FACE IDS -----------------------------------------------
|
|
local faceID_array = InnerText_To_Array (xn_geo.SelectSingleNode "FaceIDs")
|
|
for i=1 to faceID_array.count do setFaceMatID objMesh i (faceID_array[i] as integer)
|
|
|
|
-- MAP CHANNELS --------------------------------------
|
|
local xn_mapChannelsRoot = xn_obj.SelectSingleNode "MapChannels"
|
|
meshop.setNumMaps objMesh ((xn_mapChannelsRoot.GetAttribute "count") as integer)
|
|
|
|
for xn_channel in (xmlList_to_xmlArray (xn_mapChannelsRoot.SelectNodes "MapChannel")) do
|
|
(
|
|
local ch = (xn_channel.getAttribute "channel") as integer
|
|
meshop.setMapSupport objMesh ch true
|
|
|
|
-- VERTS
|
|
local verts = InnerText_To_Array (xn_channel.SelectSingleNode "Verts")
|
|
meshop.setNumMapVerts objMesh ch verts.count
|
|
for v=1 to verts.count do meshop.setMapVert objMesh ch v (string_to_point3 verts[v])
|
|
|
|
-- FACES
|
|
local faces = InnerText_To_Array (xn_channel.SelectSingleNode "Faces")
|
|
meshop.setNumMapFaces objMesh ch faces.count
|
|
for f=1 to faces.count do meshop.setMapFace objMesh ch f (string_to_point3 faces[f])
|
|
)
|
|
|
|
-- MATERIAL ----------------------------------------------
|
|
local matIndex = (xn_obj.getAttribute "MaterialIndex") as integer
|
|
local xn_Materials = xml_io.root.SelectSingleNode "Materials"
|
|
local xn_material = xn_Materials.ChildNodes.Item[matIndex-1]
|
|
|
|
objMesh.mat = xml_to_material xn_Materials.ChildNodes.Item[matIndex-1]
|
|
|
|
-- ATTRIBUTES ----------------------------------------
|
|
local xn_rsAttrs = xn_obj.SelectSingleNode "RsAttrs"
|
|
for xn_attr in (xmlList_to_xmlArray (xn_rsAttrs.SelectNodes "Attr")) do
|
|
(
|
|
local attr_idx = GetAttrIndex (GetAttrClass objMesh) (xn_attr.getAttribute "name")
|
|
local value = (xn_attr.innertext)
|
|
case (xn_attr.getAttribute "type") of
|
|
(
|
|
"bool" : value = string_to_bool value
|
|
"float" : value = value as float
|
|
"int" : value = value as integer
|
|
)
|
|
SetAttr objMesh attr_idx value
|
|
)
|
|
|
|
update objMesh
|
|
)
|
|
|
|
completeRedraw()
|
|
RsScaleTexturesOnSelectedObjs 1.0 (objects as array) quiet:true
|
|
)
|
|
|
|
return newObjects
|
|
)
|
|
)
|
|
RsObj = RsObj() |