summaryrefslogtreecommitdiffstats
path: root/maxscript
diff options
context:
space:
mode:
authorKyle K <kylek389@gmail.com>2015-04-21 02:19:05 -0500
committerKyle K <kylek389@gmail.com>2015-04-21 02:31:18 -0500
commitd216675c6b00f79d3ecf381c717286f48715a99c (patch)
treec89f6dd94b3111c56702e8ded81b2cbab8172aba /maxscript
parentcad9c1bbc9226a3d15321696c49eac2d3536782c (diff)
downloadTXRExtractor-d216675c6b00f79d3ecf381c717286f48715a99c.tar.gz
TXRExtractor-d216675c6b00f79d3ecf381c717286f48715a99c.tar.bz2
TXRExtractor-d216675c6b00f79d3ecf381c717286f48715a99c.zip
provide initial 3ds Max model import script
it is still work in progress and meshes don't have materials assigned to them yet, the model format still needs more reversing
Diffstat (limited to 'maxscript')
-rw-r--r--maxscript/wmn/credits.txt6
-rw-r--r--maxscript/wmn/dds2gtf.exebin0 -> 147456 bytes
-rw-r--r--maxscript/wmn/gtf2dds.exebin0 -> 147456 bytes
-rw-r--r--maxscript/wmn/wmn.ms837
4 files changed, 843 insertions, 0 deletions
diff --git a/maxscript/wmn/credits.txt b/maxscript/wmn/credits.txt
new file mode 100644
index 0000000..6d74ef1
--- /dev/null
+++ b/maxscript/wmn/credits.txt
@@ -0,0 +1,6 @@
+[dds2gtf.exe and gtf2dds.exe]
+- http://forum.xentax.com/viewtopic.php?p=54964#p54964
+- credits to ExeiL and JU57FL1P for coding up the GFT to DDS converter
+
+[maxscript]
+- thanks to mariokart64n for initial script http://forum.xentax.com/viewtopic.php?f=16&t=12775
diff --git a/maxscript/wmn/dds2gtf.exe b/maxscript/wmn/dds2gtf.exe
new file mode 100644
index 0000000..6277633
--- /dev/null
+++ b/maxscript/wmn/dds2gtf.exe
Binary files differ
diff --git a/maxscript/wmn/gtf2dds.exe b/maxscript/wmn/gtf2dds.exe
new file mode 100644
index 0000000..858d38a
--- /dev/null
+++ b/maxscript/wmn/gtf2dds.exe
Binary files differ
diff --git a/maxscript/wmn/wmn.ms b/maxscript/wmn/wmn.ms
new file mode 100644
index 0000000..7eef22d
--- /dev/null
+++ b/maxscript/wmn/wmn.ms
@@ -0,0 +1,837 @@
+/* ----------------------------------------------------------
+
+ Wangan Midnight 3ds Max Model Import Script
+
+
+
+ C H A N G E L O G
+
+ April 21, 2015
+ - script comments, cleanups, and some changes by nfm aka fatalhalt
+
+ April 20, 2015
+ - 5th revision by mariokart64n
+
+*/ ----------------------------------------------------------
+
+global f, g, PS3_WANGANM_IMPORTER, mscale = ((1.0/2.54)*100), tex = 1, texn = #()
+global impMsh = true, impSkl = false, dumpTex = true, DDSconv = true, guiEnabled = true, clearScene = false, debugMsg = false
+
+struct _geometry (
+ position = #(), -- vertices
+ uv_coordinate = #(),
+ matid = #(),
+ matcount = #(),
+ face = #()
+)
+
+struct _XTD_header (
+ fileid = "", -- 3 chars
+ vers = 0, -- 1 char
+ unk1 = "", -- 4 chars
+ offsets = #()
+)
+
+-- acts as container that usually stores 2 sub blocks; model data and texture
+struct _header (
+ fileid = "", -- 3 chars
+ filever = 0, -- 1 char
+ unk1 = "", -- 4 chars
+ unk2 = 0, -- long
+ count = 0, -- long, count of sub blocks in current file
+ offsets = #(), -- these offsets are relative to a sub block and not the whole file e.g. when XMD contains another XMD
+ sizes = #()
+)
+
+struct _subheader (
+ type = 0, -- short
+ string_index = 0, -- short
+ size = 0, -- long
+ unk2 = 0, -- long
+ unk3 = 0 -- long
+)
+
+-- this is a table that appears 1 long after "Bp"
+struct _filetable (
+ unk1 = 0, -- long
+ unk2 = 0, -- long, seems to store count, amount of sub blocks
+ unk3 = 0, -- long
+ offsets = #() -- addresses to sub blocks, which e.g. can store XTD or even nested XMD
+)
+
+fn RH2LH corrd = (
+ [corrd.x,-corrd.z,corrd.y]*mscale
+)
+
+fn readBEfloat fstream = (
+ bit.intAsFloat (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3)
+)
+
+fn readBElong fstream = (
+ bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3
+)
+
+fn readBEshort fstream = (
+ bit.swapBytes (readshort fstream #unsigned) 1 2
+)
+
+fn getpadding num alignment = (
+ mod (alignment-(mod num alignment)) alignment
+)
+
+fn paddstring len instring = (
+ local i, str = ""
+ instring = instring as string
+ if instring.count <=len then (
+ for i = 1 to (len-instring.count) do (
+ str += "0"
+ )
+ str = (str+instring)
+ ) else (
+ for i = 1 to len do (
+ str+="0";str[i]=instring[i]
+ )
+ )
+ return str
+)
+
+fn readFixedString bstream fixedLen = (
+ local i, str = ""
+ for i = 1 to fixedLen do (
+ str += bit.intAsChar (ReadByte bstream #unsigned)
+ )
+ str
+)
+
+fn triangle_strip fstream count = (
+ global g
+ local face_add = 1, matid = 1, vertex_start = 0
+ local count, fa, fb, fc , x, y
+ local face_flip = true
+ local face_reset = true
+
+ x = 0; while x < count do (
+ x += 1
+ if face_reset == true then (
+ x += 2
+ face_reset = false
+ face_flip = false
+ append g.matid matid
+ fa = ((readBEshort fstream)-vertex_start) + face_add
+ fb = ((readBEshort fstream)-vertex_start) + face_add
+ fc = ((readBEshort fstream)-vertex_start) + face_add
+ if face_flip == true then (
+ append g.face [fa,fc,fb]; face_flip = false
+ ) else (
+ append g.face [fa,fb,fc]; face_flip = true
+ )
+ ) else (
+ fa = fb; fb = fc; fc = readBEshort fstream
+ if fc < 0xFFFF then (
+ fc -= vertex_start
+ fc += face_add
+ append g.matid matid
+ if face_flip == true then (
+ append g.face [fa,fc,fb]; face_flip = false
+ ) else (
+ append g.face [fa,fb,fc]; face_flip = true
+ )
+ ) else (
+ face_reset = true
+ )
+ )
+ )
+)
+
+fn buildObj objname = (
+ global g
+ local j, msh --,mats = copy g.matcount #nomap
+-- local faceValid = true
+-- j = 1; while j < g.face.count and faceValid == true do (
+-- if g.face[j][1] > g.position.count or g.face[j][1] < 0 do faceValid = false
+-- if g.face[j][2] > g.position.count or g.face[j][1] < 0 do faceValid = false
+-- if g.face[j][3] > g.position.count or g.face[j][1] < 0 do faceValid = false
+-- j += 1
+-- )
+-- if faceValid == false do (g.face = #(); print "Face Range Error")
+-- print g.position.count
+-- print g.face
+ if g.position.count > 0 do (
+ msh = mesh vertices:g.position tverts:g.uv_coordinate faces:g.face -- materialIDs:g.matid
+ msh.name = objname
+ msh.numTVerts = g.uv_coordinate.count
+ msh.displayByLayer = false
+ msh.backfacecull = on
+ buildTVFaces msh
+
+ for j = 1 to g.uv_coordinate.count do setTVert msh j g.uv_coordinate[j]
+ for j = 1 to g.face.count do setTVFace msh j g.face[j]
+ convertTo msh PolyMeshObject
+-- if g.matcount.count > 0 do (
+-- msh.material = multiMaterial numsubs:g.matcount.count
+-- sort mats
+-- for j = 1 to g.matcount.count do (
+-- msh.material.materialList[j].Diffuse = random (color 0 0 0) (color 255 255 255)
+-- msh.material.materialList[j].diffuseMap = Bitmaptexture fileName:("tex_"+(paddstring 3 (findItem mats g.matcount[j]))+".tga")
+-- )
+-- )
+ )
+ msh
+)
+
+fn writeDDSheader fstream texW texH texM texC = (
+ local texP = 0, i
+ writelong fstream 0x20534444 #unsigned -- File ID
+ writelong fstream 0x7C #unsigned -- Header Size
+ case texC of ( -- dwFlags
+ "DXT1": (
+ writelong fstream 0x00081007 #unsigned
+ texP = ((texW*texH)/0x02)
+ )
+ "DXT3": (
+ writelong fstream 0x00081007 #unsigned
+ texP = (texW*texH)
+ )
+ "DXT5": (
+ writelong fstream 0x00081007 #unsigned
+ texP = (texW*texH)
+ )
+ "ATI1": (
+ writelong fstream 0x000A1007 #unsigned
+ texP = ((texW*texH)/0x20)
+ )
+ "ATI2": (
+ writelong fstream 0x000A1007 #unsigned
+ texP = (texW*texH)
+ )
+ "P8": (
+ writelong fstream 0x000A1007 #unsigned
+ texP = ((texW*texH)/0x02)
+ )
+ "ARGB16": (
+ writelong fstream 0x00081007 #unsigned
+ texP = (((texW*texH)/0x8)*0x10)
+ )
+ "ARGB32": (
+ writelong fstream 0x00081007 #unsigned
+ texP = (((texW*texH)/0x4)*0x10)
+ )
+ )
+
+ writelong fstream texW #unsigned -- Texture Width
+ writelong fstream texH #unsigned -- Texture Height
+ writelong fstream texP #unsigned -- Pitch (#of bytes in a single row across the texture)
+ writelong fstream 0x00 #unsigned -- Image Depth? Not Used, for Image Volume
+ writelong fstream texM #unsigned -- Texture MIP Count
+ for i = 1 to 11 do (
+ writelong fstream 0x00 #unsigned
+ ) -- Reserved Space
+ writelong fstream 0x20 #unsigned -- Size of PIXEL_FORMAT info, always 32bytes;
+ case texC of (
+ "DXT1": (
+ writelong fstream 0x04;writelong fstream 0x31545844 #unsigned
+ writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned
+ )
+ "DXT3": (
+ writelong fstream 0x04;writelong fstream 0x33545844 #unsigned
+ writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned
+ )
+ "DXT5": (
+ writelong fstream 0x04;writelong fstream 0x35545844 #unsigned
+ writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned
+ )
+ "ATI1": (
+ writelong fstream 0x04;writelong fstream 0x31495441 #unsigned
+ writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00401008 #unsigned
+ )
+ "ATI2": (
+ writelong fstream 0x04;writelong fstream 0x32495441 #unsigned
+ writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00401008 #unsigned
+ )
+ "P8": (
+ writelong fstream 0x20;writelong fstream 0x20203850 #unsigned
+ writelong fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00401008 #unsigned
+ )
+ "ARGB16": (
+ writelong fstream 0x41;writelong fstream 0x00000000 #unsigned
+ writelong fstream 0x10;writebyte fstream 0x00;writebyte fstream 0x0F;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0xF0;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x0F;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0xF0;writebyte fstream 0x00
+ writebyte fstream 0x00;writelong fstream 0x00001000 #unsigned
+ )
+ "ARGB32": (
+ writelong fstream 0x41;writelong fstream 0x00000000 #unsigned
+ writelong fstream 0x20;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0xFF
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0xFF;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0xFF;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00;writebyte fstream 0x00
+ writebyte fstream 0xFF;writelong fstream 0x00001000 #unsigned
+ )
+ )
+ for i = 1 to 4 do ( -- Reserved Space for CAPS
+ writelong fstream 0x00 #unsigned
+ )
+)
+
+fn getHeader = (
+ global f
+ local h = _header(), i = 0, p = ftell f
+ h.fileid = readFixedString f 3
+ h.filever = readbyte f #unsinged
+ h.unk1 = readFixedString f 4
+ h.unk2 = readBElong f
+ h.count = readBElong f
+ h.offsets = (
+ for i = 1 to h.count collect (
+ readBElong f + p
+ )
+ )
+ fseek f (getpadding (ftell f) 16) #seek_cur
+ h.sizes = (
+ for i = 1 to h.count collect (
+ readBElong f
+ )
+ )
+ fseek f (getpadding (ftell f) 16) #seek_cur
+ h
+)
+
+-- this function consumes 16 bytes from file's current position
+fn getSubHeader = (
+ global f
+ local s = _subheader()
+
+ if debugMsg == true do (format "parsing sub header at 0x%\n" (bit.intAsHex((ftell f) as integer)))
+ s.type = readBEshort f
+ s.string_index = readBEshort f
+ s.size = readBElong f
+ s.unk2 = readBElong f
+ s.unk3 = readBElong f
+ s
+)
+
+fn getTXD_header = (
+ global f
+ local t = _XTD_header(), p = ftell f
+ t.fileid = readFixedString f 3
+ t.vers = readbyte f #unsigned
+ t.unk1 = readFixedString f 4
+ t.offsets = (
+ for i = 1 to (readlong f #unsigned) collect (
+ readlong f #unsigned + p
+ )
+ )
+ t
+)
+
+fn dumpGFT spath = (
+ global f
+ local p = ftell f
+ local s, x
+ if dumpTex == true do (
+ if (readlong f #unsigned) == 0x00000501 and DDSconv == true then (
+ readBElong f
+ readBElong f
+ readBElong f
+ data_address = readBElong f + p
+ data_size = readBElong f
+ fmt = readbyte f #unsigned
+ fseek f 0x03 #seek_cur
+ readBElong f
+ w = readBEshort f
+ h = readBEshort f
+ fseek f data_address #seek_set
+ s = fopen spath "wb"
+ writeDDSheader s h w 0 (
+ case fmt of (
+ 0x85: ("ARGB32")
+ 0x86: ("DXT1")
+ 0x87: ("DXT3")
+ 0x88: ("DXT5")
+ 0xA7: ("DXT3")
+ default: (
+ format "New DDS Type: 0x%\n" (bit.intAsHex((fmt) as integer))
+ "DXT1"
+ )
+ )
+ )
+ for x = 1 to data_size do (
+ writebyte s (readbyte f #unsigned) #unsigned
+ )
+ fclose s
+ ) else (
+ fseek f -0x14 #seek_cur
+ data_size = readlong f #unsigned - 0x10
+ fseek f 0x0C #seek_cur
+ s = fopen (spath+".GFT") "wb"
+ for x = 1 to data_size do (
+ writebyte s (readbyte f #unsigned) #unsigned
+ )
+ fclose s
+ )
+ )
+)
+
+-- arg1 here is result of getTXD_header()
+fn getTXD hdr fpath = (
+ global f, tex
+ for i = 1 to hdr.offsets.count do (
+ fseek f hdr.offsets[i] #seek_set
+ size = readlong f #unsigned
+ type = readlong f #unsigned
+ unk1 = readBEshort f
+ unk2 = readBEshort f
+ unk3 = readBEshort f
+ unk4 = readBEshort f
+ if size > 0x10 do (
+ if debugMsg == true do print (fpath + "_tex_" + (paddstring 3 i) + ".dds")
+ if tex <= texn.count then (
+ dumpGFT((getFilenamePath fpath)+texn[tex] + ".dds")
+ ) else (
+ dumpGFT(fpath + "_tex_" + (paddstring 3 tex) + ".dds")
+ )
+ )
+ tex+=1
+ )
+)
+
+fn getType04 objname = (
+ global f
+ readBElong f
+ readBEshort f
+ readBEshort f
+ readBElong f
+ readBElong f
+
+ local pos = [(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ d = dummy()
+ d.position = (RH2LH(pos))
+ d.name = objname
+ d.showLinks = d.showLinksOnly = true
+ d
+)
+
+fn getType05 h = (
+ global f
+ local p = ftell f - 16
+ fseek f (p+h.size) #seek_set
+ for i = 1 to h.unk3 do (
+ p = ftell f
+ readBEshort f
+ readBEshort f
+ block_size = readBElong f
+ fseek f (p+block_size) #seek_set
+ )
+)
+
+fn getType07 strArray = ( -- materials data
+ global f
+ local p = ftell f
+ readBElong f
+ readBElong f
+ readBElong f
+ count = readBElong f
+
+ --if debugMsg == true do (format "Material Sub Block, read 1 long past count, now @ 0x%\n" (bit.intAsHex((ftell f) as integer)))
+
+ for i = 1 to count do (
+ p = ftell f
+ type = readBElong f
+ size = readBElong f
+ unk1 = readBElong f
+ unk2 = readBElong f
+ case type of (
+ 0x02: (
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ )
+ 0x03: (
+ readBElong f
+ readBElong f
+ readBElong f
+ readBElong f
+
+ --print strArray[idx]
+ )
+ 0x09: (
+ readBElong f
+ readBElong f
+ readBElong f
+ readBElong f
+ )
+ 0x0B: (
+ )
+ default : (
+ --if debugMsg == true do (format "Material Sub Block, Unknown Material Type @ 0x%\n" (bit.intAsHex((ftell f) as integer)))
+ )
+ )
+ fseek f (p + size) #seek_set
+ )
+)
+
+fn getType08 objname = ( -- geomety data
+ global f, g = _geometry()
+ local p = ftell f, getPos
+
+ unk01=readBElong f
+ unk02=readBElong f
+ unk03=readBElong f
+ unk04=readBElong f
+
+ bmin = [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+ bmax = [(readBEfloat f),(readBEfloat f),(readBEfloat f),(readBEfloat f)]
+
+ unk05=readBElong f
+ unk06=readBElong f
+ count1 = readBElong f
+ count2 = readBElong f
+
+ unk07=readBElong f
+ unk08=readBElong f
+ unk09=readBElong f
+ unk10=readBElong f
+
+-- if debugMsg == true do (
+-- format "Unknowns[%]:\t % % % % % % % % % %\n" \
+-- count1 unk01 unk02 unk03 unk04 unk05 \
+-- unk06 unk07 unk08 unk09 unk10
+-- )
+
+ for i = 1 to count2 do ( -- e.g. you would loop to grab faces then vertices and so on, see case statement
+ getPos = ftell f
+
+ readBElong f -- 0x000A0000
+ block_size = readBElong f
+ comp = readBElong f
+ datatype = readBElong f
+
+ readBElong f
+ count = readBElong f -- e.g. number of faces or vertices
+ readBElong f
+ readBElong f
+
+ case comp of (
+ 0x00: ( -- face
+ triangle_strip f count
+ )
+ 0x02: ( -- position
+ for i = 1 to count do (
+ append g.position (RH2LH([(readBEfloat f),(readBEfloat f),(readBEfloat f)]))
+ )
+ )
+ 0x03: ( -- colours
+ )
+ 0x04: ( -- normals
+ )
+ 0x05: ( -- UVs
+ for i = 1 to count do (
+ append g.uv_coordinate ([(readBEfloat f),1-(readBEfloat f),0])
+ )
+ )
+ 0x0B: ( -- Bone Indices
+-- for i = 1 to count do (
+-- b1 = readBEfloat f
+-- b2 = readBEfloat f
+-- b3 = readBEfloat f
+-- b4 = readBEfloat f
+-- )
+ )
+ 0x0C: ( -- Bone Weights
+-- for i = 1 to count do (
+-- b1 = readBEfloat f
+-- b2 = readBEfloat f
+-- b3 = readBEfloat f
+-- b4 = readBEfloat f
+-- )
+ )
+ default: (
+ format "Error Vertex Format Unsupported [%] @ 0x%\n" \
+ comp (bit.intAsHex((getPos) as integer))
+ )
+ )
+ fseek f (getPos + block_size) #seek_set
+ )
+
+ --print g.uv_coordinate.count
+ if g.uv_coordinate.count < g.position.count do (
+ for i = 1 to (g.position.count - g.uv_coordinate.count) do (
+ append g.uv_coordinate [0,0,0]
+ )
+ )
+
+ buildObj(objname)
+)
+
+fn getType21 = ( -- string data
+ global f
+ readstring f
+)
+
+-- called from getStuff()
+fn getStuffTable pos = (
+ global f
+ local t = _filetable()
+ t.unk1 = readBElong f
+ t.unk2 = readBElong f
+ t.unk3 = readBElong f
+ t.offsets = (
+ for i = 1 to t.unk2 collect (
+ readBElong f + pos
+ )
+ )
+ t
+)
+
+-- this function is called when 0x0 long magic is encounter in XMD file container
+-- arg1's position usually will be at "Bp" section here
+fn getStuff pos = (
+ global f
+ local p = ftell f, strArray = #(), boneArray = #(), subHeaderArray = #()
+ fseek f 0x80 #seek_cur -- FIX ME, NOTICE THAT IT SEEK EXTRA 80h FROM CURR POS
+
+ -- HEADER HERE DESCRIBES COUNTS FOR DATA BELOW
+ check = readlong f #unsigned
+ if check == 0x00007042 or check == 0x0000F041 or check == 0x0000C041 then ( -- check for "Bp" section
+ table = getStuffTable(pos)
+
+ -- seek to all sub blocks and parse their header solely to prefetch string array that will be used in next loop
+ for i = 1 to table.unk2 do (
+ fseek f table.offsets[i] #seek_set
+ sb = getSubHeader()
+ append subHeaderArray sb
+ if sb.type == 0x15 do (
+ append strArray (getType21())
+ )
+ )
+
+ for i = 1 to table.unk2 do (
+ fseek f (table.offsets[i] + 16) #seek_set
+ sb = subHeaderArray[i]
+ block_name = ""
+ if debugMsg == true do block_name += (i as string) + " "
+ if sb.string_index > 0 and sb.string_index <= strArray.count do (
+ block_name += strArray[(sb.string_index)] -- creates block names such as "1 Detail" or "3 mat_sitamichi00_sh"
+ )
+
+ case sb.type of (
+ 0x04: ( -- matrix?
+ if debugMsg == true do (format "Matrix? @ 0x%\n" (bit.intAsHex((table.offsets[i]) as integer)))
+ if impSkl == true do (
+ append boneArray (getType04(block_name))
+ if sb.unk2 > 0 and sb.unk2 <= boneArray.count do (
+ try (
+ boneArray[(boneArray.count)].parent = boneArray[(sb.unk2)]
+ )
+ catch (
+ if debugMsg == true do (
+ format "Illegal parent, possibly same node or ancestor node [Index:%(%) Parent:%]\n" \
+ boneArray.count sb.unk3 sb.unk2
+ )
+ )
+ )
+ )
+ )
+ 0x05: ( -- bounding box
+ if debugMsg == true do (format "Bounding Box? @ 0x%\n" (bit.intAsHex((table.offsets[i]) as integer)))
+ getType05(sb)
+ )
+ 0x07: ( -- materials
+ if debugMsg == true do (format "Material @ 0x%\n\tName: %\n" (bit.intAsHex((table.offsets[i]) as integer)) block_name)
+ getType07(strArray)
+ )
+ 0x08: ( -- geometry
+ if debugMsg == true do (format "Geometry @ 0x%\n" (bit.intAsHex((table.offsets[i]) as integer)))
+ if impMsh == true do (
+ getType08(block_name)
+ )
+ )
+ 0x0C: ( -- texture names?
+ if debugMsg == true do (format "Textures ? @ 0x%\n\tName: %\n" (bit.intAsHex((table.offsets[i]) as integer)) block_name)
+ append texn block_name
+ )
+ 0x11: ( -- IK Bone
+ if debugMsg == true do (format "IK Bone @ 0x%\n\tName: %\n" (bit.intAsHex((table.offsets[i]) as integer)) block_name)
+ )
+ 0x15: ( -- string data
+ )
+ default: (
+ format "SubBlock Not Supported [%] @ 0x%\n" \
+ sb.type (bit.intAsHex((table.offsets[i]) as integer))
+ )
+ )
+
+ ) -- end of sub block loop
+ ) else (
+ format "Error: Failed to seek to table\n"
+ )
+ if debugMsg == true do (
+ format "String Table\n"
+ for i = 1 to strArray.count do (
+ format "%:\t%\n" i strArray[i]
+ )
+ )
+)
+
+
+-- this fn reads first long of a file called magic and decides what to make of it
+-- GTF stores multiple headerless DDS image, some even are 8888:32bit
+fn readBinary filen = (
+ global f
+ local magic = readlong f #unsigned
+ fseek f -4 #seek_cur
+ case magic of (
+ 0x01444D58: ( -- XMD (Xtreme Model Data)
+ hdr = getHeader()
+ for d = 1 to hdr.count do (
+ -- seeks to an offset, grabs long and seeks back a long
+ fseek f hdr.offsets[d] #seek_set
+ filetype = readlong f #unsigned
+ fseek f hdr.offsets[d] #seek_set
+ case filetype of (
+ 0x00000000: ( -- usaully means we hit the 2 longs before X3D0037 section
+ getStuff(hdr.offsets[d])
+ )
+ 0x01444D58: ( -- nested XMD (Xtreme Model Data)
+ readBinary(filen)
+ )
+ 0x00445458: ( -- XTD (Xtreme Texture Data)
+ --getTXD( getTXD_header() )((getFilenamePath filen)+(getFilenameFile filen))
+ readBinary(filen)
+ )
+ default: (
+ format "Error: New Block Type [%] @ Address: 0x%\n" \
+ filetype (bit.intAsHex((hdr.offsets[d]) as integer))
+ )
+ )
+ )
+ )
+ 0x00445458: ( -- XTD (Xtreme Texture Data)
+ getTXD(getTXD_header())((getFilenamePath filen)+(getFilenameFile filen))
+ )
+ 0x00000501: ( -- GTF
+ dumpGFT((getFilenamePath filen)+(getFilenameFile filen)+"_tex_001.dds")
+ )
+ )
+)
+
+fn openFilen filen = (
+ global f
+ format "opening file %\n" filen
+ if filen != undefined and doesFileExist filen == true then (
+ try (fclose f) catch(gc())
+ f = fopen filen "rb"
+ if clearScene == true do (delete $*)
+
+ readBinary(filen)
+
+ if debugMsg == true do (format "last read @ 0x%\n" (bit.intAsHex((ftell f) as integer)))
+ fclose f
+ return true
+ ) else (
+ format "failed to open %\n" filen
+ return false
+ )
+)
+
+
+-- code execution starts here, first we clear listener window
+clearlistener()
+
+-- globals below are freely accessible
+if guiEnabled == false then (
+ local filen = ""
+
+ --filenames = stringstream ""
+ --format "D:\\MaxScript\\C1\\AREA_C1_ROAD_MDL_000.GRID\n" to:filenames
+ --for i = 1 to 2 do (
+ -- format "D:\\MaxScript\\C1\\AREA_C1_ROAD_MDL_%%\n" (formattedPrint i format:".3d" as string) ".GRID" to:filenames
+ --)
+ --seek filenames 0
+
+ --for i = 1 to 1 do (
+ -- filen = readLine filenames
+ -- openFilen(filen)
+ --)
+ openFilen("D:\\MaxScript\\C1\\AREA_11GO_BUIL_CUT_11GO_WAN_013.GRID")
+) else (
+ try (destroydialog PS3_WANGANM_IMPORTER) catch()
+ rollout PS3_WANGANM_IMPORTER "Wangan Midnight" (
+ group "Main" (
+ button btn1 "IMPORT" width:65 height:31 align:#center
+ label ls0 "" -- spacer
+ checkbox chk1 "Clear Scene " checked:true align:#center
+ checkbox chk3 "Import Mesh " checked:true align:#center
+ checkbox chk4 "Import Bones " checked:false align:#center
+ checkbox chk2 "Dump Textures" checked:false align:#center
+ checkbox chk5 "Convert to DDS" checked:false align:#center
+ )
+ group "About" (
+ hyperLink lb5 "Author: mariokart64n," address:"mailto:mario_kart64n@hotmail.com"
+ label lb8 " nfm aka fatalhalt" align:#left
+ label lb3 "Date: April 2015" align:#left
+ )
+ on chk1 changed theState do (
+ clearScene = theState
+ )
+ on chk2 changed theState do (
+ dumpTex = theState
+ )
+ on chk3 changed theState do (
+ impMsh = theState
+ )
+ on chk4 changed theState do (
+ impSkl = theState
+ )
+ on chk5 changed theState do (
+ DDSconv = theState
+ )
+ on PS3_WANGANM_IMPORTER open do (
+ chk1.checked = clearScene
+ chk2.checked = dumpTex
+ chk3.checked = impMsh
+ chk4.checked = impSkl
+ chk5.checked = DDSconv
+ )
+ on btn1 pressed do (
+ local filen_ = GetOpenFileName \
+ caption:"Select GRID File" \
+ types: "Wangan Midnight files (*.*)|*.*|"
+
+ if openFilen(filen_) == true do (
+ messagebox "Done!"
+ if debugMsg == true do (print texn)
+ )
+ )
+ )
+ createdialog PS3_WANGANM_IMPORTER
+)