Advertisement
Guest User

Untitled

a guest
Dec 13th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.08 KB | None | 0 0
  1. /**
  2. * MAXLancer toolkit - Copyright (c) Yuriy Alexeev <treewyrm@gmail.com>
  3. *
  4. * Export models into Freelancer formats.
  5. */
  6. macroscript ExportRigid category:"MAXLancer" tooltip:"Export Rigid" buttontext:"Export Rigid" iconName:"MAXLancer/export_rigid" (
  7. global MAXLancer
  8.  
  9. local hardpointHullColor = (dotNetClass "System.Drawing.Color").LightSteelBlue
  10.  
  11. local target -- RigidPartHelper
  12.  
  13. fn FormatSeconds ms = formattedPrint (0.001 * ms) format:".2f"
  14.  
  15. -- Get array of faces bitArrays for each independent element in mesh
  16. -- TODO: Should be put into MAXLancerTools struct
  17. fn GetMeshElements target = (
  18. local elements = #(), faces = #{1..getNumFaces target}, elementFaces
  19. while not faces.isEmpty do (append elements (elementFaces = meshOp.getElementsUsingFace target (faces as array)[1]); faces -= elementFaces) -- Reduce bitarray by faces used in element
  20. elements -- Return Array of BitArray
  21. )
  22.  
  23. -- Export .3db/.cmp
  24. rollout ExportRigidRollout "Export Rigid Model" width:440 height:352 (
  25. local meshLib -- VMeshLibrary
  26. local materialLib -- FLMaterialLibrary
  27. local textureLib -- FLTextureLibrary
  28. local animationLib -- AnimationLibrary
  29. local surfaceLib -- SurfaceLibrary
  30.  
  31. local compound = false
  32. local partCount = 0 -- Number of parts in compound model
  33. local meshCount = 0 -- Number of LOD meshes
  34. local wireCount = 0 -- Number of HUD wireframes (max at partCount)
  35. local hardpointCount = 0 -- Number of hardpoints
  36. local hullCount = 0 -- Number of individual convex hulls
  37. local hullPartCount = 0 -- Number of parts which have hulls
  38. local animationCount = 0 -- Number of animation layers
  39. local progressIndex = 0
  40.  
  41. progressBar parseProgress "" pos:[8,12] width:424 height:16 align:#left
  42. dotNetControl treeBox "System.Windows.Forms.TreeView" pos:[8,40] width:272 height:304 align:#left
  43.  
  44. groupBox modelGroup "Model Resources:" pos:[288,40] width:144 height:144
  45. checkbox hardpointsCheckbox "Hardpoints" pos:[296,60] width:128 height:16 tooltip:"Export model hardpoints to attach equipment."
  46.  
  47. checkbox meshesCheckbox "Meshes" pos:[296,80] width:128 height:16 tooltip:"Export meshes and embed mesh library into model file."
  48. checkbox wireframesCheckbox "Wireframes" pos:[296,100] width:128 height:16 tooltip:"Export HUD wireframes from spline objects or LOD visible edges."
  49. checkbox materialsCheckbox "Materials and Textures" pos:[296,120] width:128 height:16 tooltip:"Export and embed materials and textures into model file. Required for THN scenery objects and starspheres."
  50. checkbox materialAnimCheckbox "Material Animations" pos:[296,140] width:128 height:16 tooltip:"Export material animations."
  51. checkbox animationsCheckbox "Compound Animations" pos:[296,160] width:128 height:16 tooltip:"Export compound animations and embed animation library into model file."
  52.  
  53. groupBox miscGroup "Miscellaneous:" pos:[288,192] width:144 height:64
  54. checkbox timestampsCheckbox "Timestamp Fragments" pos:[296,212] width:128 height:16 tooltip:"Add timestamp marker to embedded .3db filenames."
  55. checkbox versionCheckbox "Add Exporter Version" pos:[296,232] width:128 height:16 checked:true tooltip:"Add exporter version entry into model file."
  56.  
  57. groupBox surfaceGroup "Surfaces:" pos:[288,264] width:144 height:44 align:#left
  58. checkbox surfacesCheckbox "Collision Surfaces" pos:[296,284] width:128 height:16 tooltip:"Export surface hulls into hitbox."
  59.  
  60. button exportButton "Export Model" pos:[288,320] width:144 height:24 align:#left
  61.  
  62. fn ProgressCallback = (
  63. parseProgress.value = (progressIndex += 1) * 100.0 / partCount
  64. windows.processPostedMessages()
  65. )
  66.  
  67. fn SurfaceCallback = (
  68. parseProgress.value = (progressIndex += 1) * 100.0 / hullPartCount
  69. windows.processPostedMessages()
  70. )
  71.  
  72. on exportButton pressed do try (
  73. local filename = getUserProp target #filename
  74. local result
  75. local writer
  76. local mode = 0
  77. local start
  78.  
  79. -- Replace with unsupplied for filename is optional argument for getSaveFileName
  80. filename = if filename == undefined then unsupplied else filename as string
  81.  
  82. -- Confirm export filename
  83. filename = getSaveFileName caption:"Export Freelancer Model:" filename:filename types:(if target.root then "Compound Rigid Model (.cmp)|*.cmp|" else "Rigid Model (.3db)|*.3db|")
  84.  
  85. if filename != undefined then (
  86. start = timeStamp()
  87.  
  88. result = if target.root then MAXLancer.RigidCompound filename:filename else MAXLancer.RigidPart filename:filename
  89.  
  90. parseProgress.value = progressIndex = 0
  91. parseProgress.color = blue
  92.  
  93. -- Set build mode
  94. mode = bit.set mode 1 hardpointsCheckbox.checked -- Hardpoints
  95. mode = bit.set mode 2 wireframesCheckbox.checked -- Wireframes
  96. mode = bit.set mode 3 meshesCheckbox.checked -- Levels
  97. mode = bit.set mode 6 materialsCheckbox.checked -- Materials
  98.  
  99. -- Initialize libraries
  100. meshLib = MAXLancer.VMeshLibrary()
  101. materialLib = MAXLancer.FLMaterialLibrary()
  102. textureLib = MAXLancer.FLTextureLibrary()
  103. animationLib = MAXLancer.AnimationLibrary()
  104. surfaceLib = MAXLancer.SurfaceLibrary()
  105.  
  106. -- Open UTF writer
  107. writer = MAXLancer.UTFWriter()
  108. writer.Open filename
  109.  
  110. -- Parse model
  111. result.Parse target mode progress:ProgressCallback meshLib:meshLib materialLib:materialLib textureLib:textureLib
  112.  
  113. -- Write VMeshLibrary
  114. if meshesCheckbox.checked then meshLib.WriteUTF writer
  115.  
  116. -- Write material and texture libraries
  117. if materialsCheckbox.checked then (
  118. materialLib.WriteUTF writer
  119. textureLib.WriteUTF writer
  120. )
  121.  
  122. -- Parse and write compound animation library
  123. if animationsCheckbox.checked then (
  124. animationLib.Parse target
  125. animationLib.WriteUTF writer
  126. )
  127.  
  128. -- Add Exporter Version
  129. if versionCheckbox.checked then (
  130. writer.Reset()
  131. writer.WriteFile "Exporter Version" MAXLancer.exporterVersion #string
  132. )
  133.  
  134. -- Write .3db/.cmp
  135. result.WriteUTF writer timestamps:timestampsCheckbox.checked
  136. writer.Close()
  137.  
  138. -- Parse and write surfaces
  139. if surfacesCheckbox.checked then (
  140. parseProgress.value = progressIndex = 0
  141. parseProgress.color = red
  142.  
  143. surfaceLib.Parse target progress:SurfaceCallback
  144. surfaceLib.SaveFile (getFilenamePath filename + getFilenameFile filename + ".sur")
  145. )
  146.  
  147. -- Update filename
  148. setUserProp target #filename filename
  149.  
  150. DestroyDialog ExportRigidRollout
  151. messageBox ("Model exported in " + FormatSeconds (timeStamp() - start) + " seconds to:\r\n" + filename)
  152. )
  153.  
  154. OK
  155. ) catch (
  156. DestroyDialog ExportRigidRollout
  157. messageBox (getCurrentException())
  158. if MAXLancer.debug then throw()
  159. )
  160.  
  161. fn SortByName a b = stricmp a.name b.name
  162.  
  163. fn ListHardpoints part parent = (
  164. local hardpoints = MAXLancer.GetPartHardpoints part
  165. local child
  166.  
  167. if hardpoints.count > 0 do (
  168. child = parent.Nodes.add ("Hardpoints (" + formattedPrint hardpoints.count format:"u" + ")")
  169. hardpointCount += hardpoints.count
  170.  
  171. qsort hardpoints SortByName
  172.  
  173. for hardpoint in hardpoints do child.Nodes.add hardpoint.name
  174. )
  175. )
  176.  
  177. fn ListHulls part parent = (
  178. local hulls = MAXLancer.GetPartHulls part
  179. local elements
  180. local child
  181. local subchild
  182.  
  183. if hulls.count > 0 do (
  184. child = parent.Nodes.add ("Hulls (" + formattedPrint hulls.count format:"u" + ")")
  185. hullPartCount += 1
  186.  
  187. qsort hulls SortByName
  188.  
  189. for i = 1 to hulls.count do (
  190. elements = GetMeshElements hulls[i]
  191. hullCount += elements.count
  192.  
  193. for k = 1 to elements.count do (
  194. subchild = child.Nodes.add (hulls[i].name + " (" + formattedPrint elements[k].numberSet format:"u" + " faces)")
  195.  
  196. if hulls[i].parent != part then subchild.Text += ": " + hulls[i].parent.name
  197. if hulls[i].hardpoint then subchild.ForeColor = hardpointHullColor
  198. )
  199. )
  200. )
  201. )
  202.  
  203. fn ListLevels part parent = (
  204. local levels = MAXLancer.GetPartLevels part
  205. local wireframe
  206. local child
  207. local subchild
  208. local materials = #()
  209. local faces = #()
  210.  
  211. partCount += 1
  212.  
  213. -- List LODs
  214. if levels.count > 0 do (
  215. child = parent.Nodes.add ("Levels (" + formattedPrint levels.count format:"u" + ")")
  216. meshCount += levels.count
  217.  
  218. for i = 1 to levels.count do (
  219. subchild = child.Nodes.add ("Level " + formattedPrint (i - 1) format:"u" + ": " + levels[i].name + " (" + formattedPrint (getNumFaces levels[i]) format:"u" + " faces)")
  220.  
  221. subchild.Nodes.add ("Range: " + formattedPrint levels[i].range format:"f")
  222.  
  223. -- Level will explicitly use its own visible edges for wireframe
  224. if wireframe == undefined and levels[i].wireframe then wireframe = levels[i]
  225.  
  226. -- Get mesh groups
  227. MAXLancer.GetMeshMaterials levels[i] materials faces
  228.  
  229. -- List LOD materials and face count
  230. for m = 1 to materials.count do
  231. subchild.Nodes.add (formattedPrint m format:"02u" + ": " + materials[m].name + " (" + formattedPrint faces[m].numberSet format:"u" + " faces)")
  232.  
  233. -- Level may use shape object for wireframe
  234. for item in levels[i].children while wireframe == undefined and superClassOf item == shape do wireframe = item
  235. )
  236. )
  237.  
  238. if wireframe != undefined then (
  239. parent.Nodes.add ("Wireframe: " + wireframe.name)
  240. wireCount += 1
  241. )
  242.  
  243. OK
  244. )
  245.  
  246. fn ListAnimations part parent = (
  247. local layers = MAXLancer.AnimationLibrary.GetAnimations part
  248.  
  249. if layers.count > 0 do (
  250. parent = parent.Nodes.Add "Animations"
  251. animationCount += 1
  252.  
  253. for name in layers do parent.Nodes.Add name
  254. )
  255.  
  256. OK
  257. )
  258.  
  259. fn ListCompound = (
  260. local queue = #(DataPair treeBox target)
  261. local parent
  262. local part
  263. local child
  264. local root
  265. local type
  266.  
  267. while queue.count > 0 do (
  268. parent = queue[queue.count].v1
  269. part = queue[queue.count].v2
  270. queue.count = queue.count - 1
  271.  
  272. type = if part == target then "Object Root" else case classOf part.transform.controller of (
  273. (MAXLancer.FixedJointController): "Fixed"
  274. (MAXLancer.AxisJointController): case part.transform.controller.type of (
  275. 1: "Revolute"
  276. 2: "Prismatic"
  277. 3: "Cylindric"
  278. )
  279. (MAXLancer.SphericJointController): "Spheric"
  280. (MAXLancer.LooseJointController): "Loose"
  281. default: throw (part.name + " has invalid controller.")
  282. )
  283.  
  284. child = parent.Nodes.add (part.name + " (" + type + ")")
  285.  
  286. ListLevels part child
  287. ListHardpoints part child
  288. ListHulls part child
  289. ListAnimations part child
  290.  
  291. if parent == treeBox then root = child
  292. for item in part.children where MAXLancer.HasJoint item do append queue (DataPair child item)
  293. )
  294.  
  295. root.Expand()
  296.  
  297. OK
  298. )
  299.  
  300. on ExportRigidRollout open do (
  301. treeBox.BackColor = MAXLancer.GetNetColorMan #window
  302. treeBox.ForeColor = MAXLancer.GetNetColorMan #windowText
  303.  
  304. try (
  305. compound = MAXLancer.HasParts target
  306.  
  307. if compound then ListCompound() else ListPart target treeBox
  308.  
  309. -- Setup interface
  310. meshesCheckbox.checked = meshesCheckbox.enabled = meshCount > 0
  311. wireframesCheckbox.checked = wireframesCheckbox.enabled = wireCount > 0
  312. hardpointsCheckbox.checked = hardpointsCheckbox.enabled = hardpointCount > 0
  313. surfacesCheckbox.checked = surfacesCheckbox.enabled = hullCount > 0
  314. materialAnimCheckbox.checked = materialAnimCheckbox.enabled = false
  315. animationsCheckbox.checked = animationsCheckbox.enabled = animationCount > 0
  316. timestampsCheckbox.checked = timestampsCheckbox.enabled = compound
  317. materialsCheckbox.enabled = meshCount > 0
  318.  
  319. OK
  320. ) catch (
  321. DestroyDialog ExportRigidRollout
  322. messageBox (getCurrentException())
  323. if MAXLancer.debug then throw()
  324. )
  325. )
  326. )
  327.  
  328. fn RootFilter target = isValidNode target and classOf target == MAXLancer.RigidPartHelper
  329.  
  330. on execute do if MAXLancer != undefined then (
  331. if (target = MAXLancer.PickSceneObject RootFilter) != undefined then CreateDialog ExportRigidRollout
  332. ) else messageBox "MAXLancer is not initialized."
  333. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement