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 |
}
|