/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk
1 by Henrik G.
First seed of Lenasys ... Needs to be Organized Further
1
#include <STDIO.H>
2
#include <STDLIB.H>
3
#include <STRING.H>
4
5
void parseface(char *facedata,int *varray,int *narray,int *tarray,int position, int hasuv, int hasnormals)
6
{
7
	char workstr[10];
8
9
	int readpos=0;
10
11
	int i;
12
	for(i=0;i<3;i++){
13
		int pos=0;
14
		
15
		while(readpos<strlen(facedata)&&facedata[readpos]!='/'){
16
			workstr[pos]=facedata[readpos];
17
			pos++;
18
			readpos++;
19
		}
20
		workstr[pos]=0;
21
22
		pos=0;
23
		readpos++;
24
		
25
		// -1 to compensate for wavefront file starting on 1 and not 0
26
		if (i==0){
27
			varray[position]=atoi(workstr)-1;
28
		}else if((i==1)&&(hasuv>0)){
29
			tarray[position]=atoi(workstr)-1;		
30
		}else if((i==2)&&(hasnormals>0)){
31
			narray[position]=atoi(workstr)-1;
32
		}
33
	}
34
}
35
36
37
void loadobj(char *objfilename, char *openobj, char *outputfile)
38
{
39
	FILE * pFile;
40
	pFile = fopen (objfilename,"r");
41
	
42
	
43
	char *buf;
44
	buf=(char*)malloc(1024);
45
	char *result;
46
	
47
	// foundobj is true if an object with a certain name is found
48
	// Set foundobj to true if we are loading all objects
49
	int foundobj=0;
50
	if (strcmp(openobj,"ALL")==0) foundobj=1;
51
52
	int vertcount=0;	
53
	int normalcount=0;	
54
	int texturecount=0;
55
	int facecount=0;
56
57
	int polycount=0;
58
	int quadcount=0;
59
	int trianglecount=0;
60
61
	// Global Variables for Object
62
	float *vertexlist;
63
	float *uvlist;
64
	float *normallist;
65
	int *trianglelist;
66
	int *quadlist;
67
68
	char *resultp1,*resultp2,*resultp3,*resultp4,*resultp5;
69
70
	if(pFile){
71
		printf("Msg: Success opening: %s!\n",objfilename);
72
73
		while ( fgets(buf,1024,pFile) != NULL ){
74
			if(buf[0]=='#'){
75
				// Comment - Do Nothing				
76
			}else{
77
				result=strtok(buf," \n\t");
78
				if(result!=NULL){
79
					if(strcmp(result,"v")==0){
80
						if(foundobj){
81
							// Increase vertex counter
82
							vertcount++;						
83
						}
84
					}else if(strcmp(result,"vt")==0){
85
						if(foundobj){
86
							// Increase texture coordinate counter
87
							texturecount++;						
88
						}
89
						
90
					}else if(strcmp(result,"vn")==0){
91
						if(foundobj){
92
							// Increase normal counter
93
							normalcount++;						
94
						}						
95
					}else if(strcmp(result,"f")==0){
96
						if(foundobj){
97
							// Increase face counter
98
							facecount++;						
99
							resultp1=strtok(NULL," \n\t");
100
							resultp2=strtok(NULL," \n\t");
101
							resultp3=strtok(NULL," \n\t");
102
							resultp4=strtok(NULL," \n\t");
103
							resultp5=strtok(NULL," \n\t");
104
							if((resultp4!=NULL)&&(resultp5==NULL)){
105
								quadcount++;
106
							}else if((resultp3!=NULL)&&(resultp4==NULL)){
107
								trianglecount++;
108
							}else{
109
								polycount++;
110
							}
111
						}						
112
					}else if(strcmp(result,"g")==0){
113
						if(result=strtok(NULL," \n\t")){
114
							if(!strcmp(openobj,result)){
115
								foundobj=1;
116
							}
117
						}else{
118
							printf("Error: Failed to read object name\n");	
119
						}
120
					}else{
121
//						printf("O: %s \n",buf);
122
					}
123
				}
124
			}
125
		}
126
127
		if (polycount>0){
128
			printf("Warning: Object %s in file %s contains faces that will be ignored, with more than 4 vertices.!\n",objfilename,openobj);		
129
		}
130
		
131
		if(((trianglecount+quadcount)>0)){
132
133
			// Set foundobj to true if we are loading all objects
134
			if (strcmp(openobj,"ALL")) foundobj=1;
135
136
			// Seek to beginning again
137
			fseek( pFile, 0, SEEK_SET);
138
139
			// Allocate local buffers
140
			float *localvertexlist=(float *)malloc(sizeof(float)*vertcount*3);
141
			float *localnormallist=(float *)malloc(sizeof(float)*normalcount*3);
142
			float *localuvlist=(float *)malloc(sizeof(float)*texturecount*2);
143
			int *localquadlist=(int *)malloc(sizeof(int)*quadcount*4);
144
			int *localquadlistuv=(int *)malloc(sizeof(int)*quadcount*4);
145
			int *localquadlistnormal=(int *)malloc(sizeof(int)*quadcount*4);
146
			int *localtrianglelist=(int *)malloc(sizeof(int)*trianglecount*3);
147
			int *localtrianglelistuv=(int *)malloc(sizeof(int)*trianglecount*3);
148
			int *localtrianglelistnormal=(int *)malloc(sizeof(int)*trianglecount*3);
149
150
			// Reset counters for second pass
151
			trianglecount=0;
152
			quadcount=0;
153
			normalcount=0;
154
			vertcount=0;
155
			texturecount=0;
156
157
			while ( fgets(buf,1024,pFile) != NULL ){
158
159
				if(buf[0]=='#'){
160
					// Comment - Do Nothing				
161
				}else{
162
163
					//-------------------------
164
					result = strtok(buf," \n\t");
165
					if(result!=NULL){
166
						if(strcmp(result,"v")==0){
167
							if(foundobj){
168
								result=strtok(NULL," \n\t");
169
								localvertexlist[(vertcount*3)]=atof(result);
170
								result=strtok(NULL," \n\t");
171
								localvertexlist[(vertcount*3)+1]=atof(result);
172
								result=strtok(NULL," \n\t");
173
								localvertexlist[(vertcount*3)+2]=atof(result);
174
								vertcount++;
175
							}
176
						}else if(strcmp(result,"vt")==0){
177
							if(foundobj){
178
								result=strtok(NULL," \n\t");
179
								localuvlist[(texturecount*2)]=atof(result);
180
								result=strtok(NULL," \n\t");
181
								localuvlist[(texturecount*2)+1]=atof(result);
182
								texturecount++;						
183
							}							
184
						}else if(strcmp(result,"vn")==0){
185
							if(foundobj){
186
								result=strtok(NULL," \n\t");
187
								localnormallist[(normalcount*3)]=atof(result);
188
								result=strtok(NULL," \n\t");
189
								localnormallist[(normalcount*3)+1]=atof(result);
190
								result=strtok(NULL," \n\t");
191
								localnormallist[(normalcount*3)+2]=atof(result);
192
								normalcount++;
193
							}						
194
195
						}else if(strcmp(result,"f")==0){
196
							if(foundobj){								
197
								resultp1=strtok(NULL," \n\t");
198
								resultp2=strtok(NULL," \n\t");
199
								resultp3=strtok(NULL," \n\t");
200
								resultp4=strtok(NULL," \n\t");
201
								resultp5=strtok(NULL," \n\t");
202
								if((resultp4!=NULL)&&(resultp5==NULL)){
203
									// Parse all 4 points in quad
204
									parseface(resultp1,localquadlist,localquadlistnormal,localquadlistuv,quadcount*4,texturecount,normalcount);
205
									parseface(resultp2,localquadlist,localquadlistnormal,localquadlistuv,(quadcount*4)+1,texturecount,normalcount);
206
									parseface(resultp3,localquadlist,localquadlistnormal,localquadlistuv,(quadcount*4)+2,texturecount,normalcount);
207
									parseface(resultp4,localquadlist,localquadlistnormal,localquadlistuv,(quadcount*4)+3,texturecount,normalcount);
208
209
									quadcount++;
210
211
								}else if((resultp3!=NULL)&&(resultp4==NULL)){
212
		
213
									// Parse all 3 points in triangle
214
									parseface(resultp1,localtrianglelist,localtrianglelistnormal,localtrianglelistuv,trianglecount*3,texturecount,normalcount);
215
									parseface(resultp2,localtrianglelist,localtrianglelistnormal,localtrianglelistuv,(trianglecount*3)+1,texturecount,normalcount);
216
									parseface(resultp3,localtrianglelist,localtrianglelistnormal,localtrianglelistuv,(trianglecount*3)+2,texturecount,normalcount);
217
218
									trianglecount++;								
219
								}
220
							}						
221
						}else if(strcmp(result,"g")==0){
222
							if(result=strtok(NULL," \n\t")){
223
								if(!strcmp(openobj,result)){
224
									foundobj=1;
225
								}
226
							}
227
						}
228
					}					
229
					//-------------------------
230
231
				}
232
233
			}
234
235
			int i=0;
236
237
			// Allocate buffers
238
			vertexlist=(float *)malloc(sizeof(float)*vertcount*3);
239
			normallist=(float *)malloc(sizeof(float)*vertcount*3);
240
			uvlist=(float *)malloc(sizeof(float)*vertcount*2);
241
			trianglelist=(int *)malloc(sizeof(int)*trianglecount*3);
242
			quadlist=(int *)malloc(sizeof(int)*quadcount*4);
243
		
244
			// Copy data from Per Face model to Per Vertex model first for triangles and then for quads
245
246
			// If there are triangle normals, copy triangle normal data 
247
			if(normalcount>0){
248
				printf("Msg: Copying Triangle Normals: %i / %i !\n",normalcount,trianglecount);
249
				for(i=0;i<trianglecount*3;i++){
250
					// Normal X
251
					normallist[localtrianglelist[i]*3]=localnormallist[localtrianglelistnormal[i]*3];
252
					// Normal Y
253
					normallist[(localtrianglelist[i]*3)+1]=localnormallist[(localtrianglelistnormal[i]*3)+1];
254
					// Normal Z
255
					normallist[(localtrianglelist[i]*3)+2]=localnormallist[(localtrianglelistnormal[i]*3)+2];
256
				}
257
				for(i=0;i<quadcount*4;i++){
258
					// Normal X
259
					normallist[localquadlist[i]*3]=localnormallist[localquadlistnormal[i]*3];
260
					// Normal Y
261
					normallist[(localquadlist[i]*3)+1]=localnormallist[(localquadlistnormal[i]*3)+1];
262
					// Normal Z
263
					normallist[(localquadlist[i]*3)+2]=localnormallist[(localquadlistnormal[i]*3)+2];
264
				}
265
			}else{
266
				printf("Msg: No Triangle Normals to Copy\n");
267
			}
268
			
269
			// If there are triangle uv coordinates, copy uv coordinate data 
270
			if(texturecount>0){
271
				printf("Msg: Copying Triangle UV Coordinates: %i / %i !\n",texturecount,trianglecount);
272
				for(i=0;i<trianglecount*3;i++){
273
					// U Coordinate
274
					uvlist[localtrianglelist[i]*3]=localuvlist[localtrianglelistuv[i]*3];
275
					// V Coordinate
276
					uvlist[(localtrianglelist[i]*3)+1]=localuvlist[(localtrianglelistuv[i]*3)+1];
277
				}
278
				for(i=0;i<quadcount*4;i++){
279
					// U Coordinate
280
					uvlist[localquadlist[i]*3]=localuvlist[localquadlistuv[i]*3];
281
					// V Coordinate
282
					uvlist[(localquadlist[i]*3)+1]=localuvlist[(localquadlistuv[i]*3)+1];
283
				}
284
			}else{
285
				printf("Msg: No Triangle UV Coordinates to Copy\n");
286
			}
287
288
			// Same for Quads			
289
290
291
			printf("--------------------------------\n");
292
			printf("Saving JSON Object file: %s\n", outputfile);
293
			printf("--------------------------------\n");
294
295
			// Process data to JSON
296
			printf("{\n");
297
298
			printf("\"vertexPositions\" : [");
299
			for(i=0;i<(vertcount*3);i++){
300
				if(i<((vertcount*3)-1)) {
301
						printf("%f,",localvertexlist[i]);
302
				}else{
303
						printf("%f",localvertexlist[i]);
304
				}
305
			}
306
			printf("],\n");
307
308
			printf("\"vertexNormals\" : [");
309
			if(normalcount>0){
310
					for(i=0;i<(vertcount*3);i++){
311
						if(i<((vertcount*3)-1)) {
312
								printf("%f,",normallist[i]);
313
						}else{
314
								printf("%f",normallist[i]);
315
						}
316
					}			
317
			}
318
			printf("],\n");
319
320
			printf("\"vertexTextureCoords\" : [");
321
			if(texturecount>0){
322
					for(i=0;i<(vertcount*2);i++){
323
						if(i<((vertcount*2)-1)) {
324
								printf("%f,",uvlist[i]);
325
						}else{
326
								printf("%f",uvlist[i]);
327
						}
328
					}						
329
			}
330
			printf("],\n");
331
332
			printf("\"indices\" : [");
333
			
334
			// Triangle indices
335
			for(i=0;i<(trianglecount*3);i++){
336
				if(i<((trianglecount*3)-1)) {
337
						printf("%i,",localtrianglelist[i]);
338
				}else{
339
						printf("%i",localtrianglelist[i]);
340
				}
341
			}		
342
343
			// Quad indices
344
			for(i=0;i<quadcount;i++){				
345
				if(i==(quadcount-1)) {
346
						printf("%i,%i,%i,%i,%i,%i,",localquadlist[i],localquadlist[i+1],localquadlist[i+2],localquadlist[i+2],localquadlist[i+3],localquadlist[i]);
347
				}else{
348
						printf("%i,%i,%i,%i,%i,%i ",localquadlist[i],localquadlist[i+1],localquadlist[i+2],localquadlist[i+2],localquadlist[i+3],localquadlist[i]);
349
				}
350
			}		
351
352
			printf("]\n");
353
354
			printf("}\n");
355
356
			// Free buffers
357
			free(localvertexlist);
358
			free(localnormallist);
359
			free(localuvlist);
360
			free(localtrianglelist);
361
			free(localtrianglelistuv);
362
			free(localtrianglelistnormal);
363
			free(localquadlist);
364
			free(localquadlistuv);
365
			free(localquadlistnormal);
366
367
		}else{
368
			// Multigon
369
			printf("Error: Object did not contain any triangles or quads!\n");		
370
		}
371
372
		fclose ( pFile );
373
374
		if(!foundobj){
375
			printf("Error: Failed to find object %s!\n",openobj);		
376
		}else{
377
			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);
378
		}
379
		
380
	}else{
381
		printf("Error: Failed to open %s!\n",objfilename);	
382
	}
383
384
	free(buf);
385
}
386
387
int main (int argc, char** argv) {
388
389
	if (argc < 3) {
390
			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");
391
			return 1;
392
	}
393
394
	printf("--------------------------------\n");
395
	printf("Loading Wavefront Object file: %s\n", argv[1]);
396
	printf("--------------------------------\n");
397
398
	if(argc>3){
399
			printf("Msg: Loading Object: %s\n", argv[3]);
400
			loadobj(argv[1],argv[3],argv[2]);
401
	}else{
402
			printf("Msg: Loading all Objects\n");	
403
			loadobj(argv[1],"ALL",argv[2]);
404
	}
405
406
	return 0;
407
408
}