Advertisement
maspeir

OBJ Loader.cpp

Dec 10th, 2012
1,611
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.54 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "OBJ Loader.h"
  6.  
  7. face::face()
  8. {
  9.     vertices = new vector<long>;
  10.     normals = new vector<long>;
  11.     uv = new vector<long>;
  12. }
  13.  
  14. face::face(const face &right)
  15. {
  16.     long    i;
  17.  
  18.     vertices = new vector<long>;
  19.     normals = new vector<long>;
  20.     uv = new vector<long>;
  21.  
  22.     for(i = 0;i < right.vertices->size();i++)
  23.         vertices->push_back(right.vertices->at(i));
  24.     for(i = 0;i < right.normals->size();i++)
  25.         normals->push_back(right.normals->at(i));
  26.     for(i = 0;i < right.uv->size();i++)
  27.         uv->push_back(right.uv->at(i));
  28. }
  29.  
  30. face::~face()
  31. {
  32.     delete vertices;
  33.     vertices = NULL;
  34.  
  35.     delete normals;
  36.     normals = NULL;
  37.  
  38.     delete uv;
  39.     uv = NULL;
  40. }
  41.  
  42. long face::GetNumVertices() const
  43. {
  44.     return(vertices->size());
  45. }
  46.  
  47. long face::GetNumNormals() const
  48. {
  49.     return(normals->size());
  50. }
  51.  
  52. long face::GetNumUVs() const
  53. {
  54.     return(uv->size());
  55. }
  56.  
  57. void face::AddVertex(long index)
  58. {
  59.     vertices->push_back(index);
  60. }
  61.  
  62. long face::GetVertex(long index) const
  63. {
  64.     if(index < 0 || index > vertices->size() - 1)
  65.         return(NULL);
  66.  
  67.     return(vertices->at(index));
  68. }
  69.  
  70. void face::AddNormal(long index)
  71. {
  72.     normals->push_back(index);
  73. }
  74.  
  75. long face::GetNormal(long index) const
  76. {
  77.     if(index < 0 || index > normals->size() - 1)
  78.         return(NULL);
  79.  
  80.     return(normals->at(index));
  81. }
  82.  
  83. void face::AddUV(long index)
  84. {
  85.     uv->push_back(index);
  86. }
  87.  
  88. long face::GetUV(long index) const
  89. {
  90.     if(index < 0 || index > uv->size() - 1)
  91.         return(NULL);
  92.  
  93.     return(uv->at(index));
  94. }
  95.  
  96. OBJ::OBJ()
  97. {
  98.     vertices = new vector<OBJ_vertex>;
  99.     normals = new vector<OBJ_vertex>;
  100.     uv = new vector<uv_coords>;
  101.     faces = new vector<face>;
  102. }
  103.  
  104. OBJ::~OBJ()
  105. {
  106.     delete vertices;
  107.     vertices = NULL;
  108.  
  109.     delete normals;
  110.     normals = NULL;
  111.  
  112.     delete uv;
  113.     uv = NULL;
  114.  
  115.     delete faces;
  116.     faces = NULL;
  117. }
  118.  
  119. long OBJ::GetNumVertices() const
  120. {
  121.     return(vertices->size());
  122. }
  123.  
  124. long OBJ::GetNumNormals() const
  125. {
  126.     return(normals->size());
  127. }
  128.  
  129. long OBJ::GetNumUVs() const
  130. {
  131.     return(uv->size());
  132. }
  133.  
  134. long OBJ::GetNumFaces() const
  135. {
  136.     return(faces->size());
  137. }
  138.  
  139. OBJ_vertex *OBJ::GetVertex(long index) const
  140. {
  141.     if(index < 0 || index > vertices->size() - 1)
  142.         return(NULL);
  143.  
  144.     return(&vertices->at(index));
  145. }
  146.  
  147. OBJ_vertex *OBJ::GetNormal(long index) const
  148. {
  149.     if(index < 0 || index > normals->size() - 1)
  150.         return(NULL);
  151.  
  152.     return(&normals->at(index));
  153. }
  154.  
  155. uv_coords *OBJ::GetUV(long index) const
  156. {
  157.     if(index < 0 || index > uv->size() - 1)
  158.         return(NULL);
  159.  
  160.     return(&uv->at(index));
  161. }
  162.  
  163. face *OBJ::GetFace(long index) const
  164. {
  165.     if(index < 0 || index > faces->size() - 1)
  166.         return(NULL);
  167.  
  168.     return(&faces->at(index));
  169. }
  170.  
  171. void OBJ::LoadOBJ(string file_name)
  172. {
  173.     FILE        *fs;
  174.     char        c;
  175.     bool        done,has_normals,has_uvs;
  176.     OBJ_vertex  vert;
  177.     uv_coords   uvs;
  178.     face        *temp_face;
  179.     float       x,y,z;
  180.     float       u,v;
  181.     int         vert_ind,norm_ind,uv_ind;
  182.     int         read_count;
  183.  
  184.     if(fopen_s(&fs,file_name.c_str(),"r") != 0)
  185.         return;
  186.  
  187.     done = false;
  188.     has_normals = false;
  189.     has_uvs = false;
  190.  
  191.     while(!done)
  192.     {
  193.         c = fgetc(fs);
  194.         switch(c)
  195.         {
  196.             case '#': // Comment. Fall through
  197.             case 'u': // Fall through
  198.             case 's': // Fall through
  199.             case 'g': // Group. Not supported. Fall through
  200.                 while(fgetc(fs) != '\n'); // Skip to the next line
  201.             break;
  202.             case EOF: // End of file reached. We be done.
  203.                 done = true;
  204.             break;
  205.             case 'v': // Loading vertices is easy. Faces, not so much...
  206.                 c = fgetc(fs); // The next character determines what type of vertex we are loading
  207.                 switch(c)
  208.                 {
  209.                     case ' ': // Loading vertices
  210.                         fscanf_s(fs,"%f %f %f\n",&x,&y,&z);
  211.                         vert.SetX(x);
  212.                         vert.SetY(y);
  213.                         vert.SetZ(z);
  214.                         vertices->push_back(vert);
  215.                     break;
  216.                     case 'n': // Loading normals
  217.                         has_normals = true;
  218.                         fscanf_s(fs,"%f %f %f\n",&x,&y,&z);
  219.                         vert.SetX(x);
  220.                         vert.SetY(y);
  221.                         vert.SetZ(z);
  222.                         normals->push_back(vert);
  223.                     break;
  224.                     case 't': // Loading UVs
  225.                         has_uvs = true;
  226.                         fscanf_s(fs,"%f %f\n",&u,&v);
  227.                         uvs.SetU(u);
  228.                         uvs.SetV(v);
  229.                         uv->push_back(uvs);
  230.                     break;
  231.                     default: // Uh oh... What are we trying to read here? Someone screwed up their OBJ exporter...
  232.                         cout << "Invalid vertex type: " << "v" << c << " Should be of type \"v \", \"vn\" or \"vt\"." << endl;
  233.                         return;
  234.                 }
  235.             break;
  236.             case 'f':
  237.                 if(has_normals && has_uvs)
  238.                 {
  239.                     temp_face = new face;
  240.                     while(fgetc(fs) != '\n')
  241.                     {
  242.                         vert_ind = 0;
  243.                         norm_ind = 0;
  244.                         uv_ind = 0;
  245.  
  246.                         read_count = fscanf_s(fs,"%d/%d/%d",&vert_ind,&uv_ind,&norm_ind);
  247.                         if((read_count != 3) || (vert_ind == 0) || (uv_ind == 0) || (norm_ind == 0)) // Valid indices start at 1 in a .OBJ file. Don't know why... O.o
  248.                         {
  249.                             delete temp_face;
  250.                             temp_face = NULL;
  251.  
  252.                             cout << "Invalid vertex index." << endl;
  253.                             return;
  254.                         }
  255.  
  256.                         temp_face->AddVertex(vert_ind - 1); // We want the indices to start at 0, so subtract 1.
  257.                         temp_face->AddNormal(norm_ind - 1);
  258.                         temp_face->AddUV(uv_ind - 1);
  259.                     }
  260.                     faces->push_back(*temp_face);
  261.  
  262.                     delete temp_face;
  263.                     temp_face = NULL;
  264.                 }else if(has_normals && !has_uvs){
  265.                     temp_face = new face;
  266.                     while(fgetc(fs) != '\n')
  267.                     {
  268.                         vert_ind = 0;
  269.                         norm_ind = 0;
  270.  
  271.                         read_count = fscanf_s(fs,"%d//%d",&vert_ind,&norm_ind);
  272.                         if((read_count != 2) || (vert_ind == 0) || (norm_ind == 0))
  273.                         {
  274.                             delete temp_face;
  275.                             temp_face = NULL;
  276.  
  277.                             cout << "Invalid vertex index." << endl;
  278.                             return;
  279.                         }
  280.  
  281.                         temp_face->AddVertex(vert_ind - 1);
  282.                         temp_face->AddNormal(norm_ind - 1);
  283.                         temp_face->AddUV(0);
  284.                     }
  285.                     faces->push_back(*temp_face);
  286.  
  287.                     delete temp_face;
  288.                     temp_face = NULL;
  289.                 }else if(!has_normals && has_uvs){
  290.                     temp_face = new face;
  291.                     while(fgetc(fs) != '\n')
  292.                     {
  293.                         vert_ind = 0;
  294.                         uv_ind = 0;
  295.  
  296.                         read_count = fscanf_s(fs,"%d/%d/",&vert_ind,&uv_ind);
  297.                         if((read_count != 2) || (vert_ind == 0) || (uv_ind == 0))
  298.                         {
  299.                             delete temp_face;
  300.                             temp_face = NULL;
  301.  
  302.                             cout << "Invalid vertex index." << endl;
  303.                             return;
  304.                         }
  305.  
  306.                         temp_face->AddVertex(vert_ind - 1);
  307.                         temp_face->AddNormal(0);
  308.                         temp_face->AddUV(uv_ind - 1);
  309.                     }
  310.                     faces->push_back(*temp_face);
  311.  
  312.                     delete temp_face;
  313.                     temp_face = NULL;
  314.                 }else if(!has_normals && !has_uvs){
  315.                     temp_face = new face;
  316.                     while(fgetc(fs) != '\n')
  317.                     {
  318.                         vert_ind = 0;
  319.  
  320.                         read_count = fscanf_s(fs,"%d//",&vert_ind);
  321.                         if((read_count != 1) || (vert_ind == 0))
  322.                         {
  323.                             delete temp_face;
  324.                             temp_face = NULL;
  325.  
  326.                             cout << "Invalid vertex index." << endl;
  327.                             return;
  328.                         }
  329.  
  330.                         temp_face->AddVertex(vert_ind - 1);
  331.                         temp_face->AddNormal(0);
  332.                         temp_face->AddUV(0);
  333.                     }
  334.                     faces->push_back(*temp_face);
  335.  
  336.                     delete temp_face;
  337.                     temp_face = NULL;
  338.                 }
  339.             break;
  340.         }
  341.     }
  342.  
  343.     fclose(fs);
  344. }
  345.  
  346. void OBJ::DumpOBJ(void)
  347. {
  348.     long    i,j;
  349.  
  350.     for(i = 0;i < GetNumVertices();i++)
  351.         cout << GetVertex(i)->GetX() << " " << GetVertex(i)->GetY() << " " << GetVertex(i)->GetZ() << endl;
  352.  
  353.     for(i = 0;i < GetNumNormals();i++)
  354.         cout << GetNormal(i)->GetX() << " " << GetNormal(i)->GetY() << " " << GetNormal(i)->GetZ() << endl;
  355.  
  356.     for(i = 0;i < GetNumUVs();i++)
  357.         cout << GetUV(i)->GetU() << " " << GetUV(i)->GetV() << endl;
  358.  
  359.     for(i = 0;i < GetNumFaces();i++)
  360.     {
  361.         for(j = 0;j < GetFace(i)->GetNumVertices();j++)
  362.             cout << GetFace(i)->GetVertex(j) << "/" << GetFace(i)->GetUV(j) << "/" << GetFace(i)->GetNormal(j) << " ";
  363.         cout << endl;
  364.     }
  365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement