Repository navigation
Expand file tree
/
Copy pathmodel.cpp
More file actions
166 lines (145 loc) · 5.05 KB
/
Copy pathmodel.cpp
File metadata and controls
166 lines (145 loc) · 5.05 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "model.h"
#include <iostream>
#include <fstream>
#include <sstream>
// Constructor - loads the OBJ file
Model::Model(const std::string& filename) {
std::ifstream file(filename); //get file
if (!file.is_open()) {
std::cerr << "Failed to open file: " << filename << std::endl;
return;
}
std::string line;
while (std::getline(file, line)) {// while more lines to read
if (line.empty() || line[0] == '#') continue;
std::istringstream iss(line); // process line with input string stream
std::string prefix;
iss >> prefix;
if (prefix == "v") {
vec3 v;
iss >> v.x >> v.y >> v.z;
vertices.push_back(v);
}
else if (prefix == "vt") {
vec2 uv;
iss >> uv.x >> uv.y;
uvs.push_back(uv);
}
else if (prefix == "vn"){
vec3 vn;
iss >> vn.x >> vn.y >> vn.z;
normals.push_back(vn);
}
else if (prefix == "f") {
// Read face: f v1 v2 v3 (or f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3)
// Only use vertex indices (v1, v2, v3) add 3 indices to faces vector
std::string vertex;
std::string v;
std::string vt;
std::string vn;
int counter = 0;
while (iss >> vertex && counter < 3) {//ensure there are only 3 vertices per face
// Handle "v/vt/vn" or "v//vn" format
int slash_pos1 = vertex.find('/');
int slash_pos2 = vertex.find('/', slash_pos1 + 1);
if (slash_pos1 != std::string::npos) {
v = vertex.substr(0, slash_pos1);
if (slash_pos2 != std::string::npos) {
// Format is v/vt/vn or v//vn
if (slash_pos2 > slash_pos1 + 1) {
// v/vt/vn format
vt = vertex.substr(slash_pos1 + 1, slash_pos2 - slash_pos1 - 1);
}
// Extract normal index
vn = vertex.substr(slash_pos2 + 1);
} else {
// Format is v/vt (no normal)
vt = vertex.substr(slash_pos1 + 1);
}
} else {
// No slashes, just vertex index
v = vertex;
}
int vertidx = std::stoi(v); // Convert string to int
faces.push_back(vertidx-1); // OBJ indices are 1-based
if (!vt.empty()) {
int uvidx = std::stoi(vt);
uvIndices.push_back(uvidx-1);
} else {
uvIndices.push_back(-1);
}
if (!vn.empty()) {
int normidx = std::stoi(vn);
normalIndices.push_back(normidx-1);
} else {
normalIndices.push_back(-1); // No normal for this vertex
}
counter++;
}
}
}
file.close();
std::cout << "Loaded " << filename << ": "
<< vertices.size() << " vertices, "
<< uvs.size() << " UVs, "
<< faces.size() << " faces, "
<< normals.size() << " normals" << std::endl;
}
// Destructor
Model::~Model() {
}
// Return number of vertices
int Model::nverts() const {
return vertices.size();
}
// Return number of faces
int Model::nfaces() const {
return faces.size();
}
int Model::nnormals() const {
return normals.size();
}
// Return vertex at index i
vec3 Model::vert(const int i) const {
if (i < 0 || i >= vertices.size()) {
//std::cerr << "Index out of bounds in Model::vert()" << std::endl;
return vec3();
}
return vertices[i];
}
// Return the nth vertex of face iface
vec3 Model::vert(const int iface, const int nthvert) const {
int index = iface * 3 + nthvert;
if (index < 0 || index >= faces.size()) {
//std::cerr << "Index out of bounds in Model::vert()" << std::endl;
return vec3();
}
int face_index = faces[index];
if (face_index < 0 || face_index >= vertices.size()) {
//std::cerr << "Vertex index out of bounds in Model::vert()" << std::endl;
return vec3();
}
return vertices[face_index];
}
vec3 Model::normalVert(const int normalIndex, const int nthNormal) const {
int index = normalIndex * 3 + nthNormal;
if (index < 0 || index >= normalIndices.size()) {
return vec3();
}
int normal_index = normalIndices[index];
if (normal_index < 0 || normal_index >= normals.size()) {
return vec3();
}
return normals[normal_index];
}
vec2 Model::uv(const int iface, const int nthvert) const {
int index = iface * 3 + nthvert;
if (index < 0 || index >= uvIndices.size()) {
return vec2();
}
int uv_index = uvIndices[index];
if (uv_index < 0 || uv_index >= uvs.size()) {
return vec2();
}
return uvs[uv_index];
}