-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOBJImporter.h
105 lines (93 loc) · 3.64 KB
/
OBJImporter.h
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#ifndef OBJIMPORTER_H
#define OBJIMPORTER_H
#include <vector>
#include <string>
#include <glm/glm.hpp>
#include <cstdio>
#include <cstring>
#include <iostream>
class OBJImporter {
public:
// Loads an OBJ file
static bool loadOBJ(
const char* path,
std::vector<glm::vec3>& outVertices,
std::vector<glm::vec2>& outUVs,
std::vector<glm::vec3>& outNormals
) {
// Temporary storage for vertices, uvs, and normals
std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;
std::vector<glm::vec3> tempVertices;
std::vector<glm::vec2> tempUVs;
std::vector<glm::vec3> tempNormals;
// Open the file
FILE* file = fopen(path, "r");
if (file == nullptr) {
std::cerr << "Failed to open OBJ file: " << path << std::endl;
return false;
}
// Read the file line by line
while (true) {
char lineHeader[128];
int res = fscanf(file, "%s", lineHeader);
if (res == EOF)
break; // End of file
// Process vertex positions (v)
if (strcmp(lineHeader, "v") == 0) {
glm::vec3 vertex;
fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
tempVertices.push_back(vertex);
}
// Process texture coordinates (vt)
else if (strcmp(lineHeader, "vt") == 0) {
glm::vec2 uv;
fscanf(file, "%f %f\n", &uv.x, &uv.y);
tempUVs.push_back(uv);
}
// Process vertex normals (vn)
else if (strcmp(lineHeader, "vn") == 0) {
glm::vec3 normal;
fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
tempNormals.push_back(normal);
}
// Process faces (f)
else if (strcmp(lineHeader, "f") == 0) {
unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n",
&vertexIndex[0], &uvIndex[0], &normalIndex[0],
&vertexIndex[1], &uvIndex[1], &normalIndex[1],
&vertexIndex[2], &uvIndex[2], &normalIndex[2]);
if (matches != 9) {
std::cerr << "File can't be read by this parser: " << path << std::endl;
fclose(file);
return false;
}
// Store indices
vertexIndices.push_back(vertexIndex[0]);
uvIndices.push_back(uvIndex[0]);
normalIndices.push_back(normalIndex[0]);
vertexIndices.push_back(vertexIndex[1]);
uvIndices.push_back(uvIndex[1]);
normalIndices.push_back(normalIndex[1]);
vertexIndices.push_back(vertexIndex[2]);
uvIndices.push_back(uvIndex[2]);
normalIndices.push_back(normalIndex[2]);
}
}
// Process indexed data into unindexed form
for (unsigned int i = 0; i < vertexIndices.size(); i++) {
unsigned int vertexIndex = vertexIndices[i];
glm::vec3 vertex = tempVertices[vertexIndex - 1];
outVertices.push_back(vertex);
unsigned int uvIndex = uvIndices[i];
glm::vec2 uv = tempUVs[uvIndex - 1];
outUVs.push_back(uv);
unsigned int normalIndex = normalIndices[i];
glm::vec3 normal = tempNormals[normalIndex - 1];
outNormals.push_back(normal);
}
fclose(file);
return true;
}
};
#endif // OBJIMPORTER_H