1#include "mesh.hpp"
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6
7#include <vector>
8
9#include "math.hpp"
10
11using std::vector;
12
13Mesh parse_obj(const char *filename) {
14 Mesh mesh;
15
16 FILE *file = fopen(filename, "r");
17 if (!file) {
18 printf("Failed to open file: %s\n", filename);
19 return mesh;
20 }
21
22 char line[1024];
23 while (fgets(line, sizeof(line), file)) {
24 if (strncmp(line, "#", 2) == 0 || strncmp(line, "\n", 2) == 0) {
25 continue;
26 }
27 if (strncmp(line, "v ", 2) == 0) {
28 vec3f v;
29 sscanf(line, "v %f %f %f", &v.x, &v.y, &v.z);
30 mesh.vertices.push_back(v);
31 } else if (strncmp(line, "vt ", 3) == 0) {
32 vec2f vt;
33 sscanf(line, "vt %f %f", &vt.x, &vt.y);
34 mesh.texcoords.push_back(vt);
35 } else if (strncmp(line, "vn ", 3) == 0) {
36 vec3f vn;
37 sscanf(line, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
38 mesh.normals.push_back(vn);
39 } else if (strncmp(line, "f ", 2) == 0) {
40 char *face_token = strtok(line + 2, " \n\r");
41 while (face_token) {
42 Face idx = {0, 0, 0};
43 int v = 0, vt = 0, vn = 0;
44
45 char *slash1 = strchr(face_token, '/');
46 if (slash1) {
47 *slash1 = '\0';
48 v = atoi(face_token);
49
50 char *slash2 = strchr(slash1 + 1, '/');
51 if (slash2) {
52 *slash2 = '\0';
53 vt = atoi(slash1 + 1);
54 vn = atoi(slash2 + 1);
55 } else {
56 vt = atoi(slash1 + 1);
57 }
58 } else {
59 v = atoi(face_token);
60 }
61
62 if (v > 0) idx.vertex_idx = v - 1;
63 if (vt > 0) idx.vertex_texture_idx = vt - 1;
64 if (vn > 0) idx.vertex_normal_idx = vn - 1;
65
66 mesh.faces.push_back(idx);
67 face_token = strtok(nullptr, " \n\r");
68 }
69 }
70 }
71 fclose(file);
72 return mesh;
73}