rasterizer

c++ software renderer

mesh.cpp

2.2 kB
 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}