Convert MaxScript to Ruby?
-
Hi,
since my last topic seems to have gone down without an answer (nothing I didn't expect), I would like to ask if it is possible to convert MaxScript [scripting for Gmax and 3ds Max, .ms file extension] to Ruby.
Or if that is not possible, then maybe to be able to embedd MaxScript to be used in Ruby. Or simply configure Sketchup to use MaxScript.
To answer any of these questions would mean a lot to me and it would literally change the experience of 3D modeling for games.Thank you,
-Arightwizard -
what do you need it for - be more specific
a conversion from MXS to SURuby needs a lot of work and it will not be 100% translation. it all depends on what do you want to accomplish. -
@unknownuser said:
what do you need it for - be more specific
a conversion from MXS to SURuby needs a lot of work and it will not be 100% translation. it all depends on what do you want to accomplish.I am trying to convert a .jms exporter from MaxScript to Ruby called Chimp (Version 1.6).
I am no expert in this situation, but here is the MaxScript code for chimp.ms:-- Copyright Β© 2004 Dark Knight Software -- Programmed by Jason Zimmer -- -- Chimp Halo Structure Exporter -- Version 1.6 Utility Chimp "Chimp" ( Rollout Structure "Chimp; Jms Exporter" ( local ChimpMaterials local ChimpVerts local ChimpFaces local ChimpTVerts local ChimpNormals local ChimpReverseLookup local ChimpFaceIds local ChimpCurrVert local ChimpVertexOffset local ChimpError Button Export "Export Halo Structure" RadioButtons OutputMode Labels;#("Jms File", "Listener Window") default;1 CheckBox ShowDebug "Write Debug Info" checked;true fn AddError v1 v2 v3 Id = ( SetNumVerts ChimpError ((GetNumVerts ChimpError) + 3) true SetNumFaces ChimpError ((GetNumFaces ChimpError) + 1) true SetVert ChimpError ((GetNumVerts ChimpError) - 2) v1 SetVert ChimpError ((GetNumVerts ChimpError) - 1) v2 SetVert ChimpError ((GetNumVerts ChimpError) - 0) v3 SetFace ChimpError (GetNumFaces ChimpError) ((GetNumVerts ChimpError) - 2) ((GetNumVerts ChimpError) - 1) ((GetNumVerts ChimpError) - 0) SetFaceMatId ChimpError (GetNumFaces ChimpError) Id ) fn ParseMaterials Obj = ( local i, j, Valid if SuperClassOf Obj == GeometryClass then ( ObjName = Obj.name if ObjName != "ChimpClone" then ( copy Obj name;"ChimpClone" Obj = $ChimpClone CollapseStack Obj ConvertToMesh Obj if ClassOf Obj.material == MultiMaterial then ( for i in 1 to Obj.material.count do ( Valid = 0 for j in 1 to Obj.numfaces do ( if i == (GetFaceMatId Obj j) then ( Valid = 1 ) ) if Valid == 1 then ( for j in 1 to ChimpMaterials.count do ( if ChimpMaterials[j] == Obj.material[i].name then ( Valid = 0 ) ) if Valid == 1 then ( append ChimpMaterials Obj.material[i].name if ShowDebug.checked == true then ( format " Material %; %\n" ChimpMaterials.count Obj.material[i].name ) ) ) ) )else if ClassOf Obj.material == StandardMaterial then ( Valid = 1 for j in 1 to ChimpMaterials.count do ( if ChimpMaterials[j] == Obj.material.name then ( Valid = 0 ) ) if Valid == 1 then ( append ChimpMaterials Obj.material.name if ShowDebug.checked == true then ( format " Material %; %\n" ChimpMaterials.count Obj.material.name ) ) )else( if ShowDebug.checked == true then ( format " Chimp Warning; Object '%' is using a bogus material type. Needs to be MultiMaterial or StandardMaterial\n" ObjName ) ) ) Delete Obj )else( if ShowDebug.checked == true then ( format " Chimp Warning; Could not convert object '%' into a mesh\n" ObjName ) ) ) fn ProcessGeometry Obj = ( local i, j, k, l, f, n, v1, v2, v3, n1, n2, n3, nf, OrigObj, nv1, nv2, nv3 if SuperClassOf Obj == GeometryClass then ( ObjName = Obj.name if ObjName != "ChimpClone" then ( copy Obj name;"ChimpClone" Obj = $ChimpClone CollapseStack Obj ConvertToMesh Obj if ShowDebug.checked == true then ( format " Processing Object '%' (F;% V;%)\n" ObjName Obj.numfaces Obj.numverts ) -- Build Normal Reverse Lookup ChimpReverseLookup = #() for i in 1 to Obj.numfaces do ( f = GetFace Obj i -- Build Reverse Lookup (For Normals) if ChimpReverseLookup[f[1]] == undefined then ( ChimpReverseLookup[f[1]] = #() ) if ChimpReverseLookup[f[2]] == undefined then ( ChimpReverseLookup[f[2]] = #() ) if ChimpReverseLookup[f[3]] == undefined then ( ChimpReverseLookup[f[3]] = #() ) append ChimpReverseLookup[f[1]] i append ChimpReverseLookup[f[2]] i append ChimpReverseLookup[f[3]] i ) ProgressStart ("Processing '" + ObjName + "'") for i in 1 to Obj.numfaces do ( ProgressUpdate (i * 100 / Obj.numfaces) f = GetFace Obj i -- Build Face append ChimpFaces [ChimpCurrVert + 0, ChimpCurrVert + 1, ChimpCurrVert + 2] -- Build 3 Vertecies v1 = (GetVert Obj f[1]) v2 = (GetVert Obj f[2]) v3 = (GetVert Obj f[3]) append ChimpVerts v1 append ChimpVerts v2 append ChimpVerts v3 -- Build Normals for j in 1 to 3 do ( nf = GetFace Obj i nv1 = (GetVert Obj nf[1]) nv2 = (GetVert Obj nf[2]) nv3 = (GetVert Obj nf[3]) n1 = normalize (nv1 - nv2) n2 = normalize (nv1 - nv3) n = cross n1 n2 for k = 1 to ChimpReverseLookup[f[j]].count do ( l = ChimpReverseLookup[f[j]][k] if (GetFaceMatId Obj l) == (GetFaceMatId Obj i) then ( if (GetFaceSmoothGroup Obj l) == (GetFaceSmoothGroup Obj i) then ( nf = GetFace Obj l nv1 = (GetVert Obj nf[1]) nv2 = (GetVert Obj nf[2]) nv3 = (GetVert Obj nf[3]) n1 = normalize (nv1 - nv2) n2 = normalize (nv1 - nv3) n3 = cross n1 n2 n = n + n3 ) ) ) n = Normalize n append ChimpNormals n ) -- Build Material Id if ClassOf Obj.material == MultiMaterial then ( Valid = 0 l = GetFaceMatId Obj i if l <= Obj.material.count then ( for j in 1 to ChimpMaterials.count do ( if ChimpMaterials[j] == Obj.material[l].name then ( Valid = 1 append ChimpFaceIds j ) ) ) if Valid == 0 then ( if ShowDebug.checked == true then ( format "Chimp Error; Object '%' has an unknown material id. See Orange Error Geometry.\n" ObjName ) append ChimpFaceIds 0 AddError v1 v2 v3 1 ) )else if ClassOf Obj.material == StandardMaterial then ( Valid = 0 for j in 1 to ChimpMaterials.count do ( if ChimpMaterials[j] == Obj.material.name then ( Valid = 1 append ChimpFaceIds j ) ) if Valid == 0 then ( if ShowDebug.checked == true then ( format "Chimp Error; Object '%' has an unknown material id. See Orange Error Geometry.\n" ObjName ) ChimpWarning = 1 append ChimpFaceIds 0 AddError v1 v2 v3 1 ) )else( append ChimpFaceIds 0 ) -- Build 3 Texture Coordinates if (GetNumTVerts Obj) > 0 then ( f = GetTVFace Obj i append ChimpTVerts (GetTVert Obj f[1]) append ChimpTVerts (GetTVert Obj f[2]) append ChimpTVerts (GetTVert Obj f[3]) )else( append ChimpTVerts [0, 0, 0] append ChimpTVerts [0, 0, 0] append ChimpTVerts [0, 0, 0] ) -- Increment Counters ChimpCurrVert = ChimpCurrVert + 3 ) ) Delete Obj )else( if ShowDebug.checked == true then ( format " Chimp Warning; Could not convert object '%' into a mesh\n" ObjName ) ) ) fn WriteJms = ( local Jms, i SavePath = GetSaveFileName Types;"Halo Structure File (*.jms)|*.jms|" if SavePath != undefined then ( format " Saving '%'..." SavePath Jms = CreateFile(SavePath) format "8200\n" to;Jms format "3251\n" to;Jms format "1\n" to;Jms format "frame\n" to;Jms format "-1\n" to;Jms format "-1\n" to;Jms format "0.000000 0.000000 0.000000 1.000000\n" to;Jms format "% % %\n" $frame.pos.x $frame.pos.y $frame.pos.z to;Jms format "%\n" ChimpMaterials.count to;Jms for i in 1 to ChimpMaterials.count do ( format "%\n" ChimpMaterials[i] to;Jms format "<none>\n" to;Jms ) format "0\n" to;Jms format "1\n" to;Jms format "unnamed\n" to;Jms format "%\n" ChimpVerts.count to;Jms ProgressStart "Writing Data" for i in 1 to ChimpVerts.count do ( ProgressUpdate (i * 100 / (ChimpVerts.count + ChimpFaces.count)) format "0\n" to;Jms format "% % %\n" ChimpVerts[i].x ChimpVerts[i].y ChimpVerts[i].z to;Jms format "% % %\n" ChimpNormals[i][1] ChimpNormals[i][2] ChimpNormals[i][3] to;Jms format "-1\n" to;Jms format "0\n" to;Jms format "%\n" ChimpTVerts[i][1] to;Jms format "%\n" ChimpTVerts[i][2] to;Jms format "0\n" to;Jms ) format "%\n" ChimpFaces.count to;Jms for i in 1 to ChimpFaces.count do ( ProgressUpdate ((i + ChimpVerts.count) * 100 / (ChimpVerts.count + ChimpFaces.count)) format "0\n" to;Jms format "%\n" (ChimpFaceIds[i] as integer - 1) to;Jms -- Material format "% % %\n" (ChimpFaces[i][1] as integer - 1) (ChimpFaces[i][2] as integer - 1) (ChimpFaces[i][3] as integer - 1) to;Jms ) Close Jms format "Done.\n" )else( format " Save canceled.\n" ) ) fn WriteListener = ( local i if ShowDebug.checked == true then ( format "***** Begin Jms *****\n" ) format "8200\n" format "3251\n" format "1\n" format "frame\n" format "-1\n" format "-1\n" format "0.000000 0.000000 0.000000 1.000000\n" format "% % %\n" $frame.pos.x $frame.pos.y $frame.pos.z format "%\n" ChimpMaterials.count for i in 1 to ChimpMaterials.count do ( format "%\n" ChimpMaterials[i] format "<none>\n" ) format "0\n" format "1\n" format "unnamed\n" format "%\n" ChimpVerts.count ProgressStart "Writing Data" for i in 1 to ChimpVerts.count do ( ProgressUpdate (i * 100 / (ChimpVerts.count + ChimpFaces.count)) format "0\n" format "% % %\n" ChimpVerts[i].x ChimpVerts[i].y ChimpVerts[i].z format "% % %\n" ChimpNormals[i][1] ChimpNormals[i][2] ChimpNormals[i][3] format "-1\n" format "0\n" format "%\n" ChimpTVerts[i][1] format "%\n" ChimpTVerts[i][2] format "0\n" ) format "%\n" ChimpFaces.count for i in 1 to ChimpFaces.count do ( ProgressUpdate ((i + ChimpVerts.count) * 100 / (ChimpVerts.count + ChimpFaces.count)) format "0\n" format "%\n" (ChimpFaceIds[i] as integer - 1) format "% % %\n" (ChimpFaces[i][1] as integer - 1) (ChimpFaces[i][2] as integer - 1) (ChimpFaces[i][3] as integer - 1) ) if ShowDebug.checked == true then ( format "***** End Jms *****\n" ) ) on Export Pressed do ( local i ClearListener() if ShowDebug.checked == true then ( format "----------------------------------------\n" ) if ShowDebug.checked == true then ( format "Chimp; Start...\n" ) if ShowDebug.checked == true then ( format "----------------------------------------\n" ) if SuperClassOf $ChimpError == GeometryClass then ( delete $ChimpError ) ChimpError = Box() ChimpError.Name = "ChimpError" ConvertToMesh ChimpError SetNumVerts ChimpError 0 SetNumFaces ChimpError 0 ChimpError.Material = MultiMaterial numsubs;1 -- Material Error ChimpError.Material[1].DiffuseColor = color 255 160 0 Update ChimpError if SuperClassOf $frame == GeometryClass then ( if $frame.children.count == 0 then ( MessageBox "Chimp Error; There is no geometry linked to the frame" )else( -- Parse Materials if ShowDebug.checked == true then ( format " Parsing Materials\n" ) ChimpMaterials = #() for i in 1 to $frame.children.count do ( ParseMaterials $frame.children[i] ) if ChimpMaterials.count != 0 then ( -- Geometry if ShowDebug.checked == true then ( format " Parsing Geometry\n" ) ChimpVerts = #() ChimpFaces = #() ChimpTVerts = #() ChimpNormals = #() ChimpFaceIds = #() ChimpCurrVert = 1 ChimpVertexOffset = 0 for i in 1 to $frame.children.count do ( ProcessGeometry $frame.children[i] ) if ShowDebug.checked == true then ( format " Verts; %\n" ChimpVerts.count ) if ShowDebug.checked == true then ( format " Faces; %\n" ChimpFaces.count ) if (GetNumVerts ChimpError) > 0 then ( MessageBox "Chimp found errors. View the 'ChimpError' Object and fix the corrosponding faces" )else( if OutputMode.state == 1 then ( WriteJms() ) if OutputMode.state == 2 then ( WriteListener() ) ) )else( MessageBox "Chimp Error; Unable to find any used materials.\n Ensure your objects have materials properly assigned to them." ) ) )else( MessageBox "Chimp Error; 'frame' object was not found." ) if ShowDebug.checked == true then ( format "----------------------------------------\n" ) if ShowDebug.checked == true then ( format "Chimp; End\n" ) if ShowDebug.checked == true then ( format "----------------------------------------\n" ) ChimpVerts = undefined ChimpFaces = undefined ChimpTVerts = undefined ChimpNormals = undefined ChimpFaceIds = undefined gc() ProgressEnd() ) ) Rollout Wrl "Chimp; Wrl Importer" ( local Wrl, l, Data, DataPos local ChimpError local ChimpErrorVert local ChimpErrorFace local ChimpErrorNum Button Import "Import Wrl" fn ProcessIndexedLineSet = ( format " +ProcessIndexedLineSet \n" ChimpError.name = "ChimpEdgeError" + (ChimpErrorNum as string) DataPos = DataPos + 1 -- Skip IndexedLineSet DataPos = DataPos + 1 -- Skip { DataPos = DataPos + 1 -- coordIndex while DataPos <= Data.count do ( if Data[DataPos] == "}" then ( exit ) f = [ (Data[DataPos + 0] as integer) + 1, (Data[DataPos + 1] as integer) + 1, (Data[DataPos + 1] as integer) + 1 ] ChimpErrorFace = ChimpErrorFace + 1 SetNumFaces ChimpError ChimpErrorFace true SetFace ChimpError ChimpErrorFace f SetEdgeVis ChimpError ChimpErrorFace 1 true DataPos = DataPos + 3 ) ) fn ProcessIndexedFaceSet = ( format " +ProcessIndexedFaceSet \n" DataPos = DataPos + 1 -- Skip IndexedFaceSet DataPos = DataPos + 1 -- Skip { DataPos = DataPos + 1 -- coordIndex while DataPos <= Data.count do ( if Data[DataPos] == "}" then ( exit ) f = [ (Data[DataPos + 0] as integer) + 1, (Data[DataPos + 1] as integer) + 1, (Data[DataPos + 2] as integer) + 1 ] ChimpErrorFace = ChimpErrorFace + 1 SetNumFaces ChimpError ChimpErrorFace true SetFace ChimpError ChimpErrorFace f while Data[DataPos] != "-1" do ( DataPos = DataPos + 1 ) DataPos = DataPos + 1 ) ) fn ProcessMaterial = ( format " +ProcessMaterial\n" DataPos = DataPos + 1 -- Skip Material DataPos = DataPos + 1 -- Skip { while DataPos <= Data.count do ( if Data[DataPos] == "}" then ( exit ) DataPos = DataPos + 1 ) ) fn ProcessMaterialBinding = ( format " +ProcessMaterialBinding\n" DataPos = DataPos + 1 -- Skip MaterialBinding DataPos = DataPos + 1 -- Skip { while DataPos <= Data.count do ( if Data[DataPos] == "}" then ( exit ) DataPos = DataPos + 1 ) ) fn ProcessCoordinate3 = ( format " +ProcessCoordinate3\n" DataPos = DataPos + 1 -- Skip Coordinate3 DataPos = DataPos + 1 -- Skip { DataPos = DataPos + 1 -- Skip point while DataPos <= Data.count do ( if Data[DataPos] == "}" then ( exit ) p = point3 (Data[DataPos + 0] as float) (Data[DataPos + 1] as float) (Data[DataPos + 2] as float) ChimpErrorVert = ChimpErrorVert + 1 SetNumVerts ChimpError ChimpErrorVert true SetVert ChimpError ChimpErrorVert p DataPos = DataPos + 3 ) ) fn ProcessSeparator = ( format "+ProcessSeparator\n" DataPos = DataPos + 1 -- Skip Skip Separator DataPos = DataPos + 1 -- Skip { ChimpErrorNum = ChimpErrorNum + 1 ChimpError = Box() ChimpError.name = "ChimpFaceError" + (ChimpErrorNum as string) ConvertToMesh ChimpError SetNumVerts ChimpError 0 SetNumFaces ChimpError 0 ChimpErrorVert = 0 ChimpErrorFace = 0 while DataPos <= Data.count do ( if Data[DataPos] == "}" then ( exit ) if Data[DataPos] == "Coordinate3" then ( ProcessCoordinate3() ) if Data[DataPos] == "MaterialBinding" then ( ProcessMaterialBinding() ) if Data[DataPos] == "Material" then ( ProcessMaterial() ) if Data[DataPos] == "IndexedFaceSet" then ( ProcessIndexedFaceSet() ) if Data[DataPos] == "IndexedLineSet" then ( ProcessIndexedLineSet() ) DataPos = DataPos + 1 ) Update ChimpError ) fn ProcessData = ( DataPos = 1 ChimpErrorNum = 0 while DataPos <= Data.count do ( if Data[DataPos] == "Separator" then ( ProcessSeparator() ) DataPos = DataPos + 1 ) ) on Import Pressed do ( local FileName local Temp FileName = GetOpenFileName Types;"VRML Files (*.wrl)|*.wrl|" Data = #() if FileName != undefined then ( ClearListener() Wrl = OpenFile FileName ReadLine Wrl DataString = "" while 1 == 1 do ( try ( l = TrimLeft (ReadLine Wrl) ) catch ( exit ) Temp = FilterString l " ,[]" Join Data Temp ) Close Wrl ProcessData() ) ) ) Rollout Surface "Chimp; Walking Surface" ( Button Show "Show Walking Surfaces" RadioButtons ShowMode labels;#("Show All", "Show Walkable Only", "Show Unwalkable Only") default;1 local ChimpSurface fn ProcessGeometry Obj = ( local i, f, cv, n, u, w, Valid, c45 if SuperClassOf Obj == GeometryClass then ( ObjName = Obj.name if ObjName != "ChimpClone" then ( copy Obj name;"ChimpClone" Obj = $ChimpClone CollapseStack Obj ConvertToMesh Obj c45 = cos 45 for i in 1 to Obj.numfaces do ( f = GetFace Obj i cv = GetNumVerts ChimpSurface n = GetFaceNormal Obj i w = Dot n [0, 0, 1] Valid = 0 if ShowMode.state == 1 then ( Valid = 1 ) if ShowMode.state == 2 And w >= c45 then ( Valid = 1 ) if ShowMode.state == 3 And w < c45 then ( Valid = 1 ) if Valid == 1 then ( SetNumVerts ChimpSurface (cv + 3) true SetVert ChimpSurface (cv + 1) ((GetVert Obj f[1]) + (n * 0.2)) SetVert ChimpSurface (cv + 2) ((GetVert Obj f[2]) + (n * 0.2)) SetVert ChimpSurface (cv + 3) ((GetVert Obj f[3]) + (n * 0.2)) SetNumFaces ChimpSurface ((GetNumFaces ChimpSurface) + 1) true SetFace ChimpSurface (GetNumFaces ChimpSurface) (cv + 1) (cv + 2) (cv + 3) if w >= c45 then ( SetFaceMatId ChimpSurface (GetNumFaces ChimpSurface) 1 )else( SetFaceMatId ChimpSurface (GetNumFaces ChimpSurface) 2 ) ) ) ) Delete Obj )else( format " Chimp Warning; Could not convert object '%' into a mesh\n" ObjName ) ) on Show Pressed do ( local i ClearListener() if SuperClassOf $ChimpSurface == GeometryClass then ( delete $ChimpSurface ) ChimpSurface = Box() ConvertToMesh ChimpSurface SetNumFaces ChimpSurface 0 SetNumVerts ChimpSurface 0 ChimpSurface.name = "ChimpSurface" ChimpSurface.material = MultiMaterial numsubs;2 ChimpSurface.material[1].diffusecolor = color 0 128 0 ChimpSurface.material[2].diffusecolor = color 255 0 0 if SuperClassOf $frame == GeometryClass then ( if $frame.children.count == 0 then ( MessageBox "Chimp Error; There is no geometry linked to the frame" )else( -- Geometry for i in 1 to $frame.children.count do ( ProcessGeometry $frame.children[i] ) ) )else( MessageBox "Chimp Error; 'frame' object was not found." ) Update ChimpSurface Select ChimpSurface ) ) Rollout Info "Chimp; Info" ( Label lbl1 "Chimp v1.6" Label lbl2 "Created by Jason Zimmer" Label lbl3 "www.darkknightsoftware.com" ) on Chimp Open do ( AddRollout Structure AddRollout Wrl AddRollout Surface AddRollout Info ) on Chimp Close do ( RemoveRollout Structure RemoveRollout Wrl RemoveRollout Surface RemoveRollout Info ) )
-
BTW, jms files are meshes for use in the PC game Halo (don't sue me MS! ).
If anyone is crazy enough to do this, I found a (supposedly) better plugin called "Bluestreak" here (direct link to script).
If this much time is to be spent, it should probably at least be used to convert the best example, no? Also, it might help in understanding the code to compare the two...
I just want to (politely) point out to Arightwizard how incredibly difficult this task is (with very little payoff). You're probably better off just learning to use GMax/3DS...
-
@runnerpack said:
BTW, jms files are meshes for use in the PC game Halo (don't sue me MS! ).
If anyone is crazy enough to do this, I found a (supposedly) better plugin called "Bluestreak" here (direct link to script).
If this much time is to be spent, it should probably at least be used to convert the best example, no? Also, it might help in understanding the code to compare the two...
I just want to (politely) point out to Arightwizard how incredibly difficult this task is (with very little payoff). You're probably better off just learning to use GMax/3DS...
Runnerpack, I have little difficulty using GMax - and I know that converting scripts would be difficult. I was wondering if such a thing was possible, now all that's left is for me to learn Ruby and some more MaxScript before being able to come up with what would probably change the way common HCE maps are made. And trust me, the last steps won't take long.
So I thank RunnerPack and TBD for trying to help me, and believe me, you did.
-Arightwizard -
Awesome, sounds great! Let us know if you need any help with it,
Chris
Advertisement