Advertisement
Guest User

Untitled

a guest
May 20th, 2017
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.17 KB | None | 0 0
  1. #include "objloader.h"
  2.  
  3. istream &safeGetline(istream &is, string &t)
  4. {
  5.     t.clear();
  6.     istream::sentry se(is, true);
  7.     auto sb = is.rdbuf();
  8.     for (;;)
  9.     {
  10.         auto c = sb->sbumpc();
  11.         switch (c)
  12.         {
  13.         case '\n':
  14.             return is;
  15.         case '\r':
  16.             if ('\n' == sb->sgetc())
  17.                 sb->sbumpc();
  18.             return is;
  19.         case EOF:
  20.             if (t.empty())
  21.                 is.setstate(ios::eofbit);
  22.             return is;
  23.         default:
  24.             t += static_cast<char>(c);
  25.         }
  26.     }
  27. }
  28.  
  29. string parseString(const char **token) {
  30.     string s;
  31.     *token += strspn(*token, " \n\t");
  32.     auto e = strcspn(*token, " \n\t\r");
  33.     s = string(*token, &(*token)[e]);
  34.     *token += e;
  35.     return s;
  36. }
  37.  
  38. struct VerticeA
  39. {
  40.     float x;
  41.     float y;
  42.     float z;
  43. };
  44.  
  45. struct NormalA
  46. {
  47.     float x;
  48.     float y;
  49.     float z;
  50. };
  51.  
  52. struct UVA
  53. {
  54.     float u;
  55.     float v;
  56. };
  57.  
  58. struct FaceIndexes
  59. {
  60.     int v;
  61.     int vt;
  62.     int vn;
  63. };
  64.  
  65. struct Face
  66. {
  67.     FaceIndexes point[3];
  68. };
  69.  
  70. struct ObjectAttributes
  71. {
  72.     int vcnt = 0;
  73.     int ncnt = 0;
  74.     int tcnt = 0;
  75.     int fcnt = 0;
  76.     vector<VerticeA> vertices;
  77.     vector<NormalA> normals;
  78.     vector<UVA> uvs;
  79.     vector<Face> faces;
  80.     string name;
  81. };
  82.  
  83. static const unordered_map<string, function<void(ObjectAttributes& attrib, string arguments)>> ProcessMap =
  84. {
  85.     {
  86.         "v",
  87.         [](ObjectAttributes& attrib, string arguments)
  88.         {
  89.             auto cs = arguments.c_str();
  90.             auto nextfloat = [&cs]() { size_t sz; auto f = stof(string(cs), &sz); cs += sz; return f; };
  91.             attrib.vertices.push_back({ nextfloat(), nextfloat(), nextfloat() });
  92.             ++attrib.vcnt;
  93.         }
  94.     },
  95.     {
  96.         "vt",
  97.         [](ObjectAttributes& attrib, string arguments)
  98.         {
  99.             auto cs = arguments.c_str();
  100.             auto nextfloat = [&cs]() { size_t sz; auto f = stof(string(cs), &sz); cs += sz; return f; };
  101.             attrib.uvs.push_back({ nextfloat(), nextfloat() });
  102.             ++attrib.tcnt;
  103.         }
  104.     },
  105.     {
  106.         "vn",
  107.         [](ObjectAttributes& attrib, string arguments)
  108.         {
  109.             auto cs = arguments.c_str();
  110.             auto nextfloat = [&cs]() { size_t sz; auto f = stof(string(cs), &sz); cs += sz; return f; };
  111.             attrib.normals.push_back({ nextfloat(), nextfloat(), nextfloat() });
  112.             ++attrib.ncnt;
  113.         }
  114.     },
  115.     {
  116.         "f",
  117.         [](ObjectAttributes& attrib, string arguments)
  118.         {
  119.             auto cs = arguments.c_str();
  120.             auto token = &cs;
  121.             Face f;
  122.             for (auto i = 0; i < 3; ++i)
  123.             {
  124.                 string indexes = parseString(token);
  125.                 auto cs = indexes.c_str();
  126.                 auto nextindex = [&cs]()
  127.                 {
  128.                     size_t sz;
  129.                     auto f = stof(string(cs), &sz);
  130.                     cs += sz;
  131.                     if ('/' == *cs)
  132.                         ++cs;
  133.                     return f;
  134.                 };
  135.                 f.point[i].v = static_cast<int>(nextindex());
  136.                 f.point[i].vt = static_cast<int>(nextindex());
  137.                 f.point[i].vn = static_cast<int>(nextindex());
  138.             }
  139.             attrib.faces.push_back(f);
  140.             ++attrib.fcnt;
  141.         }
  142.     },
  143.     {
  144.         "o",
  145.         [](ObjectAttributes& attrib, string arguments)
  146.         {
  147.             auto cs = arguments.c_str();
  148.             auto token = &cs;
  149.             attrib.name = parseString(token);
  150.         }
  151.     },
  152.     {
  153.         "s",
  154.         [](ObjectAttributes& attrib, string arguments)
  155.         {
  156.             //cout << "[SMOOTH GROUP]" << endl;
  157.         }
  158.     }
  159. };
  160.  
  161. bool ProcessString(string currentString, ObjectAttributes& attrib)
  162. {
  163.     static int line;
  164.     ++line;
  165.  
  166.     auto cs = currentString.c_str();
  167.     auto token = &cs;
  168.     string parameter = parseString(token);
  169.     if (parameter.empty() || '#' == parameter.at(0))
  170.         return true;
  171.     try
  172.     {
  173.         string arguments(*token);
  174.         ProcessMap.at(parameter)(attrib, arguments);
  175.         return true;
  176.     }
  177.     catch (out_of_range)
  178.     {
  179.         cout << "Obj Loader: Unsuppoted parameter: [" << parameter << "] line: " << line << endl;
  180.         return false;
  181.     }
  182. }
  183.  
  184. void LoadObj(string filename)
  185. {
  186.     cout << "Obj Loader: load file [" << filename << "]" << endl;
  187.  
  188.     ifstream ifs(filename);
  189.     if (!ifs)
  190.     {
  191.         cout << "Cannot open file!" << endl;
  192.         return;
  193.     }
  194.  
  195.     ObjectAttributes attrib;
  196.  
  197.     while (true)
  198.     {
  199.         string currentString;
  200.         safeGetline(ifs, currentString);
  201.  
  202.         if (ifs.eof())
  203.             break;
  204.         if (!ifs)
  205.         {
  206.             cout << "Cannot read file!" << endl;
  207.             return;
  208.         }
  209.  
  210.         if (!ProcessString(currentString, attrib))
  211.             return;
  212.     }
  213.  
  214.     cout << "Mesh [" << attrib.name << "]" << endl;
  215.     cout << "Vertices:\t" << attrib.vcnt << endl;
  216.     cout << "Normals:\t" << attrib.ncnt << endl;
  217.     cout << "UVs:\t" << attrib.tcnt << endl;
  218.     cout << "Faces:\t" << attrib.fcnt << endl;
  219. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement