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