Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * MAXLancer toolkit - Copyright (c) Yuriy Alexeev <treewyrm@gmail.com>
- *
- * Export models into Freelancer formats.
- */
- macroscript ExportRigid category:"MAXLancer" tooltip:"Export Rigid" buttontext:"Export Rigid" iconName:"MAXLancer/export_rigid" (
- global MAXLancer
- local hardpointHullColor = (dotNetClass "System.Drawing.Color").LightSteelBlue
- local target -- RigidPartHelper
- fn FormatSeconds ms = formattedPrint (0.001 * ms) format:".2f"
- -- Get array of faces bitArrays for each independent element in mesh
- -- TODO: Should be put into MAXLancerTools struct
- fn GetMeshElements target = (
- local elements = #(), faces = #{1..getNumFaces target}, elementFaces
- while not faces.isEmpty do (append elements (elementFaces = meshOp.getElementsUsingFace target (faces as array)[1]); faces -= elementFaces) -- Reduce bitarray by faces used in element
- elements -- Return Array of BitArray
- )
- -- Export .3db/.cmp
- rollout ExportRigidRollout "Export Rigid Model" width:440 height:352 (
- local meshLib -- VMeshLibrary
- local materialLib -- FLMaterialLibrary
- local textureLib -- FLTextureLibrary
- local animationLib -- AnimationLibrary
- local surfaceLib -- SurfaceLibrary
- local compound = false
- local partCount = 0 -- Number of parts in compound model
- local meshCount = 0 -- Number of LOD meshes
- local wireCount = 0 -- Number of HUD wireframes (max at partCount)
- local hardpointCount = 0 -- Number of hardpoints
- local hullCount = 0 -- Number of individual convex hulls
- local hullPartCount = 0 -- Number of parts which have hulls
- local animationCount = 0 -- Number of animation layers
- local progressIndex = 0
- progressBar parseProgress "" pos:[8,12] width:424 height:16 align:#left
- dotNetControl treeBox "System.Windows.Forms.TreeView" pos:[8,40] width:272 height:304 align:#left
- groupBox modelGroup "Model Resources:" pos:[288,40] width:144 height:144
- checkbox hardpointsCheckbox "Hardpoints" pos:[296,60] width:128 height:16 tooltip:"Export model hardpoints to attach equipment."
- checkbox meshesCheckbox "Meshes" pos:[296,80] width:128 height:16 tooltip:"Export meshes and embed mesh library into model file."
- checkbox wireframesCheckbox "Wireframes" pos:[296,100] width:128 height:16 tooltip:"Export HUD wireframes from spline objects or LOD visible edges."
- 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."
- checkbox materialAnimCheckbox "Material Animations" pos:[296,140] width:128 height:16 tooltip:"Export material animations."
- checkbox animationsCheckbox "Compound Animations" pos:[296,160] width:128 height:16 tooltip:"Export compound animations and embed animation library into model file."
- groupBox miscGroup "Miscellaneous:" pos:[288,192] width:144 height:64
- checkbox timestampsCheckbox "Timestamp Fragments" pos:[296,212] width:128 height:16 tooltip:"Add timestamp marker to embedded .3db filenames."
- checkbox versionCheckbox "Add Exporter Version" pos:[296,232] width:128 height:16 checked:true tooltip:"Add exporter version entry into model file."
- groupBox surfaceGroup "Surfaces:" pos:[288,264] width:144 height:44 align:#left
- checkbox surfacesCheckbox "Collision Surfaces" pos:[296,284] width:128 height:16 tooltip:"Export surface hulls into hitbox."
- button exportButton "Export Model" pos:[288,320] width:144 height:24 align:#left
- fn ProgressCallback = (
- parseProgress.value = (progressIndex += 1) * 100.0 / partCount
- windows.processPostedMessages()
- )
- fn SurfaceCallback = (
- parseProgress.value = (progressIndex += 1) * 100.0 / hullPartCount
- windows.processPostedMessages()
- )
- on exportButton pressed do try (
- local filename = getUserProp target #filename
- local result
- local writer
- local mode = 0
- local start
- -- Replace with unsupplied for filename is optional argument for getSaveFileName
- filename = if filename == undefined then unsupplied else filename as string
- -- Confirm export filename
- filename = getSaveFileName caption:"Export Freelancer Model:" filename:filename types:(if target.root then "Compound Rigid Model (.cmp)|*.cmp|" else "Rigid Model (.3db)|*.3db|")
- if filename != undefined then (
- start = timeStamp()
- result = if target.root then MAXLancer.RigidCompound filename:filename else MAXLancer.RigidPart filename:filename
- parseProgress.value = progressIndex = 0
- parseProgress.color = blue
- -- Set build mode
- mode = bit.set mode 1 hardpointsCheckbox.checked -- Hardpoints
- mode = bit.set mode 2 wireframesCheckbox.checked -- Wireframes
- mode = bit.set mode 3 meshesCheckbox.checked -- Levels
- mode = bit.set mode 6 materialsCheckbox.checked -- Materials
- -- Initialize libraries
- meshLib = MAXLancer.VMeshLibrary()
- materialLib = MAXLancer.FLMaterialLibrary()
- textureLib = MAXLancer.FLTextureLibrary()
- animationLib = MAXLancer.AnimationLibrary()
- surfaceLib = MAXLancer.SurfaceLibrary()
- -- Open UTF writer
- writer = MAXLancer.UTFWriter()
- writer.Open filename
- -- Parse model
- result.Parse target mode progress:ProgressCallback meshLib:meshLib materialLib:materialLib textureLib:textureLib
- -- Write VMeshLibrary
- if meshesCheckbox.checked then meshLib.WriteUTF writer
- -- Write material and texture libraries
- if materialsCheckbox.checked then (
- materialLib.WriteUTF writer
- textureLib.WriteUTF writer
- )
- -- Parse and write compound animation library
- if animationsCheckbox.checked then (
- animationLib.Parse target
- animationLib.WriteUTF writer
- )
- -- Add Exporter Version
- if versionCheckbox.checked then (
- writer.Reset()
- writer.WriteFile "Exporter Version" MAXLancer.exporterVersion #string
- )
- -- Write .3db/.cmp
- result.WriteUTF writer timestamps:timestampsCheckbox.checked
- writer.Close()
- -- Parse and write surfaces
- if surfacesCheckbox.checked then (
- parseProgress.value = progressIndex = 0
- parseProgress.color = red
- surfaceLib.Parse target progress:SurfaceCallback
- surfaceLib.SaveFile (getFilenamePath filename + getFilenameFile filename + ".sur")
- )
- -- Update filename
- setUserProp target #filename filename
- DestroyDialog ExportRigidRollout
- messageBox ("Model exported in " + FormatSeconds (timeStamp() - start) + " seconds to:\r\n" + filename)
- )
- OK
- ) catch (
- DestroyDialog ExportRigidRollout
- messageBox (getCurrentException())
- if MAXLancer.debug then throw()
- )
- fn SortByName a b = stricmp a.name b.name
- fn ListHardpoints part parent = (
- local hardpoints = MAXLancer.GetPartHardpoints part
- local child
- if hardpoints.count > 0 do (
- child = parent.Nodes.add ("Hardpoints (" + formattedPrint hardpoints.count format:"u" + ")")
- hardpointCount += hardpoints.count
- qsort hardpoints SortByName
- for hardpoint in hardpoints do child.Nodes.add hardpoint.name
- )
- )
- fn ListHulls part parent = (
- local hulls = MAXLancer.GetPartHulls part
- local elements
- local child
- local subchild
- if hulls.count > 0 do (
- child = parent.Nodes.add ("Hulls (" + formattedPrint hulls.count format:"u" + ")")
- hullPartCount += 1
- qsort hulls SortByName
- for i = 1 to hulls.count do (
- elements = GetMeshElements hulls[i]
- hullCount += elements.count
- for k = 1 to elements.count do (
- subchild = child.Nodes.add (hulls[i].name + " (" + formattedPrint elements[k].numberSet format:"u" + " faces)")
- if hulls[i].parent != part then subchild.Text += ": " + hulls[i].parent.name
- if hulls[i].hardpoint then subchild.ForeColor = hardpointHullColor
- )
- )
- )
- )
- fn ListLevels part parent = (
- local levels = MAXLancer.GetPartLevels part
- local wireframe
- local child
- local subchild
- local materials = #()
- local faces = #()
- partCount += 1
- -- List LODs
- if levels.count > 0 do (
- child = parent.Nodes.add ("Levels (" + formattedPrint levels.count format:"u" + ")")
- meshCount += levels.count
- for i = 1 to levels.count do (
- subchild = child.Nodes.add ("Level " + formattedPrint (i - 1) format:"u" + ": " + levels[i].name + " (" + formattedPrint (getNumFaces levels[i]) format:"u" + " faces)")
- subchild.Nodes.add ("Range: " + formattedPrint levels[i].range format:"f")
- -- Level will explicitly use its own visible edges for wireframe
- if wireframe == undefined and levels[i].wireframe then wireframe = levels[i]
- -- Get mesh groups
- MAXLancer.GetMeshMaterials levels[i] materials faces
- -- List LOD materials and face count
- for m = 1 to materials.count do
- subchild.Nodes.add (formattedPrint m format:"02u" + ": " + materials[m].name + " (" + formattedPrint faces[m].numberSet format:"u" + " faces)")
- -- Level may use shape object for wireframe
- for item in levels[i].children while wireframe == undefined and superClassOf item == shape do wireframe = item
- )
- )
- if wireframe != undefined then (
- parent.Nodes.add ("Wireframe: " + wireframe.name)
- wireCount += 1
- )
- OK
- )
- fn ListAnimations part parent = (
- local layers = MAXLancer.AnimationLibrary.GetAnimations part
- if layers.count > 0 do (
- parent = parent.Nodes.Add "Animations"
- animationCount += 1
- for name in layers do parent.Nodes.Add name
- )
- OK
- )
- fn ListCompound = (
- local queue = #(DataPair treeBox target)
- local parent
- local part
- local child
- local root
- local type
- while queue.count > 0 do (
- parent = queue[queue.count].v1
- part = queue[queue.count].v2
- queue.count = queue.count - 1
- type = if part == target then "Object Root" else case classOf part.transform.controller of (
- (MAXLancer.FixedJointController): "Fixed"
- (MAXLancer.AxisJointController): case part.transform.controller.type of (
- 1: "Revolute"
- 2: "Prismatic"
- 3: "Cylindric"
- )
- (MAXLancer.SphericJointController): "Spheric"
- (MAXLancer.LooseJointController): "Loose"
- default: throw (part.name + " has invalid controller.")
- )
- child = parent.Nodes.add (part.name + " (" + type + ")")
- ListLevels part child
- ListHardpoints part child
- ListHulls part child
- ListAnimations part child
- if parent == treeBox then root = child
- for item in part.children where MAXLancer.HasJoint item do append queue (DataPair child item)
- )
- root.Expand()
- OK
- )
- on ExportRigidRollout open do (
- treeBox.BackColor = MAXLancer.GetNetColorMan #window
- treeBox.ForeColor = MAXLancer.GetNetColorMan #windowText
- try (
- compound = MAXLancer.HasParts target
- if compound then ListCompound() else ListPart target treeBox
- -- Setup interface
- meshesCheckbox.checked = meshesCheckbox.enabled = meshCount > 0
- wireframesCheckbox.checked = wireframesCheckbox.enabled = wireCount > 0
- hardpointsCheckbox.checked = hardpointsCheckbox.enabled = hardpointCount > 0
- surfacesCheckbox.checked = surfacesCheckbox.enabled = hullCount > 0
- materialAnimCheckbox.checked = materialAnimCheckbox.enabled = false
- animationsCheckbox.checked = animationsCheckbox.enabled = animationCount > 0
- timestampsCheckbox.checked = timestampsCheckbox.enabled = compound
- materialsCheckbox.enabled = meshCount > 0
- OK
- ) catch (
- DestroyDialog ExportRigidRollout
- messageBox (getCurrentException())
- if MAXLancer.debug then throw()
- )
- )
- )
- fn RootFilter target = isValidNode target and classOf target == MAXLancer.RigidPartHelper
- on execute do if MAXLancer != undefined then (
- if (target = MAXLancer.PickSceneObject RootFilter) != undefined then CreateDialog ExportRigidRollout
- ) else messageBox "MAXLancer is not initialized."
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement