Advertisement
snake5

SGScript - .dff parser

Jun 3rd, 2013
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. global Config =
  2. {
  3.     InputDir = "x_files",
  4.     OutputDir = "x_dff",
  5. };
  6.  
  7. include_library( "fmt" );
  8. include_library( "io" );
  9. include_library( "string" );
  10.  
  11. include_file( "utils.sgs" );
  12. /* utils.sgs part */
  13. function do_nullterm( str )
  14. {
  15.     return string_part( str, 0, string_find( str, "\0" ) );
  16. }
  17. function rw_read_chunk( file )
  18. {
  19.     header = fmt_unpack( "3l", file.read( 12 ) );
  20.     data = "";
  21.     ch = [];
  22.     if( header[0] != 1 && header[0] != 2 && header[0] <= 0xff )
  23.     {
  24.         end = file.offset + header[1];
  25.         while( file.offset < end )
  26.             ch.push( rw_read_chunk( file ) );
  27.     }
  28.     else
  29.     {
  30.         data = file.read( header[1] );
  31.     }
  32.     return { type = header[0], size = header[1], data = data, ch = ch };
  33. }
  34. function rw_parse( path )
  35. {
  36.     file = io_file( path, FILE_READ );
  37.     return rw_read_chunk( file, file.size );
  38. }
  39. /* end */
  40.  
  41. global
  42.     DFF_GEOM_TRISTRIP = 1,
  43.     DFF_GEOM_HASVERTS = 2,
  44.     DFF_GEOM_HASUV = 4,
  45.     DFF_GEOM_HASCOLORS = 8,
  46.     DFF_GEOM_HASNORMALS = 16,
  47.     DFF_GEOM_DYNLIGHTING = 32,
  48.     DFF_GEOM_MULMATCOLOR = 64,
  49.     DFF_GEOM_HASUV2 = 128;
  50.  
  51. function OpenDFFFile( path )
  52. {
  53.     file = rw_parse( path );
  54.    
  55.     frames = [];
  56.     geometry = [];
  57.     foreach( ch : file.ch )
  58.     {
  59.         if( ch.type == 0x0E )
  60.         {
  61.             data = ch.ch[0].data;
  62.             cnt = fmt_unpack( "l", data )[0];
  63.             off = 4;
  64.             for( i = 0; i < cnt; ++i )
  65.             {
  66.                 m_rot = fmt_unpack( "9f", string_part( data, off ) );
  67.                 off += 4 * 9;
  68.                 m_pos = fmt_unpack( "3f", string_part( data, off ) );
  69.                 off += 4 * 3;
  70.                 afd = fmt_unpack( "-ll", string_part( data, off ) );
  71.                 off += 8;
  72.                 F = { rotation = m_rot, position = m_pos, parent = afd[0] };
  73.                 frames.push( F );
  74.             }
  75.         }
  76.         if( ch.type == 0x1A )
  77.         {
  78.             foreach( geom : ch.ch )
  79.             {
  80.                 if( geom.type != 0x0F )
  81.                     continue; // not Geometry
  82.                
  83.                 /*
  84.                     GEOMETRY STRUCT
  85.                 */
  86.                 data = geom.ch[0].data;
  87.                 pgeom = fmt_unpack( "wcclll", data );
  88.                 G = { flags = pgeom[0], numuvcoords = pgeom[1],
  89.                     gnflags = pgeom[2], numtris = pgeom[3], numverts = pgeom[4],
  90.                     numframes = pgeom[5] };
  91.                
  92.                 off = 16;
  93.                
  94.                 if( G.flags & DFF_GEOM_HASCOLORS )
  95.                 {
  96.                     G.colors = fmt_unpack( G.numverts $ "l", string_part( data, off ) );
  97.                     off += G.numverts * 4;
  98.                 }
  99.                 else G.colors = [];
  100.                
  101.                 if( G.flags & DFF_GEOM_HASUV )
  102.                 {
  103.                     G.uv = fmt_unpack( G.numverts * 2 $ "f", string_part( data, off ) );
  104.                     off += G.numverts * 8;
  105.                 }
  106.                 else G.uv = [];
  107.                
  108.                 G.faces = fmt_unpack( G.numtris * 4 $ "w", string_part( data, off ) );
  109.                 off += G.numtris * 8;
  110.                
  111.                 G.boundingsphere = fmt_unpack( "4f", string_part( data, off ) );
  112.                 off += 16;
  113.                
  114.                 G.haspn = fmt_unpack( "2l", string_part( data, off ) );
  115.                 off += 8;
  116.                
  117.                 if( G.haspn[0] )
  118.                 {
  119.                     G.verts = fmt_unpack( G.numverts * 3 $ "f", string_part( data, off ) );
  120.                     off += G.numverts * 12;
  121.                 }
  122.                 else G.verts = [];
  123.                
  124.                 if( G.haspn[1] )
  125.                 {
  126.                     G.normals = fmt_unpack( G.numverts * 3 $ "f", string_part( data, off ) );
  127.                     off += G.numverts * 12;
  128.                 }
  129.                 else G.normals = [];
  130.                
  131.                 /*
  132.                     MATERIALS
  133.                 */
  134.                 G.materials = [];
  135.                
  136.                 foreach( mtl : geom.ch[1].ch )
  137.                 {
  138.                     if( mtl.type != 0x07 )
  139.                         continue; // not Material
  140.                    
  141.                     pmtl = fmt_unpack( "llllfff", mtl.ch[0].data );
  142.                     M = { color = pmtl[1], hastex = pmtl[3],
  143.                         ambient = pmtl[4], specular = pmtl[5], diffuse = pmtl[6] };
  144.                    
  145.                     if( M.hastex )
  146.                     {
  147.                         M.tex_flags = fmt_unpack( "w", mtl.ch[1].ch[0].data )[0];
  148.                         M.tex_diffuse = do_nullterm( mtl.ch[1].ch[1].data );
  149.                         M.tex_alpha = do_nullterm( mtl.ch[1].ch[2].data );
  150.                     }
  151.                    
  152.                     G.materials.push( M );
  153.                 }
  154.                
  155.                 /*
  156.                     "BIN MESH PLG" / SPLITS
  157.                 */
  158.                 G.splits = [];
  159.                 data = geom.ch[2].ch[0].data;
  160.                
  161.                 pspls = fmt_unpack( "lll", data );
  162.                 off = 12;
  163.                
  164.                 G.numindices = pspls[2];
  165.                
  166.                 for( i = 0; i < pspls[1]; ++i )
  167.                 {
  168.                     pspl = fmt_unpack( "ll", string_part( data, off ) );
  169.                     off += 8;
  170.                    
  171.                     S = { material_id = pspl[1] };
  172.                     S.indices = fmt_unpack( pspl[0] $ "l", string_part( data, off ) );
  173.                     off += pspl[0] * 4;
  174.                    
  175.                     G.splits.push( S );
  176.                 }
  177.                
  178.                 geometry.push( G );
  179.             }
  180.         }
  181.     }
  182.    
  183.     data = { frames = frames, geometry = geometry };
  184.    
  185.     io_file_write( "dump.dff.txt", dumpvar( data, 1000 ) );
  186.     printvar( data );
  187.    
  188.     return data;
  189. }
  190.  
  191. OpenDFFFile( "x_files/airportgate.dff" );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement