aboutsummaryrefslogtreecommitdiff
path: root/src/obj_parser.cpp
blob: 7791678e5523b6a979fb8d37dc79fb643420e82b (plain) (blame)
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
#include "obj_parser.h"

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstddef>
#include <array>
#include "math/vector.h"
#include "o3d/mesh.h"
#include "o3d/vertex_data.h"

namespace engine {

namespace {

std::vector<std::string> split(const std::string& s, char sep) {
    std::vector<std::string> res;
    std::string::size_type last_ind = 0;
    for (std::string::size_type ind = 0; ind < s.length(); ind++) {
        if (s[ind] == sep) {
            res.push_back(s.substr(last_ind, ind - last_ind));
            last_ind = ind + 1;
        }
    }
    res.push_back(s.substr(last_ind));
    return res;
}

}

o3d::Mesh parse_object(const std::string& obj_path) {
    o3d::Mesh mesh;
    mesh.vertices_data.push_back(o3d::VertexData(0.f, 0.f));
    std::ifstream obj_file(obj_path);
    std::string line;
    while (std::getline(obj_file, line)) {
        if (line.length() == 0 || line[0] == '#')
            continue;
        if (line.rfind("o ", 0) == 0) {
            std::cout << "Object: " << line.substr(2) << std::endl;
        } else if (line.rfind("v ", 0) == 0) {
            auto s_coords = split(line.substr(2), ' ');
            math::Vector3 v{std::stof(s_coords[0]), std::stof(s_coords[1]), std::stof(s_coords[2])};
            std::cout << "Vertex x: " << v.x << " y: " << v.y << " z: " << v.z << std::endl;
            mesh.vertices.push_back(v);
        } else if (line.rfind("vn ", 0) == 0) {
            auto s_coords = split(line.substr(3), ' ');
            math::Vector3 vn{std::stof(s_coords[0]), std::stof(s_coords[1]), std::stof(s_coords[2])};
            std::cout << "Vertex normal x: " << vn.x << " y: " << vn.y << " z: " << vn.z << std::endl;
            mesh.normals.push_back(vn);
        } else if (line.rfind("s ", 0) == 0) {
            auto smooth = false;
            auto s_smooth = line.substr(2);
            if (s_smooth == "0" || s_smooth == "off") {
                smooth = false;
            } else if (s_smooth == "1" || s_smooth == "on") {
                smooth = true;
            }
            std::cout << "Smooth: " << std::boolalpha << smooth << std::endl;
        } else if (line.rfind("f ", 0) == 0) {
            std::array<std::array<std::size_t, 3>, 3> indices;
            auto line_split = split(line.substr(2), ' ');
            for (int i = 0; i < 3; i++) {
                auto indices_s_group = split(line_split[i], '/');
                indices[i][0] = std::stoi(indices_s_group[0]) - 1;
                indices[i][1] = std::stoi(indices_s_group[2]) - 1;
                indices[i][2] = 0;
            }
            std::cout << "Face:"
                << " 1: vertex: " << indices[0][0] << " normal: " << indices[0][1]
                << " 2: vertex: " << indices[1][0] << " normal: " << indices[1][1]
                << " 3: vertex: " << indices[2][0] << " normal: " << indices[2][1]
                << std::endl;
            mesh.indices.push_back(indices);
        }
    }
    return mesh;
}

}