1 #ifdef _WIN32
2 #include "windows.h"
3 #endif
4 #include "GL/gl.h"
5
6 #include "string.h"
7 #include "stdio.h"
8
9 #include "cmc.h"
10 #include "3dobject.h"
11
12 #include "vector.h"
13 #include "myglutaux.h"
14
15
16 extern void Normal (double vector1[3],double vector2[3],double resultado[3]);
17
18
19 bool lookfor(char *tag,FILE *fp);
20 int lookfor2(char *tag,char *tag2,FILE *fp);
21 bool lookforinside(char *tag,FILE *fp);
22 bool nexttag(char *tag,FILE *fp);
23 bool nexttaginside(char *tag,FILE *fp);
24 bool skipinfo(FILE *fp);
25 bool readcomment(char *data,FILE *fp);
26
loadASE(char * file,char * texturedir)27 bool C3DObject::loadASE(char *file,char *texturedir)
28 {
29 int i=0,j=0;
30 int *smooth=0;
31 int *facematerial=0;
32 int **materials=0,nmaterials=0,*nsubmaterials=0;
33 char ***material_bitmaps=0;
34 char buffer[256];
35 FILE *fp;
36
37 fp=fopen(file,"r");
38 if (fp==NULL) return false;
39
40 /* Look for the materials: */
41 if (!lookfor("MATERIAL_LIST",fp) ||
42 !lookfor("MATERIAL_COUNT",fp)) {
43 fclose(fp);
44 return false;
45 } /* if */
46
47 if (1!=fscanf(fp,"%i",&nmaterials)) {
48 fclose(fp);
49 return false;
50 } /* if */
51
52 materials=new int *[nmaterials];
53 nsubmaterials=new int[nmaterials];
54 material_bitmaps=new char **[nmaterials];
55
56 for(j=0;j<nmaterials;j++) {
57 if (!lookfor("MATERIAL",fp) ||
58 !lookfor("MATERIAL_CLASS",fp) ||
59 !readcomment(buffer,fp)) {
60 fclose(fp);
61 return false;
62 } /* if */
63
64 if (strcmp(buffer,"Standard")==0) {
65 /* Standard Material, has no Submaterials: */
66 nsubmaterials[j]=1;
67 materials[j]=new int[1];
68 materials[j][0]=0;
69 material_bitmaps[j]=new char *[1];
70 material_bitmaps[j][0]=0;
71 if (lookforinside("MAP_DIFFUSE",fp) &&
72 lookfor("BITMAP",fp)) {
73 char bmpname[256],bmpname2[256];
74 int k,l;
75
76 if (!readcomment(bmpname,fp)) {
77 fclose(fp);
78 return false;
79 } /* if */
80
81 for(l=0,k=0;bmpname[l]!=0;l++) {
82 if (bmpname[l]=='\\' || bmpname[l]=='/') {
83 k=l;
84 } /* if */
85 } /* for */
86 if (k!=0) k++;
87
88 sprintf(bmpname2,"%s/%s",texturedir,bmpname+k);
89 material_bitmaps[j][0]=new char[strlen(bmpname2)+1];
90 strcpy(material_bitmaps[j][0],bmpname2);
91 // materials[j][0]=createTexture(bmpname2);
92 } /* if */
93 } else {
94 /* Composed material, has submaterials: */
95 if (!lookfor("NUMSUBMTLS",fp) ||
96 1!=fscanf(fp,"%i",&(nsubmaterials[j]))) {
97 fclose(fp);
98 return false;
99 } /* if */
100
101 materials[j]=new int[nsubmaterials[j]];
102 for(i=0;i<nsubmaterials[j];i++) materials[j][i]=0;
103 material_bitmaps[j]=new char *[nsubmaterials[j]];
104 for(i=0;i<nsubmaterials[j];i++) material_bitmaps[j][i]=0;
105
106 for(i=0;i<nsubmaterials[j];i++) {
107 if (!lookfor("SUBMATERIAL",fp)) {
108 fclose(fp);
109 return false;
110 } /* if */
111 if (lookforinside("MAP_DIFFUSE",fp) &&
112 lookfor("BITMAP",fp)) {
113 char bmpname[256],bmpname2[256];
114 int k,l;
115
116 if (!readcomment(bmpname,fp)) {
117 fclose(fp);
118 return false;
119 } /* if */
120
121 for(l=0,k=0;bmpname[l]!=0;l++) {
122 if (bmpname[l]=='\\' || bmpname[l]=='/') {
123 k=l;
124 } /* if */
125 } /* for */
126 if (k!=0) k++;
127
128 sprintf(bmpname2,"%s/%s",texturedir,bmpname+k);
129 material_bitmaps[j][i]=new char[strlen(bmpname2)+1];
130 strcpy(material_bitmaps[j][i],bmpname2);
131 // materials[j][i]=createTexture(bmpname2);
132 } /* if */
133 } /* for */
134 } /* if */
135 } /* if */
136
137 if (!lookfor("GEOMOBJECT",fp) ||
138 !lookfor("MESH",fp)) {
139 fclose(fp);
140 return false;
141 } /* if */
142
143 if (!lookfor("MESH_NUMVERTEX",fp) ||
144 1!=fscanf(fp,"%i",&npuntos)) {
145 fclose(fp);
146 return false;
147 } /* if */
148
149 puntos=new float[npuntos*3];
150 for(i=0;i<npuntos*3;i++) puntos[i]=0.0F;
151
152 if (!lookfor("MESH_NUMFACES",fp) ||
153 1!=fscanf(fp,"%i",&ncaras)) {
154 fclose(fp);
155 return false;
156 } /* if */
157
158 caras=new int[ncaras*3];
159 smooth=new int[ncaras];
160 facematerial=new int[ncaras];
161 r=new float[ncaras];
162 g=new float[ncaras];
163 b=new float[ncaras];
164 for(i=0;i<ncaras*3;i++) {
165 caras[i]=0;
166 } /* for */
167 for(i=0;i<ncaras;i++) {
168 r[i]=0.5;
169 g[i]=0.5;
170 b[i]=0.5;
171 } /* for */
172
173 if (!lookfor("MESH_VERTEX_LIST",fp)) {
174 fclose(fp);
175 return false;
176 } /* if */
177
178 for(i=0;i<npuntos;i++) {
179 int p;
180 float x,y,z;
181
182 if (!lookfor("MESH_VERTEX",fp) ||
183 4!=fscanf(fp,"%i %f %f %f",&p,&x,&y,&z)) {
184 fclose(fp);
185 return false;
186 } /* if */
187
188 puntos[p*3]=x;
189 puntos[p*3+1]=y;
190 puntos[p*3+2]=z;
191 } /* for */
192
193 if (!lookfor("MESH_FACE_LIST",fp)) {
194 fclose(fp);
195 return false;
196 } /* if */
197
198 for(i=0;i<ncaras;i++) {
199 int p1,p2,p3,s,mid;
200 char buffer[32];
201
202 if (!lookfor("MESH_FACE",fp) ||
203 7!=fscanf(fp,"%s %s %i %s %i %s %i",buffer,buffer,&p1,buffer,&p2,buffer,&p3)) {
204 fclose(fp);
205 return false;
206 } /* if */
207
208 caras[i*3]=p1;
209 caras[i*3+1]=p2;
210 caras[i*3+2]=p3;
211
212 if (!lookfor("MESH_SMOOTHING",fp) ||
213 1!=fscanf(fp,"%i",&s)) {
214 fclose(fp);
215 return false;
216 } /* if */
217 smooth[i]=s;
218
219 if (!lookfor("MESH_MTLID",fp) ||
220 1!=fscanf(fp,"%i",&mid)) {
221 fclose(fp);
222 return false;
223 } /* if */
224 facematerial[i]=mid;
225
226 } /* for */
227
228 if (nmaterials!=0) {
229 int v=lookfor2("MESH_FACEMAPLIST","MESH_NUMTVERTEX",fp);
230
231 if (v==1) {
232 /* MESH_FACEMAPLIST: */
233 int f;
234 float x,y,z;
235
236 textures=new unsigned int[ncaras];
237 tx=new float[ncaras*3];
238 ty=new float[ncaras*3];
239
240 for(i=0;i<ncaras;i++) {
241 if (!lookfor("MESH_FACEMAP",fp) ||
242 1!=fscanf(fp,"%i",&f)) {
243 fclose(fp);
244 return false;
245 } /* if */
246
247 // textures[f]=materials[facematerial[f]];
248 if (!lookfor("MESH_FACEMAPVERT",fp) ||
249 3!=fscanf(fp,"%f %f %f",&x,&y,&z)) {
250 fclose(fp);
251 return false;
252 } /* if */
253 tx[f*3]=x;
254 ty[f*3]=1-y;
255 if (!lookfor("MESH_FACEMAPVERT",fp) ||
256 3!=fscanf(fp,"%f %f %f",&x,&y,&z)) {
257 fclose(fp);
258 return false;
259 } /* if */
260 tx[f*3+1]=x;
261 ty[f*3+1]=1-y;
262 if (!lookfor("MESH_FACEMAPVERT",fp) ||
263 3!=fscanf(fp,"%f %f %f",&x,&y,&z)) {
264 fclose(fp);
265 return false;
266 } /* if */
267 tx[f*3+2]=x;
268 ty[f*3+2]=1-y;
269 } /* for */
270 } /* if */
271 if (v==2) {
272 /* MESH_NUMTVERTEX: */
273 int ntv,ntf,n,p1,p2,p3;
274 float *tv,x,y;
275
276 if (1!=fscanf(fp,"%i",&ntv) ||
277 !lookfor("MESH_TVERTLIST",fp)) {
278 fclose(fp);
279 return false;
280 } /* if */
281
282 tv=new float[ntv*2];
283 for(i=0;i<ntv;i++) {
284 if (!lookfor("MESH_TVERT",fp) ||
285 3!=fscanf(fp,"%i %f %f",&n,&x,&y)) {
286 fclose(fp);
287 return false;
288 } /* if */
289 tv[n*2]=x;
290 tv[n*2+1]=y;
291 } /* for */
292
293 if (!lookfor("MESH_NUMTVFACES",fp) ||
294 1!=fscanf(fp,"%i",&ntf) ||
295 !lookfor("MESH_TFACELIST",fp)) {
296 fclose(fp);
297 return false;
298 } /* if */
299
300 textures=new unsigned int[ncaras];
301 tx=new float[ncaras*3];
302 ty=new float[ncaras*3];
303
304 for(i=0;i<ntf;i++) {
305 if (!lookfor("MESH_TFACE",fp) ||
306 4!=fscanf(fp,"%i %i %i %i",&n,&p1,&p2,&p3)) {
307 fclose(fp);
308 return false;
309 } /* if */
310 tx[n*3]=tv[p1*2];
311 ty[n*3]=1-tv[p1*2+1];
312 tx[n*3+1]=tv[p2*2];
313 ty[n*3+1]=1-tv[p2*2+1];
314 tx[n*3+2]=tv[p3*2];
315 ty[n*3+2]=1-tv[p3*2+1];
316 // textures[n]=materials[facematerial[n]];
317 } /* for */
318
319 delete tv;
320 } /* if */
321
322 /* Create all the materials used by the faces: */
323 {
324 int mid;
325
326 if (!lookfor("MATERIAL_REF",fp) ||
327 1!=fscanf(fp,"%i",&mid)) {
328 fclose(fp);
329 return false;
330 } /* if */
331
332 for(i=0;i<ncaras;i++) {
333 if (facematerial[i]>nsubmaterials[mid]) facematerial[i]=0;
334 if (materials[mid][facematerial[i]]==0 &&
335 material_bitmaps[mid][facematerial[i]]!=0) {
336 materials[mid][facematerial[i]]=createTexture(material_bitmaps[mid][facematerial[i]]);
337 } /* if */
338 textures[i]=materials[mid][facematerial[i]];
339 } /* for */
340 }
341 } /* if */
342
343 for(j=0;j<nmaterials;j++) {
344 delete materials[j];
345 materials[j]=0;
346 for(i=0;i<nsubmaterials[j];i++) {
347 delete material_bitmaps[j][i];
348 material_bitmaps[j][i]=0;
349 } /* for */
350 delete material_bitmaps[j];
351 material_bitmaps[j]=0;
352 } /* for */
353 delete material_bitmaps;
354 delete nsubmaterials;
355 delete materials;
356
357 CalculaNormales(smooth);
358 cmc.set(puntos,npuntos);
359
360 delete smooth;
361 delete facematerial;
362
363 fclose(fp);
364 return true;
365 } /* C3DObject::loadASE */
366
367
nexttag(char * tag,FILE * fp)368 bool nexttag(char *tag,FILE *fp)
369 {
370 int c;
371
372 do{
373 c=fgetc(fp);
374 }while(c!='*' && c!=EOF);
375 if (c==EOF) return false;
376
377 if (1!=fscanf(fp,"%s",tag)) return false;
378
379 return true;
380 } /* nexttag */
381
382
383
nexttaginside(char * tag,FILE * fp)384 bool nexttaginside(char *tag,FILE *fp)
385 {
386 int parentheses=0;
387 bool instring=false;
388 int c;
389
390 do{
391 c=fgetc(fp);
392 if (c=='\"') {
393 if (instring) instring=false;
394 else instring=true;
395 } /* if */
396 if (!instring && c=='{') parentheses++;
397 if (!instring && c=='}') parentheses--;
398 }while(instring || (c!='*' && c!=EOF && parentheses>=0));
399 if (c==EOF || parentheses<0) return false;
400
401 if (1!=fscanf(fp,"%s",tag)) return false;
402
403 return true;
404 } /* nexttaginside */
405
406
skipinfo(FILE * fp,int parentheses)407 bool skipinfo(FILE *fp,int parentheses)
408 {
409 bool instring=false;
410 int c;
411
412 do{
413 c=fgetc(fp);
414 if (c=='\"') {
415 if (instring) instring=false;
416 else instring=true;
417 } /* if */
418 if (!instring && c=='{') parentheses++;
419 if (!instring && c=='}') parentheses--;
420 }while((c!='\n' || parentheses!=0 || instring==true) && c!=EOF);
421 if (c==EOF) return false;
422
423 return true;
424 } /* skipinfo */
425
426
lookfor(char * tag,FILE * fp)427 bool lookfor(char *tag,FILE *fp)
428 {
429 char tagname[256];
430
431 for(;;) {
432 if (!nexttag(tagname,fp)) return false;
433 if (strcmp(tag,tagname)==0) return true;
434 skipinfo(fp,0);
435 } /* forever */
436
437 return false;
438 } /* lookfor */
439
440
lookfor2(char * tag,char * tag2,FILE * fp)441 int lookfor2(char *tag,char *tag2,FILE *fp)
442 {
443 char tagname[256];
444
445 for(;;) {
446 if (!nexttag(tagname,fp)) return 0;
447 if (strcmp(tag,tagname)==0) return 1;
448 if (strcmp(tag2,tagname)==0) return 2;
449 skipinfo(fp,0);
450 } /* forever */
451
452 return 0;
453 } /* lookfor2 */
454
455
456
lookforinside(char * tag,FILE * fp)457 bool lookforinside(char *tag,FILE *fp)
458 {
459 char tagname[256];
460
461 for(;;) {
462 if (!nexttaginside(tagname,fp)) return false;
463 if (strcmp(tag,tagname)==0) return true;
464 skipinfo(fp,0);
465 } /* forever */
466
467 return false;
468 } /* lookforinside */
469
470
readcomment(char * data,FILE * fp)471 bool readcomment(char *data,FILE *fp)
472 {
473 int c;
474
475 while(fgetc(fp)!='\"');
476
477 do{
478 c=fgetc(fp);
479 *data=c;
480 data++;
481 }while(c!='\"' && c!=EOF);
482 if (c==EOF) return false;
483 data--;
484 *data=0;
485
486 return true;
487 } /* readcomment */
488