-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModel.cpp
More file actions
85 lines (75 loc) · 2.7 KB
/
Model.cpp
File metadata and controls
85 lines (75 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <fstream>
#include <string>
#include <regex>
#include <cstdlib>
#include "Model.h"
int Model::getNumVertices() { return numVertices; }
int Model::getNumIndices() { return numIndices; }
std::vector<GLuint> Model::getIndices() { return indices; }
std::vector<glm::vec3> Model::getVertices() { return vertices; }
std::vector<glm::vec2> Model::getTexCoords() { return texCoords; }
std::vector<glm::vec3> Model::getNormals() { return normals; }
std::vector<glm::vec3> Model::getTangents() { return tangents; }
//this model importer only imports .obj tiles that consist exclusively of triangles
Model ModelImporter::parseOBJ(const char* filePath)
{
Model m;
std::vector<glm::vec3> vertices, normals;
std::vector<glm::vec2> texCoords;
std::ifstream modelFile(filePath);
std::string line;
std::regex vtxLn{"^v\\s+"};
std::regex texLn{"^vt\\s+"};
std::regex normLn{"^vn\\s+"};
std::regex faceLn{"^f\\s+(\\d+)\\/(\\d+)\\/(\\d+)\\s+(\\d+)\\/(\\d+)\\/(\\d+)\\s+(\\d+)\\/(\\d+)\\/(\\d+)"};
std::smatch m2;
std::string test="f 8021/4274/8291 8023/4276/8291 8022/4275/8291";
std::regex_search(test, m2, faceLn);
//read each line
for(std::getline(modelFile,line); !modelFile.eof(); std::getline(modelFile,line))
{
//variables for matches of the lines
std::smatch match;
char* text = const_cast<char*>(line.c_str())+2;
if(std::regex_search(line, match, vtxLn))
{
double x{strtod(text, &text)}, y{strtod(text, &text)}, z{strtod(text, &text)};
vertices.push_back(glm::vec3{x,y,z});
}
else if(std::regex_search(line, match, texLn))
{
double s{strtod(text, &text)}, t{strtod(text, &text)};
texCoords.push_back(glm::vec2{s,t});
}
else if(std::regex_search(line, match, normLn))
{
double x{strtod(text, &text)}, y{strtod(text, &text)}, z{strtod(text, &text)};
normals.push_back(glm::vec3{x,y,z});
}
else if(std::regex_search(line, match, faceLn))
{
//extract each corner's values
for(int i=0; i<3; ++i)
{
int off=i*3;
int cVtx{stoi(match[off+1].str())-1}, cTX{stoi(match[off+2].str())-1}, cNorm{stoi(match[off+3].str())-1};
m.vertices.push_back(vertices[cVtx]);
m.texCoords.push_back(texCoords[cTX]);
m.normals.push_back(normals[cNorm]);
}
}
else
continue;
}
//configure sizes
m.numVertices = m.numIndices = m.vertices.size();
//configure indices. This is wasteful, since I the vertices will be a 1to1 mapping
//but I don't want to write another version of the rendering code for the case where
//we don't have indices.
m.indices.resize(m.numIndices);
for(GLuint i=0;i<m.numIndices;++i)
m.indices[i]=i;
//fill the tangents array with garbage date, because we don't have tangents in the model
m.tangents.resize(m.numVertices, glm::vec3{0,0,0});
return m;
}