-- RMT (RandomMeshthings) 3d fileformat importer v. 0.7 Alpha -- Author: Lauri Mäki - http://random.gfxile.net -- website: http://random.gfxile.net/RMT/ -- free for any use - tellware - tell me if you use. -- TODO: -- missing triangle strips -- missing vertex colors macroscript RMTimporter category:"RNDtools" buttontext:"RMT_Importer" tooltip:"RMT_Importer" ( debugfile = createfile "r:\debug.txt" struct RMTchunk (Version,RealsAsFloats,MeshCount) struct MESHchunk (Name,InitPos,VertexCount,Ibuffertype,UVcount) struct VERTEXchunk (Scale,Accuracy,VertexData) struct NORMALchunk (Accuracy,NormalData) struct UVchunk (ID,UVW,Scale,Accuracy,UVdata) struct INDEXchunk (ID,MatID,Indexcount,IndexData) struct VCOLchunk (Accuracy,VCOLdata) struct MATERIALchunk (ID,Shading,Blending,Opacity,PerspCorr,Texturemap,Reflectionmap,Lightmap,Glossymap,Normalmap,Shader) struct BITMAPchunk (ID,filename) fn RstringWlength xfile slength = ( tempstringe = "" for c=1 to slength do ( intchar = readbyte xfile #unsigned append tempstringe (bit.intaschar intchar) ) tempstringe ) fn GiveChunks xfile = ( ChunkPile = #() ChunkPile[2] = #() chunkpile[3] = #() chunkpile[4] = #() chunkpile[5] = #() -- get eof position fseek xfile 0 #seek_end endfile = ftell xfile --debug print endfile to:debugfile -- back to start fseek xfile 0 #seek_set currentmesh = 0 -- and read chunks while (ftell xfile)!=endfile do ( chunktype = readshort xfile #unsigned chunksize = readlong xfile #unsigned case chunktype of ( 23248: ( -- RMT-chunk ChunkPile[1] local tempchunk = RMTchunk 0 0 0 tempchunk.Version = readbyte xfile #unsigned tempchunk.RealsAsFloats = readbyte xfile #unsigned tempchunk.MeshCount = readshort xfile #unsigned for m=1 to tempchunk.meshcount do ( ChunkPile[2][m] = #() ) ChunkPile[1] = tempchunk ) 4096: ( -- MESH-chunk ChunkPile[2][currentmesh][1] currentmesh+=1 local tempchunk = MESHchunk 0 0 0 0 0 namelength = readbyte xfile #unsigned tempchunk.name = RstringWlength xfile namelength if ChunkPile[1].RealsAsFloats==1 then ( tempchunk.initpos = point3 (readfloat xfile) (readfloat xfile) (readfloat xfile) ) else ( tempchunk.initpos = point3 (readlong xfile #signed) (readlong xfile #signed) (readlong xfile #signed) ) tempchunk.Vertexcount = readlong xfile #signed tempchunk.Ibuffertype = readbyte xfile #unsigned tempchunk.UVcount = readbyte xfile #unsigned ChunkPile[2][currentmesh][1] = tempchunk ) 4352: ( -- VERTEXBUFFER-chunk ChunkPile[2][currentmesh][2] local tempchunk = VERTEXchunk 0 0 0 if ChunkPile[1].RealsAsFloats==1 then ( tempchunk.scale = point3 (readfloat xfile) (readfloat xfile) (readfloat xfile) ) else ( tempchunk.scale = point3 (readlong xfile #signed) (readlong xfile #signed) (readlong xfile #signed) ) tempchunk.accuracy = readbyte xfile #unsigned temparray = #() for v=1 to ChunkPile[2][currentmesh][1].vertexcount do ( case tempchunk.accuracy of ( 1: ( --int8 temparray[v] = point3 (readbyte xfile #signed) (readbyte xfile #signed) (readbyte xfile #signed) ) 2: ( --int16 temparray[v] = point3 (readshort xfile #signed) (readshort xfile #signed) (readshort xfile #signed) ) 3: ( --real32 if chunkpile[1].realsasfloats==1 then ( temparray[v] = point3 (readfloat xfile) (readfloat xfile) (readfloat xfile) ) else ( temparray[v] = point3 (readlong xfile #signed) (readlong xfile #signed) (readlong xfile #signed) ) ) ) ) tempchunk.vertexdata = temparray ChunkPile[2][currentmesh][2] = tempchunk ) 4608: ( -- NORMALBUFFER-chunk ChunkPile[2][currentmesh][3] local tempchunk = NORMALchunk 0 0 tempchunk.accuracy = readbyte xfile #unsigned temparray=#() for v=1 to ChunkPile[2][currentmesh][1].vertexcount do ( case tempchunk.accuracy of ( 1: ( --int8 temparray[v] = point3 (readbyte xfile #signed) (readbyte xfile #signed) (readbyte xfile #signed) ) 2: ( --int16 temparray[v] = point3 (readshort xfile #signed) (readshort xfile #signed) (readshort xfile #signed) ) 3: ( --real32 if chunkpile[1].realsasfloats==1 then ( temparray[v] = point3 (readfloat xfile) (readfloat xfile) (readfloat xfile) ) else ( temparray[v] = point3 (readlong xfile #signed) (readlong xfile #unsigned) (readlong xfile #unsigned) ) ) ) ) tempchunk.normaldata = temparray ChunkPile[2][currentmesh][3] = tempchunk ) 4864: ( -- UVBUFFER-chunk ChunkPile[2][currentmesh][4] local tempchunk = UVchunk 0 0 0 0 0 tempchunk.ID = readbyte xfile #unsigned tempchunk.UVW = readbyte xfile #unsigned tempchunk.scale = readbyte xfile #unsigned tempchunk.accuracy = readbyte xfile #unsigned temparray=#() if tempchunk.uvw==1 then ( for v=1 to ChunkPile[2][currentmesh][1].vertexcount do ( case tempchunk.accuracy of ( 1: ( --int8 temparray[v] = point3 (readbyte xfile #signed) (readbyte xfile #signed) (readbyte xfile #signed) ) 2: ( --int16 temparray[v] = point3 (readshort xfile #signed) (readshort xfile #signed) (readshort xfile #signed) ) 3: ( --real32 if chunkpile[1].realsasfloats==1 then ( temparray[v] = point3 (readfloat xfile) (readfloat xfile) (readfloat xfile) ) else ( temparray[v] = point3 (readlong xfile #signed) (readlong xfile #unsigned) (readlong xfile #unsigned) ) ) ) ) ) else ( for v=1 to ChunkPile[2][currentmesh][1].vertexcount do ( case tempchunk.accuracy of ( 1: ( --int8 temparray[v] = point2 (readbyte xfile #signed) (readbyte xfile #signed) ) 2: ( --int16 temparray[v] = point2 (readshort xfile #signed) (readshort xfile #signed) ) 3: ( --real32 if chunkpile[1].realsasfloats==1 then ( temparray[v] = point2 (readfloat xfile) (readfloat xfile) ) else ( temparray[v] = point2 (readlong xfile #signed) (readlong xfile #unsigned) ) ) ) ) ) tempchunk.uvdata = temparray if chunkpile[2][currentmesh][4]==undefined do chunkpile[2][currentmesh][4] = #() append chunkpile[2][currentmesh][4] tempchunk ) 5120: ( -- INDEXBUFFER-chunk ChunkPile[2][currentmesh][5] local tempchunk = INDEXchunk 0 0 0 0 tempchunk.ID = readshort xfile #unsigned tempchunk.MatID = readbyte xfile #unsigned tempchunk.Indexcount = readlong xfile #unsigned temparray = #() case of ( (ChunkPile[2][currentmesh][1].vertexcount<257): ( for i=1 to (tempchunk.indexcount/3) do ( temparray[i] = point3 (readbyte xfile #unsigned) (readbyte xfile #unsigned) (readbyte xfile #unsigned) ) ) (ChunkPile[2][currentmesh][1].vertexcount>256 AND ChunkPile[2][currentmesh][1].vertexcount<65536): ( for i=1 to (tempchunk.indexcount/3) do ( temparray[i] = point3 (readshort xfile #unsigned) (readshort xfile #unsigned) (readshort xfile #unsigned) ) ) (ChunkPile[2][currentmesh][1].vertexcount>65535): ( for i=1 to (tempchunk.indexcount/3) do ( temparray[i] = point3 (readlong xfile #signed) (readlong xfile #signed) (readlong xfile #signed) ) ) ) tempchunk.Indexdata = temparray if chunkpile[2][currentmesh][5] == undefined do chunkpile[2][currentmesh][5] = #() append ChunkPile[2][currentmesh][5] tempchunk ) 5376: ( -- VCOLBUFFER-chunk ChunkPile[2][currentmesh][6] local tempchunk = VCOLchunk 0 0 tempchunk.accuracy = readbyte xfile #unsigned temparray=#() case tempchunk.accuracy of ( 1: ( for v=1 to chunkpile[2][currentmesh][1].vertexcount do ( temparray[v] = readbyte xfile #unsigned ) ) 2: ( for v=1 to chunkpile[2][currentmesh][1].vertexcount do ( temparray[v] = readshort xfile #unsigned ) ) 3: ( for v=1 to chunkpile[2][currentmesh][1].vertexcount do ( temparray[v] = color (readbyte xfile #unsigned) (readbyte xfile #unsigned) (readbyte xfile #unsigned) (readbyte xfile #unsigned) ) ) 4: ( if chunkpile[1].realsasfloats==1 then ( for v=1 to chunkpile[2][currentmesh][1].vertexcount do ( temparray[v] = color (readfloat xfile) (readfloat xfile) (readfloat xfile) (readfloat xfile) ) ) else ( for v=1 to chunkpile[2][currentmesh][1].vertexcount do ( temparray[v] = color (readlong xfile #unsigned) (readlong xfile #unsigned) (readlong xfile #unsigned) (readlong xfile #unsigned) ) ) ) ) tempchunk.vcoldata = temparray ChunkPile[2][currentmesh][6] = tempchunk ) 8192: ( -- MATERIAL-chunk ChunkPile[3] local tempchunk = MATERIALchunk 0 0 0 0 0 0 0 0 0 0 0 tempchunk.ID = readbyte xfile #unsigned tempchunk.shading = readbyte xfile #unsigned tempchunk.blending = readbyte xfile #unsigned tempchunk.Opacity = readbyte xfile #unsigned tempchunk.PerspCorr = readbyte xfile #unsigned tempchunk.Texturemap = readbyte xfile #unsigned tempchunk.Reflectionmap = readbyte xfile #unsigned tempchunk.Lightmap = readbyte xfile #unsigned tempchunk.Glossymap = readbyte xfile #unsigned tempchunk.Normalmap = readbyte xfile #unsigned tempchunk.Shader = readbyte xfile #unsigned append ChunkPile[3] tempchunk ) 8448: ( -- BITMAPINFO-chunk ChunkPile[4] local tempchunk = BITMAPchunk 0 0 tempchunk.ID = readbyte xfile #unsigned filenamelength = readbyte xfile #unsigned tempchunk.filename = RstringWlength xfile filenamelength append ChunkPile[4] tempchunk ) 8704: ( -- SHADERINFO-chunk ChunkPile[5] local tempchunk = BITMAPchunk 0 0 tempchunk.ID = readbyte xfile #unsigned filenamelength = readbyte xfile #unsigned tempchunk.filename = RstringWlength xfile filenamelength append ChunkPile[5] tempchunk ) ) ) ChunkPile ) fn gettexture ID ch = ( for tex=1 to ch[4].count do ( if ch[4][tex].ID==ID do return ch[4][tex].filename ) return undefined ) fn getshader ID ch = ( for tex=1 to ch[5].count do ( if ch[5][tex].ID==ID do return ch[5][tex].filename ) return undefined ) fn ProcessChunks Ch = ( print ch meshdatarray = #() meshdatarray[1] = #() meshdatarray[2] = #() -- creating materials for mat=1 to ch[3].count do ( tempmaterial = standard() tempmaterial.name = (ch[3][mat].ID as string) case ch[3][mat].shading of ( 1: ( tempmaterial.selfillumamount=100.0 ) 2: ( tempmaterial.faceted==true ) ) case ch[3][mat].blending of ( 2: ( tempmaterial.opacitytype=0 ) 3: ( tempmaterial.opacitytype=2 ) 4: ( tempmaterial.opacitytype=1 ) ) tempmaterial.opacity = ((ch[3][mat].opacity/255)*100) persp=true case ch[3][mat].perspcorr of ( 0: ( persp=false ) 1: ( persp=true ) ) tempmaterial.facemap = persp tempmaterial.diffusemap = gettexture ch[3][mat].texturemap Ch tempmaterial.reflectionmap = gettexture ch[3][mat].reflectionmap Ch tempmaterial.selfillummap = gettexture ch[3][mat].lightmap Ch tempmaterial.glossinessmap = gettexture ch[3][mat].glossymap Ch tempmaterial.bumpmap = gettexture ch[3][mat].normalmap Ch tempmaterial.filtermap = getshader ch[3][mat].shader Ch append meshdatarray[1] tempmaterial ) losmaterialos = multimaterial numsubs:meshdatarray[1].count -- creating material array for mat=1 to meshdatarray[1].count do ( losmaterialos[mat] = meshdatarray[1][mat] ) -- creating meshes for mesh=1 to ch[1].meshcount do ( newmesh = editable_mesh() newmesh.name = ch[2][mesh][1].name newmesh.pos = point3 ch[2][mesh][1].initpos.x ch[2][mesh][1].initpos.z ch[2][mesh][1].initpos.y newmesh.material = losmaterialos vertarray = #() tempvert = point3 0 0 0 case ch[2][mesh][2].accuracy of ( 1: ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert = point3 0 0 0 tempvert.x = ((ch[2][mesh][2].vertexdata[v].x/127)*ch[2][mesh][2].scale.x) tempvert.z = ((ch[2][mesh][2].vertexdata[v].y/127)*ch[2][mesh][2].scale.y) -- flip happens tempvert.y = ((ch[2][mesh][2].vertexdata[v].z/127)*ch[2][mesh][2].scale.z) append vertarray tempvert ) ) 2: ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert = point3 0 0 0 tempvert.x = ((ch[2][mesh][2].vertexdata[v].x/32767)*ch[2][mesh][2].scale.x) tempvert.z = ((ch[2][mesh][2].vertexdata[v].y/32767)*ch[2][mesh][2].scale.y) -- flip happens tempvert.y = ((ch[2][mesh][2].vertexdata[v].z/32767)*ch[2][mesh][2].scale.z) append vertarray tempvert ) ) 3: ( if ch[1].realsasfloats == 1 then ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert = point3 0 0 0 tempvert.x = ch[2][mesh][2].vertexdata[v].x tempvert.z = ch[2][mesh][2].vertexdata[v].y -- flip happens tempvert.y = ch[2][mesh][2].vertexdata[v].z append vertarray tempvert ) ) else ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert = point3 0 0 0 tempvert.x = ((ch[2][mesh][2].vertexdata[v].x/2147483647)*ch[2][mesh][2].scale.x) tempvert.z = ((ch[2][mesh][2].vertexdata[v].y/2147483647)*ch[2][mesh][2].scale.y) -- flip happens tempvert.y = ((ch[2][mesh][2].vertexdata[v].z/2147483647)*ch[2][mesh][2].scale.z) append vertarray tempvert ) ) ) )-- end of case indexarray = #() matidarray = #() -- combining indexbuffers for ib=1 to ch[2][mesh][5].count do ( indexarray=join indexarray ch[2][mesh][5][ib].indexdata for i=1 to (ch[2][mesh][5][ib].indexcount/3) do ( append matidarray ch[2][mesh][5][ib].matid -- spawns wrong id's as those are constructed from pieces.!!!! ) ) -- creating the current mesh print vertarray setmesh newmesh vertices:vertarray faces:indexarray materialIDs:matidarray update newmesh -- processing uv data uvarray= #() for uv=1 to ch[2][mesh][4].count do ( uvarray[uv]=#() if ch[2][mesh][4][uv].uvw==1 then ( tempvert = point3 0 0 0 case ch[2][mesh][4][uv].accuracy of ( 1: ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = (ch[2][mesh][4][uv].uvdata[v].x/127)*ch[2][mesh][4][uv].scale tempvert.y = (ch[2][mesh][4][uv].uvdata[v].y/127)*ch[2][mesh][4][uv].scale tempvert.z = (ch[2][mesh][4][uv].uvdata[v].z/127)*ch[2][mesh][4][uv].scale append uvarray[uv] tempvert ) ) 2: ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = (ch[2][mesh][4][uv].uvdata[v].x/32767)*ch[2][mesh][4][uv].scale tempvert.y = (ch[2][mesh][4][uv].uvdata[v].y/32767)*ch[2][mesh][4][uv].scale tempvert.z = (ch[2][mesh][4][uv].uvdata[v].z/32767)*ch[2][mesh][4][uv].scale append uvarray[uv] tempvert ) ) 3: ( if ch[1].realsasfloats == 1 then ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = ch[2][mesh][4][uv].uvdata[v].x tempvert.y = ch[2][mesh][4][uv].uvdata[v].y tempvert.z = ch[2][mesh][4][uv].uvdata[v].z append uvarray[uv] tempvert ) ) else ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = (ch[2][mesh][4][uv].uvdata[v].x/2147483647)*ch[2][mesh][4][uv].scale tempvert.y = (ch[2][mesh][4][uv].uvdata[v].y/2147483647)*ch[2][mesh][4][uv].scale tempvert.z = (ch[2][mesh][4][uv].uvdata[v].z/2147483647)*ch[2][mesh][4][uv].scale append uvarray[uv] tempvert ) ) ) ) ) else ( tempvert = point3 0 0 0 case ch[2][mesh][4][uv].accuracy of ( 1: ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = (ch[2][mesh][4][uv].uvdata[v].x/127)*ch[2][mesh][4][uv].scale tempvert.y = (ch[2][mesh][4][uv].uvdata[v].y/127)*ch[2][mesh][4][uv].scale append uvarray[uv] tempvert ) ) 2: ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = (ch[2][mesh][4][uv].uvdata[v].x/32767)*ch[2][mesh][4][uv].scale tempvert.y = (ch[2][mesh][4][uv].uvdata[v].y/32767)*ch[2][mesh][4][uv].scale append uvarray[uv] tempvert ) ) 3: ( if ch[1].realsasfloats == 1 then ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = ch[2][mesh][4][uv].uvdata[v].x tempvert.y = ch[2][mesh][4][uv].uvdata[v].y append uvarray[uv] tempvert ) ) else ( for v=1 to ch[2][mesh][1].vertexcount do ( tempvert.x = (ch[2][mesh][4][uv].uvdata[v].x/2147483647)*ch[2][mesh][4][uv].scale tempvert.y = (ch[2][mesh][4][uv].uvdata[v].y/2147483647)*ch[2][mesh][4][uv].scale append uvarray[uv] tempvert ) ) ) )-- end of if-else ) -- end of uv-loop -- setting uv-channels and data for the mesh meshop.setnummaps newmesh uvarray.count keep:false for uv=1 to uvarray.count do ( meshop.setmapsupport newmesh uv true meshop.setnummapverts newmesh uv uvarray[uv].count keep:false for v=1 to uvarray[uv].count do ( meshop.setMapVert newmesh uv v uvarray[uv][v] ) meshop.buildMapFaces newmesh uv keep:false ) meshop.setmapsupport newmesh 0 true meshop.setmapsupport newmesh -2 true if ch[2][mesh][6].vcoldata!=undefined do ( for v=1 to Ch[2][mesh][6].vcoldata.count do ( meshop.setmapvert newmesh 0 v (point3 0 0 0) -- LOS PLACEHOLEROS! meshop.setmapvert newmesh -2 v (point3 0 0 0) ) ) ) append meshdatarray[2] newmesh ) -- end of mesh-loop meshdatarray ) -- struct VCOLchunk (Accuracy,VCOLdata) -- open file rmtfilename = getopenfilename caption:"import RMT file" types:"RandomMeshThings(*.rmt)|*.rmt" if rmtfilename!=undefined then ( rmtfile = fopen rmtfilename "rb" ) else ( return 0 ) -- read chunks ChunkList = #() Chunkpile = GiveChunks rmtfile Meshdata = ProcessChunks Chunkpile select meshdata[2] )