TORCS  1.3.10
The Open Racing Car Simulator
Loading...
Searching...
No Matches
grloadac.cpp
Go to the documentation of this file.
1/*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 2001 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id$
22*/
23
24#include <plib/ssg.h>
25#include <zlib.h>
26
27#include "grssgext.h"
28#include "grvtxtable.h"
29#include "grmultitexstate.h"
30#include "grmain.h"
31#include "grtexture.h"
32int inGroup=0;
33
34
35#define FGETS(buf, len, file) gzgets(file, buf, len)
36#define FGETC(file) gzgetc(file)
37#define FOPEN(path, mode) gzopen(path, mode)
38#define FCLOSE(fd) gzclose(fd)
39
40static double t_xmax;
41static double t_ymax;
42static double t_xmin;
43static double t_ymin;
44
45double shad_xmax;
46double shad_ymax;
47double shad_xmin;
48double shad_ymin;
51
52
53static gzFile loader_fd ;
54
55
57{
58 sgVec4 spec ;
59 sgVec4 emis ;
60 sgVec4 amb ;
61 sgVec4 rgb ;
62 float shi ;
63} ;
64
65static int num_materials = 0 ;
66static sgVec3 *vtab = NULL ;
67static sgVec3 *ntab = NULL ;
68static sgVec2 *t0tab = NULL;
69static sgVec2 *t1tab = NULL;
70static sgVec2 *t2tab = NULL;
71static sgVec2 *t3tab = NULL;
72static ssgIndexArray *vertlist=NULL;
73static ssgIndexArray *striplist=NULL;
74static int totalnv=0;
75static int totalstripe=0;
76static int usenormal = 0;
77static int nv;
78static int isacar = TRUE;
79static int usestrip=TRUE;
80static int usegroup=TRUE;
81static int mapLevel;
82static int numMapLevel;
83static int indexCar;
84
85static int isaWindow;
86
87static ssgLoaderOptions *current_options = NULL ;
89static sgVec4 *current_colour = NULL ;
90static ssgBranch *current_branch = NULL ;
91static char *current_tfname = NULL ;
92static char *current_tbase = NULL ;
93static char *current_ttiled = NULL ;
94static char *current_tskids = NULL ;
95static char *current_tshad = NULL ;
96static char *current_data = NULL ;
97#define NOTEXTURE "empty_texture_no_mapping"
98#define MAX_MATERIALS 1000 /* This *ought* to be enough! */
100static sgVec4 *clist [ MAX_MATERIALS ] ;
101
102static sgMat4 current_matrix ;
103static sgVec2 texrep ;
104static sgVec2 texoff ;
105
106static int do_material ( char *s ) ;
107static int do_object ( char *s ) ;
108static int do_name ( char *s ) ;
109static int do_data ( char *s ) ;
110static int do_texture ( char *s ) ;
111static int do_texrep ( char *s ) ;
112static int do_texoff ( char *s ) ;
113static int do_rot ( char *s ) ;
114static int do_loc ( char *s ) ;
115static int do_url ( char *s ) ;
116static int do_numvert ( char *s ) ;
117static int do_numsurf ( char *s ) ;
118static int do_surf ( char *s ) ;
119static int do_mat ( char *s ) ;
120static int do_refs ( char *s ) ;
121static int do_kids ( char *s ) ;
122
123static int do_obj_world ( char *s ) ;
124static int do_obj_poly ( char *s ) ;
125static int do_obj_group ( char *s ) ;
126static int do_obj_light ( char *s ) ;
127/*static void myssgStripify ( ssgEntity *ent );*/
128#define PARSE_CONT 0
129#define PARSE_POP 1
130
131struct Tag
132{
133 const char *token ;
134 int (*func) ( char *s ) ;
135} ;
136
137
138static void skip_spaces ( char **s )
139{
140 while ( **s == ' ' || **s == '\t' )
141 (*s)++ ;
142}
143
144
145static void skip_quotes ( char **s )
146{
147 skip_spaces ( s ) ;
148
149 if ( **s == '\"' )
150 {
151 (*s)++ ;
152
153 char *t = *s ;
154
155 while ( *t != '\0' && *t != '\"' )
156 t++ ;
157
158 if ( *t != '\"' )
159 ulSetError ( UL_WARNING, "ac_to_gl: Mismatched double-quote ('\"') in '%900s'", *s ) ;
160
161 *t = '\0' ;
162 }
163 else
164 ulSetError ( UL_WARNING, "ac_to_gl: Expected double-quote ('\"') in '%900s'", *s ) ;
165}
166
167
168
169static int search ( Tag *tags, char *s )
170{
171 skip_spaces ( & s ) ;
172
173 for ( int i = 0 ; tags[i].token != NULL ; i++ )
174 if ( ulStrNEqual ( tags[i].token, s, strlen(tags[i].token) ) )
175 {
176 s += strlen ( tags[i].token ) ;
177
178 skip_spaces ( & s ) ;
179
180 return (*(tags[i].func))( s ) ;
181 }
182
183 ulSetError ( UL_WARNING, "ac_to_gl: Unrecognised token '%900s' (%d)", s , strlen(s)) ;
184
185 return 0 ; /* Should never get here */
186}
187
188static Tag top_tags [] =
189{
190 { "MATERIAL", do_material },
191 { "OBJECT" , do_object },
192} ;
193
194
195static Tag object_tags [] =
196{
197 { "name" , do_name },
198 { "data" , do_data },
199 { "texture" , do_texture },
200 { "texrep" , do_texrep },
201 { "texoff" , do_texoff },
202 { "rot" , do_rot },
203 { "loc" , do_loc },
204 { "url" , do_url },
205 { "numvert" , do_numvert },
206 { "numsurf" , do_numsurf },
207 { "kids" , do_kids },
208 { NULL, NULL }
209} ;
210
211static Tag surf_tag [] =
212{
213 { "SURF" , do_surf },
214 { NULL, NULL }
215} ;
216
217static Tag surface_tags [] =
218{
219 { "mat" , do_mat },
220 { "refs" , do_refs },
221 { NULL, NULL }
222} ;
223
224static Tag obj_type_tags [] =
225 {
226 { "world", do_obj_world },
227 { "poly" , do_obj_poly },
228 { "group", do_obj_group },
229 { "light", do_obj_light },
230 { NULL, NULL }
231 } ;
232
233#define OBJ_WORLD 0
234#define OBJ_POLY 1
235#define OBJ_GROUP 2
236#define OBJ_LIGHT 3
237
238static int do_obj_world ( char * ) { return OBJ_WORLD ; }
239static int do_obj_poly ( char * ) { return OBJ_POLY ; }
240static int do_obj_group ( char * ) { return OBJ_GROUP ; }
241static int do_obj_light ( char * ) { return OBJ_LIGHT ; }
242static ssgEntity *myssgLoadAC ( const char *fname, const ssgLoaderOptions* options );
243
244
245static int last_num_kids = -1 ;
246static int current_flags = -1 ;
247
248static ssgState *get_state ( _ssgMaterial *mat )
249{
250#ifdef EEE_PAS_COMPRIS
251#warning: HELLO ---------------------
252 if (current_tfname != NULL) {
253 ssgState *st = current_options -> createState ( current_tfname ) ;
254 /* printf("creating texture : %s\n",current_tfname); */
255 if ( st != NULL )
256 return st ;
257 }
258#endif
259
260 //ssgSimpleState *st = new ssgSimpleState () ;
262
263 st -> setMaterial ( GL_SPECULAR, mat -> spec ) ;
264 st -> setMaterial ( GL_EMISSION, mat -> emis ) ;
265 st -> setMaterial ( GL_AMBIENT_AND_DIFFUSE, mat -> amb ) ;
266 st -> setShininess ( mat -> shi ) ;
267
268 st -> enable ( GL_COLOR_MATERIAL ) ;
269 st -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;
270
271 st -> enable ( GL_LIGHTING ) ;
272
273 st -> setShadeModel ( GL_SMOOTH ) ;
274 //st -> setShadeModel ( GL_FLAT ) ;
275
276 st -> setAlphaClamp(0);
277
278 if (isaWindow) {
279 st -> enable ( GL_BLEND );
280 st -> setTranslucent () ;
281 } else if (isacar) {
282 st -> enable ( GL_BLEND );
283 st -> setOpaque () ;
284 } else if ( mat -> rgb[3] < 0.99 ) {
285 st -> enable ( GL_ALPHA_TEST ) ;
286 st -> enable ( GL_BLEND ) ;
287 st -> setTranslucent () ;
288 } else {
289 st -> disable ( GL_BLEND ) ;
290 st -> setOpaque () ;
291 }
292
293 if (current_tfname != NULL) {
294 st -> setTexture( current_options -> createTexture(current_tfname) ) ;
295 st -> enable( GL_TEXTURE_2D ) ;
296
297 if (strstr(current_tfname,"tree")!=NULL || strstr(current_tfname,"trans-")!=NULL || strstr(current_tfname,"arbor")!=NULL)
298 {
299 st->setAlphaClamp(0.65f);
300 st -> enable ( GL_ALPHA_TEST ) ;
301 st -> enable ( GL_BLEND );
302 }
303 } else {
304 st -> disable ( GL_BLEND ) ;
305 st -> disable( GL_TEXTURE_2D ) ;
306 }
307
308 return st ;
309}
310
311static ssgState *get_state_ext ( char * name)
312{
313 if (name==NULL) {
314 return NULL;
315 }
317 st->disable(GL_BLEND);
318 st->setOpaque();
319
320 if (name != NULL) {
321 st->setTexture(current_options->createTexture(name));
322 st->enable(GL_TEXTURE_2D) ;
323 if (strstr(current_tfname,"tree")!=NULL || strstr(current_tfname,"trans-")!=NULL || strstr(current_tfname,"arbor")!=NULL) {
324 st->enable(GL_BLEND);
325 st->setAlphaClamp(0.7f);
326 st->enable(GL_ALPHA_TEST);
327 }
328 } else {
329 st->disable(GL_BLEND);
330 st->disable(GL_TEXTURE_2D);
331 }
332 return st ;
333}
334
335
336static int do_material ( char *s )
337{
338 char name [ 1024 ] ;
339 sgVec4 rgb ;
340 sgVec4 amb ;
341 sgVec4 emis ;
342 sgVec4 spec ;
343 int shi ;
344 float trans ;
345
346 if ( sscanf ( s,
347 "%1023s rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f",
348 name,
349 &rgb [0], &rgb [1], &rgb [2],
350 &amb [0], &amb [1], &amb [2],
351 &emis[0], &emis[1], &emis[2],
352 &spec[0], &spec[1], &spec[2],
353 &shi,
354 &trans ) != 15 )
355 {
356 // Buffer size in plib is 1024, I allow here just 900 characters, such that the WHOLE
357 // string fits the buffer.
358 ulSetError ( UL_WARNING, "grloadac:do_material: Can't parse this MATERIAL:%900s", s ) ;
359 }
360 else
361 {
362 char *nm = name ;
363
364 skip_quotes ( &nm ) ;
365
366 amb [ 3 ] = emis [ 3 ] = spec [ 3 ] = 1.0f ;
367 rgb [ 3 ] = 1.0f - trans ;
368
370 clist [ num_materials ] = new sgVec4 [ 1 ] ;
371
372 sgCopyVec4 ( clist [ num_materials ][ 0 ], rgb ) ;
373
375 sgCopyVec4 ( current_material -> spec, spec ) ;
376 sgCopyVec4 ( current_material -> emis, emis ) ;
377 sgCopyVec4 ( current_material -> rgb , rgb ) ;
378 sgCopyVec4 ( current_material -> amb , amb ) ;
379 current_material -> shi = (float) shi ;
380 }
381
382 num_materials++ ;
383 return PARSE_CONT ;
384}
385
386
387static int do_object ( char * s )
388{
389 //ssgBranch *current_branch_g = NULL;
390 int obj_type = search(obj_type_tags, s);
391
392 delete [] current_tfname;
393 current_tfname = NULL;
394
395 char buffer[1024];
396
397 sgSetVec2(texrep, 1.0f, 1.0f);
398 sgSetVec2(texoff, 0.0f, 0.0f);
399
400 sgMakeIdentMat4 ( current_matrix ) ;
401
402 ssgEntity *old_cb = current_branch ;
403
404 if (obj_type == OBJ_GROUP) {
405 ssgBranch *current_branch_g = NULL;
406 inGroup = 1;
407 current_branch_g = new ssgBranchCb();
408 current_branch->addKid(current_branch_g);
409 current_branch = (ssgTransform*) current_branch_g;
410
411 extern int preScene(ssgEntity *e);
412 current_branch_g->setCallback(SSG_CALLBACK_PREDRAW, preScene);
413 } else {
414 inGroup=0;
415 }
416
417 ssgTransform *tr = new ssgTransform () ;
418
419 tr -> setTransform ( current_matrix ) ;
420
421 current_branch -> addKid ( tr ) ;
422 current_branch = tr ;
423
424 while ( FGETS ( buffer, 1024, loader_fd ) != NULL )
425 if ( search ( object_tags, buffer ) == PARSE_POP )
426 break ;
427
428 int num_kids = last_num_kids ;
429
430 for ( int i = 0 ; i < num_kids ; i++ ) {
431 /* EE: bad hack for buggy .acc format... */
432 if (FGETS ( buffer, 1024, loader_fd ) != NULL )
433 search ( top_tags, buffer ) ;
434 else
435 break;
436 }
437
438 current_branch = (ssgBranch *) old_cb ;
439 return PARSE_CONT ;
440}
441
442
443static int do_name ( char *s )
444{
445 char *q=NULL;
446 skip_quotes ( &s ) ;
447
448 /* Window flag */
449 if (!strncmp(s, "WI", 2)) {
450 isaWindow = TRUE;
451 } else {
452 isaWindow = FALSE;
453 }
454
455 if (strstr(s,"__TKMN"))
456 usegroup=TRUE;
457
458 if (!strncmp(s, "TKMN",4))
459 {
460 q=strstr(s,"_g");
461 if (q!=NULL)
462 *q='\0';
463/* if (inGroup!=0) */
464/* { */
465/* printf("ingroup =%s\n",s); */
466/* } */
467 }
468
469 if (!strncmp(s, "DR", 2)) {
470 current_branch -> setName ( "DRIVER" );
471 } else {
472 current_branch -> setName ( s ) ;
473 }
474
475 return PARSE_CONT ;
476}
477
478
479static int do_data ( char *s )
480{
481 int len = strtol ( s, NULL, 0 ) ;
482
483 current_data = new char [ len + 1 ] ;
484
485 for ( int i = 0 ; i < len ; i++ )
486 current_data [ i ] = FGETC ( loader_fd ) ;
487
488 current_data [ len ] = '\0' ;
489
490 FGETC ( loader_fd ) ; /* Final RETURN */
491
492 ssgBranch *br = current_options -> createBranch ( current_data ) ;
493
494 if ( br != NULL )
495 {
496 current_branch -> addKid ( br ) ;
497 current_branch = br ;
498 }
499
500 /* delete [] current_data ; */
501 current_data = NULL ;
502
503 return PARSE_CONT ;
504}
505
506
507static int do_texture ( char *s )
508{
509 char *p ;
510
511 if ( s == NULL || s[0] == '\0' )
512 current_tfname = NULL ;
513 else
514 {
515 if ((p=strstr(s," base"))!=NULL)
516 {
517 *p='\0';
518 numMapLevel=1;
520 delete [] current_tbase ;
521 delete [] current_tfname ;
522 delete [] current_ttiled ;
523 current_ttiled = 0;
524 delete [] current_tskids ;
525 current_tskids = 0;
526 delete [] current_tshad ;
527 current_tshad = 0;
528 skip_quotes ( &s ) ;
529 current_tbase = new char [ strlen(s)+1 ] ;
530 current_tfname = new char [ strlen(s)+1 ] ;
531 strcpy ( current_tbase, s ) ;
532 strcpy ( current_tfname, s ) ;
533 }
534 else if ((p=strstr(s," tiled"))!=NULL)
535 {
536 *p='\0';
537 delete [] current_ttiled ;
539 delete [] current_tskids ;
540 current_tskids = 0;
541 delete [] current_tshad ;
542 current_tshad = 0;
543 if (!strstr(s,NOTEXTURE))
544 {
545 numMapLevel++;;
547 skip_quotes ( &s ) ;
548 current_ttiled = new char [ strlen(s)+1 ] ;
549 strcpy ( current_ttiled, s ) ;
550 }
551 }
552 else if ((p=strstr(s," skids"))!=NULL)
553 {
554 *p='\0';
555 delete [] current_tskids ;
556 current_tskids = 0;
557 delete [] current_tshad ;
558 current_tshad = 0;
559 if (!strstr(s,NOTEXTURE))
560 {
561 numMapLevel++;;
563 skip_quotes ( &s ) ;
564 current_tskids = new char [ strlen(s)+1 ] ;
565 strcpy ( current_tskids, s ) ;
566 }
567 }
568 else if ((p=strstr(s," shad"))!=NULL)
569 {
570 *p='\0';
571 delete [] current_tshad ;
572 current_tshad = 0;
573 if (!strstr(s,NOTEXTURE))
574 {
575 numMapLevel++;;
577 skip_quotes ( &s ) ;
578 current_tshad = new char [ strlen(s)+1 ] ;
579 strcpy ( current_tshad, s ) ;
580 }
581 }
582 else
583 {
584 skip_quotes ( &s ) ;
585 numMapLevel=1;
587 delete [] current_tfname ;
588 delete [] current_tbase ;
589 current_tbase = 0;
590 delete [] current_ttiled ;
591 current_ttiled = 0;
592 delete [] current_tskids ;
593 current_tskids = 0;
594 delete [] current_tshad ;
595 current_tshad = 0;
596 current_tfname = new char [ strlen(s)+1 ] ;
597 strcpy ( current_tfname, s ) ;
598 }
599 }
600
601 return PARSE_CONT ;
602}
603
604
605static int do_texrep ( char *s )
606{
607 if ( sscanf ( s, "%f %f", & texrep [ 0 ], & texrep [ 1 ] ) != 2 )
608 ulSetError ( UL_WARNING, "ac_to_gl: Illegal texrep record." ) ;
609
610 return PARSE_CONT ;
611}
612
613
614static int do_texoff ( char *s )
615{
616 if ( sscanf ( s, "%f %f", & texoff [ 0 ], & texoff [ 1 ] ) != 2 )
617 ulSetError ( UL_WARNING, "ac_to_gl: Illegal texoff record." ) ;
618
619 return PARSE_CONT ;
620}
621
622static int do_rot ( char *s )
623{
624 current_matrix [ 0 ][ 3 ] = current_matrix [ 1 ][ 3 ] = current_matrix [ 2 ][ 3 ] =
625 current_matrix [ 3 ][ 0 ] = current_matrix [ 3 ][ 1 ] = current_matrix [ 3 ][ 2 ] = 0.0f ;
626 current_matrix [ 3 ][ 3 ] = 1.0f ;
627
628 if ( sscanf ( s, "%f %f %f %f %f %f %f %f %f",
629 & current_matrix [ 0 ] [ 0 ], & current_matrix [ 0 ] [ 1 ], & current_matrix [ 0 ] [ 2 ],
630 & current_matrix [ 1 ] [ 0 ], & current_matrix [ 1 ] [ 1 ], & current_matrix [ 1 ] [ 2 ],
631 & current_matrix [ 2 ] [ 0 ], & current_matrix [ 2 ] [ 1 ], & current_matrix [ 2 ] [ 2 ] ) != 9 )
632 ulSetError ( UL_WARNING, "ac_to_gl: Illegal rot record." ) ;
633
634 ((ssgTransform *)current_branch) -> setTransform ( current_matrix ) ;
635 return PARSE_CONT ;
636}
637
638static int do_loc ( char *s )
639{
640 if ( sscanf ( s, "%f %f %f", & current_matrix [ 3 ][ 0 ], & current_matrix [ 3 ][ 2 ], & current_matrix [ 3 ][ 1 ] ) != 3 )
641 ulSetError ( UL_WARNING, "ac_to_gl: Illegal loc record." ) ;
642
643 current_matrix [ 3 ][ 1 ] = - current_matrix [ 3 ][ 1 ] ;
644 current_matrix [ 3 ][ 3 ] = 1.0f ;
645 ((ssgTransform *)current_branch) -> setTransform ( current_matrix ) ;
646
647 return PARSE_CONT ;
648}
649
650static int do_url ( char *s )
651{
652 skip_quotes ( & s ) ;
653
654#ifdef PRINT_URLS
655 printf ( "/* URL: \"%s\" */\n", s ) ;
656#endif
657
658 return PARSE_CONT ;
659}
660
661static int do_numvert ( char *s )
662{
663 char buffer [ 1024 ] ;
664
665 nv = strtol ( s, NULL, 0 ) ;
666
667 delete [] vtab ;
668 delete [] ntab ;
669 delete [] t0tab ;
670 delete [] t1tab ;
671 delete [] t2tab ;
672 delete [] t3tab ;
673 totalnv=nv;
674 totalstripe=0;
675
676 vtab = new sgVec3 [ nv ] ;
677 ntab = new sgVec3 [ nv ] ;
678 t0tab = new sgVec2 [ nv ] ;
679 t1tab = new sgVec2 [ nv ] ;
680 t2tab = new sgVec2 [ nv ] ;
681 t3tab = new sgVec2 [ nv ] ;
682
683 if (vertlist != NULL) {
684 ssgDeRefDelete(vertlist);
685 }
686 if (striplist != NULL) {
687 ssgDeRefDelete(striplist);
688 }
689
690 vertlist=new ssgIndexArray ();
691 vertlist->ref();
692 striplist=new ssgIndexArray ();
693 striplist->ref();
694
695 for ( int i = 0 ; i < nv ; i++ )
696 {
697 FGETS ( buffer, 1024, loader_fd ) ;
698
699 if ( sscanf ( buffer, "%f %f %f %f %f %f",
700 &vtab[i][0], &vtab[i][1], &vtab[i][2],&ntab[i][0], &ntab[i][1], &ntab[i][2] ) != 6 )
701 {
702 usenormal=0;
703 if ( sscanf ( buffer, "%f %f %f",
704 &vtab[i][0], &vtab[i][1], &vtab[i][2] ) != 3 )
705 {
706 ulSetError ( UL_FATAL, "ac_to_gl: Illegal vertex record." ) ;
707 }
708 }
709 else
710 {
711 usenormal=1;
712 float tmp = ntab[i][1] ;
713 ntab[i][1] = -ntab[i][2] ;
714 ntab[i][2] = tmp ;
715 }
716
717 float tmp = vtab[i][1] ;
718 vtab[i][1] = -vtab[i][2] ;
719 vtab[i][2] = tmp ;
720
721 if (vtab[i][0] >t_xmax)
722 t_xmax=vtab[i][0];
723 if (vtab[i][0] <t_xmin)
724 t_xmin=vtab[i][0];
725
726 if (vtab[i][1] >t_ymax)
727 t_ymax=vtab[i][1];
728 if (vtab[i][1] <t_ymin)
729 t_ymin=vtab[i][1];
730
731 }
732
733 return PARSE_CONT ;
734}
735
736static int do_numsurf ( char *s )
737{
738 int ns = strtol ( s, NULL, 0 ) ;
739
740 for ( int i = 0 ; i < ns ; i++ )
741 {
742 char buffer [ 1024 ] ;
743
744 FGETS ( buffer, 1024, loader_fd ) ;
745 search ( surf_tag, buffer ) ;
746 }
747
748 return PARSE_CONT ;
749}
750
751static int do_surf ( char *s )
752{
753 current_flags = strtol ( s, NULL, 0 ) ;
754
755 char buffer [ 1024 ] ;
756
757 while ( FGETS ( buffer, 1024, loader_fd ) != NULL )
758 if ( search ( surface_tags, buffer ) == PARSE_POP )
759 break ;
760
761 return PARSE_CONT ;
762}
763
764
765static int do_mat ( char *s )
766{
767 int mat = strtol ( s, NULL, 0 ) ;
768
769 current_material = mlist [ mat ] ;
770 current_colour = clist [ mat ] ;
771
772 return PARSE_CONT ;
773}
774
775
776static int do_refs( char *s )
777{
778 int nrefs = strtol( s, NULL, 0 );
779 char buffer[1024];
780
781 if (nrefs == 0) {
782 return PARSE_POP ;
783 }
784
785 ssgVertexArray *vlist = new ssgVertexArray(nrefs);
786 ssgTexCoordArray *tlist = new ssgTexCoordArray (nrefs);
787 ssgTexCoordArray *tlist1 = NULL;
788 ssgTexCoordArray *tlist2 = NULL;
789 ssgTexCoordArray *tlist3 = NULL;
790 //ssgIndexArray *vindices = new ssgIndexArray(nrefs);
791 ssgNormalArray *nrm = new ssgNormalArray(nrefs);
792
793 if (numMapLevel > 1) {
794 tlist1 = new ssgTexCoordArray(nrefs);
795 }
796 if (numMapLevel > 2) {
797 tlist2 = new ssgTexCoordArray(nrefs);
798 }
799 if (numMapLevel > 3) {
800 tlist3 = new ssgTexCoordArray(nrefs);
801 }
802
803 for (int i = 0; i < nrefs; i++) {
804 FGETS(buffer, 1024, loader_fd);
805
806 int vtx;
807 sgVec2 tc;
808 sgVec2 tc1 = {0};
809 sgVec2 tc2 = {0};
810 sgVec2 tc3 = {0};
811 int tn=0;
812 tn= sscanf ( buffer, "%d %f %f %f %f %f %f %f %f", &vtx,
813 &tc[0],&tc[1],
814 &tc1[0],&tc1[1],
815 &tc2[0],&tc2[1],
816 &tc3[0],&tc3[1]);
817
818 if (tn < 3 )
819 {
820 ulSetError ( UL_FATAL, "ac_to_gl: Illegal ref record not enough text coord." ) ;
821 }
822
823 tc[0] *= texrep[0] ;
824 tc[1] *= texrep[1] ;
825 tc[0] += texoff[0] ;
826 tc[1] += texoff[1] ;
827
828 tlist -> add ( tc ) ;
829 t0tab[vtx][0]=tc[0];
830 t0tab[vtx][1]=tc[1];
831
832 t1tab[vtx][0]=tc1[0];
833 t1tab[vtx][1]=tc1[1];
834
835 t2tab[vtx][0]=tc2[0];
836 t2tab[vtx][1]=tc2[1];
837
838 t3tab[vtx][0]=tc3[0];
839 t3tab[vtx][1]=tc3[1];
840
841 if (numMapLevel > 1) {
842 tlist1->add(tc1);
843 }
844 if (numMapLevel > 2) {
845 tlist2->add(tc2);
846 }
847 if (numMapLevel > 3) {
848 tlist3->add(tc3);
849 }
850
851 vlist->add(vtab[vtx]);
852 if (usenormal == 1) {
853 nrm->add(ntab[vtx]);
854 }
855 //vindices-> add (i);
856 vertlist->add(vtx);
857 }
858 #ifdef GUIONS
859 if (usenormal==1) {
860 printf("use normal\n");
861 }
862 #endif /* GUIONS */
863
864 ssgColourArray *col = new ssgColourArray(1);
865
866 col->add(*current_colour);
867
868 sgVec3 nm;
869
870 if (usenormal == 0) {
871 if (nrefs < 3) {
872 sgSetVec3 (nm, 0.0f, 0.0f, 1.0f);
873 } else {
874 sgMakeNormal (nm, vlist->get(0), vlist->get(1), vlist->get(2));
875 }
876 nrm -> add ( nm ) ;
877 }
878
879
880 int type = ( current_flags & 0x0F ) ;
881 if ( type >= 0 && type <= 4 ) {
882 GLenum gltype = GL_TRIANGLES ;
883 switch ( type )
884 {
885 case 0 : gltype = GL_TRIANGLE_FAN ;
886 break ;
887 case 1 : gltype = GL_LINE_LOOP ;
888 break ;
889 case 2 : gltype = GL_LINE_STRIP ;
890 break ;
891 case 4 : gltype = GL_TRIANGLE_STRIP ;
892 usestrip=TRUE;
893 break ;
894 }
895
896#ifdef NORMAL_TEST
897 /* GUIONS TEST that draw all the normals of a car */
898 if(isacar == TRUE) {
899 ssgVertexArray *vlinelist = new ssgVertexArray(nv*2);
900 for (i = 0; i < nv; i++) {
901 sgVec3 tv;
902 tv[0] = ntab[i][0]*0.2 + vtab[i][0];
903 tv[1] = ntab[i][1]*0.2 + vtab[i][1];
904 tv[2] = ntab[i][2]*0.2 + vtab[i][2];
905 vlinelist->add(vtab[i]);
906 vlinelist->add(tv);
907 }
908 ssgVtxTable *vline = new ssgVtxTable(GL_LINES, vlinelist, NULL, NULL, NULL);
909 current_branch->addKid(current_options->createLeaf(vline, 0));
910 }
911#endif
912
913 /* check the number of texture units */
916 }
917 if (isacar == TRUE) {
919 if (tlist1 && maxTextureUnits > 1) {
921 numMapLevel = 2;
922 }
923 if (tlist2 && maxTextureUnits > 2) {
925 numMapLevel = 3;
926 }
927 }
928#define VTXARRAY_GUIONS
929#ifdef VTXARRAY_GUIONS
930 if (usestrip == FALSE)
931#endif
932 {
933 /* TEST
934 if (isacar==FALSE)
935 {numMapLevel=1;
936 mapLevel=LEVEL0;
937 }
938 */
939 grVtxTable* vtab = new grVtxTable ( gltype,
940 vlist, nrm, tlist,tlist1,tlist2,tlist3,numMapLevel,mapLevel, col, indexCar ) ;
941 /* good */
942 /*ssgVtxArray* vtab = new ssgVtxArray ( gltype,
943 vlist, nrm, tlist, col , vindices) ;*/
944
945 /*striplist-> add (nrefs);
946 grVtxTable* vtab = new grVtxTable ( gltype,
947 vlist,
948 striplist,
949 1,vertlist,
950 nrm, tlist,tlist1,tlist2,tlist3,numMapLevel,mapLevel, col, indexCar ) ;*/
951
952 /*printf("name ob =%s , numMapLevel =%d , maoLevel=%d \n", current_branch -> getName ( ) ,numMapLevel, mapLevel);*/
953
954 vtab -> setState ( get_state ( current_material ) ) ;
955 vtab -> setCullFace ( ! ( (current_flags>>4) & 0x02 ) ) ;
956
957 if (numMapLevel>1)
958 vtab -> setState1 (get_state_ext (current_ttiled ));
959 if (numMapLevel>2)
960 vtab -> setState2 (get_state_ext (current_tskids ));
961 if (numMapLevel>3)
962 vtab -> setState3 (get_state_ext (current_tshad ));
963
964 ssgLeaf* leaf = current_options -> createLeaf ( vtab, 0 ) ;
965
966 if (leaf) {
967 current_branch->addKid(leaf);
968 } else {
969 // TODO: delete leaf or vtab?
970 delete vtab;
971 }
972 }
973#ifdef VTXARRAY_GUIONS
974 else {
975 /* memorize the stripe index */
976 striplist-> add (nrefs);
977 totalstripe++;
978 delete vlist;
979 vlist = 0;
980 delete tlist;
981 tlist = 0;
982 delete tlist1;
983 tlist1 = 0;
984 delete tlist2;
985 tlist2 = 0;
986 delete tlist3;
987 tlist3 = 0;
988 /*delete vindices;
989 vindices = 0;*/
990 delete nrm;
991 nrm = 0;
992 }
993 #endif
994 }
995
996 if (col->getRef() == 0) {
997 delete col;
998 }
999 return PARSE_POP ;
1000}
1001
1002static int do_kids ( char *s )
1003{
1004 last_num_kids = strtol(s, NULL, 0);
1005
1006#ifdef VTXARRAY_GUIONS
1007 if (last_num_kids == 0 && usestrip == TRUE && inGroup != 1) {
1008 ssgVertexArray *vlist = new ssgVertexArray(totalnv);
1009 ssgNormalArray *nrm = new ssgNormalArray(totalnv);
1010 ssgTexCoordArray *tlist0 = new ssgTexCoordArray(totalnv);
1011 ssgTexCoordArray *tlist1 = NULL;
1012 ssgTexCoordArray *tlist2 = NULL;
1013 ssgTexCoordArray *tlist3 = NULL;
1014 /* if (numMapLevel>1) */
1015 tlist1 = new ssgTexCoordArray(totalnv);
1016 /* if (numMapLevel>2) */
1017 tlist2 = new ssgTexCoordArray(totalnv);
1018 /* if (numMapLevel>3) */
1019 tlist3 = new ssgTexCoordArray(totalnv);
1020 for (int i = 0; i < totalnv; i++) {
1021 tlist0 -> add ( t0tab[i] ) ;
1022 /* if (numMapLevel>1) */
1023 tlist1 -> add ( t1tab[i] ) ;
1024 /* if (numMapLevel>2) */
1025 tlist2 -> add ( t2tab[i] ) ;
1026 /* if (numMapLevel>3) */
1027 tlist3 -> add ( t3tab[i] ) ;
1028 vlist -> add ( vtab[i] ) ;
1029 if (usenormal==1) {
1030 nrm -> add ( ntab[i] ) ;
1031 }
1032 }
1033
1034 ssgColourArray *col = new ssgColourArray ( 1 ) ;
1035 col -> add ( *current_colour ) ;
1036
1037 /* int type = ( current_flags & 0x0F ) ; */
1038 GLenum gltype = GL_TRIANGLE_STRIP ;
1039
1040 /* check the number of texture units */
1043 if (isacar==TRUE) {
1045 if (tlist1 && maxTextureUnits>2) {
1047 numMapLevel=2;
1048 }
1049 if (tlist2 && maxTextureUnits>2){
1051 numMapLevel=3;
1052 }
1053 }
1054 /*ssgVtxArray* vtab = new ssgVtxArray ( gltype,
1055 vlist, nrm, tlist0, col , vertlist) ;*/
1056
1057 grVtxTable* vtab = new grVtxTable ( gltype,
1058 vlist,
1059 striplist,
1061 vertlist,
1062 nrm,
1063 tlist0,tlist1,tlist2,tlist3,
1065 col,
1066 indexCar ) ;
1067 vtab -> setState ( get_state ( current_material ) ) ;
1068 vtab -> setCullFace ( ! ( (current_flags>>4) & 0x02 ) ) ;
1069 if (numMapLevel>1)
1070 vtab -> setState1 (get_state_ext (current_ttiled ));
1071 if (numMapLevel>2)
1072 vtab -> setState2 (get_state_ext (current_tskids ));
1073 if (numMapLevel>3)
1074 vtab -> setState3 (get_state_ext (current_tshad ));
1075 ssgLeaf* leaf = current_options -> createLeaf ( vtab, 0 ) ;
1076
1077 if (leaf) {
1078 current_branch -> addKid ( leaf ) ;
1079 } else {
1080 delete vtab;
1081 }
1082 }
1083#endif
1084
1085 numMapLevel=1;
1087 return PARSE_POP ;
1088}
1089
1090
1091void myssgFlatten(ssgEntity *obj)
1092{
1093
1094 if ( obj -> isAKindOf ( ssgTypeBranch() ) )
1095 {
1096 ssgBranch *br = (ssgBranch *) obj ;
1097#ifdef WIN32
1098 if (!strnicmp(br->getKid(0)->getName(), "tkmn",4))
1099#else
1100 if (!strncasecmp(br->getKid(0)->getName(), "tkmn",4))
1101#endif
1102 {
1103 ssgFlatten(br->getKid(0));
1104 }
1105 else
1106 {
1107 for ( int i = 0 ; i < br -> getNumKids () ; i++ )
1108 ssgFlatten( br -> getKid ( i ) );
1109 }
1110 }
1111 return ;
1112
1113}
1114
1115ssgEntity *grssgCarLoadAC3D ( const char *fname, const ssgLoaderOptions* options,int index )
1116{
1117
1118 isacar=TRUE;
1119 usestrip=FALSE;
1120 indexCar=index;
1121 t_xmax=-999999.0;
1122 t_ymax=-999999.0;
1123 t_xmin=+999999.0;
1124 t_ymin=+999999.0;
1125
1126 GfOut("CarLoadAC3D loading %s\n", fname);
1127
1128 ssgEntity *obj = myssgLoadAC ( fname, options ) ;
1129
1130 if ( obj == NULL )
1131 return NULL ;
1132
1133 /* Do some simple optimisations */
1134
1135 ssgBranch *model = new ssgBranch () ;
1136 model -> addKid ( obj ) ;
1137 if(usestrip==FALSE)
1138 {
1139 /*myssgFlatten(obj);*/
1140 ssgFlatten ( obj ) ;
1141 ssgStripify ( model ) ;
1142 }
1145 return model ;
1146
1147}
1148
1149ssgEntity *grssgLoadAC3D ( const char *fname, const ssgLoaderOptions* options )
1150{
1151 isacar=FALSE;
1152 usegroup=FALSE;
1153 usestrip=FALSE;
1154
1155 t_xmax=-999999.0;
1156 t_ymax=-999999.0;
1157 t_xmin=+999999.0;
1158 t_ymin=+999999.0;
1159
1160 GfOut("LoadAC3D loading %s\n", fname);
1161
1162 ssgEntity *obj = myssgLoadAC ( fname, options ) ;
1163
1164 if ( obj == NULL )
1165 return NULL ;
1166
1167
1168 /* Do some simple optimisations */
1169
1170 ssgBranch *model = new ssgBranch () ;
1171 model -> addKid ( obj ) ;
1172 if ((usegroup==FALSE) && (usestrip==FALSE))
1173 {
1174 ssgFlatten ( obj ) ;
1175 ssgStripify ( model ) ;
1176 }
1181
1182 return model ;
1183}
1184
1185/*
1186 Original function for backwards compatibility...
1187*/
1188static ssgEntity *myssgLoadAC ( const char *fname, const ssgLoaderOptions* options )
1189{
1190
1191 if (maxTextureUnits==0)
1192 {
1193 InitMultiTex();
1194 }
1195
1196 ssgSetCurrentOptions ( (ssgLoaderOptions*)options ) ;
1197 current_options = ssgGetCurrentOptions () ;
1198
1199 char filename [ 1024 ] ;
1200 current_options -> makeModelPath ( filename, fname ) ;
1201
1202 num_materials = 0 ;
1203 vtab = NULL ;
1204
1205 current_material = NULL ;
1206 current_colour = NULL ;
1207 current_tfname = NULL ;
1208 current_branch = NULL ;
1209
1210 sgSetVec2 ( texrep, 1.0, 1.0 ) ;
1211 sgSetVec2 ( texoff, 0.0, 0.0 ) ;
1212
1213 loader_fd = FOPEN ( filename, "rb" ) ;
1214
1215 if ( loader_fd == NULL )
1216 {
1217 ulSetError ( UL_WARNING, "ssgLoadAC: Failed to open '%900s' for reading", filename ) ;
1218 return NULL ;
1219 }
1220
1221 char buffer [ 1024 ] ;
1222 int firsttime = TRUE ;
1223
1224 current_branch = new ssgTransform () ;
1225
1226 while ( FGETS ( buffer, 1024, loader_fd ) != NULL )
1227 {
1228 char *s = buffer ;
1229
1230
1231 /* Skip leading whitespace */
1232
1233 skip_spaces ( & s ) ;
1234
1235 /* Skip blank lines and comments */
1236
1237 if ( *s < ' ' && *s != '\t' ) continue ;
1238 if ( *s == '#' || *s == ';' ) continue ;
1239
1240 if ( firsttime )
1241 {
1242 firsttime = FALSE ;
1243
1244 if ( ! ulStrNEqual ( s, "AC3D", 4 ) )
1245 {
1246 FCLOSE ( loader_fd ) ;
1247 ulSetError ( UL_WARNING, "ssgLoadAC: '%900s' is not in AC3D format.", filename ) ;
1248 return NULL ;
1249 }
1250 }
1251 else
1252 search ( top_tags, s ) ;
1253 }
1254
1255 delete [] current_tfname;
1256 current_tfname = NULL ;
1257 delete [] vtab ;
1258 vtab = 0;
1259
1260 int i;
1261 for (i = 0; i < num_materials; i++) {
1262 delete mlist[i];
1263 delete [] clist[i];
1264 }
1265
1266 FCLOSE ( loader_fd ) ;
1267
1268 return current_branch ;
1269
1270}
1271
static Point q[4]
Definition Convex.cpp:55
static Point p[4]
Definition Convex.cpp:54
virtual void setTexture(ssgTexture *tex)
Definition grtexture.h:55
double carTrackRatioX
Definition grloadac.cpp:49
double carTrackRatioY
Definition grloadac.cpp:50
static ssgBranch * current_branch
Definition grloadac.cpp:90
double shad_xmin
Definition grloadac.cpp:47
#define OBJ_LIGHT
Definition grloadac.cpp:236
static double t_xmin
Definition grloadac.cpp:42
static int do_texrep(char *s)
Definition grloadac.cpp:605
static gzFile loader_fd
Definition grloadac.cpp:53
static sgVec2 * t1tab
Definition grloadac.cpp:69
double shad_xmax
Definition grloadac.cpp:45
static sgVec2 * t3tab
Definition grloadac.cpp:71
static int do_name(char *s)
Definition grloadac.cpp:443
static char * current_ttiled
Definition grloadac.cpp:93
#define NOTEXTURE
Definition grloadac.cpp:97
ssgEntity * grssgLoadAC3D(const char *fname, const ssgLoaderOptions *options)
static int totalnv
Definition grloadac.cpp:74
void myssgFlatten(ssgEntity *obj)
static Tag obj_type_tags[]
Definition grloadac.cpp:224
#define OBJ_POLY
Definition grloadac.cpp:234
static int do_obj_poly(char *s)
Definition grloadac.cpp:239
static sgVec2 texoff
Definition grloadac.cpp:104
static int mapLevel
Definition grloadac.cpp:81
#define OBJ_WORLD
Definition grloadac.cpp:233
static sgVec4 * current_colour
Definition grloadac.cpp:89
static int last_num_kids
Definition grloadac.cpp:245
static sgVec2 texrep
Definition grloadac.cpp:103
static void skip_spaces(char **s)
Definition grloadac.cpp:138
static ssgState * get_state_ext(char *name)
Definition grloadac.cpp:311
#define PARSE_POP
Definition grloadac.cpp:129
static Tag surface_tags[]
Definition grloadac.cpp:217
static char * current_data
Definition grloadac.cpp:96
static int current_flags
Definition grloadac.cpp:246
static char * current_tshad
Definition grloadac.cpp:95
static Tag surf_tag[]
Definition grloadac.cpp:211
static ssgLoaderOptions * current_options
Definition grloadac.cpp:87
static int do_object(char *s)
Definition grloadac.cpp:387
static double t_ymax
Definition grloadac.cpp:41
static int do_obj_light(char *s)
Definition grloadac.cpp:241
static char * current_tfname
Definition grloadac.cpp:91
static char * current_tskids
Definition grloadac.cpp:94
static Tag object_tags[]
Definition grloadac.cpp:195
#define MAX_MATERIALS
Definition grloadac.cpp:98
static int isaWindow
Definition grloadac.cpp:85
int inGroup
Definition grloadac.cpp:32
#define FCLOSE(fd)
Definition grloadac.cpp:38
static int usegroup
Definition grloadac.cpp:80
double shad_ymax
Definition grloadac.cpp:46
static double t_xmax
Definition grloadac.cpp:40
static int do_data(char *s)
Definition grloadac.cpp:479
static int do_mat(char *s)
Definition grloadac.cpp:765
static double t_ymin
Definition grloadac.cpp:43
static sgVec3 * ntab
Definition grloadac.cpp:67
static int do_surf(char *s)
Definition grloadac.cpp:751
static sgVec3 * vtab
Definition grloadac.cpp:66
#define FGETC(file)
Definition grloadac.cpp:36
static int do_numvert(char *s)
Definition grloadac.cpp:661
static int do_material(char *s)
Definition grloadac.cpp:336
static sgVec2 * t0tab
Definition grloadac.cpp:68
static int do_texoff(char *s)
Definition grloadac.cpp:614
static int isacar
Definition grloadac.cpp:78
ssgEntity * grssgCarLoadAC3D(const char *fname, const ssgLoaderOptions *options, int index)
static int nv
Definition grloadac.cpp:77
static int do_kids(char *s)
static int usestrip
Definition grloadac.cpp:79
static int do_numsurf(char *s)
Definition grloadac.cpp:736
static Tag top_tags[]
Definition grloadac.cpp:188
static void skip_quotes(char **s)
Definition grloadac.cpp:145
static _ssgMaterial * current_material
Definition grloadac.cpp:88
static int indexCar
Definition grloadac.cpp:83
#define PARSE_CONT
Definition grloadac.cpp:128
static int do_refs(char *s)
Definition grloadac.cpp:776
static char * current_tbase
Definition grloadac.cpp:92
static ssgEntity * myssgLoadAC(const char *fname, const ssgLoaderOptions *options)
double shad_ymin
Definition grloadac.cpp:48
static int do_obj_world(char *s)
Definition grloadac.cpp:238
static int numMapLevel
Definition grloadac.cpp:82
static ssgIndexArray * vertlist
Definition grloadac.cpp:72
static _ssgMaterial * mlist[MAX_MATERIALS]
Definition grloadac.cpp:99
static int search(Tag *tags, char *s)
Definition grloadac.cpp:169
static sgVec4 * clist[MAX_MATERIALS]
Definition grloadac.cpp:100
static int num_materials
Definition grloadac.cpp:65
static sgMat4 current_matrix
Definition grloadac.cpp:102
static int usenormal
Definition grloadac.cpp:76
static int do_obj_group(char *s)
Definition grloadac.cpp:240
static ssgIndexArray * striplist
Definition grloadac.cpp:73
static int do_rot(char *s)
Definition grloadac.cpp:622
static int totalstripe
Definition grloadac.cpp:75
#define FGETS(buf, len, file)
Definition grloadac.cpp:35
static ssgState * get_state(_ssgMaterial *mat)
Definition grloadac.cpp:248
static int do_texture(char *s)
Definition grloadac.cpp:507
#define OBJ_GROUP
Definition grloadac.cpp:235
static int do_url(char *s)
Definition grloadac.cpp:650
static sgVec2 * t2tab
Definition grloadac.cpp:70
#define FOPEN(path, mode)
Definition grloadac.cpp:37
static int do_loc(char *s)
Definition grloadac.cpp:638
int maxTextureUnits
Definition grmain.cpp:47
bool InitMultiTex(void)
Definition grmain.cpp:83
int preScene(ssgEntity *e)
Definition grscene.cpp:88
static ssgLoaderOptionsEx options
Definition grscene.cpp:167
This file contains the divergences from PLIB.
grManagedState * grStateFactory(void)
Definition grtexture.h:76
#define LEVEL3
Definition grvtxtable.h:55
#define LEVELC3
Definition grvtxtable.h:51
#define LEVEL1
Definition grvtxtable.h:53
#define LEVELC
Definition grvtxtable.h:49
#define LEVEL0
Definition grvtxtable.h:52
#define LEVEL2
Definition grvtxtable.h:54
#define LEVELC2
Definition grvtxtable.h:50
sgVec4 spec
Definition grloadac.cpp:58
sgVec4 emis
Definition grloadac.cpp:59
const char * token
Definition grloadac.cpp:133
int(* func)(char *s)
Definition grloadac.cpp:134
#define GfOut
Definition tgf.h:372