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

  1. #include "xentax.h"
  2. #include "x_smc.h"
  3. #include "x_dae.h"
  4.  
  5. /*
  6. bool GeometryToDAE(const char* path, const char* name, const GEOMETRY& data, const MATERIAL_LIST& materials, const TEXTURE_LIST& textures, const SKELETON_LIST& sl)
  7. {
  8.  if(!path || !strlen(path)) return error("DAE EXPORT: Expecting pathname.");
  9.  if(!name || !strlen(name)) return error("DAE EXPORT: Expecting filename.");
  10.  if(!data.meshlist.size()) return error("DAE EXPORT: Expecting geometry.");
  11.  
  12.  // create DAE file
  13.  stringstream ss;
  14.  ss << path << name << ".dae";
  15.  ofstream ofile(ss.str().c_str());
  16.  if(!ofile) return error("DAE EXPORT: Error creating output file."); 
  17.  
  18.  // save <collada>
  19.  ofile << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl;
  20.  ofile << "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" << endl;
  21.  ofile << endl;
  22.  
  23.  // save <asset>
  24.  ofile << " <!-- ASSET -->" << endl;
  25.  ofile << " <asset>" << endl;
  26.  ofile << "  <created>2012-01-01T21:00:00Z</created>" << endl;
  27.  ofile << "  <modified>2012-01-01T21:00:00Z</modified>" << endl;
  28.  ofile << "  <up_axis>Z_UP</up_axis>" << endl;
  29.  ofile << " </asset>" << endl;
  30.  ofile << endl;
  31.  
  32.  // save <library_images>
  33.  if(textures.size())
  34.    {
  35.     ofile << " <!-- LIBRARY_IMAGES -->" << endl;
  36.     ofile << " <library_images>" << endl;
  37.     for(size_t i = 0; i < textures.size(); i++) {
  38.         ofile << "  <image id=\"" << textures[i].id << "\">" << endl;
  39.         ofile << "   <init_from>" << textures[i].filename << "</init_from>" << endl;
  40.         ofile << "  </image>" << endl;
  41.        }
  42.     ofile << " </library_images>" << endl;
  43.     ofile << endl;
  44.    }
  45.  
  46.  // save <library_effects>
  47.  ofile << " <!-- LIBRARY_EFFECTS -->" << endl;
  48.  ofile << " <library_effects>" << endl;
  49.  for(size_t i = 0; i < materials.size(); i++)
  50.     {
  51.      // important texture information
  52.      bool has_basemap = materials[i].basemap != 0xFFFFFFFF;
  53.      bool has_specmap = materials[i].specmap != 0xFFFFFFFF;
  54.      bool has_normmap = materials[i].normmap != 0xFFFFFFFF;
  55.      bool has_bumpmap = materials[i].bumpmap != 0xFFFFFFFF;
  56.      bool has_map = (has_basemap || has_specmap || has_normmap || has_bumpmap);
  57.  
  58.      stringstream e_id; // effect
  59.      e_id << "effects_" << setfill('0') << setw(3) << i;
  60.  
  61.      ofile << "  <effect id=\"" << e_id.str() << "\">" << endl;
  62.      ofile << "   <profile_COMMON>" << endl;
  63.      ofile << "    <technique sid=\"common\">" << endl;
  64.  
  65.      // base map parameters
  66.      stringstream basemap_id1;
  67.      stringstream basemap_id2;
  68.      basemap_id1 << "basemap_" << setfill('0') << setw(3) << i;
  69.      basemap_id2 << "basemap_options_" << setfill('0') << setw(3) << i;
  70.  
  71.      if(has_basemap)
  72.        {
  73.         // parameter #1
  74.         ofile << "     <newparam sid=\"" << basemap_id1.str() << "\">" << endl;
  75.         ofile << "      <surface type=\"2D\">" << endl;
  76.         ofile << "       <init_from>" << textures[materials[i].basemap].id << "</init_from>" << endl;
  77.         ofile << "       <format>A8R8G8B8</format>" << endl;
  78.         ofile << "      </surface>" << endl;
  79.         ofile << "     </newparam>" << endl;
  80.         // parameter #2
  81.         ofile << "     <newparam sid=\"" << basemap_id2.str() << "\">" << endl;
  82.         ofile << "      <sampler2D>" << endl;
  83.         ofile << "       <source>" << basemap_id1.str() << "</source>" << endl;
  84.         ofile << "       <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>" << endl;
  85.         ofile << "       <magfilter>LINEAR</magfilter>" << endl;
  86.         ofile << "      </sampler2D>" << endl;
  87.         ofile << "     </newparam>" << endl;
  88.        }
  89.  
  90.      // spec map parameters
  91.      stringstream specmap_id1;
  92.      stringstream specmap_id2;
  93.      specmap_id1 << "specmap_" << setfill('0') << setw(3) << i;
  94.      specmap_id2 << "specmap_options_" << setfill('0') << setw(3) << i;
  95.  
  96.      if(has_specmap)
  97.        {
  98.         // parameter #1
  99.         ofile << "     <newparam sid=\"" << specmap_id1.str() << "\">" << endl;
  100.         ofile << "      <surface type=\"2D\">" << endl;
  101.         ofile << "       <init_from>" << textures[materials[i].specmap].id << "</init_from>" << endl;
  102.         ofile << "       <format>A8R8G8B8</format>" << endl;
  103.         ofile << "      </surface>" << endl;
  104.         ofile << "     </newparam>" << endl;
  105.         // parameter #2
  106.         ofile << "     <newparam sid=\"" << specmap_id2.str() << "\">" << endl;
  107.         ofile << "      <sampler2D>" << endl;
  108.         ofile << "       <source>" << specmap_id1.str() << "</source>" << endl;
  109.         ofile << "       <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>" << endl;
  110.         ofile << "       <magfilter>LINEAR</magfilter>" << endl;
  111.         ofile << "      </sampler2D>" << endl;
  112.         ofile << "     </newparam>" << endl;
  113.        }
  114.  
  115.      // norm map parameters
  116.      stringstream normmap_id1;
  117.      stringstream normmap_id2;
  118.      normmap_id1 << "normmap_" << setfill('0') << setw(3) << i;
  119.      normmap_id2 << "normmap_options_" << setfill('0') << setw(3) << i;
  120.  
  121.      if(has_normmap)
  122.        {
  123.         // parameter #1
  124.         ofile << "     <newparam sid=\"" << normmap_id1.str() << "\">" << endl;
  125.         ofile << "      <surface type=\"2D\">" << endl;
  126.         ofile << "       <init_from>" << textures[materials[i].normmap].id << "</init_from>" << endl;
  127.         ofile << "       <format>A8R8G8B8</format>" << endl;
  128.         ofile << "      </surface>" << endl;
  129.         ofile << "     </newparam>" << endl;
  130.         // parameter #2
  131.         ofile << "     <newparam sid=\"" << normmap_id2.str() << "\">" << endl;
  132.         ofile << "      <sampler2D>" << endl;
  133.         ofile << "       <source>" << normmap_id1.str() << "</source>" << endl;
  134.         ofile << "       <minfilter>LINEAR_MIPMAP_LINEAR</minfilter>" << endl;
  135.         ofile << "       <magfilter>LINEAR</magfilter>" << endl;
  136.         ofile << "      </sampler2D>" << endl;
  137.         ofile << "     </newparam>" << endl;
  138.        }
  139.  
  140.      ofile << "     <lambert>" << endl;
  141.      if(has_basemap) {
  142.         ofile << "      <diffuse>" << endl;
  143.         ofile << "       <texture texture=\"" << basemap_id2.str() << "\" texcoord=\"TEX0\" />" << endl;
  144.         ofile << "      </diffuse>" << endl;
  145.        }
  146.      if(has_specmap) {
  147.         ofile << "      <specular>" << endl;
  148.         ofile << "       <texture texture=\"" << specmap_id2.str() << "\" texcoord=\"TEX0\" />" << endl;
  149.         ofile << "      </specular>" << endl;
  150.        }
  151.      ofile << "     </lambert>" << endl;
  152.  
  153.      if(has_normmap) {
  154.         ofile << "      <extra>" << endl;
  155.         ofile << "       <technique profile=\"OpenCOLLADA3dsMax\">" << endl;
  156.         ofile << "        <bump bumptype=\"NORMALMAP\">" << endl;
  157.         ofile << "         <texture texture=\"" << normmap_id2.str() << "\" texcoord=\"TEX0\" />" << endl;
  158.         ofile << "        </bump>" << endl;
  159.         ofile << "       </technique>" << endl;
  160.         ofile << "      </extra>" << endl;
  161.        }
  162.  
  163.      ofile << "    </technique>" << endl;
  164.      ofile << "   </profile_COMMON>" << endl;
  165.      ofile << "  </effect>" << endl;
  166.     }
  167.  ofile << " </library_effects>" << endl;
  168.  ofile << endl;
  169.  
  170.  // save <library_materials>
  171.  ofile << " <!-- LIBRARY_MATERIALS -->" << endl;
  172.  ofile << " <library_materials>" << endl;
  173.  for(size_t i = 0; i < materials.size(); i++) {
  174.      ofile << "  <material id=\"" << materials[i].id << "\">" << endl;
  175.      ofile << "   <instance_effect url=\"#effects_" << setfill('0') << setw(3) << i << "\" />" << endl;
  176.      ofile << "  </material>" << endl;
  177.     }
  178.  ofile << " </library_materials>" << endl;
  179.  ofile << endl;
  180.  
  181.  // save <library_geometries>
  182.  ofile << " <!-- LIBRARY_GEOMETRIES -->" << endl;
  183.  ofile << " <library_geometries>" << endl;
  184.  ofile << "  <geometry id=\"" << data.id << "\" name=\"" << data.name << "\">" << endl;
  185.  ofile << "   <mesh>" << endl;
  186.  
  187.  // for each mesh
  188.  for(size_t mesh_index = 0; mesh_index < data.meshlist.size(); mesh_index++)
  189.     {
  190.      // get vertices
  191.      VTX_BUFFER& vertices = data.meshlist[mesh_index]->vertices;
  192.      size_t n_vertices = vertices.elem;
  193.  
  194.      // get surfaces
  195.      std::deque<IDX_BUFFER>& surfaces = data.meshlist[mesh_index]->surfaces;
  196.      size_t n_surfaces = surfaces.size();
  197.  
  198.      // get properties
  199.      bool has_vertex = (vertices.flags & VERTEX_POSITION) != 0;
  200.      bool has_normal = (vertices.flags & VERTEX_NORMAL) != 0;
  201.      bool has_texmap = (vertices.flags & VERTEX_UV) != 0;
  202.  
  203.      // vertex data identifiers
  204.      stringstream pid; pid << data.id << "_position";
  205.      stringstream nid; nid << data.id << "_normal";
  206.      stringstream tid; tid << data.id << "_uv";
  207.      stringstream vid; vid << data.id << "_vertices";
  208.      
  209.      // save <source> (positions)
  210.      if(has_vertex) {
  211.         size_t n_values = n_vertices*3;
  212.         ofile << "    <source id=\"" << pid.str() << "\" name=\"" << pid.str() << "\">" << endl;
  213.         ofile << "     <float_array id=\"" << pid.str() << "_array\" name=\"" << pid.str() << "_array\" count=\"" << n_values << "\">" << endl;
  214.         for(size_t i = 0; i < n_vertices; i++) ofile << "      " << vertices.data[i].vx << " " << vertices.data[i].vy << " " << vertices.data[i].vz << endl;
  215.         ofile << "     </float_array>" << endl;
  216.         ofile << "     <technique_common>" << endl;
  217.         ofile << "      <accessor source=\"#" << pid.str() << "_array\" count=\"" << n_vertices << "\" stride=\"3\">" << endl;
  218.         ofile << "       <param name=\"X\" type=\"float\" />" << endl;
  219.         ofile << "       <param name=\"Y\" type=\"float\" />" << endl;
  220.         ofile << "       <param name=\"Z\" type=\"float\" />" << endl;
  221.         ofile << "      </accessor>" << endl;
  222.         ofile << "     </technique_common>" << endl;
  223.         ofile << "    </source>" << endl;
  224.        }
  225.  
  226.      // save <source> (normals)
  227.      if(has_normal) {
  228.         size_t n_values = n_vertices*3;
  229.         ofile << "    <source id=\"" << nid.str() << "\" name=\"" << nid.str() << "\">" << endl;
  230.         ofile << "     <float_array id=\"" << nid.str() << "_array\" name=\"" << nid.str() << "_array\" count=\"" << n_values << "\">" << endl;
  231.         for(size_t i = 0; i < n_vertices; i++) ofile << "      " << vertices.data[i].nx << " " << vertices.data[i].ny << " " << vertices.data[i].nz << endl;
  232.         ofile << "     </float_array>" << endl;
  233.         ofile << "     <technique_common>" << endl;
  234.         ofile << "      <accessor source=\"#" << nid.str() << "_array\" count=\"" << n_vertices << "\" stride=\"3\">" << endl;
  235.         ofile << "       <param name=\"X\" type=\"float\" />" << endl;
  236.         ofile << "       <param name=\"Y\" type=\"float\" />" << endl;
  237.         ofile << "       <param name=\"Z\" type=\"float\" />" << endl;
  238.         ofile << "      </accessor>" << endl;
  239.         ofile << "     </technique_common>" << endl;
  240.         ofile << "    </source>" << endl;
  241.        }
  242.  
  243.      // save <source> (UV)
  244.      if(has_texmap) {
  245.         size_t n_values = n_vertices*2;
  246.         ofile << "    <source id=\"" << tid.str() << "\" name=\"" << tid.str() << "\">" << endl;
  247.         ofile << "     <float_array id=\"" << tid.str() << "_array\" name=\"" << tid.str() << "_array\" count=\"" << n_values << "\">" << endl;
  248.         for(size_t i = 0; i < n_vertices; i++) ofile << "      " << vertices.data[i].tu << " " << vertices.data[i].tv << endl;
  249.         ofile << "     </float_array>" << endl;
  250.         ofile << "     <technique_common>" << endl;
  251.         ofile << "      <accessor source=\"#" << tid.str() << "_array\" count=\"" << n_vertices << "\" stride=\"2\">" << endl;
  252.         ofile << "       <param name=\"S\" type=\"float\" />" << endl;
  253.         ofile << "       <param name=\"T\" type=\"float\" />" << endl;
  254.         ofile << "      </accessor>" << endl;
  255.         ofile << "     </technique_common>" << endl;
  256.         ofile << "    </source>" << endl;
  257.        }
  258.  
  259.      // save <vertices>
  260.      if(has_vertex) {
  261.         ofile << "    <vertices id=\"" << vid.str() << "\">" << endl;
  262.         ofile << "     <input semantic=\"POSITION\" source=\"#" << pid.str() << "\" />" << endl;
  263.         ofile << "    </vertices>" << endl;
  264.        }
  265.  
  266.      // save <polygons>
  267.      for(size_t i = 0; i < surfaces.size(); i++)
  268.         {
  269.          unsigned char type = surfaces[i].type;
  270.          unsigned char format = surfaces[i].format;
  271.  
  272.          // material index
  273.          uint32 material_index = surfaces[i].material;
  274.          if(!(material_index < materials.size())) return error("DAE EXPORT: Material index out of range.");
  275.          string material_id = materials[material_index].id;
  276.  
  277.          if(type == FACE_TYPE_TRIANGLES)
  278.            {
  279.             // begin
  280.             size_t n_triangles = surfaces[i].elem/3;
  281.             ofile << "    <triangles count=\"" << n_triangles << "\" material=\"" << material_id << "\">" << endl;
  282.  
  283.             // position + normals + texture
  284.             if(has_vertex && has_normal && has_texmap) {
  285.                ofile << "     <input semantic=\"VERTEX\" source=\"#" << vid.str() << "\" offset=\"0\" />" << endl;
  286.                ofile << "     <input semantic=\"NORMAL\" source=\"#" << nid.str() << "\" offset=\"1\" />" << endl;
  287.                ofile << "     <input semantic=\"TEXCOORD\" source=\"#" << tid.str() << "\" offset=\"2\" />" << endl;
  288.                ofile << "     <p>" << endl;
  289.  
  290.                if(format == FACE_FORMAT_UINT_08) {
  291.                   uint08* data = reinterpret_cast<uint08*>(surfaces[i].data.get());
  292.                   size_t curr = 0;
  293.                   for(size_t j = 0; j < n_triangles; j++) {
  294.                       size_t a = data[curr++];
  295.                       size_t b = data[curr++];
  296.                       size_t c = data[curr++];
  297.                       ofile << "     " << a << " " << a << " " <<  a << " " << b << " " << b << " " << b << " " << c << " " << c << " " << c << endl;
  298.                      }
  299.                  }
  300.                else if(format == FACE_FORMAT_UINT_16) {
  301.                   uint16* data = reinterpret_cast<uint16*>(surfaces[i].data.get());
  302.                   size_t curr = 0;
  303.                   for(size_t j = 0; j < n_triangles; j++) {
  304.                       size_t a = data[curr++];
  305.                       size_t b = data[curr++];
  306.                       size_t c = data[curr++];
  307.                       ofile << "     " << a << " " << a << " " << a << " " << b << " " << b << " " << b << " " << c << " " << c << " " << c << endl;
  308.                      }
  309.                  }
  310.                else if(format == FACE_FORMAT_UINT_32) {
  311.                   uint32* data = reinterpret_cast<uint32*>(surfaces[i].data.get());
  312.                   size_t curr = 0;
  313.                   for(size_t j = 0; j < n_triangles; j++) {
  314.                       size_t a = data[curr++];
  315.                       size_t b = data[curr++];
  316.                       size_t c = data[curr++];
  317.                       ofile << "     " << a << " " << a << " " << a << " " << b << " " << b << " " << b << " " << c << " " << c << " " << c << endl;
  318.                      }
  319.                  }
  320.  
  321.                ofile << "</p>" << endl;
  322.               }
  323.             // position
  324.             else if(has_vertex && !has_normal && !has_texmap) {
  325.                ofile << "     <input semantic=\"VERTEX\" source=\"#" << vid.str() << "\" offset=\"0\" />" << endl;
  326.               }
  327.             // position + texture
  328.             else if(!has_normal && has_texmap)
  329.               {
  330.                ofile << "     <input semantic=\"VERTEX\" source=\"#" << vid.str() << "\" offset=\"0\" />" << endl;
  331.                ofile << "     <input semantic=\"TEXCOORD\" source=\"#" << tid.str() << "\" offset=\"1\" />" << endl;
  332.                ofile << "     <p>" << endl;
  333.  
  334.                if(format == FACE_FORMAT_UINT_08) {
  335.                   uint08* data = reinterpret_cast<uint08*>(surfaces[i].data.get());
  336.                   size_t curr = 0;
  337.                   for(size_t j = 0; j < n_triangles; j++) {
  338.                       size_t a = data[curr++];
  339.                       size_t b = data[curr++];
  340.                       size_t c = data[curr++];
  341.                       ofile << "     " << a << " " << a << " " << b << " " << b << " " << c << " " << c << endl;
  342.                      }
  343.                  }
  344.                else if(format == FACE_FORMAT_UINT_16) {
  345.                   uint16* data = reinterpret_cast<uint16*>(surfaces[i].data.get());
  346.                   size_t curr = 0;
  347.                   for(size_t j = 0; j < n_triangles; j++) {
  348.                       size_t a = data[curr++];
  349.                       size_t b = data[curr++];
  350.                       size_t c = data[curr++];
  351.                       ofile << "     " << a << " " << a << " " << b << " " << b << " " << c << " " << c << endl;
  352.                      }
  353.                  }
  354.                else if(format == FACE_FORMAT_UINT_32) {
  355.                   uint32* data = reinterpret_cast<uint32*>(surfaces[i].data.get());
  356.                   size_t curr = 0;
  357.                   for(size_t j = 0; j < n_triangles; j++) {
  358.                       size_t a = data[curr++];
  359.                       size_t b = data[curr++];
  360.                       size_t c = data[curr++];
  361.                       ofile << "     " << a << " " << a << " " << b << " " << b << " " << c << " " << c << endl;
  362.                      }
  363.                  }
  364.  
  365.                ofile << "     </p>" << endl;
  366.               }
  367.             // position + normals
  368.             else if(has_normal && !has_texmap)
  369.               {
  370.                ofile << "     <input semantic=\"VERTEX\" source=\"#" << vid.str() << "\" offset=\"0\" />" << endl;
  371.                ofile << "     <input semantic=\"NORMAL\" source=\"#" << nid.str() << "\" offset=\"1\" />" << endl;
  372.                ofile << "     <p>" << endl;
  373.  
  374.                if(format == FACE_FORMAT_UINT_08) {
  375.                   uint08* data = reinterpret_cast<uint08*>(surfaces[i].data.get());
  376.                   size_t curr = 0;
  377.                   for(size_t j = 0; j < n_triangles; j++) {
  378.                       size_t a = data[curr++];
  379.                       size_t b = data[curr++];
  380.                       size_t c = data[curr++];
  381.                       ofile << "     " << a << " " << a << " " << b << " " << b << " " << c << " " << c << endl;
  382.                      }
  383.                  }
  384.                else if(format == FACE_FORMAT_UINT_16) {
  385.                   uint16* data = reinterpret_cast<uint16*>(surfaces[i].data.get());
  386.                   size_t curr = 0;
  387.                   for(size_t j = 0; j < n_triangles; j++) {
  388.                       size_t a = data[curr++];
  389.                       size_t b = data[curr++];
  390.                       size_t c = data[curr++];
  391.                       ofile << "     " << a << " " << a << " " << b << " " << b << " " << c << " " << c << endl;
  392.                      }
  393.                  }
  394.                else if(format == FACE_FORMAT_UINT_32) {
  395.                   uint32* data = reinterpret_cast<uint32*>(surfaces[i].data.get());
  396.                   size_t curr = 0;
  397.                   for(size_t j = 0; j < n_triangles; j++) {
  398.                       size_t a = data[curr++];
  399.                       size_t b = data[curr++];
  400.                       size_t c = data[curr++];
  401.                       ofile << "     " << a << " " << a << " " << b << " " << b << " " << c << " " << c << endl;
  402.                      }
  403.                  }
  404.  
  405.                ofile << "     </p>" << endl;
  406.               }
  407.             else return error("DAE EXPORT: Invalid input semantics.");
  408.  
  409.             // end
  410.             ofile << "    </triangles>" << endl;
  411.            }
  412.          else if(type == FACE_TYPE_TRISTRIP)
  413.            {
  414.            }
  415.          else if(type == FACE_TYPE_TRISTRIPCUT)
  416.            {
  417.            }
  418.          else
  419.             return error("DAE EXPORT: Invalid face type.");
  420.         }
  421.     }
  422.  
  423.  // terminate <library_geometries>
  424.  ofile << "   </mesh>" << endl;
  425.  ofile << "  </geometry>" << endl;
  426.  ofile << " </library_geometries>" << endl;
  427.  ofile << endl;
  428.  
  429.  // skeleton and weights
  430.  bool has_skeletons = (sl.size() > 0);
  431.  if(has_skeletons)
  432.    {
  433.     // save <library_nodes>
  434.     ofile << " <!-- LIBRARY_NODES -->" << endl;
  435.     ofile << " <library_nodes>" << endl;
  436.     for(size_t i = 0; i < sl.size(); i++) {
  437.         stringstream ss;
  438.         sl[i].tree.PrintColladaNodeHeirarchy(sl[i].id, ss);
  439.         ofile << ss.str();
  440.        }
  441.     ofile << " </library_nodes>" << endl;
  442.     ofile << endl;
  443.  
  444.     // save <library_controllers>
  445.     ofile << " <!-- LIBRARY_CONTROLLERS -->" << endl;
  446.     ofile << " <library_controllers>" << endl;
  447.     for(size_t i = 0; i < data.meshlist.size(); i++)
  448.        {
  449.         ofile << "  <controller id=\"" << data.id << "_controller\">" << endl;
  450.         ofile << "   <skin source=\"#" << data.id << "\">" << endl;
  451.         for(size_t j = 0; j < sl.size(); j++) {
  452.             stringstream ss;
  453.             sl[j].tree.PrintColladaJoints(sl[j].id, ss);
  454.             ofile << ss.str();
  455.            }
  456.         for(size_t j = 0; j < sl.size(); j++) {
  457.             stringstream ss;
  458.             sl[j].tree.PrintColladaBindMatrices(sl[j].id, ss);
  459.             ofile << ss.str();
  460.            }
  461.         // vertex weights
  462.         if(data.meshlist[i]->vertices.flags & VERTEX_WEIGHTS)
  463.           {
  464.            size_t n_weights = 4*data.meshlist[i]->vertices.elem;
  465.            ofile << "    <source id=\"" << data.id << "_weights\">" << endl;
  466.            ofile << "     <float_array count=\"" << n_weights << "\">" << endl;
  467.            for(size_t j = 0; j < data.meshlist[i]->vertices.elem; j++) {
  468.                float w1 = data.meshlist[i]->vertices.data[j].w1;
  469.                float w2 = data.meshlist[i]->vertices.data[j].w2;
  470.                float w3 = data.meshlist[i]->vertices.data[j].w3;
  471.                float w4 = data.meshlist[i]->vertices.data[j].w4;
  472.                ofile << "      " << w1 << " " << w2 << " " << w3 << " " << w4 << endl;
  473.               }
  474.            ofile << "     </float_array>" << endl;
  475.            ofile << "     <technique_common>" << endl;
  476.            ofile << "      <acessor source=\"#" << data.id << "_weights\" count=\"" << n_weights << "\" stride=\"1\">" << endl;
  477.            ofile << "       <param name=\"WEIGHT\" type=\"float\" />" << endl;
  478.            ofile << "      </acessor>" << endl;
  479.            ofile << "     </technique_common>" << endl;
  480.            ofile << "    </source>" << endl;
  481.           }
  482.         // joints
  483.         for(size_t j = 0; j < sl.size(); j++) {
  484.             ofile << "    <joints>" << endl;
  485.             ofile << "     <input semantic=\"JOINT\" source=\"#" << sl[j].id << "_joints\" />" << endl;
  486.             ofile << "     <input semantic=\"INV_BIND_MATRIX\" source=\"#" << sl[j].id << "_matrices\" />" << endl;
  487.             ofile << "    </joints>" << endl;
  488.            }
  489.         // vertex weights
  490.         for(size_t j = 0; j < sl.size(); j++) {
  491.             ofile << "    <vertex_weights count=\"" << data.meshlist[i]->vertices.elem << "\">" << endl;
  492.             ofile << "     <input semantic=\"JOINT\" source=\"#" << sl[j].id << "_joints\"/>" << endl;
  493.             ofile << "     <input semantic=\"WEIGHT\" source=\"#" << data.id << "_weights\"/>" << endl;
  494.             ofile << "     <vcount>";
  495.             for(size_t k = 0; k < data.meshlist[i]->vertices.elem - 1; k++) ofile << "4 ";
  496.             ofile << 4 << "</vcount>" << endl;
  497.             ofile << "     <v>" << endl;
  498.             for(size_t k = 0; k < data.meshlist[i]->vertices.elem; k++) {
  499.                 size_t weight_offset = 4*k;
  500.                 ofile << "      " <<
  501.                          data.meshlist[i]->vertices.data[k].b1 << " " << weight_offset + 0 << " " <<
  502.                          data.meshlist[i]->vertices.data[k].b2 << " " << weight_offset + 1 << " " <<
  503.                          data.meshlist[i]->vertices.data[k].b3 << " " << weight_offset + 2 << " " <<
  504.                          data.meshlist[i]->vertices.data[k].b4 << " " << weight_offset + 3 << endl;
  505.                }
  506.             ofile << "     </v>" << endl;
  507.             ofile << "    </vertex_weights>" << endl;
  508.            }
  509.         ofile << "   </skin>" << endl;
  510.         ofile << "  </controller>" << endl;
  511.        }
  512.     ofile << " </library_controllers>" << endl;
  513.     ofile << endl;
  514.    }
  515.  
  516.  // save <scene>
  517.  ofile << " <!-- SCENE -->" << endl;
  518.  ofile << " <library_visual_scenes>" << endl;
  519.  ofile << "  <visual_scene id=\"DefaultScene\">" << endl;
  520.  ofile << "   <node id=\"DefaultNode\" name=\"DefaultNode\">" << endl;
  521.  ofile << "    <rotate>1 0 0 90</rotate>" << endl;
  522.  ofile << "    <instance_geometry url=\"#" << data.id << "\">" << endl;
  523.  for(size_t i = 0; i < materials.size(); i++)
  524.     {
  525.      ofile << "     <bind_material>" << endl;
  526.      ofile << "      <technique_common>" << endl;
  527.      ofile << "       <instance_material symbol=\"" << materials[i].id << "\" target=\"#" << materials[i].id << "\">" << endl;
  528.      ofile << "        <bind_vertex_input semantic=\"TEX0\" input_semantic=\"TEXCOORD\" input_set=\"0\" />" << endl;
  529.      ofile << "       </instance_material>" << endl;
  530.      ofile << "      </technique_common>" << endl;
  531.      ofile << "     </bind_material>" << endl;
  532.     }
  533.  ofile << "    </instance_geometry>" << endl;
  534.  ofile << "   </node>" << endl;
  535.  
  536.  // create skeleton instances
  537.  for(size_t i = 0; i < sl.size(); i++)
  538.     {
  539.      // create skeleton instance (refers to a list of node names)
  540.      ofile << "   <!-- SKELETON INSTANCE -->" << endl;
  541.      ofile << "   <node id=\"" << sl[i].id << "_instance\">" << endl;
  542.      ofile << "    <rotate>1 0 0 90</rotate>" << endl;
  543.      ofile << "    <instance_node url=\"#" << sl[i].id << "\" />" << endl;
  544.      ofile << "   </node>" << endl;
  545.      // create skeleton controller (must define which skeleton and which controller to use)
  546.      ofile << "   <!-- SKELETON CONTROLLER INSTANCE -->" << endl;
  547.      ofile << "   <node>" << endl;
  548.      ofile << "    <instance_controller url=\"#" << data.id << "_controller\">" << endl;
  549.      ofile << "     <skeleton>#" << sl[i].id << "_instance</skeleton>" << endl;
  550.      ofile << "    </instance_controller>" << endl;
  551.      ofile << "   </node>" << endl;
  552.     }
  553.  ofile << "  </visual_scene>" << endl;
  554.  ofile << " </library_visual_scenes>" << endl;
  555.  ofile << endl;
  556.  
  557.  // save <scene>
  558.  ofile << " <!-- SCENE -->" << endl;
  559.  ofile << " <scene>" << endl;
  560.  ofile << "  <instance_visual_scene url=\"#DefaultScene\"></instance_visual_scene>" << endl;
  561.  ofile << " </scene>" << endl;
  562.  ofile << endl;
  563.  
  564.  // finish <collada>
  565.  ofile << "</COLLADA>";
  566.  return true;
  567. }
  568.  
  569. */