Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

OBJ Loader.cpp

By: maspeir on Dec 10th, 2012  |  syntax: C++  |  size: 7.54 KB  |  views: 671  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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. }