Advertisement
kirby_422

ASS exporter - gmax support

Nov 7th, 2011
325
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.66 KB | None | 0 0
  1. --***************************************************************************
  2. --* BlueStreak .ASS Exporter by TheGhost *
  3. --* for 3ds Max v6+ and Halo 2 Vista *
  4. --***************************************************************************
  5. --* Description: Exports an ASS representation of a 3ds max scene. *
  6. --*-------------------------------------------------------------------------*
  7. --* Submit bugs to TheGhost on the Halo 2 Vista forums. Visit the forums *
  8. --* for additional help at http://www.h2vista.net. *
  9. --*-------------------------------------------------------------------------*
  10. --* Copyright (C) 2006 Adam Papamarcos (mailto:papamarcos@gmail.com) *
  11. --* This program is free software; you can redistribute it and/or modify it *
  12. --* under the terms of the GNU General Public License as published by the *
  13. --* Free Software Foundation; either version 2 of the License, or (at your *
  14. --* option) any later version. This program is distributed in the hope that *
  15. --* it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
  16. --* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
  17. --* the GNU General Public License for more details. A full copy of this *
  18. --* license is available at http://www.gnu.org/licenses/gpl.txt. *
  19. --*-------------------------------------------------------------------------*
  20.  
  21. -- Script Version 1.0.1
  22.  
  23. objs = #()
  24. materials = #()
  25. ass = undefined
  26. exportFailed = false
  27. maxver = maxVersion()
  28.  
  29. numDecimalPlaces = 10
  30. fn uniStr dbl =
  31. (
  32. local strRep = dbl as string
  33. if (findString strRep "e" == undefined) then
  34. (
  35. local strInd = findString strRep "."
  36. local currDecPlaces = strRep.count - strInd
  37. local zerosToAdd = numDecimalPlaces - currDecPlaces
  38. for z = 1 to zerosToAdd do
  39. (
  40. append strRep "0"
  41. )
  42. )
  43. strRep
  44. )
  45.  
  46. eps = 0.00001
  47. fn numsAreClose n1 n2 =
  48. (
  49. (abs(n1 - n2) <= eps)
  50. )
  51.  
  52.  
  53. rollout roll "BlueStreak .ASS Exporter" width:255 height:313
  54. (
  55. GroupBox grp1 "" pos:[7,-1] width:239 height:34
  56. label lbl_title "BlueStreak .ASS Exporter" pos:[61,13] width:129 height:13
  57. edittext edt_info "" pos:[3,40] width:243 height:191 enabled:true
  58. button export_button "Export .ASS File" pos:[63,254] width:128 height:31
  59. label lbl_by "Script by TheGhost" pos:[7,290] width:101 height:14 enabled:false
  60. label lbl5 "v1.0.1" pos:[211,280] width:38 height:14 enabled:false
  61.  
  62.  
  63. checkbox chk_jms "Save to ASS File (3ds max only)" pos:[17,233] width:174 height:16 checked:true
  64.  
  65. on roll open do
  66. (
  67. ClearListener()
  68. if maxver[1] <= 4200 then
  69. (
  70. edt_info.text = "Max version " + (maxver[1] / 1000.0) as string + " (gmax) detected.\n"
  71. chk_jms.checked = false
  72. chk_jms.enabled = false
  73. )
  74. else
  75. (
  76. edt_info.text = "3ds Max version " + (maxver[1] / 1000.0) as string + " detected.\n"
  77. chk_jms.enabled = true
  78. chk_jms.checked = true
  79. )
  80. )
  81. on export_button pressed do
  82. (
  83. objs = #()
  84. materials = #()
  85. ass = undefined
  86. exportFailed = false
  87.  
  88. if chk_jms.checked == true then
  89. (
  90. local output_name = getSaveFileName caption:"Select File to Export" \
  91. filename: "C:\\Program Files\\Microsoft Games\\Halo 2 Map Editor\\data\\" \
  92. types:("BlueStreak ASS (*.ASS)|*.ASS|All Files (*.*)|*.*|")
  93.  
  94. if output_name != undefined then
  95. (
  96. ass = createfile output_name
  97. exportFailed = false
  98. )
  99. else
  100. (
  101. exportFailed = true
  102. messageBox "Failed to create file path" title:"BlueStreak: Export error"
  103.  
  104. )
  105. )
  106. else
  107. (
  108. ClearListener()
  109. ass = listener
  110. exportFailed = false
  111. )
  112.  
  113.  
  114. if (exportFailed != true) then
  115. (
  116. if chk_jms.checked == true then
  117. (edt_info.text += "Exporting to " + output_name + "\r\n\r\n")
  118. else
  119. (edt_info.text += "Exporting to Max Listener \r\n\r\n")
  120.  
  121. clearListener()
  122. clearSelection()
  123. max select all
  124. objs = selection as array
  125. clearSelection()
  126.  
  127. format "%\n" ";### HEADER ###" to:ass
  128. format "%\n" 2 to:ass
  129. format "%\n" "\"MAX\"" to:ass
  130. format "%\n" ("\"" + (maxver[1] / 1000.0) as string + "\"") to:ass
  131. format "%\n" ("\"" + sysInfo.username as string + "\"") to:ass
  132. format "%\n\n" ("\"" + sysInfo.computername as string + "\"") to:ass
  133.  
  134. local sub_slot_name = #()
  135.  
  136. for i = 1 to objs.count do
  137. (
  138. local tmesh = snapshotAsMesh objs[i]
  139. if (objs[i].material != undefined) then
  140. (
  141. if (classOf objs[i].material == Multimaterial) then
  142. (
  143. for m = 1 to objs[i].material.count do
  144. (
  145. local extent
  146. if (classOf objs[i] == Sphere or classOf objs[i] == Box or classOf objs[i] == Cylinder) then
  147. (
  148. extent = 1
  149. )
  150. else
  151. (
  152. extent = getNumFaces tmesh
  153. )
  154.  
  155. for f = 1 to extent do
  156. (
  157. matID = getFaceMatID tmesh f
  158. if (findItem materials objs[i].material[matID] == 0) then
  159. (
  160. append materials objs[i].material[matID]
  161. local full_ssn = getSubMtlSlotName objs[i].material matID
  162. local ssn = substring full_ssn (4 + (matID as string).count) -1
  163. append sub_slot_name ssn
  164. )
  165. )
  166. )
  167. )
  168. else
  169. (
  170. if (findItem materials objs[i].material == 0) then
  171. (
  172. append materials objs[i].material
  173. append sub_slot_name ""
  174. )
  175. )
  176. )
  177. )
  178.  
  179. format "%\n" ";### MATERIALS ###" to:ass
  180. format "%\n\n" materials.count to:ass
  181.  
  182. for m = 1 to materials.count do
  183. (
  184. format "%\n" (";MATERIAL " + (m - 1) as string) to:ass
  185. format "%\n" ("\"" + materials[m].name as string + "\"") to:ass
  186. format "%\n\n" ("\"" + sub_slot_name[m] as string + "\"") to:ass
  187. )
  188.  
  189. format "%\n" ";### OBJECTS ###" to:ass
  190. format "%\n" objs.count to:ass
  191.  
  192. for j = 1 to objs.count do
  193. (
  194. format "\n%\n" (";OBJECT " + (j - 1) as string + " - '" + objs[j].name + "'") to:ass
  195.  
  196. edt_info.text += ("Object " + j as string + ": \"" + objs[j].name + "\"\r\n")
  197.  
  198. local tmesh = snapshotAsMesh objs[j]
  199.  
  200. if (classOf objs[j] == Sphere or classOf objs[j] == Box or classOf objs[j] == Cylinder) then
  201. (
  202. local material_index
  203.  
  204. if (classOf objs[j].material == Multimaterial) then
  205. (
  206. for m = 1 to objs[j].material.count do
  207. (
  208. matID = getFaceMatID tmesh 1
  209. material_index = findItem materials objs[j].material[matID]
  210. )
  211. )
  212. else
  213. (
  214. material_index = findItem materials objs[j].material
  215. )
  216.  
  217. material_index -= 1
  218. if (classOf objs[j] == Sphere) then
  219. (
  220. edt_info.text += "Type: Sphere\r\n\r\n"
  221. format "%\n" "\"SPHERE\"" to:ass
  222. format "%\n" "\"\"" to:ass
  223. format "%\n" "\"\"" to:ass
  224. format "%\n" material_index to:ass
  225. format "%\n" (uniStr objs[j].radius) to:ass
  226. )
  227. else
  228. (
  229. if (classOf objs[j] == Box) then
  230. (
  231. edt_info.text += "Type: Box\r\n\r\n"
  232. format "%\n" "\"BOX\"" to:ass
  233. format "%\n" "\"\"" to:ass
  234. format "%\n" "\"\"" to:ass
  235. format "%\n" material_index to:ass
  236. format "%\t%\t%\n" (uniStr (objs[j].length / 2.0)) (uniStr (objs[j].width / 2.0)) (uniStr (objs[j].height / 2.0)) to:ass
  237. )
  238. else
  239. (
  240. edt_info.text += "Type: Pill\r\n\r\n"
  241. format "%\n" "\"PILL\"" to:ass
  242. format "%\n" "\"\"" to:ass
  243. format "%\n" "\"\"" to:ass
  244. format "%\n" material_index to:ass
  245. format "%\n" (uniStr objs[j].height) to:ass
  246. format "%\n" (uniStr objs[j].radius) to:ass
  247. )
  248. )
  249. )
  250.  
  251. else
  252. (
  253. edt_info.text += "Type: Mesh\r\n"
  254. format "%\n" "\"MESH\"" to:ass
  255. format "%\n" "\"\"" to:ass
  256. format "%\n" "\"\"" to:ass
  257.  
  258. local xyz = #()
  259. local ijk = #()
  260. local uvw = #()
  261.  
  262. local vertIndex_uniqueVert_map = #()
  263.  
  264. local numUniqueVerts = 0
  265. local uniqueVert_vertIndex = #()
  266. local uniqueVert_normalID = #()
  267. local uniqueVert_tvertUV = #()
  268.  
  269. local face_vert_indices = #()
  270. local face_shader_index = #()
  271.  
  272. local numFaces = getNumFaces tmesh
  273. local en = Edit_Normals()
  274. addModifier objs[j] en
  275.  
  276. select objs[j]
  277. max modify mode
  278. subobjectLevel = 1
  279.  
  280. for f = 1 to numFaces do
  281. (
  282. local verts = getFace tmesh f
  283. local tverts = getTVFace tmesh f
  284. local matID = getFaceMatID tmesh f
  285.  
  286. local vert_indices = #()
  287.  
  288. for v = 1 to 3 do
  289. (
  290. local vert_index = verts[v]
  291. local normal_index = en.getNormalID f v
  292. local tvert_index = tverts[v]
  293.  
  294. local tvertUV = [(getTVert tmesh tvert_index).x,(getTVert tmesh tvert_index).y]
  295.  
  296. if (vertIndex_uniqueVert_map[vert_index] == undefined) then
  297. (
  298. numUniqueVerts += 1
  299. vertIndex_uniqueVert_map[vert_index] = #(numUniqueVerts)
  300. vert_indices[v] = numUniqueVerts
  301. uniqueVert_vertIndex[numUniqueVerts] = vert_index
  302. uniqueVert_normalID[numUniqueVerts] = normal_index
  303. uniqueVert_tvertUV[numUniqueVerts] = tvertUV
  304. )
  305. else
  306. (
  307. local uniqueVert = true
  308. for c = 1 to vertIndex_uniqueVert_map[vert_index].count do
  309. (
  310. uniqueVertIndex = vertIndex_uniqueVert_map[vert_index][c]
  311.  
  312. if (normal_index == uniqueVert_normalID[uniqueVertIndex] and (numsAreClose tvertUV.x uniqueVert_tvertUV[uniqueVertIndex].x) and (numsAreClose tvertUV.y uniqueVert_tvertUV[uniqueVertIndex].y)) then
  313. (
  314. uniqueVert = false
  315. vert_indices[v] = uniqueVertIndex
  316. )
  317. )
  318. if (uniqueVert == true) then
  319. (
  320. numUniqueVerts += 1
  321. append vertIndex_uniqueVert_map[vert_index] numUniqueVerts
  322. vert_indices[v] = numUniqueVerts
  323. uniqueVert_vertIndex[numUniqueVerts] = vert_index
  324. uniqueVert_normalID[numUniqueVerts] = normal_index
  325. uniqueVert_tvertUV[numUniqueVerts] = tvertUV
  326. )
  327. )
  328. )
  329.  
  330. face_vert_indices[f] = vert_indices
  331. face_shader_index[f] = (findItem materials objs[j].material[matID])
  332. )
  333.  
  334. edt_info.text += "Unique Vertices: " + numUniqueVerts as string + "\r\n"
  335. edt_info.text += "Number of Faces: " + numFaces as string + "\r\n\r\n"
  336.  
  337. format "%\n" numUniqueVerts to:ass
  338.  
  339. for v = 1 to numUniqueVerts do
  340. (
  341. local xyz = in coordsys local (getVert objs[j] uniqueVert_vertIndex[v])
  342. local ijk = in coordsys local (en.getNormal uniqueVert_normalID[v])
  343. local uv = uniqueVert_tvertUV[v]
  344.  
  345. format "%\t%\t%\n" (uniStr xyz.x) (uniStr xyz.y) (uniStr xyz.z) to:ass
  346. format "%\t%\t%\n" (uniStr ijk.x) (uniStr ijk.y) (uniStr ijk.z) to:ass
  347. format "%\n" 0 to:ass
  348. format "%\n" 1 to:ass
  349. format "%\t%\n" (uniStr uv.x) (uniStr uv.y) to:ass
  350. )
  351.  
  352. format "%\n" numFaces to:ass
  353.  
  354. for f = 1 to numFaces do
  355. (
  356. format "%\n" (face_shader_index[f] - 1) to:ass
  357. format "%\n" (face_vert_indices[f][1] - 1) to:ass
  358. format "%\n" (face_vert_indices[f][2] - 1) to:ass
  359. format "%\n" (face_vert_indices[f][3] - 1) to:ass
  360. )
  361.  
  362. max create mode
  363. clearSelection()
  364. deleteModifier objs[j] en
  365. )
  366. )
  367.  
  368. local numInstances = objs.count
  369.  
  370. edt_info.text += "Number of Instances: " + numInstances as string + "\r\n"
  371.  
  372. format "\n%\n" ";### INSTANCES ###" to:ass
  373. format "%\n\n" (numInstances + 1) to:ass
  374.  
  375. format "%\n" ";INSTANCE 0" to:ass
  376. format "%\n" -1 to:ass
  377. format "%\n" "\"Scene Root\"" to:ass
  378. format "%\n" -1 to:ass
  379. format "%\n" -1 to:ass
  380. format "%\n" 0 to:ass
  381. format "%\t%\t%\t%\n" "0.0000000000" "0.0000000000" "0.0000000000" "1.0000000000" to:ass
  382. format "%\t%\t%\n" "0.0000000000" "0.0000000000" "0.0000000000" to:ass
  383. format "%\n" "1.0000000000" to:ass
  384. format "%\t%\t%\t%\n" "0.0000000000" "0.0000000000" "0.0000000000" "1.0000000000" to:ass
  385. format "%\t%\t%\n" "0.0000000000" "0.0000000000" "0.0000000000" to:ass
  386. format "%\n\n" "1.0000000000" to:ass
  387.  
  388. for i = 1 to numInstances do
  389. (
  390. format "%\n" (";INSTANCE " + (i as string)) to:ass
  391. format "%\n" (i - 1) to:ass
  392. format "%\n" ("\"" + objs[i].name + "\"") to:ass
  393. format "%\n" (123 + i) to:ass
  394.  
  395. if (objs[i].parent == undefined) then
  396. (
  397. format "%\n" 0 to:ass
  398. )
  399. else
  400. (
  401. format "%\n" (findItem objs objs[i].parent) to:ass
  402. )
  403.  
  404. format "%\n" 0 to:ass
  405.  
  406. local rot = in coordsys parent objs[i].rotation
  407. local trans = in coordsys parent objs[i].pos
  408. local scal = in coordsys parent objs[i].scale
  409. format "%\t%\t%\t%\n" (uniStr rot.x) (uniStr rot.y) (uniStr rot.z) (uniStr rot.w) to:ass
  410. format "%\t%\t%\n" (uniStr trans.x) (uniStr trans.y) (uniStr trans.z) to:ass
  411. if (scal.x != scal.y or scal.y != scal.z) then
  412. (
  413. messageBox ("Warning: Object '" + objs[i].name + "' does not have a uniform scale in\r\n" \
  414. + "the x, y, and z directions. This WILL cause undesired results!") \
  415. title: "BlueStreak: Critical error"
  416. )
  417. format "%\n" (uniStr scal.x) to:ass
  418.  
  419. local offset_rot = objs[i].objectoffsetrot
  420. local offset_pos = objs[i].objectoffsetpos
  421. local offset_scale = objs[i].objectoffsetscale
  422.  
  423. format "%\t%\t%\t%\n" (uniStr offset_rot.x) (uniStr offset_rot.y) (uniStr offset_rot.z) (uniStr offset_rot.w) to:ass
  424. format "%\t%\t%\n" (uniStr offset_pos.x) (uniStr offset_pos.y) (uniStr offset_pos.z) to:ass
  425. format "%\n\n" (uniStr offset_scale.x) to:ass
  426. )
  427.  
  428. if chk_jms.checked == true then
  429. (
  430. close ass
  431. )
  432. )
  433. )
  434. )
  435.  
  436. CreateDialog roll
  437.  
  438. -- End of Script --
  439.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement