#include "objparser.h" #include #include #include #include #include #include "types.h" namespace kek::ObjParser { static bool readFaceVertex(std::istringstream &stream, uint32_t *outVertex, uint32_t *outTexture, uint32_t *outNormal) { std::string face; stream >> face; size_t first = face.find('/'); if(first == std::string::npos) return false; size_t second = face.find('/', first + 1); if(second == std::string::npos) return false; *outVertex = std::stoi(face.substr(0, first)); *outTexture = std::stoi(face.substr(first + 1, second)); *outNormal = std::stoi(face.substr(second + 1, face.length())); return true; } Mesh *parse(MemoryBuffer *buf) { std::vector vertexPositions; std::vector vertexNormals; std::vector vertexTexCoords; std::vector vertices; std::vector indices; std::istream stream(buf); std::string line; while(std::getline(stream, line)) { std::istringstream str(line); std::string cmd; str >> cmd; if(cmd == "#") continue; if(cmd == "v") { float x, y, z; str >> x >> y >> z; vertexPositions.push_back(glm::vec3(x, y, z)); }else if(cmd == "vn") { float x, y, z; str >> x >> y >> z; vertexNormals.push_back(glm::normalize(glm::vec3(x, y, z))); }else if(cmd == "vt") { float u, v = 1.0f; str >> u >> v; vertexTexCoords.push_back(glm::vec2(u, v)); }else if(cmd == "f") { uint32_t v1, v1T, v1N; readFaceVertex(str, &v1, &v1T, &v1N); uint32_t v2, v2T, v2N; readFaceVertex(str, &v2, &v2T, &v2N); uint32_t v3, v3T, v3N; readFaceVertex(str, &v3, &v3T, &v3N); vertices.push_back(Vertex(vertexPositions[v1 - 1], vertexNormals[v1N - 1], vertexTexCoords[v1T - 1])); indices.push_back(indices.size()); vertices.push_back(Vertex(vertexPositions[v2 - 1], vertexNormals[v2N - 1], vertexTexCoords[v2T - 1])); indices.push_back(indices.size()); vertices.push_back(Vertex(vertexPositions[v3 - 1], vertexNormals[v3N - 1], vertexTexCoords[v3T - 1])); indices.push_back(indices.size()); }else { std::cout << "Ignoring unknown OBJ command: " << cmd << std::endl; } } for(glm::vec3 v : vertexNormals) { std::cout << v.x << " " << v.y << " " << v.z << std::endl; } return new Mesh(vertices, indices); } }