Star Wars Galaxies .MGN format (not the same as .MSH)

 advanced
 Posts: 45
 Joined: Sun Jul 16, 2006 6:54 am
 Location: Around
 Contact:
Star Wars Galaxies .MGN format (not the same as .MSH)
Hey all, newcomer to these forums, figured this'd be the place to ask this.
Since stumbling upon the SWGExplorer project here, I've had an interesting time extracting models, etc. I'd like to convert some of these for use in gmax to port them into Jedi Academy, but the problem is I can't find support for the format outside of Ultimate Unwrap3d. Unfortunately, I don't have the funds to shell out $50 to convert like 5 rather smallish models. I'm wondering if anyone here would be willing to have a look at the files/plugin and write/create a base for something I could use in gmax, blender or the like? I have a basic knowledge of C++, so I may be able to finish writing such a plugin.
EDIT: Just remembered The MGN is not just a mesh but also has references to shader files and bones. Thought it might be good to include.
Since stumbling upon the SWGExplorer project here, I've had an interesting time extracting models, etc. I'd like to convert some of these for use in gmax to port them into Jedi Academy, but the problem is I can't find support for the format outside of Ultimate Unwrap3d. Unfortunately, I don't have the funds to shell out $50 to convert like 5 rather smallish models. I'm wondering if anyone here would be willing to have a look at the files/plugin and write/create a base for something I could use in gmax, blender or the like? I have a basic knowledge of C++, so I may be able to finish writing such a plugin.
EDIT: Just remembered The MGN is not just a mesh but also has references to shader files and bones. Thought it might be good to include.

 advanced
 Posts: 77
 Joined: Fri Jan 07, 2005 7:47 am
 Has thanked: 1 time
 Been thanked: 3 times
