-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwaveFrontLoader.cpp
More file actions
305 lines (250 loc) · 7.28 KB
/
waveFrontLoader.cpp
File metadata and controls
305 lines (250 loc) · 7.28 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
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#include "waveFrontLoader.h"
waveFrontLoader::waveFrontLoader()
{
indexCount = 0;
faceCount = 0;
materialColorCount = 0;
materialCount = 0;
materialBool = false;
}
void waveFrontLoader::loadFile(const char *fileName)
{
//if we're using a material file, load it
if (materialBool == true)
{
ifstream matFile;
char matLine[255];
char materialFile[255];
strncpy(materialFile, fileName, sizeof(materialFile));
strncat(materialFile, ".mtl", sizeof(materialFile) - strlen(materialFile) - 1);
//open file in openframeworks data folder
matFile.open(ofToDataPath(materialFile).c_str());
if (matFile.is_open())
{
while (matFile.getline(matLine, 255))
{
parseMaterial(matLine);
}
}
matFile.close();
}
//get filename and open corresponding .obj file
ifstream objFile;
char line[255];
char objectFile[255];
strncpy(objectFile, fileName, sizeof(objectFile));
strncat(objectFile, ".obj", sizeof(objectFile) - strlen(objectFile) - 1);
//open file in openframeworks data folder
objFile.open(ofToDataPath(objectFile).c_str());
if (objFile.is_open())
{
while (objFile.getline(line,255))
{
parseLine(line);
}
}
objFile.close();
}
void waveFrontLoader::loadMaterial(bool load)
{
if (load == true)
{
materialBool = true;
}
else
{
materialBool = false;
}
}
void waveFrontLoader::parseLine(char *line)
{
//If empty, don't do anything with it
if(!strlen(line))
{
return;
}
//get line type identifier from char string
char *lineType = strtok(strdup(line), " ");
//parse line depending on type
if (!strcmp(lineType, "usemtl")) // Use Material
{
parseMaterialLocation(line);
}
else if (!strcmp(lineType, "v")) // Vertices
{
parseVertex(line);
}
else if (!strcmp(lineType, "vn")) // Normals
{
parseNormal(line);
}
else if (!strcmp(lineType, "f")) // Indices (Faces)
{
parseFace(line);
}
}
void waveFrontLoader::parseVertex(char *line)
{
float x;
float y;
float z;
vertices.push_back(ofVec3f(x,y,z));
//get coordinates from vertex line and assign
sscanf(line, "v %f %f %f", &vertices.back().x, &vertices.back().y, &vertices.back().z);
}
void waveFrontLoader::parseNormal(char *line)
{
float x;
float y;
float z;
normals.push_back(ofVec3f(x,y,z));
//get coordinates from normal line and assign
sscanf(line, "vn %f %f %f", &normals.back().x, &normals.back().y, &normals.back().z);
}
void waveFrontLoader::parseFace(char *line)
{
//var to hold and discard un-needed texture data
int discard;
faceCount++;
indices.push_back(Index());
//get vertex and normal indices, discard texture data for now
if(sscanf(line, "f %d//%d %d//%d %d//%d",
&indices.back().v1,
&indices.back().vn1,
&indices.back().v2,
&indices.back().vn2,
&indices.back().v3,
&indices.back().vn3) <= 1)
{
sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d",
&indices.back().v1,
&discard,
&indices.back().vn1,
&indices.back().v2,
&discard,
&indices.back().vn2,
&indices.back().v3,
&discard,
&indices.back().vn3);
}
}
void waveFrontLoader::parseMaterialLocation(char *line)
{
materialCount++;
char materialName[255];
sscanf(line, "usemtl %s", materialName);
materialLocations[faceCount] = materialName;
}
void waveFrontLoader::parseMaterial(char *line)
{
//If empty, don't do anything with it
if(!strlen(line))
{
return;
}
//get line type identifier from char string
char *lineType = strtok(strdup(line), " ");
if (!strcmp(lineType, "newmtl")) // Material Name
{
sscanf(line, "newmtl %s", tempMatName);
materialColorCount++;
}
else if (!strcmp(lineType, "Ka")) // Ambient Color
{
sscanf(line, "Ka %f %f %f", &tempColor.ambientColor.r, &tempColor.ambientColor.g, &tempColor.ambientColor.b);
}
else if (!strcmp(lineType, "Kd")) // Diffuse Color
{
sscanf(line, "Kd %f %f %f", &tempColor.diffuseColor.r, &tempColor.diffuseColor.g, &tempColor.diffuseColor.b);
}
else if (!strcmp(lineType, "Ks")) // Specular Color
{
sscanf(line, "Ks %f %f %f", &tempColor.specularColor.r, &tempColor.specularColor.g, &tempColor.specularColor.b);
}
else if (!strcmp(lineType, "d")) // Alpha
{
sscanf(line, "d %f", &tempColor.alpha);
}
else if (!strcmp(lineType, "illum")) // End of material signifier
{
//it's the end of this material, so add to material map, and reset vars
materialColors[tempMatName] = tempColor;
tempColor = emptyColor;
}
}
ofMesh waveFrontLoader::generateMesh()
{
int materialCount = materialColors.size();
int localIndexCount = 0;
ofColor vertColor;
ofColor defaultColor = ofColor(0.0, 255.0, 0.0);
for (std::vector<Index>::iterator i = indices.begin(); i != indices.end(); ++i)
{
if (materialLocations[localIndexCount] != "")
{
vertColor = mapColor(materialColors[materialLocations[localIndexCount]].diffuseColor);
}
//draw triangles
addFace(&vertices[(i->v1) - 1], &normals[(i->vn1) - 1], &vertColor);
addFace(&vertices[(i->v2) - 1], &normals[(i->vn2) - 1], &vertColor);
addFace(&vertices[(i->v3) - 1], &normals[(i->vn3) - 1], &vertColor);
localIndexCount++;
}
return mesh;
}
void waveFrontLoader::addFace(ofVec3f *vertex, ofVec3f *normal, ofColor *color)
{
//temp vars
int vertIndex;
int normIndex;
//check if this vertex exists already
std::map<int,ofVec3f>::iterator faceIt;
for (faceIt = faceVertices.begin(); faceIt != faceVertices.end(); ++faceIt)
{
if (faceIt->second == *vertex)
{
vertIndex = faceIt->first;
}
}
//check if this normal exists already
std::map<int,ofVec3f>::iterator normIt;
for (normIt = faceNormals.begin(); normIt != faceNormals.end(); ++normIt)
{
if (normIt->second == *normal)
{
normIndex = normIt->first;
}
}
//if a vertex and normal exist at this position, use those aready created
//otherwise, add new
if (vertIndex == normIndex)
{
mesh.addIndex(vertIndex);
}
else
{
int currentIndex = indexCount++;
//add vertex
mesh.addVertex(*vertex);
faceVertices[currentIndex] = *vertex;
//add color
mesh.addColor(*color);
//add normal
mesh.addNormal(*normal);
faceNormals[currentIndex] = *normal;
//add index
mesh.addIndex(currentIndex);
}
}
ofColor waveFrontLoader::mapColor(colorRGB vertexColor)
{
float red = ofMap(vertexColor.r, 0.0, 1.0, 0.0, 255.0);
float green = ofMap(vertexColor.g, 0.0, 1.0, 0.0, 255.0);
float blue = ofMap(vertexColor.b, 0.0, 1.0, 0.0, 255.0);
ofColor newColor = ofColor(red, green, blue);
return newColor;
}
waveFrontLoader::~waveFrontLoader()
{
//
}