home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5036 / source.7z / main.cpp next >
Encoding:
C/C++ Source or Header  |  2012-02-05  |  19.5 KB  |  631 lines

  1. #include "xentax.h"
  2. #include "stdres.h"
  3. #include "ps3_gundam_crossfire.h"
  4. #include "xb360_onechanbara2.h"
  5.  
  6. INT_PTR CALLBACK RipperProc(HWND dialog, UINT message, WPARAM wparam, LPARAM lparam);
  7. bool is_face_flipped(const float* v1, const float* v2, const float* v3, const float* n1, const float* n2, const float* n3);
  8.  
  9. bool Test(void)
  10. {
  11.  ifstream ifile("anna1u.chr", ios::binary);
  12.  if(!ifile) return false;
  13.  
  14.  ifile.seekg(0x14);
  15.  uint32 vbuffer_offset = LE_read_uint32(ifile);
  16.  uint32 ibuffer_offset = LE_read_uint32(ifile);
  17.  uint32 tbuffer_offset = LE_read_uint32(ifile);
  18.  
  19.  // calculate vertex buffer properties
  20.  uint32 vbuffer_size = ibuffer_offset - vbuffer_offset;
  21.  uint32 vertices = vbuffer_size/32;
  22.  cout << "size of vertex buffer in bytes = " << vbuffer_size << endl;
  23.  cout << "number of vertices = " << vertices << endl;
  24.  cout << endl;
  25.  
  26.  // calculate index buffer properties
  27.  uint32 ibuffer_size = tbuffer_offset - ibuffer_offset;
  28.  uint32 indices = ibuffer_size/2;
  29.  cout << "size of index buffer in bytes = " << ibuffer_size << endl;
  30.  cout << "number of indices = " << indices << endl;
  31.  cout << endl;
  32.  
  33.  // read number of textures
  34.  ifile.seekg(0x2C);
  35.  uint32 n_textures = LE_read_uint32(ifile);
  36.  cout << "number of textures = " << n_textures << endl;
  37.  
  38.  // surface data
  39.  deque<size_t> stripsizes;
  40.  deque<size_t> stripimage;
  41.  deque<bool> stripeffect;
  42.  
  43.  // read surfaces
  44.  uint32 curr_surface = 0;
  45.  ifile.seekg(0x40);
  46.  for(;;)
  47.     {
  48.      uint32 temp1 = LE_read_uint32(ifile);
  49.      if(temp1 == 0)
  50.        {
  51.         uint32 h01 = temp1;
  52.         uint32 h02 = LE_read_uint32(ifile);
  53.         uint32 h03 = LE_read_uint16(ifile);
  54.         uint32 h04 = LE_read_uint16(ifile);
  55.         cout << "h01 = " << h01 << endl;
  56.         cout << "h02 = " << h02 << endl;
  57.         cout << "h03 = " << h03 << endl;
  58.         cout << "h04 = " << h04 << endl;
  59.  
  60.         // read a bunch of half-floats
  61.         LE_read_float16(ifile);
  62.         LE_read_float16(ifile);
  63.         LE_read_float16(ifile);
  64.         LE_read_float16(ifile);
  65.         LE_read_float16(ifile);
  66.         LE_read_float16(ifile);
  67.         LE_read_float16(ifile);
  68.         LE_read_float16(ifile);
  69.        }
  70.      else if(temp1 == 1)
  71.        {
  72.         cout << "surface " << curr_surface++ << endl;
  73.         uint32 param01 = LE_read_uint32(ifile);
  74.         uint32 param02 = LE_read_uint32(ifile);
  75.         uint16 param03 = LE_read_uint16(ifile); // usually 68
  76.         uint16 param04 = LE_read_uint16(ifile);
  77.         uint32 param05 = LE_read_uint32(ifile);
  78.         uint32 param06 = LE_read_uint32(ifile);
  79.         uint32 param07 = LE_read_uint32(ifile);
  80.         uint32 param08 = LE_read_uint32(ifile);
  81.         uint32 param09 = LE_read_uint32(ifile);
  82.         uint32 param10 = LE_read_uint32(ifile);
  83.         uint32 param11 = LE_read_uint32(ifile); // texture
  84.         uint32 param12 = LE_read_uint32(ifile);
  85.         uint32 param13 = LE_read_uint32(ifile);
  86.         uint32 param14 = LE_read_uint32(ifile); // number of indices to use
  87.         stripeffect.push_back((param05 == 3));
  88.         stripimage.push_back(param11);
  89.         stripsizes.push_back(param14);
  90.  
  91.         cout << param01 << endl;
  92.         cout << param02 << endl;
  93.         cout << param03 << endl; // usually 68
  94.         cout << param04 << endl;
  95.         cout << param05 << endl;
  96.         cout << param06 << endl;
  97.         cout << param07 << endl;
  98.         cout << param08 << endl;
  99.         cout << param09 << endl;
  100.         cout << param10 << endl;
  101.         cout << param11 << endl;
  102.         cout << param12 << endl;
  103.         cout << param13 << endl;
  104.         cout << param14 << endl;
  105.         cout << endl;
  106.        }
  107.      else if(temp1 == 2)
  108.        {
  109.         cout << "surface " << curr_surface++ << endl;
  110.         uint32 param01 = LE_read_uint32(ifile); // texture
  111.         uint32 param02 = LE_read_uint32(ifile);
  112.         uint32 param03 = LE_read_uint32(ifile);
  113.         uint32 param04 = LE_read_uint32(ifile);
  114.         stripeffect.push_back(false);
  115.         stripimage.push_back(param01);
  116.         stripsizes.push_back(param04);
  117.  
  118.         cout << param01 << endl;
  119.         cout << param02 << endl;
  120.         cout << param03 << endl; // usually 68
  121.         cout << param04 << endl;
  122.         cout << endl;
  123.        }
  124.      else if(temp1 == 0xFFFFFFFF)
  125.        {
  126.         // marks last surface?
  127.        }
  128.      else
  129.         break;
  130.     }
  131.  
  132.  // create OBJ file
  133.  ofstream ofile("output.obj");
  134.  ofile << "o output.obj" << endl;
  135.  ofile << "mtllib " << "output" << ".mtl" << endl;
  136.  
  137.  // move file pointer to vertex buffer
  138.  ifile.seekg(vbuffer_offset);
  139.  
  140.  // create vertex buffer
  141.  VERTEX_BUFFER vbuffer;
  142.  vbuffer.flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_UV;
  143.  vbuffer.elem = vertices;
  144.  vbuffer.data.reset(new VERTEX[vbuffer.elem]);
  145.  
  146.  // read vertex data
  147.  for(uint32 i = 0; i < vertices; i++)
  148.     {
  149.      // read vertex data
  150.      VERTEX v;
  151.      v.vx = LE_read_float16(ifile);
  152.      v.vy = LE_read_float16(ifile);
  153.      v.vz = LE_read_float16(ifile);
  154.             LE_read_float16(ifile);
  155.      v.nx = LE_read_float16(ifile);
  156.      v.ny = LE_read_float16(ifile);
  157.      v.nz = LE_read_float16(ifile);
  158.             LE_read_float16(ifile);
  159.      v.tu = LE_read_float16(ifile);
  160.      v.tv = 1.0f - LE_read_float16(ifile);
  161.             LE_read_float16(ifile);
  162.             LE_read_float16(ifile);
  163.             LE_read_float16(ifile);
  164.             LE_read_float16(ifile);
  165.             LE_read_float16(ifile);
  166.             LE_read_float16(ifile);
  167.  
  168.      // save vertex data
  169.      vbuffer.data[i] = v;
  170.  
  171.      // save vertex data
  172.      ofile << "v " << v.vx << " " << v.vy << " " << v.vz << endl;
  173.      ofile << "vn " << v.nx << " " << v.ny << " " << v.nz << endl;
  174.      ofile << "vt " << v.tu << " " << v.tv << endl;
  175.     }
  176.  
  177.  // move to index data
  178.  ifile.seekg(ibuffer_offset);
  179.  
  180.  // read index data
  181.  boost::shared_array<uint16> ibuffer(new uint16[indices]);
  182.  LE_read_array(ifile, ibuffer.get(), indices);
  183.  
  184.  // 
  185.  uint32 sum = 0;
  186.  for(size_t i = 0; i < stripsizes.size(); i++) sum += stripsizes[i];
  187.  cout << "sum = " << sum << endl;
  188.  cout << "indices = " << indices << endl;
  189.  uint32 leftover = indices - sum;
  190.  cout << "leftover = " << leftover << endl;
  191.  cout << endl;
  192.  
  193.  // process surfaces
  194.  uint32 offset = 0;
  195.  for(size_t i = 0; i < stripsizes.size(); i++)
  196.     {
  197.      uint32 indices = stripsizes[i];
  198.      cout << "surface indices = " << indices << endl;
  199.  
  200.      if(!stripeffect[i]) // TEST
  201.      {
  202.  
  203.      // save group
  204.      ofile << "g " << "surface_" << setfill('0') << setw(3) << i << endl;
  205.      ofile << "usemtl " << "surface_" << setfill('0') << setw(3) << i << endl;
  206.  
  207.      // save first triangle
  208.      uint32 a = ibuffer[offset + 0] + 1;
  209.      uint32 b = ibuffer[offset + 1] + 1;
  210.      uint32 c = ibuffer[offset + 2] + 1;
  211.  
  212.      float v1[3] = { vbuffer.data[a - 1].vx, vbuffer.data[a - 1].vy, vbuffer.data[a - 1].vz };
  213.      float v2[3] = { vbuffer.data[b - 1].vx, vbuffer.data[b - 1].vy, vbuffer.data[b - 1].vz };
  214.      float v3[3] = { vbuffer.data[c - 1].vx, vbuffer.data[c - 1].vy, vbuffer.data[c - 1].vz };
  215.      float n1[3] = { vbuffer.data[a - 1].nx, vbuffer.data[a - 1].ny, vbuffer.data[a - 1].nz };
  216.      float n2[3] = { vbuffer.data[b - 1].nx, vbuffer.data[b - 1].ny, vbuffer.data[b - 1].nz };
  217.      float n3[3] = { vbuffer.data[c - 1].nx, vbuffer.data[c - 1].ny, vbuffer.data[c - 1].nz };
  218.  
  219.      if(is_face_flipped(v1, v2, v3, n1, n2, n3)) {
  220.         ofile << "f " << a << "/" << a << "/" << a << " " <<
  221.                          c << "/" << c << "/" << c << " " <<
  222.                          b << "/" << b << "/" << b << endl;
  223.        }
  224.      else {
  225.         ofile << "f " << a << "/" << a << "/" << a << " " <<
  226.                          b << "/" << b << "/" << b << " " <<
  227.                          c << "/" << c << "/" << c << endl;
  228.        }
  229.  
  230.      // save other triangles
  231.      for(size_t j = 3; j < stripsizes[i]; j++)
  232.         {
  233.          a = b;
  234.          b = c;
  235.          c = ibuffer[offset + j] + 1;
  236.      
  237.          // skip degenerate triangles
  238.          if(a == b || a == c || b == c)
  239.             continue;
  240.      
  241.          if(j % 2)
  242.            {
  243.             float v1[3] = { vbuffer.data[a - 1].vx, vbuffer.data[a - 1].vy, vbuffer.data[a - 1].vz };
  244.             float v2[3] = { vbuffer.data[c - 1].vx, vbuffer.data[c - 1].vy, vbuffer.data[c - 1].vz };
  245.             float v3[3] = { vbuffer.data[b - 1].vx, vbuffer.data[b - 1].vy, vbuffer.data[b - 1].vz };
  246.             float n1[3] = { vbuffer.data[a - 1].nx, vbuffer.data[a - 1].ny, vbuffer.data[a - 1].nz };
  247.             float n2[3] = { vbuffer.data[c - 1].nx, vbuffer.data[c - 1].ny, vbuffer.data[c - 1].nz };
  248.             float n3[3] = { vbuffer.data[b - 1].nx, vbuffer.data[b - 1].ny, vbuffer.data[b - 1].nz };
  249.  
  250.             if(is_face_flipped(v1, v2, v3, n1, n2, n3)) {
  251.                ofile << "f " << a << "/" << a << "/" << a << " " <<
  252.                                 b << "/" << b << "/" << b << " " <<
  253.                                 c << "/" << c << "/" << c << endl;
  254.               }
  255.             else {
  256.                ofile << "f " << a << "/" << a << "/" << a << " " <<
  257.                                 c << "/" << c << "/" << c << " " <<
  258.                                 b << "/" << b << "/" << b << endl;
  259.               }
  260.            }
  261.          else
  262.            {
  263.             float v1[3] = { vbuffer.data[a - 1].vx, vbuffer.data[a - 1].vy, vbuffer.data[a - 1].vz };
  264.             float v2[3] = { vbuffer.data[b - 1].vx, vbuffer.data[b - 1].vy, vbuffer.data[b - 1].vz };
  265.             float v3[3] = { vbuffer.data[c - 1].vx, vbuffer.data[c - 1].vy, vbuffer.data[c - 1].vz };
  266.             float n1[3] = { vbuffer.data[a - 1].nx, vbuffer.data[a - 1].ny, vbuffer.data[a - 1].nz };
  267.             float n2[3] = { vbuffer.data[b - 1].nx, vbuffer.data[b - 1].ny, vbuffer.data[b - 1].nz };
  268.             float n3[3] = { vbuffer.data[c - 1].nx, vbuffer.data[c - 1].ny, vbuffer.data[c - 1].nz };
  269.  
  270.             if(is_face_flipped(v1, v2, v3, n1, n2, n3)) {
  271.                ofile << "f " << a << "/" << a << "/" << a << " " <<
  272.                                 c << "/" << c << "/" << c << " " <<
  273.                                 b << "/" << b << "/" << b << endl;
  274.               }
  275.             else {
  276.                ofile << "f " << a << "/" << a << "/" << a << " " <<
  277.                                 b << "/" << b << "/" << b << " " <<
  278.                                 c << "/" << c << "/" << c << endl;
  279.               }
  280.            }
  281.         }
  282.  
  283.      } // TEST
  284.  
  285.      // move offset
  286.      offset += stripsizes[i];
  287.     }
  288.  
  289.  // save materials
  290.  ofstream mtlfile("output.mtl");
  291.  if(!mtlfile) return error("OBJ EXPORT: Error creating material file.");
  292.  for(size_t i = 0; i < stripsizes.size(); i++) {
  293.      mtlfile << "newmtl " << "surface_" << setfill('0') << setw(3) << i << endl;
  294.      mtlfile << "Ka 0 0 0" << endl;
  295.      mtlfile << "Kd 0.784314 0.784314 0.784314" << endl;
  296.      mtlfile << "Ks 0 0 0" << endl;
  297.      mtlfile << "Ni 1" << endl;
  298.      mtlfile << "Ns 400" << endl;
  299.      mtlfile << "Tf 1 1 1" << endl;
  300.      mtlfile << "d 1" << endl;
  301.      mtlfile << "map_Kd texture_" << setfill('0') << setw(3) << stripimage[i] << ".png" << endl;
  302.      mtlfile << endl;
  303.     }
  304.  
  305.  // move to texture data
  306.  ifile.seekg(tbuffer_offset);
  307.  
  308.  struct TEXTUREINFO { uint32 p1, p2, p3, p4; };
  309.  deque<TEXTUREINFO> tinfo;
  310.  
  311.  // read texture info
  312.  for(size_t i = 0; i < n_textures; i++)
  313.     {
  314.      TEXTUREINFO item;
  315.      item.p1 = LE_read_uint32(ifile);
  316.      item.p2 = LE_read_uint32(ifile);
  317.      item.p3 = LE_read_uint32(ifile);
  318.      item.p4 = LE_read_uint32(ifile);
  319.      tinfo.push_back(item);
  320.     }
  321.  
  322.  // read texture data
  323.  for(size_t i = 0; i < n_textures; i++)
  324.     {
  325.      TEXTUREINFO item = tinfo[i];
  326.  
  327.      // 
  328.      stringstream ss;
  329.      ss << "texture_" << setfill('0') << setw(3) << i << ".dds";
  330.      ofstream ddsfile(ss.str().c_str(), ios::binary);
  331.      ddsfile.write("DDS ", 4);
  332.  
  333.      // save DDS header
  334.      DDS_HEADER header;
  335.      CreateUncompressedDDSHeader(item.p1, item.p2, 0, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, FALSE, &header);
  336.      ddsfile.write((char*)&header, sizeof(header));
  337.  
  338.      // save DDS data
  339.      boost::shared_array<char> data(new char[item.p3]);
  340.      ifile.read(data.get(), item.p3);
  341.      ddsfile.write(data.get(), item.p3);
  342.     }
  343.  
  344.  return true;
  345. }
  346.  
  347. void Test2(void)
  348. {
  349.  // negate z to convert to right-hand space
  350.  double points[7][3] = {
  351.   { -3.38441, 147.212, 2.82783 }, // 0
  352.   { -4.17231, 147.948, 2.17650 }, // 1
  353.   { -3.65146, 147.122, 2.01224 }, // 2
  354.   { -3.98159, 147.350, 1.01742 }, // 50
  355.   { -4.53017, 148.112, 1.25919 }, // 62
  356.   { -3.84511, 148.011, 2.93451 }, // 63
  357.   { -4.57004, 148.829, 2.43792 }, // 64
  358.  };
  359.  
  360.  // triangle
  361.  double v1[3] = { 26.3867, 136.591, -1.16695 };
  362.  double v2[3] = { 26.304, 138.489, -1.08023 };
  363.  double v3[3] = { 23.769, 136.48, -1.12714 };
  364.  
  365.  // compute a
  366.  double a[3] = {
  367.   v2[0] - v1[0],
  368.   v2[1] - v1[1],
  369.   v2[2] - v1[2],
  370.  };
  371.  double da = std::sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
  372.  a[0] /= da;
  373.  a[1] /= da;
  374.  a[2] /= da;
  375.  
  376.  // compute b
  377.  double b[3] = {
  378.   v3[0] - v1[0],
  379.   v3[1] - v1[1],
  380.   v3[2] - v1[2],
  381.  };
  382.  double db = std::sqrt(b[0]*b[0] + b[1]*b[1] + b[2]*b[2]);
  383.  b[0] /= db;
  384.  b[1] /= db;
  385.  b[2] /= db;
  386.  
  387.  // compute c
  388.  double c[3] = {
  389.   a[1]*b[2] - a[2]*b[1],
  390.   a[2]*b[0] - a[0]*b[2],
  391.   a[0]*b[1] - a[1]*b[0],
  392.  };
  393.  double dc = std::sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
  394.  c[0] /= dc;
  395.  c[1] /= dc;
  396.  c[2] /= dc;
  397.  
  398.  cout << "normal = " << c[0] << "," << c[1] << "," << c[2] << endl;
  399.  
  400.  // compute d
  401.  double d[3] = {
  402.   -6,
  403.    94,
  404.    -123,
  405.  };
  406.  double dd = std::sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);
  407.  d[0] /= dd;
  408.  d[1] /= dd;
  409.  d[2] /= dd;
  410.  cout << "normal = " << d[0] << "," << d[1] << "," << d[2] << endl;
  411. }
  412.  
  413. int main()
  414. {
  415.  //PS3::GundamCrossfire::extract();
  416.  XB360::Onechanbara2::extract();
  417.  
  418. /*
  419.  ifstream ifile("nina1u.kmd", ios::binary);
  420.  
  421.  LE_read_uint32(ifile);
  422.  LE_read_uint32(ifile);
  423.  LE_read_uint32(ifile); // 98
  424.  LE_read_uint32(ifile); // ??
  425.  LE_read_uint32(ifile); // 8
  426.  LE_read_uint32(ifile); // 0xDC0 + 0x10 = offset to data
  427.  LE_read_uint32(ifile); // 0xC9F
  428.  LE_read_uint32(ifile); // 0x1FBC
  429.  LE_read_uint32(ifile); // 0x5F34
  430.  LE_read_uint32(ifile); // 0x581
  431.  LE_read_uint32(ifile); // 0x2ABE
  432.  LE_read_uint32(ifile); // 0
  433.  LE_read_uint32(ifile); // 0
  434.  LE_read_uint32(ifile); // 0xD0D
  435.  LE_read_uint32(ifile); // 0
  436.  LE_read_uint32(ifile); // 0
  437.  LE_read_uint32(ifile); // 0
  438.  LE_read_uint32(ifile); // 0
  439.  LE_read_uint32(ifile); // 0xB9D60 = offset
  440.  LE_read_uint32(ifile); // 0
  441.  LE_read_uint32(ifile); // 0
  442.  LE_read_uint32(ifile); // 0
  443.  LE_read_uint32(ifile); // 0
  444.  LE_read_uint32(ifile); // 0xFC160
  445.  LE_read_uint32(ifile); // 0x1070A0
  446.  LE_read_uint32(ifile); // 0x1077A0
  447.  LE_read_uint32(ifile); // 0
  448.  LE_read_uint32(ifile); // 0
  449.  LE_read_uint32(ifile); // 0
  450.  LE_read_uint32(ifile); // 0
  451.  LE_read_uint32(ifile); // 0
  452.  LE_read_uint32(ifile); // 0xFFFFFFFF
  453.  
  454.  ofstream ofile("test.obj");
  455.  ofile << "o test.obj" << endl;
  456.  
  457.  struct bone {
  458.   uint32 parent;
  459.   float x;
  460.   float y;
  461.   float z;
  462.   float x_abs;
  463.   float y_abs;
  464.   float z_abs;
  465.  };
  466.  map<uint32, bone> bonemap;
  467.  typedef map<uint32, bone>::value_type boneitem;
  468.  typedef map<uint32, bone>::iterator bone_iterator;
  469.  
  470.  ifile.seekg(0x7C);
  471.  size_t max_parent = 0;
  472.  for(size_t i = 0; i < 98; i++)
  473.     {
  474.      uint32 parent = LE_read_uint32(ifile);
  475.      float x = LE_read_float32(ifile);
  476.      float y = LE_read_float32(ifile);
  477.      float z = LE_read_float32(ifile);
  478.      float sx = LE_read_float32(ifile);
  479.      float sy = LE_read_float32(ifile);
  480.      float sz = LE_read_float32(ifile);
  481.      LE_read_uint32(ifile);
  482.      cout << endl;
  483.  
  484.      bone b;
  485.      b.parent = parent;
  486.      b.x = x*sx;
  487.      b.y = y*sy;
  488.      b.z = z*sz;
  489.      b.x_abs = b.x;
  490.      b.y_abs = b.y;
  491.      b.z_abs = b.z;
  492.  
  493.      // add bone
  494.      bonemap.insert(boneitem(i, b));
  495.     }
  496.  
  497.  for(bone_iterator i = bonemap.begin(); i != bonemap.end(); i++)
  498.     {
  499.      bone_iterator iter = bonemap.find(i->second.parent);
  500.      if(iter != bonemap.end()) {
  501.         i->second.x_abs += iter->second.x_abs;
  502.         i->second.y_abs += iter->second.y_abs;
  503.         i->second.z_abs += iter->second.z_abs;
  504.        }
  505.      ofile << "v " << i->second.x_abs << " " << i->second.y_abs << " " << i->second.z_abs << endl;
  506.     }
  507.  
  508.  ifstream chrfile("nina1u.chr", ios::binary);
  509.  chrfile.seekg(0x14BC);
  510.  size_t n_bones = 106;
  511.  float x = 0;
  512.  float y = 0;
  513.  float z = 0;
  514.  for(size_t i = 0; i < n_bones; i++) {
  515.      float m[16];
  516.      m[ 0] = LE_read_float32(chrfile);
  517.      m[ 1] = LE_read_float32(chrfile);
  518.      m[ 2] = LE_read_float32(chrfile);
  519.      m[ 3] = LE_read_float32(chrfile);
  520.      m[ 4] = LE_read_float32(chrfile);
  521.      m[ 5] = LE_read_float32(chrfile);
  522.      m[ 6] = LE_read_float32(chrfile);
  523.      m[ 7] = LE_read_float32(chrfile);
  524.      m[ 8] = LE_read_float32(chrfile);
  525.      m[ 9] = LE_read_float32(chrfile);
  526.      m[10] = LE_read_float32(chrfile);
  527.      m[11] = LE_read_float32(chrfile);
  528.      m[12] = LE_read_float32(chrfile);
  529.      m[13] = LE_read_float32(chrfile);
  530.      m[14] = LE_read_float32(chrfile);
  531.      m[15] = LE_read_float32(chrfile);
  532.      x = m[12];
  533.      y = m[13];
  534.      z = m[14];
  535.  
  536.      // cout << m[ 0] << " " << m[ 1] << " " << m[ 2] << " " << m[ 3] << endl;
  537.      // cout << m[ 4] << " " << m[ 5] << " " << m[ 6] << " " << m[ 7] << endl;
  538.      // cout << m[ 8] << " " << m[ 9] << " " << m[10] << " " << m[11] << endl;
  539.      // cout << m[12] << " " << m[13] << " " << m[14] << " " << m[15] << endl;
  540.      // cout << endl;
  541.  
  542.      //ofile << "v " << x << " " << y << " " << z << endl;
  543.     }
  544. */
  545.  
  546.  return 0;
  547. }
  548.  
  549. INT_PTR CALLBACK RipperProc(HWND dialog, UINT message, WPARAM wparam, LPARAM lparam)
  550. {
  551.  switch(message) {
  552.    case(WM_INITDIALOG) :
  553.        {
  554.         HWND system = GetDlgItem(dialog, IDC_SYSTEM);
  555.         if(!system) {
  556.            MessageBox(dialog, TEXT("Dialog control missing."), TEXT("Error"), MB_ICONSTOP);
  557.            EndDialog(dialog, IDCANCEL);
  558.           }
  559.         SendMessage(system, CB_ADDSTRING, 0, (LPARAM)TEXT("Playstation 3"));
  560.         SendMessage(system, CB_ADDSTRING, 0, (LPARAM)TEXT("PC"));
  561.         SendMessage(system, CB_ADDSTRING, 0, (LPARAM)TEXT("XBox 360"));
  562.         SendMessage(system, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
  563.         return TRUE;
  564.        }
  565.    case(WM_COMMAND) : {
  566.         int cmd = LOWORD(wparam);
  567.         if(cmd == IDOK) {
  568.            EndDialog(dialog, IDOK);
  569.            return TRUE;
  570.           }
  571.         if(cmd == IDCANCEL) {
  572.            EndDialog(dialog, IDCANCEL);
  573.            return TRUE;
  574.           }
  575.         return FALSE;
  576.        }
  577.   }
  578.  return FALSE;
  579. }
  580.  
  581. bool is_face_flipped(const float* v1, const float* v2, const float* v3, const float* n1, const float* n2, const float* n3)
  582. {
  583.  // compute a
  584.  float a[3] = {
  585.   v2[0] - v1[0],
  586.   v2[1] - v1[1],
  587.   v2[2] - v1[2],
  588.  };
  589.  float da = std::sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
  590.  a[0] /= da;
  591.  a[1] /= da;
  592.  a[2] /= da;
  593.  
  594.  // compute b
  595.  float b[3] = {
  596.   v3[0] - v1[0],
  597.   v3[1] - v1[1],
  598.   v3[2] - v1[2],
  599.  };
  600.  float db = std::sqrt(b[0]*b[0] + b[1]*b[1] + b[2]*b[2]);
  601.  b[0] /= db;
  602.  b[1] /= db;
  603.  b[2] /= db;
  604.  
  605.  // compute c
  606.  float c[3] = {
  607.   a[1]*b[2] - a[2]*b[1],
  608.   a[2]*b[0] - a[0]*b[2],
  609.   a[0]*b[1] - a[1]*b[0],
  610.  };
  611.  float dc = std::sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
  612.  c[0] /= dc;
  613.  c[1] /= dc;
  614.  c[2] /= dc;
  615.  
  616.  // compute average of vertex normals
  617.  float q[3] = {
  618.   (n1[0] + n2[0] + n3[0])/3.0f,
  619.   (n1[1] + n2[1] + n3[1])/3.0f,
  620.   (n1[2] + n2[2] + n3[2])/3.0f,
  621.  };
  622.  float dq = std::sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2]);
  623.  q[0] /= dq;
  624.  q[1] /= dq;
  625.  q[2] /= dq;
  626.  
  627.  // now compute angle between two normals
  628.  float angle = std::acos((c[0]*q[0] + c[1]*q[1] + c[2]*q[2]));
  629.  angle = angle*(180.0f/3.1415f);
  630.  return (angle > 90.0f);
  631. }