-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjLoader.cpp
More file actions
140 lines (112 loc) · 3.64 KB
/
Copy pathObjLoader.cpp
File metadata and controls
140 lines (112 loc) · 3.64 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
#include "ObjLoader.h"
// Custom libraries
#include "object3D.h"
#include "sanitize.h"
// External libraries
#include <glad/glad.h>
#include <glm/glm.hpp>
// Standard libraries
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
constexpr char VERT[] = "v"; // Vertex position.
constexpr char NORMAL[] = "vn"; // Vertex normals.
constexpr char UVS[] = "vt"; // Vertex texture coordinates.
constexpr char INDEX[] = "f"; // Index data.
// Object indicies delimeter
#define INDEX_DEL '/'
void importOBJAsset(Object3D* object, const char* filepath, const glm::vec4* rgba)
{
// Sanitization checks
checkptr(object)
if (!CHECK_CLASS(object, Object3D*)) throw std::runtime_error("ERROR: The input object is not Object3D");
checkptr(filepath)
std::ifstream file(filepath, std::ios::in);
if (file.fail()) { std::cout << "ERROR: Filepath is invalid, may not exist or may be incorrect at... " << filepath << std::endl; return; }
std::vector<glm::vec3> tmp_positions, tmp_normals;
std::vector<glm::vec2> tmp_uvs;
// Index: 5/1/1 --- pos/uv/normals.
// Obj index 1 is 0 in C++.
std::vector<GLuint> temp_index_pos, temp_index_uvs, temp_index_normals;
// Temporary information to store vertex positional, normal and texture coordinate information.
GLdouble x, y, z;
// Read every line on file. - https://stackoverflow.com/questions/7868936/read-file-line-by-line-using-ifstream-in-c - Date Accessed: 19/11/2023
#pragma omp parallel
{
#pragma omp parallel for
for (std::string line; std::getline(file, line);) {
std::stringstream ss(line);
std::string string;
ss >> string;
// Get all vertices and indices and store into temporary vectors.
if (string == VERT) {
ss >> x >> y >> z;
tmp_positions.push_back({ x,y,z });
}
// Fetch all vertex normal data.
if (string == NORMAL) {
ss >> x >> y >> z;
tmp_normals.push_back({ x,y,z });
}
// Fetch all vertex UV normal data.
if (string == UVS) {
ss >> x >> y;
// Flip Y-axis UV correction.
tmp_uvs.push_back(glm::vec2(x, 1 - y));
}
if (string == INDEX) {
std::string index;
while (ss >> index) {
std::stringstream ss_data(index);
size_t i = 0;
// Split current index into separate elements with the '/' delimeter.
for (std::string data; std::getline(ss_data, data, INDEX_DEL); ++i) {
// 0 - Vertex position index
if (i == 0) {
temp_index_pos.push_back((std::stoi(data) - 1));
}
// 1 - Vertex texture coordinates index.
else if (i == 1) {
temp_index_uvs.push_back((std::stoi(data) - 1));
}
// 2 - 2 - Vertex normals index.
else if (i == 2) {
temp_index_normals.push_back((std::stoi(data) - 1));
}
}
}
}
}
}
// Copy information
#pragma omp parallel for
for (GLuint& index : temp_index_pos) {
object->vertex_positions.push_back(tmp_positions[index]);
}
#pragma omp parallel for
for (GLuint& index : temp_index_uvs) {
object->texture_coords.push_back(tmp_uvs[index]);
}
#pragma omp parallel for
for (GLuint& index : temp_index_normals) {
object->vertex_normals.push_back(tmp_normals[index]);
}
object->indices = temp_index_pos;
// Assign colours
if (rgba != nullptr) object->vertex_colours.assign(object->vertex_positions.size(), *rgba);
else { object->vertex_colours.push_back({ 1,1,1,1 }); }
// Reduce size for mem clearup.
tmp_positions.clear();
tmp_positions.resize(0);
tmp_normals.clear();
tmp_normals.resize(0);
tmp_uvs.clear();
tmp_uvs.resize(0);
temp_index_pos.clear();
temp_index_pos.resize(0);
temp_index_uvs.clear();
temp_index_uvs.resize(0);
temp_index_normals.clear();
temp_index_normals.resize(0);
}