utility swgmgntest "SWG MGN Importer"
(

 Vars 

local modelName
local impTypes
local seqs  Sequences
local mtls  Materials
local geos  Geometry
local objs  Bones, Helpers, Lights, Attachments
local pivot
local geobones
local notes  Note Track
local meshes = #()

 Structures 

struct File
(
pos, end, bstream,
 Helper function to init the toplevel chunk rover
fn Init stream=
(
bstream = stream
pos = ftell bstream
fseek bstream 0 #seek_end
end = ftell bstream
),
fn fReadHead=
(
fseek bstream pos #seek_set
local id = ReadLong bstream #unsigned
local tag = File.GetName id
pos += 4
tag
),
fn fReadFloat=
(
local id
local i = 0
while (id == undefined) and (i < 10) do
(
fseek bstream pos #seek_set
id = ReadFloat bstream
i += 1
)
if i == 10 then
(
print ("problem: " + (pos as string))
)
pos += 4
id
),
fn fReadLong=
(
fseek bstream pos #seek_set
local id = ReadLong bstream
pos += 4
id
),
fn fReadShort=
(
fseek bstream pos #seek_set
local id = ReadShort bstream #unsigned
pos += 2
id
),
fn fReadByte=
(
fseek bstream pos #seek_set
local id = ReadByte bstream
pos += 1
id
),
fn fReadString n=
(
fseek bstream pos #seek_set
local id = ReadString bstream
pos += n*80
id
),
fn GetName id=
(
case id of
(
0x33544F44: #DOT3
0x4C54494F: #OITL
0x20435A4F: #OZC
0x4C434456: #VDCL
UNKNOWN
default: #UNKNOWN
)
)
)
fn sflip numb =
(
local bits = #()
local n
for n = 1 to n = 16 do
(
bits[n] = bit.get numb n
)
for n = 1 to n = 8 do
(
numb = bit.set numb n bits[(n+8)]
) for n = 9 to n = 16 do
(
numb = bit.set numb n bits[(n8)]
) return numb
)
fn lflip numb =
(
local bits = #()
local n
for n = 1 to n = 32 do
(
bits[n] = bit.get numb n
)
for n = 1 to n = 8 do
(
numb = bit.set numb n bits[(24+n)]
)
for n = 9 to n = 16 do
(
numb = bit.set numb n bits[(8+n)]
)
for n = 17 to n = 24 do
(
numb = bit.set numb n bits[(n8)]
)
for n = 25 to n = 32 do
(
numb = bit.set numb n bits[(n24)]
)
return numb
)

 User Interface 

group "Import MSH"
(
button importButton "Import MGN..."
)

 Main Import Function 

on importButton pressed do
(
 Show open file dialog box
local objFileName = getOpenFileName caption:"Import MGN" types:"SWG model File (*.mgn)*.mgnAll Files (*.*)*.*"
local isValid = true
if objFileName != undefined then
(
 If user made a selection, begin importing
if doesFileExist objFileName then
(
 Open up the file as a binary stream
local bstream = fopen objFileName "rb"
local mdx = File()
local refx
local refy
local refz
local verts = #()
local test = #()
local faces = #()
local normals = #()
mdx.Init bstream
mdx.pos = 44
local nbones = mdx.fReadLong()
local nverts = mdx.fReadLong()
local nweights = mdx.fReadLong()
local nnormals = mdx.fReadLong()
mdx.pos = 60
local nummesh = mdx.fReadLong()
mdx.pos = 83
local str = mdx.fReadByte()
messagebox ("str length is " + (str as string))
mdx.pos += (str + 6)
messagebox ("reading nverts at " + (mdx.pos as string))
local tests = mdx.fReadShort()
messagebox ("tests before flip is " + (tests as string))
tests = sflip tests
mdx.pos += (8 + tests)
messagebox ("reading verts at " + (mdx.pos as string))
for n = 1 to n = nverts do
(
x = mdx.fReadFloat()
y = mdx.fReadFloat()
z = mdx.fReadFloat()
verts[n] = point3 x z y
)
mdx.pos += 6 local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len + 6)
messagebox ("pos before twit is " + (mdx.pos as string))
twdt
local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len + 6)
messagebox ("pos before norm is " + (mdx.pos as string))
norm local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len)
messagebox ("pos before head reading is " + (mdx.pos as string))
local head = mdx.fReadHead()
if (head == #DOT3) then (
mdx.pos += 2
dot3
local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len)
) else (
mdx.pos = 4
)
mdx.pos += 7
str = mdx.fReadByte()
mdx.pos += (str)
local type
if mdx.fReadHead() == #OZC then
(
type = true
) else (
type = false
)
mdx.pos += 2
local j = mdx.fReadShort()
j = sflip j
mdx.pos += j
for w = 1 to w = nummesh do
(
messagebox ("pos of form is " + (mdx.pos as string))
mdx.pos += 19
str = mdx.fReadByte()
mdx.pos += (str + 6)
local jump = mdx.fReadShort()
jump = sflip jump
jump += mdx.pos
local size = mdx.fReadLong()
local ppoints = #()
for n = 1 to n = size do
(
x = mdx.fReadLong()
ppoints[n] = (x + 1)
)
mdx.pos = (jump + 6)
NIDX
messagebox ("pos of NIDX is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
mdx.pos += (jump)
local header = mdx.fReadHead()
if ((header == #DOT3) or (header == #VDCL)) then
(
mdx.pos += 2
DOT3
messagebox ("pos of dot3 is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
mdx.pos += (jump + 6)
) else (
mdx.pos += 2
)
TXCI
messagebox ("TXCI pos is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
mdx.pos += (jump + 18)
FORM
messagebox ("FORM pos is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
local tverts = #()
for m = 1 to m = (jump / do
(
x = mdx.fReadFloat()
y = mdx.fReadFloat()
tverts[m] = point3 x (1y) 0
)
mdx.pos += 24
messagebox ("pos of face is " + (mdx.pos as string))
local fc
face block
mdx.pos += 6
jump = mdx.fReadShort()
jump = sflip jump
local jump2 = jump
jump += mdx.pos
fc = mdx.fReadLong()
messagebox ("nfaces: " + (fc as string))
for n = 1 to n = fc do
(
if (((fc * 14) + 4) <= jump2) then (mdx.pos += 2)
x = mdx.fReadLong()
y = mdx.fReadLong()
z = mdx.fReadLong()
messagebox ("x is " + (x as string) + " y is " + (y as string) + " z is " + (z as string))
faces[n] = point3 ppoints[(x+1)] ppoints[(y+1)] ppoints[(z+1)]
)
mdx.pos = jump
test[w] = mesh numverts: nverts numfaces: fc
for b = 1 to b = nverts do
(
test[w].vertices = verts
)
for b = 1 to b = fc do
(
test[w].faces = faces
)
setNumTVerts test[w] nverts
for k = 1 to k = tverts.count do
(
setTVert test[w] ppoints[k] tverts[k]
)
buildTVFaces test[w]
for k = 1 to test[w].numfaces do
(
setTVFace test[w] k faces[k]
)
for k = 1 to k = tverts.count do
(
setTVert test[w] ppoints[k] tverts[k]
)
)
) )
)
)
getNodeByName <string> exact:<boolean>
(

 Vars 

local modelName
local impTypes
local seqs  Sequences
local mtls  Materials
local geos  Geometry
local objs  Bones, Helpers, Lights, Attachments
local pivot
local geobones
local notes  Note Track
local meshes = #()

 Structures 

struct File
(
pos, end, bstream,
 Helper function to init the toplevel chunk rover
fn Init stream=
(
bstream = stream
pos = ftell bstream
fseek bstream 0 #seek_end
end = ftell bstream
),
fn fReadHead=
(
fseek bstream pos #seek_set
local id = ReadLong bstream #unsigned
local tag = File.GetName id
pos += 4
tag
),
fn fReadFloat=
(
local id
local i = 0
while (id == undefined) and (i < 10) do
(
fseek bstream pos #seek_set
id = ReadFloat bstream
i += 1
)
if i == 10 then
(
print ("problem: " + (pos as string))
)
pos += 4
id
),
fn fReadLong=
(
fseek bstream pos #seek_set
local id = ReadLong bstream
pos += 4
id
),
fn fReadShort=
(
fseek bstream pos #seek_set
local id = ReadShort bstream #unsigned
pos += 2
id
),
fn fReadByte=
(
fseek bstream pos #seek_set
local id = ReadByte bstream
pos += 1
id
),
fn fReadString n=
(
fseek bstream pos #seek_set
local id = ReadString bstream
pos += n*80
id
),
fn GetName id=
(
case id of
(
0x33544F44: #DOT3
0x4C54494F: #OITL
0x20435A4F: #OZC
0x4C434456: #VDCL
UNKNOWN
default: #UNKNOWN
)
)
)
fn sflip numb =
(
local bits = #()
local n
for n = 1 to n = 16 do
(
bits[n] = bit.get numb n
)
for n = 1 to n = 8 do
(
numb = bit.set numb n bits[(n+8)]
) for n = 9 to n = 16 do
(
numb = bit.set numb n bits[(n8)]
) return numb
)
fn lflip numb =
(
local bits = #()
local n
for n = 1 to n = 32 do
(
bits[n] = bit.get numb n
)
for n = 1 to n = 8 do
(
numb = bit.set numb n bits[(24+n)]
)
for n = 9 to n = 16 do
(
numb = bit.set numb n bits[(8+n)]
)
for n = 17 to n = 24 do
(
numb = bit.set numb n bits[(n8)]
)
for n = 25 to n = 32 do
(
numb = bit.set numb n bits[(n24)]
)
return numb
)

 User Interface 

group "Import MSH"
(
button importButton "Import MGN..."
)

 Main Import Function 

on importButton pressed do
(
 Show open file dialog box
local objFileName = getOpenFileName caption:"Import MGN" types:"SWG model File (*.mgn)*.mgnAll Files (*.*)*.*"
local isValid = true
if objFileName != undefined then
(
 If user made a selection, begin importing
if doesFileExist objFileName then
(
 Open up the file as a binary stream
local bstream = fopen objFileName "rb"
local mdx = File()
local refx
local refy
local refz
local verts = #()
local test = #()
local faces = #()
local normals = #()
mdx.Init bstream
mdx.pos = 44
local nbones = mdx.fReadLong()
local nverts = mdx.fReadLong()
local nweights = mdx.fReadLong()
local nnormals = mdx.fReadLong()
mdx.pos = 60
local nummesh = mdx.fReadLong()
mdx.pos = 83
local str = mdx.fReadByte()
messagebox ("str length is " + (str as string))
mdx.pos += (str + 6)
messagebox ("reading nverts at " + (mdx.pos as string))
local tests = mdx.fReadShort()
messagebox ("tests before flip is " + (tests as string))
tests = sflip tests
mdx.pos += (8 + tests)
messagebox ("reading verts at " + (mdx.pos as string))
for n = 1 to n = nverts do
(
x = mdx.fReadFloat()
y = mdx.fReadFloat()
z = mdx.fReadFloat()
verts[n] = point3 x z y
)
mdx.pos += 6 local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len + 6)
messagebox ("pos before twit is " + (mdx.pos as string))
twdt
local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len + 6)
messagebox ("pos before norm is " + (mdx.pos as string))
norm local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len)
messagebox ("pos before head reading is " + (mdx.pos as string))
local head = mdx.fReadHead()
if (head == #DOT3) then (
mdx.pos += 2
dot3
local len = mdx.fReadShort()
len = sflip len
mdx.pos += (len)
) else (
mdx.pos = 4
)
mdx.pos += 7
str = mdx.fReadByte()
mdx.pos += (str)
local type
if mdx.fReadHead() == #OZC then
(
type = true
) else (
type = false
)
mdx.pos += 2
local j = mdx.fReadShort()
j = sflip j
mdx.pos += j
for w = 1 to w = nummesh do
(
messagebox ("pos of form is " + (mdx.pos as string))
mdx.pos += 19
str = mdx.fReadByte()
mdx.pos += (str + 6)
local jump = mdx.fReadShort()
jump = sflip jump
jump += mdx.pos
local size = mdx.fReadLong()
local ppoints = #()
for n = 1 to n = size do
(
x = mdx.fReadLong()
ppoints[n] = (x + 1)
)
mdx.pos = (jump + 6)
NIDX
messagebox ("pos of NIDX is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
mdx.pos += (jump)
local header = mdx.fReadHead()
if ((header == #DOT3) or (header == #VDCL)) then
(
mdx.pos += 2
DOT3
messagebox ("pos of dot3 is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
mdx.pos += (jump + 6)
) else (
mdx.pos += 2
)
TXCI
messagebox ("TXCI pos is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
mdx.pos += (jump + 18)
FORM
messagebox ("FORM pos is " + (mdx.pos as string))
jump = mdx.fReadShort()
jump = sflip jump
local tverts = #()
for m = 1 to m = (jump / do
(
x = mdx.fReadFloat()
y = mdx.fReadFloat()
tverts[m] = point3 x (1y) 0
)
mdx.pos += 24
messagebox ("pos of face is " + (mdx.pos as string))
local fc
face block
mdx.pos += 6
jump = mdx.fReadShort()
jump = sflip jump
local jump2 = jump
jump += mdx.pos
fc = mdx.fReadLong()
messagebox ("nfaces: " + (fc as string))
for n = 1 to n = fc do
(
if (((fc * 14) + 4) <= jump2) then (mdx.pos += 2)
x = mdx.fReadLong()
y = mdx.fReadLong()
z = mdx.fReadLong()
messagebox ("x is " + (x as string) + " y is " + (y as string) + " z is " + (z as string))
faces[n] = point3 ppoints[(x+1)] ppoints[(y+1)] ppoints[(z+1)]
)
mdx.pos = jump
test[w] = mesh numverts: nverts numfaces: fc
for b = 1 to b = nverts do
(
test[w].vertices = verts
)
for b = 1 to b = fc do
(
test[w].faces = faces
)
setNumTVerts test[w] nverts
for k = 1 to k = tverts.count do
(
setTVert test[w] ppoints[k] tverts[k]
)
buildTVFaces test[w]
for k = 1 to test[w].numfaces do
(
setTVFace test[w] k faces[k]
)
for k = 1 to k = tverts.count do
(
setTVert test[w] ppoints[k] tverts[k]
)
)
) )
)
)
getNodeByName <string> exact:<boolean>

 advanced
 Posts: 45
 Joined: Sun Jul 16, 2006 6:54 am
 Location: Around
 Contact:
Will test, post results shortly. FYI the board's smilified some of the characters, I'll have a hack at converting them back to the original.
Many thanks ^_^
EDIT: Ok, after doing a few copy/paste operations and taking 5 minutes to realize there's a new rollout XD I try and import a few models. I keep getting some variable type errors, str will come up as being of an undefined type. Apparently it doesn't care if it was modified in the previous line without error.
I'm trying to do a little bit of degugging here, but unfortunately I'm not really familiar with MAXscript. For starters, there are no variable types.
Many thanks ^_^
EDIT: Ok, after doing a few copy/paste operations and taking 5 minutes to realize there's a new rollout XD I try and import a few models. I keep getting some variable type errors, str will come up as being of an undefined type. Apparently it doesn't care if it was modified in the previous line without error.
I'm trying to do a little bit of degugging here, but unfortunately I'm not really familiar with MAXscript. For starters, there are no variable types.

 advanced
 Posts: 45
 Joined: Sun Jul 16, 2006 6:54 am
 Location: Around
 Contact:
Found a new error on a different model When I try to load the composite helmet, I get a message saying we got a negative number in an array index. This doesn't seem to appear on any other model. Original problem was with a '+' operation on an undefined type of variable. Attaching test models for your examination.
You do not have the required permissions to view the files attached to this post.

 ultran00b
 Posts: 5
 Joined: Thu Nov 09, 2006 1:59 am
Ok so I entered in the code and the problem I get is, how do I open and or import the .mgn file? As far as I can tell I went to MAXscript hit run and clicked on the mgn script I entered, I get no messages or success or failure, so I try to open the file and go to "All files" and click the file to open but 3ds max says it can't open it, and when I try to import it says improper format. I'd appreciate any and all help, thanks.

 advanced
 Posts: 45
 Joined: Sun Jul 16, 2006 6:54 am
 Location: Around
 Contact:

 advanced
 Posts: 45
 Joined: Sun Jul 16, 2006 6:54 am
 Location: Around
 Contact:

 ultran00b
 Posts: 5
 Joined: Thu Nov 09, 2006 1:59 am

 advanced
 Posts: 45
 Joined: Sun Jul 16, 2006 6:54 am
 Location: Around
 Contact:

 ultran00b
 Posts: 2
 Joined: Sun Nov 12, 2006 6:12 pm
 Contact:
hello i'm a swg modder but i have no knowledge of such scripts. Anyone want to tell me how to use/install the one posted?
EDIT: or can someone just post the plugin they created with the script?
EDIT #2: i noticed someone posted something about Autodesk. Does this mean the plugin will work with Maya as well?
EDIT: or can someone just post the plugin they created with the script?
EDIT #2: i noticed someone posted something about Autodesk. Does this mean the plugin will work with Maya as well?