KekEngine/src/kekengine/cpp/objparser.cpp
2022-10-08 00:14:45 +02:00

85 lines
2.3 KiB
C++

#include "objparser.h"
#include <iostream>
#include <string>
#include <sstream>
#include <glm/glm.hpp>
#include <memory>
#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<glm::vec3> vertexPositions;
std::vector<glm::vec3> vertexNormals;
std::vector<glm::vec2> vertexTexCoords;
std::vector<Vertex> vertices;
std::vector<uint32_t> 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);
}
}