-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathObjReader.h
191 lines (166 loc) · 6.05 KB
/
ObjReader.h
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
185
186
187
188
189
190
191
//
// Created by Brett on 4/1/2018.
//
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cmath>
#include <array>
#include <deque>
#include "Vertex.h"
#include "Shapes.h"
#ifndef PROGRAM2_OBJREADER_H
#define PROGRAM2_OBJREADER_H
class ObjReader{
public:
static int faceNum;
static int vertNum;
// color of object can be set
static float r;
static float g;
static float b;
static void setRGB(float _r, float _g, float _b){
r = _r;
g = _g;
b = _b;
}
// break string into deque (so we can remove first) of words
static deque<string> tokenize(string str){
deque<string> arr;
stringstream ss(str);
for (int i = 0; ss.good() && i < 4;++i){
string temp;
ss >> temp;
arr.push_back(temp);
// set number of faces and vertices using file data
if(i == 1){
if(arr[i] == "Faces:"){
ss >> faceNum;
}
else if( arr[i] == "Vertices:"){
ss >> vertNum;
}
}
}
return arr;
}
// use face normals and arrange data so that it's ready for model class
static vector<Triangle> parseFlat(vector <vector<float>> vertexArr,vector <vector<int>> faceArr) {
vector<Triangle> finalData; // data to be send to Model
Vertex* verts = new Vertex[vertNum]; // array of Vertex objects to store data about that vertex
// for every vertex
for (int i = 0; i < vertNum; ++i) {
// set x,y,z values for Vertex obj
float x = vertexArr[i][0];
float y = vertexArr[i][1];
float z = vertexArr[i][2];
verts[i].setXYZ(x, y, z);
}
// for every face
for (vector<int> face: faceArr){
// get face normal
vector<float> v1 = vertexArr[face[0]-1];
vector<float> v2 = vertexArr[face[1]-1];
vector<float> v3 = vertexArr[face[2]-1];
vector<vec3> points = {glm::vec3(v1[0], v1[1], v1[2]),glm::vec3(v2[0], v2[1], v2[2]),glm::vec3(v3[0], v3[1], v3[2])};
glm::vec3 color(r,g,b);
Triangle currTriangle(points, color);
finalData.push_back(currTriangle);
}
return finalData;
}
/*
// calculate average normals and arrange data so that it's ready for model class
static vector<float> parseSmooth(vector <vector<float>> vertexArr,vector <vector<int>> faceArr){
vector<float> finalData; // data to be send to Model
Vertex* verts = new Vertex[vertNum]; // array of Vertex objects to store data about that vertex
// for every vertex
for (int i = 0; i < vertNum; ++i) {
// set x,y,z values for Vertex obj
float x = vertexArr[i][0];
float y = vertexArr[i][1];
float z = vertexArr[i][2];
verts[i].setXYZ(x,y,z);
// for every face
for (int j = 0; j < faceNum; ++j) {
// for every vertex in that face
for (int k = 0; k < 3; ++k) {
// if the vertex matches the current vertex in vertArr
if(faceArr[j][k] - 1 == i){
// add that face to the vertex's faces
vector<float> v1 = vertexArr[faceArr[j][0]-1];
vector<float> v2 = vertexArr[faceArr[j][1]-1];
vector<float> v3 = vertexArr[faceArr[j][2]-1];
Face f = Face(v1,v2,v3);
verts[i].addFace(f);
}
}
}
// calculate normal based on faces just added
verts[i].calcNormal();
}
// for every face given by obj file
for (vector<int> face: faceArr){
// add the vertex data of the vertices in that face
for (int index : face){
verts[index-1].setColor(r,g,b);
vector<float> data = verts[index-1].getData();
finalData.insert(finalData.end(),data.begin(),data.end());
}
}
return finalData;
}
*/
// read in obj file, parse lines, pass data for further parsing before returning result
static vector<Triangle> readInObj(bool smooth, string& fileName){
// read duck obj file
ifstream file;
file.open(fileName);
if(file){
string str;
vector <vector<float>> vertexArr;
vector <vector<int>> faceArr;
// for each line in file
while (getline(file, str))
{
// store words in line
deque<string> words = tokenize(str);
// if first word is "v", parse and rest of line to vertexArr
if(words.front() == "v" ){
words.pop_front();
vector<float> floats;
for(string word : words){
float f = stof(word);
floats.push_back(f);
}
vertexArr.push_back(floats);
}
// if first word is "f", parse and rest of line to faceArr
else if (words.front() == "f" ){
words.pop_front();
vector<int> ints;
for(string word : words){
int integer = stoi(word);
ints.push_back(integer);
}
faceArr.push_back(ints);
}
}
// if smooth vertices requested, pass arrays to parseSmooth to get final result
if(smooth){
//return parseSmooth(vertexArr, faceArr);
}
// otherwise pass to parseFlat
else{
return parseFlat(vertexArr,faceArr);
}
}
}
};
float ObjReader::r = 1;
float ObjReader::g = 0;
float ObjReader::b = 0;
int ObjReader::faceNum = 0;
int ObjReader::vertNum = 0;
#endif //PROGRAM2_OBJREADER_H