85 lines
2.3 KiB
C++
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);
|
|
}
|
|
|
|
}
|