TORCS  1.3.9
The Open Racing Car Simulator
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"
32 int 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 
40 static double t_xmax;
41 static double t_ymax;
42 static double t_xmin;
43 static double t_ymin;
44 
45 double shad_xmax;
46 double shad_ymax;
47 double shad_xmin;
48 double shad_ymin;
49 double carTrackRatioX=0;
50 double carTrackRatioY=0;
51 
52 
53 static gzFile loader_fd ;
54 
55 
57 {
58  sgVec4 spec ;
59  sgVec4 emis ;
60  sgVec4 amb ;
61  sgVec4 rgb ;
62  float shi ;
63 } ;
64 
65 static int num_materials = 0 ;
66 static sgVec3 *vtab = NULL ;
67 static sgVec3 *ntab = NULL ;
68 static sgVec2 *t0tab = NULL;
69 static sgVec2 *t1tab = NULL;
70 static sgVec2 *t2tab = NULL;
71 static sgVec2 *t3tab = NULL;
72 static ssgIndexArray *vertlist=NULL;
73 static ssgIndexArray *striplist=NULL;
74 static int totalnv=0;
75 static int totalstripe=0;
76 static int usenormal = 0;
77 static int nv;
78 static int isacar = TRUE;
79 static int usestrip=TRUE;
80 static int usegroup=TRUE;
81 static int mapLevel;
82 static int numMapLevel;
83 static int indexCar;
84 
85 static int isaWindow;
86 
87 static ssgLoaderOptions *current_options = NULL ;
89 static sgVec4 *current_colour = NULL ;
90 static ssgBranch *current_branch = NULL ;
91 static char *current_tfname = NULL ;
92 static char *current_tbase = NULL ;
93 static char *current_ttiled = NULL ;
94 static char *current_tskids = NULL ;
95 static char *current_tshad = NULL ;
96 static char *current_data = NULL ;
97 #define NOTEXTURE "empty_texture_no_mapping"
98 #define MAX_MATERIALS 1000 /* This *ought* to be enough! */
100 static sgVec4 *clist [ MAX_MATERIALS ] ;
101 
102 static sgMat4 current_matrix ;
103 static sgVec2 texrep ;
104 static sgVec2 texoff ;
105 
106 static int do_material ( char *s ) ;
107 static int do_object ( char *s ) ;
108 static int do_name ( char *s ) ;
109 static int do_data ( char *s ) ;
110 static int do_texture ( char *s ) ;
111 static int do_texrep ( char *s ) ;
112 static int do_texoff ( char *s ) ;
113 static int do_rot ( char *s ) ;
114 static int do_loc ( char *s ) ;
115 static int do_url ( char *s ) ;
116 static int do_numvert ( char *s ) ;
117 static int do_numsurf ( char *s ) ;
118 static int do_surf ( char *s ) ;
119 static int do_mat ( char *s ) ;
120 static int do_refs ( char *s ) ;
121 static int do_kids ( char *s ) ;
122 
123 static int do_obj_world ( char *s ) ;
124 static int do_obj_poly ( char *s ) ;
125 static int do_obj_group ( char *s ) ;
126 static int do_obj_light ( char *s ) ;
127 /*static void myssgStripify ( ssgEntity *ent );*/
128 #define PARSE_CONT 0
129 #define PARSE_POP 1
130 
131 struct Tag
132 {
133  const char *token ;
134  int (*func) ( char *s ) ;
135 } ;
136 
137 
138 static void skip_spaces ( char **s )
139 {
140  while ( **s == ' ' || **s == '\t' )
141  (*s)++ ;
142 }
143 
144 
145 static 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 
169 static 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 
188 static Tag top_tags [] =
189 {
190  { "MATERIAL", do_material },
191  { "OBJECT" , do_object },
192 } ;
193 
194 
195 static 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 
211 static Tag surf_tag [] =
212 {
213  { "SURF" , do_surf },
214  { NULL, NULL }
215 } ;
216 
217 static Tag surface_tags [] =
218 {
219  { "mat" , do_mat },
220  { "refs" , do_refs },
221  { NULL, NULL }
222 } ;
223 
224 static 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 
238 static int do_obj_world ( char * ) { return OBJ_WORLD ; }
239 static int do_obj_poly ( char * ) { return OBJ_POLY ; }
240 static int do_obj_group ( char * ) { return OBJ_GROUP ; }
241 static int do_obj_light ( char * ) { return OBJ_LIGHT ; }
242 static ssgEntity *myssgLoadAC ( const char *fname, const ssgLoaderOptions* options );
243 
244 
245 static int last_num_kids = -1 ;
246 static int current_flags = -1 ;
247 
248 static 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 
311 static ssgState *get_state_ext ( char * name)
312 {
313  if (name==NULL) {
314  return NULL;
315  }
316  grMultiTexState *st = new grMultiTexState();
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 
336 static 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 
369  mlist [ num_materials ] = new _ssgMaterial ;
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 
387 static 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 
443 static 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 
479 static 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 
507 static 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 ;
538  current_ttiled=0;
539  delete [] current_tskids ;
540  current_tskids = 0;
541  delete [] current_tshad ;
542  current_tshad = 0;
543  if (!strstr(s,NOTEXTURE))
544  {
545  numMapLevel++;;
546  mapLevel|=LEVEL1;
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++;;
562  mapLevel|=LEVEL2;
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++;;
576  mapLevel|=LEVEL3;
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 
605 static 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 
614 static 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 
622 static 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 
638 static 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 
650 static 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 
661 static 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 
736 static 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 
751 static 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 
765 static 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 
776 static 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) {
920  mapLevel = LEVELC2;
921  numMapLevel = 2;
922  }
923  if (tlist2 && maxTextureUnits > 2) {
924  mapLevel = LEVELC3;
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 
1002 static 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) {
1044  mapLevel=LEVELC;
1045  if (tlist1 && maxTextureUnits>2) {
1046  mapLevel=LEVELC2;
1047  numMapLevel=2;
1048  }
1049  if (tlist2 && maxTextureUnits>2){
1050  mapLevel=LEVELC3;
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,
1060  totalstripe,
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;
1086  mapLevel=LEVEL0;
1087  return PARSE_POP ;
1088 }
1089 
1090 
1091 void 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 
1115 ssgEntity *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 
1149 ssgEntity *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  }
1177  shad_xmax=t_xmax;
1178  shad_ymax=t_ymax;
1179  shad_xmin=t_xmin;
1180  shad_ymin=t_ymin;
1181 
1182  return model ;
1183 }
1184 
1185 /*
1186  Original function for backwards compatibility...
1187 */
1188 static 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 ssgState * get_state_ext(char *name)
Definition: grloadac.cpp:311
static _ssgMaterial * current_material
Definition: grloadac.cpp:88
static sgVec2 texoff
Definition: grloadac.cpp:104
static int isaWindow
Definition: grloadac.cpp:85
static Point q[4]
Definition: Convex.cpp:55
static int do_surf(char *s)
Definition: grloadac.cpp:751
int inGroup
Definition: grloadac.cpp:32
static Tag top_tags[]
Definition: grloadac.cpp:188
static ssgLoaderOptionsEx options
Definition: grscene.cpp:165
static void skip_quotes(char **s)
Definition: grloadac.cpp:145
static int usestrip
Definition: grloadac.cpp:79
static _ssgMaterial * mlist[MAX_MATERIALS]
Definition: grloadac.cpp:99
#define OBJ_POLY
Definition: grloadac.cpp:234
static int do_data(char *s)
Definition: grloadac.cpp:479
double carTrackRatioX
Definition: grloadac.cpp:49
static int do_obj_poly(char *s)
Definition: grloadac.cpp:239
static sgVec2 * t0tab
Definition: grloadac.cpp:68
#define FGETS(buf, len, file)
Definition: grloadac.cpp:35
static char * current_tshad
Definition: grloadac.cpp:95
static int isacar
Definition: grloadac.cpp:78
static sgVec2 texrep
Definition: grloadac.cpp:103
#define OBJ_GROUP
Definition: grloadac.cpp:235
#define OBJ_WORLD
Definition: grloadac.cpp:233
double shad_ymin
Definition: grloadac.cpp:48
static sgVec2 * t2tab
Definition: grloadac.cpp:70
static int do_rot(char *s)
Definition: grloadac.cpp:622
static int numMapLevel
Definition: grloadac.cpp:82
static double t_ymin
Definition: grloadac.cpp:43
static char * current_data
Definition: grloadac.cpp:96
static int do_name(char *s)
Definition: grloadac.cpp:443
static int do_texoff(char *s)
Definition: grloadac.cpp:614
static sgVec4 * current_colour
Definition: grloadac.cpp:89
static char * current_tfname
Definition: grloadac.cpp:91
static ssgLoaderOptions * current_options
Definition: grloadac.cpp:87
static char * current_tbase
Definition: grloadac.cpp:92
#define FOPEN(path, mode)
Definition: grloadac.cpp:37
static Tag surf_tag[]
Definition: grloadac.cpp:211
static char * current_tskids
Definition: grloadac.cpp:94
bool InitMultiTex(void)
Definition: grmain.cpp:84
static ssgBranch * current_branch
Definition: grloadac.cpp:90
static double t_xmin
Definition: grloadac.cpp:42
#define LEVELC2
Definition: grvtxtable.h:51
static int current_flags
Definition: grloadac.cpp:246
static sgVec2 * t3tab
Definition: grloadac.cpp:71
#define NOTEXTURE
Definition: grloadac.cpp:97
static ssgState * get_state(_ssgMaterial *mat)
Definition: grloadac.cpp:248
static double t_xmax
Definition: grloadac.cpp:40
static int do_object(char *s)
Definition: grloadac.cpp:387
#define LEVEL3
Definition: grvtxtable.h:58
int(* func)(char *s)
Definition: grloadac.cpp:134
static ssgIndexArray * striplist
Definition: grloadac.cpp:73
grManagedState * grStateFactory(void)
Definition: grtexture.h:73
static Tag object_tags[]
Definition: grloadac.cpp:195
#define GfOut
Definition: tgf.h:373
static int do_url(char *s)
Definition: grloadac.cpp:650
static sgVec3 * ntab
Definition: grloadac.cpp:67
ssgEntity * grssgCarLoadAC3D(const char *fname, const ssgLoaderOptions *options, int index)
Definition: grloadac.cpp:1115
static Point p[4]
Definition: Convex.cpp:54
#define PARSE_POP
Definition: grloadac.cpp:129
#define LEVELC
Definition: grvtxtable.h:49
#define FCLOSE(fd)
Definition: grloadac.cpp:38
static int do_refs(char *s)
Definition: grloadac.cpp:776
#define LEVEL1
Definition: grvtxtable.h:56
static int usegroup
Definition: grloadac.cpp:80
static int do_obj_group(char *s)
Definition: grloadac.cpp:240
static int indexCar
Definition: grloadac.cpp:83
sgVec4 amb
Definition: grloadac.cpp:60
static ssgIndexArray * vertlist
Definition: grloadac.cpp:72
static int do_texture(char *s)
Definition: grloadac.cpp:507
const char * token
Definition: grloadac.cpp:133
static int do_numvert(char *s)
Definition: grloadac.cpp:661
#define FGETC(file)
Definition: grloadac.cpp:36
static gzFile loader_fd
Definition: grloadac.cpp:53
sgVec4 emis
Definition: grloadac.cpp:59
sgVec4 rgb
Definition: grloadac.cpp:61
static int do_loc(char *s)
Definition: grloadac.cpp:638
static int num_materials
Definition: grloadac.cpp:65
#define PARSE_CONT
Definition: grloadac.cpp:128
static char * current_ttiled
Definition: grloadac.cpp:93
double shad_xmax
Definition: grloadac.cpp:45
static int do_obj_world(char *s)
Definition: grloadac.cpp:238
static int mapLevel
Definition: grloadac.cpp:81
sgVec4 spec
Definition: grloadac.cpp:58
#define LEVELC3
Definition: grvtxtable.h:53
static int do_mat(char *s)
Definition: grloadac.cpp:765
virtual void setTexture(ssgTexture *tex)
Definition: grtexture.h:55
static sgMat4 current_matrix
Definition: grloadac.cpp:102
static sgVec2 * t1tab
Definition: grloadac.cpp:69
static int do_kids(char *s)
Definition: grloadac.cpp:1002
static sgVec4 * clist[MAX_MATERIALS]
Definition: grloadac.cpp:100
int maxTextureUnits
Definition: grmain.cpp:48
int preScene(ssgEntity *e)
Definition: grscene.cpp:86
static int do_obj_light(char *s)
Definition: grloadac.cpp:241
static ssgEntity * myssgLoadAC(const char *fname, const ssgLoaderOptions *options)
Definition: grloadac.cpp:1188
#define LEVEL2
Definition: grvtxtable.h:57
static Tag obj_type_tags[]
Definition: grloadac.cpp:224
static int totalnv
Definition: grloadac.cpp:74
void myssgFlatten(ssgEntity *obj)
Definition: grloadac.cpp:1091
static int do_texrep(char *s)
Definition: grloadac.cpp:605
static double t_ymax
Definition: grloadac.cpp:41
double carTrackRatioY
Definition: grloadac.cpp:50
static int nv
Definition: grloadac.cpp:77
ssgEntity * grssgLoadAC3D(const char *fname, const ssgLoaderOptions *options)
Definition: grloadac.cpp:1149
This file contains the divergences from PLIB.
static sgVec3 * vtab
Definition: grloadac.cpp:66
static int do_numsurf(char *s)
Definition: grloadac.cpp:736
#define MAX_MATERIALS
Definition: grloadac.cpp:98
static void skip_spaces(char **s)
Definition: grloadac.cpp:138
#define LEVEL0
Definition: grvtxtable.h:55
static int search(Tag *tags, char *s)
Definition: grloadac.cpp:169
static Tag surface_tags[]
Definition: grloadac.cpp:217
static int last_num_kids
Definition: grloadac.cpp:245
double shad_ymax
Definition: grloadac.cpp:46
double shad_xmin
Definition: grloadac.cpp:47
static int totalstripe
Definition: grloadac.cpp:75
static int usenormal
Definition: grloadac.cpp:76
static int do_material(char *s)
Definition: grloadac.cpp:336
#define OBJ_LIGHT
Definition: grloadac.cpp:236