Files
gtav-src/tools_ng/wildwest/script/3dsMax/General_tools/RsObj/RsObj.ms
T
2025-09-29 00:52:08 +02:00

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()