home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 5257 / source.7z / x_obj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2012-02-28  |  13.2 KB  |  286 lines

  1. #include "xentax.h"
  2. #include "x_smc.h"
  3. #include "x_obj.h"
  4.  
  5. /*
  6. //bool GeometryToOBJ(const char* path, const char* name, const SIMPLEMODELCONTAINER& data)
  7. {
  8.  // create OBJ file
  9.  stringstream ss;
  10.  ss << path << name << ".obj";
  11.  ofstream objfile(ss.str().c_str());
  12.  if(!objfile) return error("OBJ EXPORT: Error creating output file.");
  13.  
  14.  // OBJ file header
  15.  objfile << "o " << name << ".obj" << endl;
  16.  objfile << "mtllib " << name << ".mtl" << endl;
  17.  
  18.  struct OBJOFFSETINFO {
  19.   uint32 vertex_base;
  20.   uint32 normal_base;
  21.   uint32 texmap_base;
  22.  };
  23.  
  24.  // index to each vertex buffer
  25.  OBJOFFSETINFO ooi = { 0, 0, 0 };
  26.  std::deque<OBJOFFSETINFO> offset_list;
  27.  for(size_t i = 0; i < vd.size(); i++) {
  28.      offset_list.push_back(ooi);
  29.      if(vd[i].flags & VERTEX_POSITION) ooi.vertex_base += vd[i].elem;
  30.      if(vd[i].flags & VERTEX_NORMAL) ooi.normal_base += vd[i].elem;
  31.      if(vd[i].flags & VERTEX_UV) ooi.texmap_base += vd[i].elem;
  32.     }
  33.  
  34.  // output vertices
  35.  for(size_t i = 0; i < vd.size(); i++) {
  36.      if(vd[i].flags & VERTEX_POSITION) {
  37.         objfile << "# POSITION BUFFER " << i << endl;
  38.         for(size_t j = 0; j < vd[i].elem; j++)
  39.             objfile << "v " << vd[i].data[j].vx << " " << vd[i].data[j].vy << " " << vd[i].data[j].vz << endl;
  40.        }
  41.     }
  42.  for(size_t i = 0; i < vd.size(); i++) {
  43.      if(vd[i].flags & VERTEX_NORMAL) {
  44.         objfile << "# NORMAL BUFFER " << i << endl;
  45.         for(size_t j = 0; j < vd[i].elem; j++)
  46.             objfile << "vn " << vd[i].data[j].nx << " " << vd[i].data[j].ny << " " << vd[i].data[j].nz << endl;
  47.        }
  48.     }
  49.  for(size_t i = 0; i < vd.size(); i++) {
  50.      if(vd[i].flags & VERTEX_UV) {
  51.         objfile << "# UV BUFFER " << i << endl;
  52.         for(size_t j = 0; j < vd[i].elem; j++)
  53.             objfile << "vt " << vd[i].data[j].tu << " " << vd[i].data[j].tv << endl;
  54.        }
  55.     }
  56.  
  57.  // output faces
  58.  for(size_t i = 0; i < fd.size(); i++)
  59.     {
  60.      objfile << "# INDEX BUFFER " << i << endl;
  61.      objfile << "g " << fd[i].name.c_str() << endl;
  62.      objfile << "usemtl " << fd[i].name.c_str() << endl;
  63.  
  64.      // set vertex buffer reference index
  65.      uint32 vertex_buffer_index = fd[i].reference;
  66.      if(!(vertex_buffer_index < offset_list.size())) return error("OBJ EXPORT: Invalid vertex buffer reference.");
  67.  
  68.      // set vertex buffer properties
  69.      bool has_vertex = (vd[vertex_buffer_index].flags & VERTEX_POSITION) != 0;
  70.      bool has_normal = (vd[vertex_buffer_index].flags & VERTEX_NORMAL) != 0;
  71.      bool has_texmap = (vd[vertex_buffer_index].flags & VERTEX_UV) != 0;
  72.  
  73.      // set base vertex
  74.      uint32 base_vertex = offset_list[vertex_buffer_index].vertex_base;
  75.      uint32 base_normal = offset_list[vertex_buffer_index].normal_base;
  76.      uint32 base_texmap = offset_list[vertex_buffer_index].texmap_base;
  77.  
  78.      // tri-strips
  79.      if(fd[i].type == FACE_TYPE_TRISTRIP)
  80.        {
  81.         // validate
  82.         if(fd[i].elem < 3) return error("OBJ EXPORT: Tri-strips require at least three points.");
  83.  
  84.         if(fd[i].format == FACE_FORMAT_UINT_16)
  85.           {
  86.            // first triangle
  87.            const uint16* data = reinterpret_cast<uint16*>(fd[i].data.get());
  88.            uint32 va = base_vertex + data[0] + 1;
  89.            uint32 vb = base_vertex + data[1] + 1;
  90.            uint32 vc = base_vertex + data[2] + 1;
  91.            uint32 na = base_normal + data[0] + 1;
  92.            uint32 nb = base_normal + data[1] + 1;
  93.            uint32 nc = base_normal + data[2] + 1;
  94.            uint32 ta = base_texmap + data[0] + 1;
  95.            uint32 tb = base_texmap + data[1] + 1;
  96.            uint32 tc = base_texmap + data[2] + 1;
  97.  
  98.            // first triangle (draw only if not degenerate)
  99.            if(!(va == vb || va == vc || vb == vc)) {
  100.               if(!has_normal && !has_texmap) objfile << "f " << va << " " << vb << " " << vc << endl;
  101.               else if(!has_normal && has_texmap) objfile << "f " << va << "/" << ta << " " << vb << "/" << tb << " " << vc << "/" << tc << endl;
  102.               else if(!has_texmap && has_normal) objfile << "f " << va << "//" << na << " " << vb << "//" << nb << " " << vc << "//" << nc << endl;
  103.               else objfile << "f " << va << "/" << ta << "/" << na << " " << vb << "/" << tb << "/" << nb << " " << vc << "/" << tc << "/" << nc << endl;
  104.              }
  105.  
  106.            // other triangles
  107.            for(size_t j = 3; j < fd[i].elem; j++)
  108.               {
  109.                // update position
  110.                va = vb;
  111.                vb = vc;
  112.                vc = base_vertex + data[j] + 1;
  113.  
  114.                // update normal
  115.                if(has_normal) {
  116.                   na = nb;
  117.                   nb = nc;
  118.                   nc = base_normal + data[j] + 1;
  119.                  }
  120.  
  121.                // update UV
  122.                if(has_texmap) {
  123.                   ta = tb;
  124.                   tb = tc;
  125.                   tc = base_texmap + data[j] + 1;
  126.                  }
  127.  
  128.                // skip degenerate triangles
  129.                if(va == vb || va == vc || vb == vc) continue;
  130.  
  131.                if(!has_normal && !has_texmap) {
  132.                   if(j % 2) objfile << "f " << va << " " << vc << " " << vb << endl;
  133.                   else objfile << "f " << va << " " << vb << " " << vc << endl;
  134.                  }
  135.                else if(!has_normal && has_texmap) {
  136.                   if(j % 2) objfile << "f " << va << "/" << ta << " " << vc << "/" << tc << " " << vb << "/" << tb << endl;
  137.                   else objfile << "f " << va << "/" << ta << " " << vb << "/" << tb << " " << vc << "/" << tc << endl;
  138.                  }
  139.                else if(has_normal && !has_texmap) {
  140.                   if(j % 2) objfile << "f " << va << "//" << na << " " << vc << "//" << nc << " " << vb << "//" << nb << endl;
  141.                   else objfile << "f " << va << "//" << na << " " << vb << "//" << nb << " " << vc << "//" << nc << endl;
  142.                  }
  143.                else {
  144.                   if(j % 2) objfile << "f " << va << "/" << ta << "/" << na << " " << vc << "/" << tc << "/" << nc << " " << vb << "/" << tb << "/" << nb << endl;
  145.                   else objfile << "f " << va << "/" << ta << "/" << na << " " << vb << "/" << tb << "/" << nb << " " << vc << "/" << tc << "/" << nc << endl;
  146.                  }
  147.               }
  148.           }
  149.         else if(fd[i].format == FACE_FORMAT_UINT_32)
  150.           {
  151.            // first triangle
  152.            const uint32* data = reinterpret_cast<uint32*>(fd[i].data.get());
  153.            uint32 va = base_vertex + data[0] + 1;
  154.            uint32 vb = base_vertex + data[1] + 1;
  155.            uint32 vc = base_vertex + data[2] + 1;
  156.            uint32 na = base_normal + data[0] + 1;
  157.            uint32 nb = base_normal + data[1] + 1;
  158.            uint32 nc = base_normal + data[2] + 1;
  159.            uint32 ta = base_texmap + data[0] + 1;
  160.            uint32 tb = base_texmap + data[1] + 1;
  161.            uint32 tc = base_texmap + data[2] + 1;
  162.            if(!has_normal && !has_texmap) objfile << "f " << va << " " << vb << " " << vc << endl;
  163.            else if(!has_normal && has_texmap) objfile << "f " << va << "/" << ta << " " << vb << "/" << tb << " " << vc << "/" << tc << endl;
  164.            else if(!has_texmap && has_normal) objfile << "f " << va << "//" << na << " " << vb << "//" << nb << " " << vc << "//" << nc << endl;
  165.            else objfile << "f " << va << "/" << ta << "/" << na << " " << vb << "/" << tb << "/" << nb << " " << vc << "/" << tc << "/" << nc << endl;
  166.  
  167.            // other triangles
  168.            for(size_t j = 3; j < fd[i].elem; j++)
  169.               {
  170.                va = vb;
  171.                vb = vc;
  172.                vc = base_vertex + data[j] + 1;
  173.  
  174.                if(has_normal) {
  175.                   na = nb;
  176.                   nb = nc;
  177.                   nc = base_normal + data[j] + 1;
  178.                  }
  179.                if(has_texmap) {
  180.                   ta = tb;
  181.                   tb = tc;
  182.                   tc = base_texmap + data[j] + 1;
  183.                  }
  184.  
  185.                if(!has_normal && !has_texmap) {
  186.                   if(j % 2) objfile << "f " << va << " " << vc << " " << vb << endl;
  187.                   else objfile << "f " << va << " " << vb << " " << vc << endl;
  188.                  }
  189.                else if(!has_normal && has_texmap) {
  190.                   if(j % 2) objfile << "f " << va << "/" << ta << " " << vc << "/" << tc << " " << vb << "/" << tb << endl;
  191.                   else objfile << "f " << va << "/" << ta << " " << vb << "/" << tb << " " << vc << "/" << tc << endl;
  192.                  }
  193.                else if(has_normal && !has_texmap) {
  194.                   if(j % 2) objfile << "f " << va << "//" << na << " " << vc << "//" << nc << " " << vb << "//" << nb << endl;
  195.                   else objfile << "f " << va << "//" << na << " " << vb << "//" << nb << " " << vc << "//" << nc << endl;
  196.                  }
  197.                else {
  198.                   if(j % 2) objfile << "f " << va << "/" << ta << "/" << na << " " << vc << "/" << tc << "/" << nc << " " << vb << "/" << tb << "/" << nb << endl;
  199.                   else objfile << "f " << va << "/" << ta << "/" << na << " " << vb << "/" << tb << "/" << nb << " " << vc << "/" << tc << "/" << nc << endl;
  200.                  }
  201.               }
  202.           }
  203.         else
  204.            return error("OBJ EXPORT: Invalid index buffer data format.");
  205.        }
  206.      // triangles
  207.      else if(fd[i].type == FACE_TYPE_TRIANGLES)
  208.        {
  209.         if(fd[i].format == FACE_FORMAT_UINT_16)
  210.           {
  211.            size_t n_triangles = fd[i].elem/3;
  212.            for(size_t j = 0; j < n_triangles; j++)
  213.               {
  214.                // base OBJ indices
  215.                const uint16* ib_data = reinterpret_cast<uint16*>(fd[i].data.get());
  216.                uint32 va = base_vertex + ib_data[(3*j + 0)] + 1;
  217.                uint32 vb = base_vertex + ib_data[(3*j + 1)] + 1;
  218.                uint32 vc = base_vertex + ib_data[(3*j + 2)] + 1;
  219.                uint32 na = base_normal + ib_data[(3*j + 0)] + 1;
  220.                uint32 nb = base_normal + ib_data[(3*j + 1)] + 1;
  221.                uint32 nc = base_normal + ib_data[(3*j + 2)] + 1;
  222.                uint32 ta = base_texmap + ib_data[(3*j + 0)] + 1;
  223.                uint32 tb = base_texmap + ib_data[(3*j + 1)] + 1;
  224.                uint32 tc = base_texmap + ib_data[(3*j + 2)] + 1;
  225.  
  226.                // write triangle
  227.                if(!has_normal && !has_texmap) objfile << "f " << va << " " << vb << " " << vc << endl;
  228.                else if(!has_normal && has_texmap) objfile << "f " << va << "/" << ta << " " << vb << "/" << tb << " " << vc << "/" << tc << endl;
  229.                else if(has_normal && !has_texmap) objfile << "f " << va << "//" << na << " " << vb << "//" << nb << " " << vc << "//" << nc << endl;
  230.                else objfile << "f " << va << "/" << ta << "/" << na << " " << vb << "/" << tb << "/" << nb << " " << vc << "/" << tc << "/" << nc << endl;
  231.               }
  232.           }
  233.         else if(fd[i].format == FACE_FORMAT_UINT_32)
  234.           {
  235.            size_t n_triangles = fd[i].elem/3;
  236.            for(size_t j = 0; j < n_triangles; j++)
  237.               {
  238.                // base OBJ indices
  239.                const uint32* ib_data = reinterpret_cast<uint32*>(fd[i].data.get());
  240.                uint32 va = base_vertex + ib_data[(3*j + 0)] + 1;
  241.                uint32 vb = base_vertex + ib_data[(3*j + 1)] + 1;
  242.                uint32 vc = base_vertex + ib_data[(3*j + 2)] + 1;
  243.                uint32 na = base_normal + ib_data[(3*j + 0)] + 1;
  244.                uint32 nb = base_normal + ib_data[(3*j + 1)] + 1;
  245.                uint32 nc = base_normal + ib_data[(3*j + 2)] + 1;
  246.                uint32 ta = base_texmap + ib_data[(3*j + 0)] + 1;
  247.                uint32 tb = base_texmap + ib_data[(3*j + 1)] + 1;
  248.                uint32 tc = base_texmap + ib_data[(3*j + 2)] + 1;
  249.  
  250.                // write triangle
  251.                if(!has_normal && !has_texmap) objfile << "f " << va << " " << vb << " " << vc << endl;
  252.                else if(!has_normal && has_texmap) objfile << "f " << va << "/" << ta << " " << vb << "/" << tb << " " << vc << "/" << tc << endl;
  253.                else if(has_normal && !has_texmap) objfile << "f " << va << "//" << na << " " << vb << "//" << nb << " " << vc << "//" << nc << endl;
  254.                else objfile << "f " << va << "/" << ta << "/" << na << " " << vb << "/" << tb << "/" << nb << " " << vc << "/" << tc << "/" << nc << endl;
  255.               }
  256.           }
  257.        }
  258.     }
  259.  
  260.  // create MTL file
  261.  stringstream mtlfilename;
  262.  mtlfilename << path << name << ".mtl" << ends;
  263.  ofstream mtlfile(mtlfilename.str().c_str());
  264.  if(!mtlfile) return error("OBJ EXPORT: Error creating material file.");
  265.  
  266.  // save materials
  267.  for(size_t i = 0; i < fd.size(); i++)
  268.     {
  269.      mtlfile << "newmtl " << fd[i].name.c_str() << endl;
  270.      mtlfile << "Ka 0 0 0" << endl;
  271.      mtlfile << "Kd 0.784314 0.784314 0.784314" << endl;
  272.      mtlfile << "Ks 0 0 0" << endl;
  273.      mtlfile << "Ni 1" << endl;
  274.      mtlfile << "Ns 400" << endl;
  275.      mtlfile << "Tf 1 1 1" << endl;
  276.      mtlfile << "d 1" << endl;
  277.      //if(fd[i].basemap.length()) mtlfile << "map_Ka " << fd[i].basemap << endl;
  278.      //if(fd[i].basemap.length()) mtlfile << "map_Kd " << fd[i].basemap << endl;
  279.      //if(fd[i].specmap.length()) mtlfile << "map_Ks " << fd[i].specmap << endl;
  280.      //if(fd[i].basemap.length()) mtlfile << "map_d  " << fd[i].basemap << endl;
  281.      mtlfile << endl;
  282.     }
  283.  
  284.  return true;
  285. }
  286. */