objParser.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "objParser.h"
  2. Mesh& OBJ::buildMeshFromFile(Mesh &mesh, std::string &path){
  3. //Open file containing vertex data
  4. std::ifstream file;
  5. file.open(path.c_str());
  6. //Get vertices and normal data &
  7. //Get face, normal and texture indices
  8. loadFileData(mesh, file);
  9. file.close();
  10. }
  11. bool OBJ::fileExists(std::string &path){
  12. std::ifstream file(path.c_str());
  13. return file.good();
  14. }
  15. //Main OBJ parsing function
  16. void OBJ::loadFileData(Mesh &mesh, std::ifstream &file){
  17. std::string line, key, x ,y ,z;
  18. Vector3i indices[3];
  19. char delimeter = '/';
  20. while(!file.eof()){
  21. std::getline(file,line);
  22. std::istringstream iss(line);
  23. iss >> key;
  24. if(key == "v"){ //Vertex data
  25. iss >> x >> y >> z;
  26. Vector3f vertex(std::stof(x),std::stof(y),std::stof(z));
  27. mesh.vertices.push_back(vertex);
  28. }
  29. else if(key == "vn"){ //Normal data
  30. iss >> x >> y >> z;
  31. Vector3f normal(std::stof(x),std::stof(y),std::stof(z));
  32. mesh.normals.push_back(normal);
  33. }
  34. else if(key == "f"){ //index data
  35. iss >> x >> y >> z;
  36. std::vector<std::string> splitX = splitStr(x,delimeter);
  37. std::vector<std::string> splitY = splitStr(y,delimeter);
  38. std::vector<std::string> splitZ = splitStr(z,delimeter);
  39. for(int i = 0; i < splitX.size(); ++i){
  40. //Subtracted by 1 because OBJ files count indices starting by 1
  41. indices[i] = Vector3i(std::stoi(splitX[i])-1,std::stoi(splitY[i])-1,std::stoi(splitZ[i])-1);
  42. }
  43. printf("\n");
  44. mesh.vertexIndices.push_back(indices[0]);
  45. mesh.textureIndices.push_back(indices[1]);
  46. mesh.normalsIndices.push_back(indices[2]);
  47. }
  48. }
  49. mesh.numVertices = mesh.vertices.size();
  50. mesh.numFaces = mesh.vertexIndices.size();
  51. //Reset file in case you want to re-read it
  52. file.clear();
  53. file.seekg(0, file.beg);
  54. }
  55. //Creates stringstream of string and subdivides it by the delimeter and returns
  56. //a vector of the individual components of the string
  57. std::vector<std::string> OBJ::splitStr(std::string &str, char delim){
  58. std::stringstream ss(str);
  59. std::string token;
  60. std::vector<std::string> splitString;
  61. while(std::getline(ss,token,delim)){
  62. if(token == ""){
  63. //If token is empty just write 0 it will result in a -1 index
  64. //Since that index number is nonsensical you can catch it pretty easily later
  65. splitString.push_back("0");
  66. }
  67. else{
  68. splitString.push_back(token);
  69. }
  70. }
  71. return splitString;
  72. }