home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 4988 / tekken.7z / tekken.py next >
Encoding:
Python Source  |  2012-01-15  |  13.7 KB  |  455 lines

  1. import array
  2. import xentax
  3.  
  4. class Vertex3D:
  5.     def __init__(self, vx, vy, vz, nx, ny, nz, tu, tv):
  6.         self.vx = vx;
  7.         self.vy = vy;
  8.         self.vz = vz;
  9.         self.nx = nx;
  10.         self.ny = ny;
  11.         self.nz = nz;
  12.         self.tu = tu;
  13.         self.tv = tv;
  14.         
  15. class SurfaceInfo:
  16.     def __init__(self, ti, si, sl):
  17.         self.textureIndex = ti;
  18.         self.startIndex = si;
  19.         self.stripLength = sl;
  20.  
  21. class TextureInfo:
  22.     def __init__(self, p1, p2, p3, p4):
  23.         self.p1 = p1; # width
  24.         self.p2 = p2; # height
  25.         self.p3 = p3; # size of data
  26.         self.p4 = p4; # offset to data
  27.  
  28. #
  29. # SPECIFY FILENAME WITHOUT EXTENSION
  30. # MODIFY THIS TO LOAD ANOTHER MODEL
  31. #
  32. filename = 'law1u';
  33.  
  34. #
  35. # OPEN CHR FILE
  36. #
  37. ifile = open(filename + '.chr', 'rb');
  38.  
  39. #
  40. # OPEN OBJ FILE
  41. #
  42. ofile = open(filename + '.obj', 'wt');
  43.  
  44. #
  45. # OPEN MTL FILE
  46. #
  47. mfile = open(filename + '.mtl', 'wt');
  48.  
  49. #
  50. # SAVE OBJ HEADER
  51. #
  52. ofile.write('o ' + filename + '.obj\n');
  53. ofile.write('mtllib ' + filename + '.mtl\n');
  54. ofile.write('\n');
  55.  
  56. #
  57. # READ OFFSETS
  58. #
  59. ifile.seek(0x14);
  60. offset1 = xentax.LE_read_uint32(ifile); # vertex buffer offset
  61. offset2 = xentax.LE_read_uint32(ifile); # index buffer offset
  62. offset3 = xentax.LE_read_uint32(ifile); # texture data offset
  63. offset4 = xentax.LE_read_uint32(ifile); # skeleton data offset
  64.  
  65. #
  66. # CALCULATE VERTEX BUFFER PROPERTIES
  67. #
  68. vbuffer_size = offset2 - offset1;
  69. vertices = int(vbuffer_size/0x20);
  70.  
  71. #
  72. # CALCULATE INDEX BUFFER PROPERTIES
  73. #
  74. ibuffer_size = offset3 - offset2;
  75. indices = int(ibuffer_size/0x2);
  76.  
  77. #
  78. # READ SURFACE DATA
  79. #
  80. surface_array = [];
  81. ifile.seek(0x40);
  82. while True:
  83.     type = xentax.LE_read_uint32(ifile);
  84.     if type == 0:
  85.        param02 = xentax.LE_read_uint32(ifile);
  86.        param03 = xentax.LE_read_uint16(ifile);
  87.        param04 = xentax.LE_read_uint16(ifile);
  88.        param05 = xentax.LE_read_float16(ifile);
  89.        param06 = xentax.LE_read_float16(ifile);
  90.        param07 = xentax.LE_read_float16(ifile);
  91.        param08 = xentax.LE_read_float16(ifile);
  92.        param09 = xentax.LE_read_float16(ifile);
  93.        param10 = xentax.LE_read_float16(ifile);
  94.        param11 = xentax.LE_read_float16(ifile);
  95.        param12 = xentax.LE_read_float16(ifile);
  96.     elif type == 1:
  97.        d02 = xentax.LE_read_uint32(ifile);
  98.        d03 = xentax.LE_read_uint32(ifile);
  99.        d04 = xentax.LE_read_uint16(ifile);
  100.        d05 = xentax.LE_read_uint16(ifile);
  101.        d06 = xentax.LE_read_uint32(ifile);
  102.        d07 = xentax.LE_read_uint32(ifile);
  103.        d08 = xentax.LE_read_uint32(ifile);
  104.        d09 = xentax.LE_read_uint32(ifile);
  105.        d10 = xentax.LE_read_uint32(ifile);
  106.        d11 = xentax.LE_read_uint32(ifile);
  107.        d12 = xentax.LE_read_uint32(ifile);
  108.        d13 = xentax.LE_read_uint32(ifile);
  109.        d14 = xentax.LE_read_uint32(ifile);
  110.        d15 = xentax.LE_read_uint32(ifile); 
  111.        surface_array.append(SurfaceInfo(d12, d14, d15));
  112.     elif type == 2:
  113.        u02 = xentax.LE_read_uint32(ifile);
  114.        u03 = xentax.LE_read_uint32(ifile);
  115.        u04 = xentax.LE_read_uint32(ifile);
  116.        u05 = xentax.LE_read_uint32(ifile);
  117.        surface_array.append(SurfaceInfo(u02, u04, u05));
  118.     elif type == 0xFFFFFFFF:
  119.        if ifile.tell() == offset4:
  120.           break;
  121.     else:
  122.        print('UNKNOWN ENTRY TYPE:');
  123.        print(type);
  124.        print(ifile.tell());
  125.        break;
  126.  
  127. #
  128. # MOVE TO VERTEX DATA
  129. #
  130. ifile.seek(offset1);
  131.  
  132. #
  133. # READ VERTEX DATA
  134. #
  135. vbuffer = [];
  136. for i in range(vertices):
  137.  
  138.     # read vertex
  139.     vx = xentax.LE_read_float16(ifile);
  140.     vy = xentax.LE_read_float16(ifile);
  141.     vz = xentax.LE_read_float16(ifile);
  142.     u1 = xentax.LE_read_float16(ifile);
  143.     nx = xentax.LE_read_float16(ifile);
  144.     ny = xentax.LE_read_float16(ifile);
  145.     nz = xentax.LE_read_float16(ifile);
  146.     u2 = xentax.LE_read_float16(ifile);
  147.     tu = xentax.LE_read_float16(ifile);
  148.     tv = 1.0 - xentax.LE_read_float16(ifile);
  149.     u3 = xentax.LE_read_float16(ifile);
  150.     u4 = xentax.LE_read_float16(ifile);
  151.     u5 = xentax.LE_read_float16(ifile);
  152.     u6 = xentax.LE_read_float16(ifile);
  153.     u7 = xentax.LE_read_float16(ifile);
  154.     u8 = xentax.LE_read_float16(ifile);
  155.     
  156.     # save vertex
  157.     vbuffer.append(Vertex3D(vx, vy, vz, nx, ny, nz, tu, tv));
  158.     
  159.     # save vertex
  160.     strlist = []
  161.     strlist.append('v ');
  162.     strlist.append(str(vx));
  163.     strlist.append(' ');
  164.     strlist.append(str(vy));
  165.     strlist.append(' ');
  166.     strlist.append(str(vz));
  167.     strlist.append('\n');
  168.     ofile.write(''.join(strlist));
  169.  
  170.     # save normal
  171.     strlist = []
  172.     strlist.append('vn ');
  173.     strlist.append(str(nx));
  174.     strlist.append(' ');
  175.     strlist.append(str(ny));
  176.     strlist.append(' ');
  177.     strlist.append(str(nz));
  178.     strlist.append('\n');
  179.     ofile.write(''.join(strlist));
  180.  
  181.     # save UV
  182.     strlist = []
  183.     strlist.append('vt ');
  184.     strlist.append(str(tu));
  185.     strlist.append(' ');
  186.     strlist.append(str(tv));
  187.     strlist.append('\n');
  188.     ofile.write(''.join(strlist));
  189.  
  190.     # extra newline
  191.     ofile.write('\n');
  192.  
  193. #
  194. # MOVE TO INDEX DATA
  195. #
  196. ifile.seek(offset2);
  197.     
  198. #
  199. # PROCESS SURFACES
  200. #
  201. for index in range(len(surface_array)):
  202.  
  203.     # save group
  204.     ofile.write('g ' + filename + '_' + str(surface_array[index].textureIndex) + '\n');
  205.     ofile.write('usemtl ' + filename + '_' + str(surface_array[index].textureIndex) + '\n');
  206.  
  207.     # read first triangle in triangle strip
  208.     a = xentax.LE_read_uint16(ifile) + 1;
  209.     b = xentax.LE_read_uint16(ifile) + 1;
  210.     c = xentax.LE_read_uint16(ifile) + 1;
  211.  
  212.     # vertex and normals
  213.     v1 = [ vbuffer[a - 1].vx, vbuffer[a - 1].vy, vbuffer[a - 1].vz ];
  214.     v2 = [ vbuffer[b - 1].vx, vbuffer[b - 1].vy, vbuffer[b - 1].vz ];
  215.     v3 = [ vbuffer[c - 1].vx, vbuffer[c - 1].vy, vbuffer[c - 1].vz ];
  216.     n1 = [ vbuffer[a - 1].nx, vbuffer[a - 1].ny, vbuffer[a - 1].nz ];
  217.     n2 = [ vbuffer[b - 1].nx, vbuffer[b - 1].ny, vbuffer[b - 1].nz ];
  218.     n3 = [ vbuffer[c - 1].nx, vbuffer[c - 1].ny, vbuffer[c - 1].nz ];
  219.      
  220.     # save points to OBJ file
  221.     if xentax.is_face_flipped(v1, v2, v3, n1, n2, n3) == False:
  222.        strlist = []
  223.        strlist.append('f ');
  224.        strlist.append(str(a));
  225.        strlist.append('/');
  226.        strlist.append(str(a));
  227.        strlist.append('/');
  228.        strlist.append(str(a));
  229.        strlist.append(' ');
  230.        strlist.append(str(b));
  231.        strlist.append('/');
  232.        strlist.append(str(b));
  233.        strlist.append('/');
  234.        strlist.append(str(b));
  235.        strlist.append(' ');
  236.        strlist.append(str(c));
  237.        strlist.append('/');
  238.        strlist.append(str(c));
  239.        strlist.append('/');
  240.        strlist.append(str(c));
  241.        strlist.append(' ');
  242.        strlist.append('\n');
  243.        ofile.write(''.join(strlist));
  244.     else:
  245.        strlist = []
  246.        strlist.append('f ');
  247.        strlist.append(str(a));
  248.        strlist.append('/');
  249.        strlist.append(str(a));
  250.        strlist.append('/');
  251.        strlist.append(str(a));
  252.        strlist.append(' ');
  253.        strlist.append(str(c));
  254.        strlist.append('/');
  255.        strlist.append(str(c));
  256.        strlist.append('/');
  257.        strlist.append(str(c));
  258.        strlist.append(' ');
  259.        strlist.append(str(b));
  260.        strlist.append('/');
  261.        strlist.append(str(b));
  262.        strlist.append('/');
  263.        strlist.append(str(b));
  264.        strlist.append(' ');
  265.        strlist.append('\n');
  266.        ofile.write(''.join(strlist));
  267.  
  268.     for i in range(3, surface_array[index].stripLength):
  269.  
  270.         # read one more point
  271.         a = b;
  272.         b = c;
  273.         c = xentax.LE_read_uint16(ifile) + 1;
  274.     
  275.         # do not output degenerate triangles
  276.         if a == b or a == c or b == c:
  277.            continue;
  278.  
  279.         # save triangles to OBJ file
  280.         if ((i % 2) == 0):
  281.  
  282.            # vertex and normals
  283.            v1 = [ vbuffer[a - 1].vx, vbuffer[a - 1].vy, vbuffer[a - 1].vz ];
  284.            v2 = [ vbuffer[b - 1].vx, vbuffer[b - 1].vy, vbuffer[b - 1].vz ];
  285.            v3 = [ vbuffer[c - 1].vx, vbuffer[c - 1].vy, vbuffer[c - 1].vz ];
  286.            n1 = [ vbuffer[a - 1].nx, vbuffer[a - 1].ny, vbuffer[a - 1].nz ];
  287.            n2 = [ vbuffer[b - 1].nx, vbuffer[b - 1].ny, vbuffer[b - 1].nz ];
  288.            n3 = [ vbuffer[c - 1].nx, vbuffer[c - 1].ny, vbuffer[c - 1].nz ];
  289.  
  290.            # save points to OBJ file
  291.            if xentax.is_face_flipped(v1, v2, v3, n1, n2, n3) == False:
  292.               strlist = []
  293.               strlist.append('f ');
  294.               strlist.append(str(a));
  295.               strlist.append('/');
  296.               strlist.append(str(a));
  297.               strlist.append('/');
  298.               strlist.append(str(a));
  299.               strlist.append(' ');
  300.               strlist.append(str(b));
  301.               strlist.append('/');
  302.               strlist.append(str(b));
  303.               strlist.append('/');
  304.               strlist.append(str(b));
  305.               strlist.append(' ');
  306.               strlist.append(str(c));
  307.               strlist.append('/');
  308.               strlist.append(str(c));
  309.               strlist.append('/');
  310.               strlist.append(str(c));
  311.               strlist.append(' ');
  312.               strlist.append('\n');
  313.               ofile.write(''.join(strlist));
  314.            else:
  315.               strlist = []
  316.               strlist.append('f ');
  317.               strlist.append(str(a));
  318.               strlist.append('/');
  319.               strlist.append(str(a));
  320.               strlist.append('/');
  321.               strlist.append(str(a));
  322.               strlist.append(' ');
  323.               strlist.append(str(c));
  324.               strlist.append('/');
  325.               strlist.append(str(c));
  326.               strlist.append('/');
  327.               strlist.append(str(c));
  328.               strlist.append(' ');
  329.               strlist.append(str(b));
  330.               strlist.append('/');
  331.               strlist.append(str(b));
  332.               strlist.append('/');
  333.               strlist.append(str(b));
  334.               strlist.append(' ');
  335.               strlist.append('\n');
  336.               ofile.write(''.join(strlist));
  337.               
  338.         else:
  339.         
  340.            # vertex and normals
  341.            v1 = [ vbuffer[a - 1].vx, vbuffer[a - 1].vy, vbuffer[a - 1].vz ];
  342.            v2 = [ vbuffer[c - 1].vx, vbuffer[c - 1].vy, vbuffer[c - 1].vz ];
  343.            v3 = [ vbuffer[b - 1].vx, vbuffer[b - 1].vy, vbuffer[b - 1].vz ];
  344.            n1 = [ vbuffer[a - 1].nx, vbuffer[a - 1].ny, vbuffer[a - 1].nz ];
  345.            n2 = [ vbuffer[c - 1].nx, vbuffer[c - 1].ny, vbuffer[c - 1].nz ];
  346.            n3 = [ vbuffer[b - 1].nx, vbuffer[b - 1].ny, vbuffer[b - 1].nz ];
  347.  
  348.            # save points to OBJ file
  349.            if xentax.is_face_flipped(v1, v2, v3, n1, n2, n3) == False:
  350.               strlist = []
  351.               strlist.append('f ');
  352.               strlist.append(str(a));
  353.               strlist.append('/');
  354.               strlist.append(str(a));
  355.               strlist.append('/');
  356.               strlist.append(str(a));
  357.               strlist.append(' ');
  358.               strlist.append(str(c));
  359.               strlist.append('/');
  360.               strlist.append(str(c));
  361.               strlist.append('/');
  362.               strlist.append(str(c));
  363.               strlist.append(' ');
  364.               strlist.append(str(b));
  365.               strlist.append('/');
  366.               strlist.append(str(b));
  367.               strlist.append('/');
  368.               strlist.append(str(b));
  369.               strlist.append(' ');
  370.               strlist.append('\n');
  371.               ofile.write(''.join(strlist));
  372.            else:
  373.               strlist = []
  374.               strlist.append('f ');
  375.               strlist.append(str(a));
  376.               strlist.append('/');
  377.               strlist.append(str(a));
  378.               strlist.append('/');
  379.               strlist.append(str(a));
  380.               strlist.append(' ');
  381.               strlist.append(str(b));
  382.               strlist.append('/');
  383.               strlist.append(str(b));
  384.               strlist.append('/');
  385.               strlist.append(str(b));
  386.               strlist.append(' ');
  387.               strlist.append(str(c));
  388.               strlist.append('/');
  389.               strlist.append(str(c));
  390.               strlist.append('/');
  391.               strlist.append(str(c));
  392.               strlist.append(' ');
  393.               strlist.append('\n');
  394.               ofile.write(''.join(strlist));
  395.  
  396.     # separate groups
  397.     ofile.write('\n');
  398.  
  399. #
  400. # READ NUMBER OF TEXTURES
  401. #
  402. ifile.seek(0x2C);
  403. n_textures = xentax.LE_read_uint32(ifile);
  404.  
  405. #
  406. # MOVE TO TEXTURE DATA
  407. #
  408. ifile.seek(offset3);
  409.  
  410. #
  411. # READ TEXTURE INFORMATION
  412. #
  413. texture_info = [];
  414. for i in range(n_textures):
  415.     p1 = xentax.LE_read_uint32(ifile);
  416.     p2 = xentax.LE_read_uint32(ifile);
  417.     p3 = xentax.LE_read_uint32(ifile);
  418.     p4 = xentax.LE_read_uint32(ifile);
  419.     texture_info.append(TextureInfo(p1, p2, p3, p4));
  420.  
  421. #
  422. # READ TEXTURES
  423. #
  424. for i in range(n_textures):
  425.     # move to texture offset
  426.     ifile.seek(texture_info[i].p4);
  427.     # read texture data
  428.     data = array.array('B');
  429.     data.fromfile(ifile, texture_info[i].p3);
  430.     # save data
  431.     tfile = open(filename + '_' + str(i) + '.dds', 'wb');
  432.     xentax.WriteUncompressedDDSHeader(tfile, texture_info[i].p1, texture_info[i].p2, False, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
  433.     data.tofile(tfile);
  434.     tfile.close();
  435.  
  436. #
  437. # SAVE MATERIAL DATA
  438. #
  439. for i in range(n_textures):
  440.      mfile.write('newmtl ' + filename + '_' + str(i) + '\n');
  441.      mfile.write('Ka 0 0 0' + '\n');
  442.      mfile.write('Kd 0.784314 0.784314 0.784314' + '\n');
  443.      mfile.write('Ks 0 0 0' + '\n');
  444.      mfile.write('Ni 1' + '\n');
  445.      mfile.write('Ns 400' + '\n');
  446.      mfile.write('Tf 1 1 1' + '\n');
  447.      mfile.write('d 1' + '\n');
  448.      mfile.write('map_Kd ' + filename + '_' + str(i) + '.dds' + '\n');
  449.      mfile.write('\n');
  450.  
  451. #
  452. # CLOSE FILE
  453. #
  454. ofile.close();
  455. ifile.close();