Back to index

nux  3.0.0
MeshFileLoader-OBJ.cpp
Go to the documentation of this file.
00001 
00002 #include "GLResource.h"
00003 #include "MeshFileLoader-OBJ.h"
00004 #include "MeshData.h"
00005 #include "NuxCore/Math/Vector3.h"
00006 #include "NuxCore/Math/Vector2.h"
00007 
00008 namespace nux
00009 {
00010 #define TOKEN_VERTEX_POS "v"
00011 #define TOKEN_VERTEX_NOR "vn"
00012 #define TOKEN_VERTEX_TEX "vt"
00013 #define TOKEN_FACE "f"
00014 
00015   struct ObjMeshVertex
00016   {
00017     nux::Vector3 pos;
00018     nux::Vector2 texcoord;
00019     nux::Vector3 normal;
00020   };
00021 
00022   /* This is a triangle, that we can render */
00023   struct ObjMeshFace
00024   {
00025     ObjMeshVertex vertices[3];
00026   };
00027 
00028   /* This contains a list of triangles */
00029   struct ObjMesh
00030   {
00031     std::vector<ObjMeshFace> faces;
00032   };
00033 
00034   /* Internal structure */
00035   struct _ObjMeshFaceIndex
00036   {
00037     int pos_index[3];
00038     int tex_index[3];
00039     int nor_index[3];
00040   };
00041 
00042   MeshData* LoadMeshFile_OBJ(const char* filename)
00043   {
00044     std::vector<nux::Vector4>           positions;
00045     std::vector<nux::Vector2>           texcoords;
00046     std::vector<nux::Vector3>           normals;
00047     std::vector<_ObjMeshFaceIndex>  faces;
00058     std::ifstream filestream;
00059     filestream.open(filename);
00060 
00061     std::string line_stream;    // No longer depending on char arrays thanks to: Dale Weiler
00062 
00063     while (std::getline(filestream, line_stream))
00064     {
00065       std::stringstream str_stream(line_stream);
00066       std::string type_str;
00067       str_stream >> type_str;
00068 
00069       if (type_str == TOKEN_VERTEX_POS)
00070       {
00071         nux::Vector4 pos;
00072         str_stream >> pos.x >> pos.y >> pos.z;
00073         pos.w = 1.0f;
00074         positions.push_back(pos);
00075       }
00076       else if (type_str == TOKEN_VERTEX_TEX)
00077       {
00078         nux::Vector2 tex;
00079         str_stream >> tex.x >> tex.y;
00080         texcoords.push_back(tex);
00081       }
00082       else if (type_str == TOKEN_VERTEX_NOR)
00083       {
00084         nux::Vector3 nor;
00085         str_stream >> nor.x >> nor.y >> nor.z;
00086         normals.push_back(nor);
00087       }
00088       else if (type_str == TOKEN_FACE)
00089       {
00090         _ObjMeshFaceIndex face_index;
00091         char interupt;
00092         for (int i = 0; i < 3; ++i)
00093         {
00094           str_stream >> face_index.pos_index[i] >> interupt
00095                        >> face_index.tex_index[i]  >> interupt
00096                        >> face_index.nor_index[i];
00097         }
00098         faces.push_back(face_index);
00099       }
00100     }
00101     // Explicit closing of the file
00102     filestream.close();
00103 
00104     nux::MeshData* md = new nux::MeshData;
00105     md->Allocate(faces.size(), nux::NUX_MESH_TRIANGLE, 3*faces.size(), 16 + 12 + 8);
00106 
00107     //md->_mesh_primitive_type = nux::NuxMeshPrimitiveType::NUX_MESH_TRIANGLE;
00108 
00109     size_t i = 0;
00110 
00111     float* vertex_buffer = (float*)md->_vertex_data;
00112 //     for (i = 0; i < positions.size(); i++)
00113 //     {
00114 //       vertex_buffer[9*i + 0] = positions[i].x;
00115 //       vertex_buffer[9*i + 1] = positions[i].y;
00116 //       vertex_buffer[9*i + 2] = positions[i].z;
00117 //       vertex_buffer[9*i + 3] = positions[i].w;
00118 // 
00119 //       vertex_buffer[9*i + 4] = normals[i].x;
00120 //       vertex_buffer[9*i + 5] = normals[i].y;
00121 //       vertex_buffer[9*i + 6] = normals[i].z;
00122 // 
00123 //       vertex_buffer[9*i + 7] = texcoords[i].x;
00124 //       vertex_buffer[9*i + 8] = texcoords[i].y;
00125 //     }
00126 
00127     int* index_buffer = (int*)md->_index_data;
00128     for (i = 0; i < faces.size(); i++)
00129     {
00130       index_buffer[3*i + 0] = 3*i + 0;  //faces[i].pos_index[0]-1;
00131       index_buffer[3*i + 1] = 3*i + 1;  //faces[i].pos_index[1]-1;
00132       index_buffer[3*i + 2] = 3*i + 2;  //faces[i].pos_index[2]-1;
00133 
00134       for (int j = 0; j < 3; j++)
00135       {
00136         int vi    = faces[i].pos_index[j]-1;
00137         int ni    = faces[i].nor_index[j]-1;
00138         int ti    = faces[i].tex_index[j]-1;
00139 
00140         vertex_buffer[27*i + 9*j + 0] = positions[vi].x;
00141         vertex_buffer[27*i + 9*j + 1] = positions[vi].y;
00142         vertex_buffer[27*i + 9*j + 2] = positions[vi].z;
00143         vertex_buffer[27*i + 9*j + 3] = positions[vi].w;
00144 
00145         vertex_buffer[27*i + 9*j + 4] = normals[ni].x;
00146         vertex_buffer[27*i + 9*j + 5] = normals[ni].y;
00147         vertex_buffer[27*i + 9*j + 6] = normals[ni].z;
00148 
00149         vertex_buffer[27*i + 9*j + 7] = texcoords[ti].x;
00150         vertex_buffer[27*i + 9*j + 8] = texcoords[ti].y;
00151       }
00152     }
00153 
00154     return md;
00155   }
00156 }