5
void parseface(char *facedata,int *varray,int *narray,int *tarray,int position, int hasuv, int hasnormals) {
9
for(i = 0; i < 3; i++) {
11
while(readpos < strlen(facedata) && facedata[readpos] != '/') {
12
workstr[pos] = facedata[readpos];
20
// -1 to compensate for wavefront file starting on 1 and not 0
22
varray[position] = atoi(workstr) - 1;
23
} else if((i == 1) && (hasuv > 0)) {
24
tarray[position] = atoi(workstr) - 1;
25
} else if((i == 2) && (hasnormals > 0)) {
26
narray[position] = atoi(workstr) - 1;
31
void loadobj(char *objfilename, char *openobj, char *outputfile) {
33
pFile = fopen(objfilename, "r");
35
buf = (char*)malloc(1024);
38
// foundobj is true if an object with a certain name is found
39
// Set foundobj to true if we are loading all objects
41
if(strcmp(openobj, "ALL") == 0) {
50
int trianglecount = 0;
52
// Global Variables for Object
58
char *resultp1, *resultp2, *resultp3, *resultp4, *resultp5;
61
printf("Msg: Success opening: %s!\n", objfilename);
62
while(fgets(buf, 1024, pFile) != NULL) {
64
// Comment - Do Nothing
66
result = strtok(buf, " \n\t");
68
if(strcmp(result, "v") == 0) {
70
//Increase vertex counter
73
} else if(strcmp(result, "vt") == 0) {
75
// Increase texture coordinate counter
78
} else if(strcmp(result, "vn") == 0) {
80
// Increase normal counter
83
} else if(strcmp(result, "f") == 0) {
85
// Increase face counter
87
resultp1 = strtok(NULL, " \n\t");
88
resultp2 = strtok(NULL, " \n\t");
89
resultp3 = strtok(NULL, " \n\t");
90
resultp4 = strtok(NULL, " \n\t");
91
resultp5 = strtok(NULL, " \n\t");
92
if((resultp4 != NULL)&&(resultp5 == NULL)) {
94
} else if((resultp3 != NULL)&&(resultp4 == NULL)) {
100
} else if(strcmp(result, "g") == 0) {
101
if(result=strtok(NULL, " \n\t")) {
102
if(!strcmp(openobj, result)) {
106
printf("Error: Failed to read object name\n");
109
//printf("O: %s \n",buf);
116
printf("Warning: Object %s in file %s contains faces that will be ignored, with more than 4 vertices.!\n", objfilename, openobj);
119
if(((trianglecount + quadcount) > 0)) {
120
// Set foundobj to true if we are loading all objects
121
if(strcmp(openobj, "ALL")) {
125
// Seek to beginning again
126
fseek(pFile, 0, SEEK_SET);
128
// Allocate local buffers
129
float *localvertexlist = (float *) malloc (sizeof(float) * vertcount * 3);
130
float *localnormallist = (float *) malloc (sizeof(float) * normalcount * 3);
131
float *localuvlist = (float *) malloc (sizeof(float) * texturecount * 2);
132
int *localquadlist = (int *) malloc (sizeof(int) * quadcount * 4);
133
int *localquadlistuv = (int *) malloc (sizeof(int) * quadcount * 4);
134
int *localquadlistnormal = (int *) malloc (sizeof(int) * quadcount * 4);
135
int *localtrianglelist = (int *) malloc (sizeof(int) * trianglecount * 3);
136
int *localtrianglelistuv = (int *) malloc (sizeof(int) * trianglecount * 3);
137
int *localtrianglelistnormal = (int *) malloc (sizeof(int) * trianglecount * 3);
139
// Reset counters for second pass
146
while(fgets(buf, 1024, pFile) != NULL) {
148
// Comment - Do Nothing
150
result = strtok(buf, " \n\t");
152
if(strcmp(result, "v") == 0) {
154
result = strtok(NULL, " \n\t");
155
localvertexlist[(vertcount * 3)] = atof(result);
156
result = strtok(NULL, " \n\t");
157
localvertexlist[(vertcount * 3) + 1] = atof(result);
158
result = strtok(NULL, " \n\t");
159
localvertexlist[(vertcount * 3) + 2] = atof(result);
162
} else if(strcmp(result, "vt") == 0) {
164
result = strtok(NULL, " \n\t");
165
localuvlist[(texturecount * 2)] = atof(result);
166
result = strtok(NULL, " \n\t");
167
localuvlist[(texturecount * 2) + 1] = atof(result);
170
} else if(strcmp(result, "vn") == 0) {
172
result = strtok(NULL, " \n\t");
173
localnormallist[(normalcount * 3)] = atof(result);
174
result = strtok(NULL, " \n\t");
175
localnormallist[(normalcount * 3) + 1] = atof(result);
176
result = strtok(NULL, " \n\t");
177
localnormallist[(normalcount * 3) + 2] = atof(result);
180
} else if(strcmp(result, "f") == 0) {
182
resultp1 = strtok(NULL, " \n\t");
183
resultp2 = strtok(NULL, " \n\t");
184
resultp3 = strtok(NULL, " \n\t");
185
resultp4 = strtok(NULL, " \n\t");
186
resultp5 = strtok(NULL, " \n\t");
187
if((resultp4 != NULL)&&(resultp5 == NULL)) {
188
// Parse all 4 points in quad
189
parseface(resultp1, localquadlist, localquadlistnormal, localquadlistuv, quadcount * 4, texturecount, normalcount);
190
parseface(resultp2, localquadlist, localquadlistnormal, localquadlistuv, (quadcount * 4) + 1, texturecount, normalcount);
191
parseface(resultp3, localquadlist, localquadlistnormal, localquadlistuv, (quadcount * 4) + 2, texturecount, normalcount);
192
parseface(resultp4, localquadlist, localquadlistnormal, localquadlistuv, (quadcount * 4) + 3, texturecount, normalcount);
194
} else if((resultp3 != NULL)&&(resultp4 == NULL)) {
195
// Parse all 3 points in triangle
196
parseface(resultp1, localtrianglelist, localtrianglelistnormal, localtrianglelistuv, trianglecount * 3, texturecount, normalcount);
197
parseface(resultp2, localtrianglelist, localtrianglelistnormal, localtrianglelistuv, (trianglecount * 3) + 1, texturecount, normalcount);
198
parseface(resultp3, localtrianglelist, localtrianglelistnormal, localtrianglelistuv, (trianglecount * 3) + 2, texturecount, normalcount);
202
} else if(strcmp(result, "g") == 0) {
203
if(result = strtok(NULL, " \n\t")) {
204
if(!strcmp(openobj, result)) {
214
vertexlist = (float *) malloc (sizeof(float) * vertcount * 3);
215
normallist = (float *) malloc (sizeof(float) * vertcount * 3);
216
uvlist = (float *) malloc (sizeof(float) * vertcount * 2);
217
trianglelist = (int *) malloc (sizeof(int) * trianglecount * 3);
218
quadlist = (int *) malloc (sizeof(int) * quadcount * 4);
220
// Copy data from Per Face model to Per Vertex model first for triangles and then for quads
221
// If there are triangle normals, copy triangle normal data
222
if(normalcount > 0) {
223
printf("Msg: Copying Triangle Normals: %i / %i !\n", normalcount, trianglecount);
224
for(i = 0; i < trianglecount * 3; i++) {
226
normallist[localtrianglelist[i] * 3] = localnormallist[localtrianglelistnormal[i] * 3];
228
normallist[(localtrianglelist[i] * 3 ) + 1 ] = localnormallist[(localtrianglelistnormal[i] * 3) + 1 ];
230
normallist[(localtrianglelist[i] * 3) + 2] = localnormallist[(localtrianglelistnormal[i] * 3) + 2];
232
for(i = 0; i < quadcount * 4; i++) {
234
normallist[localquadlist[i] * 3] = localnormallist[localquadlistnormal[i] * 3];
236
normallist[(localquadlist[i] * 3) + 1] = localnormallist[(localquadlistnormal[i] * 3) + 1];
238
normallist[(localquadlist[i] * 3) + 2] = localnormallist[(localquadlistnormal[i] * 3) + 2];
241
printf("Msg: No Triangle Normals to Copy\n");
244
// If there are triangle uv coordinates, copy uv coordinate data
245
if(texturecount > 0) {
246
printf("Msg: Copying Triangle UV Coordinates: %i / %i !\n", texturecount, trianglecount);
247
for(i = 0; i < trianglecount * 3; i++) {
249
uvlist[localtrianglelist[i] * 3] = localuvlist[localtrianglelistuv[i] * 3];
251
uvlist[(localtrianglelist[i] * 3) + 1] = localuvlist[(localtrianglelistuv[i] * 3) + 1];
253
for(i = 0;i < quadcount * 4; i++) {
255
uvlist[localquadlist[i] * 3] = localuvlist[localquadlistuv[i] * 3];
257
uvlist[(localquadlist[i] * 3) + 1] = localuvlist[(localquadlistuv[i] * 3) + 1];
260
printf("Msg: No Triangle UV Coordinates to Copy\n");
264
printf("--------------------------------\n");
265
printf("Saving JSON Object file: %s\n", outputfile);
266
printf("--------------------------------\n");
268
// Process data to JSON
270
printf("\"vertexPositions\" : [");
271
for(i = 0; i < (vertcount * 3); i++) {
272
if(i < ((vertcount * 3) - 1)) {
273
printf("%f,", localvertexlist[i]);
275
printf("%f", localvertexlist[i]);
279
printf("\"vertexNormals\" : [");
280
if(normalcount > 0) {
281
for(i = 0; i < (vertcount * 3); i++) {
282
if(i < ((vertcount * 3) - 1)) {
283
printf("%f,", normallist[i]);
285
printf("%f", normallist[i]);
290
printf("\"vertexTextureCoords\" : [");
291
if(texturecount > 0) {
292
for(i = 0; i < (vertcount * 2); i++){
293
if(i < ((vertcount * 2) - 1)) {
294
printf("%f,", uvlist[i]);
296
printf("%f", uvlist[i]);
301
printf("\"indices\" : [");
304
for(i = 0; i < (trianglecount * 3); i++) {
305
if(i < ((trianglecount * 3) - 1)) {
306
printf("%i,", localtrianglelist[i]);
308
printf("%i", localtrianglelist[i]);
313
for(i = 0; i < quadcount; i++) {
314
if(i == (quadcount - 1)) {
315
printf("%i,%i,%i,%i,%i,%i,", localquadlist[i], localquadlist[i + 1], localquadlist[i + 2], localquadlist[i + 2], localquadlist[i + 3], localquadlist[i]);
317
printf("%i,%i,%i,%i,%i,%i ", localquadlist[i], localquadlist[i + 1], localquadlist[i + 2], localquadlist[i + 2], localquadlist[i + 3], localquadlist[i]);
325
free(localvertexlist);
326
free(localnormallist);
328
free(localtrianglelist);
329
free(localtrianglelistuv);
330
free(localtrianglelistnormal);
332
free(localquadlistuv);
333
free(localquadlistnormal);
336
printf("Error: Object did not contain any triangles or quads!\n");
341
printf("Error: Failed to find object %s!\n", openobj);
343
printf("Msg: Sucessful Parsing of Object %s in File %s\nMsg: %i vertices %i normals %i texture coordinates %i faces (%i triangles %i quads %i polys)\n", openobj, objfilename, vertcount, normalcount, texturecount, facecount, trianglecount, quadcount, polycount);
347
printf("Error: Failed to open %s!\n", objfilename);
352
int main(int argc, char** argv) {
354
printf("ERROR: not enough arguments. must have LOADFILE and SAVEFILE and if you want to process only a specific object, the name of object to process\n");
358
printf("--------------------------------\n");
359
printf("Loading Wavefront Object file: %s\n", argv[1]);
360
printf("--------------------------------\n");
363
printf("Msg: Loading Object: %s\n", argv[3]);
364
loadobj(argv[1], argv[3], argv[2]);
366
printf("Msg: Loading all Objects\n");
367
loadobj(argv[1], "ALL", argv[2]);