This repository was archived by the owner on Jun 11, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmesh.cpp
More file actions
184 lines (160 loc) · 5.43 KB
/
mesh.cpp
File metadata and controls
184 lines (160 loc) · 5.43 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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include "mesh.h"
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <sstream>
#include <string>
#include <rw_math.h>
#include <assert.h>
#include <set>
using namespace std;
vector<string> split_face_element(const string &element, FaceFormat &assumed_ff, FaceFormat &cur_ff) {
vector<string> result;
stringstream ss(element);
string token;
while (getline(ss, token, '/')) {
result.push_back(token);
}
if (result.size() == 3 && result[1] == "") { // v//vn
cur_ff = FaceFormat::VVN;
} else if (result.size() == 3) { // v/vt/vn
cur_ff = FaceFormat::VVTVN;
} else if (result.size() == 2) { // v/vt
cur_ff = FaceFormat::VVT;
} else if (result.size() == 1) { // v
cur_ff = FaceFormat::V;
}
if (assumed_ff == FaceFormat::UNDEFINED) {
assumed_ff = cur_ff;
}
return result;
}
static void pack_and_order_data(Mesh *out_mesh) {
// Preallocate space for the packed array
out_mesh->packed = (float *) malloc(sizeof(float) * NUM_PACKED_ELEMENTS * out_mesh->v.size());
// Make sure that all the indices are the same length (they should be)
// NOTE(ray): Not sure if I want to return an error code
if (out_mesh->v_idx.size() > 0 && out_mesh->uv_idx.size() > 0 && out_mesh->n_idx.size() > 0) {
assert(out_mesh->v_idx.size() == out_mesh->uv_idx.size() && out_mesh->v_idx.size() == out_mesh->n_idx.size());
// Pack the vertex data
for (int i = 0; i < out_mesh->v_idx.size(); ++i) {
memcpy(out_mesh->packed + (NUM_PACKED_ELEMENTS * out_mesh->v_idx[i]),
out_mesh->v.data() + out_mesh->v_idx[i], sizeof(Vec3));
memcpy(out_mesh->packed + (NUM_PACKED_ELEMENTS * out_mesh->v_idx[i]) + 3,
out_mesh->uv.data() + out_mesh->uv_idx[i], sizeof(Vec2));
memcpy(out_mesh->packed + (NUM_PACKED_ELEMENTS * out_mesh->v_idx[i]) + 5,
out_mesh->n.data() + out_mesh->n_idx[i], sizeof(Vec3));
}
// Loop through the temporary buffers
for (int i = 0; i < out_mesh->v_idx.size(); ++i) {
out_mesh->buf_v.push_back(out_mesh->v[out_mesh->v_idx[i]]);
out_mesh->buf_uv.push_back(out_mesh->uv[out_mesh->uv_idx[i]]);
out_mesh->buf_n.push_back(out_mesh->n[out_mesh->n_idx[i]]);
}
} else {
// Pack the vertex data
for (int i = 0; i < out_mesh->v_idx.size(); ++i) {
memcpy(out_mesh->packed + (NUM_PACKED_ELEMENTS * out_mesh->v_idx[i]),
out_mesh->v.data() + out_mesh->v_idx[i], sizeof(Vec3));
}
// Loop through the temporary buffers
for (int i = 0; i < out_mesh->v_idx.size(); ++i) {
out_mesh->buf_v.push_back(out_mesh->v[out_mesh->v_idx[i]]);
}
}
}
// NOTE(ray): We're storing a lot more data than necessary for debug reasons
uint8_t load_obj(Mesh *out_mesh, const char *obj_path) {
cout << "Loading obj: " << obj_path << endl;
FaceFormat assumed_ff = FaceFormat::UNDEFINED;
FaceFormat cur_ff = FaceFormat::UNDEFINED;
vector<int> v_idx;
vector<int> uv_idx;
vector<int> n_idx;
// Read the file
ifstream obj_file;
obj_file.open(obj_path);
if (!obj_file.is_open()) {
cout << "Error reading file: " << obj_path << endl;
return -1;
}
string line;
float x, y, z;
while (getline(obj_file, line)) {
string s;
istringstream iss(line);
iss >> s;
if (s == "#") {
continue;
} else if (s == "v") {
iss >> x >> y >> z;
if (iss.fail()) {
iss.clear();
//puts("V FAILED");
return -2;
}
out_mesh->v.push_back({{x, y, z}});
} else if (s == "vt") {
iss >> x >> y;
if (iss.fail()) {
iss.clear();
//puts("uv FAILED");
return -3;
}
// NOTE(ray): There's an optional w value
// Should be vec2 for optimal packing but just make it vec3 for now
out_mesh->uv.push_back({{x, y}});
} else if (s == "vn") {
iss >> x >> y >> z;
if (iss.fail()) {
iss.clear();
//puts("n FAILED");
return -4;
}
out_mesh->n.push_back({{x, y, z}});
} else if (s == "f") {
// NOTE(ray): Possible formats: v, v//vn, v/vt, v/vt/vn
int num_pushed = 0;
while (!iss.eof()) {
iss >> s;
vector<string> face_components = split_face_element(s, assumed_ff, cur_ff);
if (assumed_ff != cur_ff) {
//puts("f failed");
return -5;
}
++num_pushed;
switch (assumed_ff) {
case FaceFormat::V:
out_mesh->v_idx.push_back(stoi(face_components[0])-1);
break;
case FaceFormat::VVT:
out_mesh->v_idx.push_back(stoi(face_components[0])-1);
out_mesh->uv_idx.push_back(stoi(face_components[1])-1);
break;
case FaceFormat::VVN:
out_mesh->v_idx.push_back(stoi(face_components[0])-1);
out_mesh->n_idx.push_back(stoi(face_components[2])-1);
break;
case FaceFormat::VVTVN:
out_mesh->v_idx.push_back(stoi(face_components[0])-1);
out_mesh->uv_idx.push_back(stoi(face_components[1])-1);
out_mesh->n_idx.push_back(stoi(face_components[2])-1);
break;
default:
// This should NEVER happen
return -69;
}
}
// We want to know how many vertices that a face has
// NOTE(ray): We don't do anything with this data yet
out_mesh->f.push_back(num_pushed);
if (iss.fail()) {
iss.clear();
}
}
}
pack_and_order_data(out_mesh);
out_mesh->format = cur_ff;
obj_file.close();
return 0;
}