1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998,2002  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 Software
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: ssg.h 2126 2007-10-02 00:49:30Z fayjf $
22 */
23 
24 
25 #ifndef _INCLUDED_SSG_H_
26 #define _INCLUDED_SSG_H_
27 
28 #include <stdio.h>
29 #include "sg.h"
30 
31 #ifdef UL_MAC_OSX
32 #  include <OpenGL/gl.h>
33 #else
34 #  include <GL/gl.h>
35 #endif
36 
37 #include "ssgconf.h"
38 
39 #ifndef _SSG_PUBLIC
40 #define _SSG_PUBLIC  protected
41 #endif
42 
43 extern int sgebug ;
44 
45 enum ssgCullResult
46 {
47   SSG_OUTSIDE  = SG_OUTSIDE,
48   SSG_INSIDE   = SG_INSIDE,
49   SSG_STRADDLE = SG_STRADDLE
50 } ;
51 
52 #define SSG_MAXPATH   50
53 
54 #define SSGTRAV_CULL   1
55 #define SSGTRAV_ISECT  2
56 #define SSGTRAV_HOT    4
57 #define SSGTRAV_LOS    8
58 
59 class ssgList            ;
60 class ssgKidList         ;
61 class ssgBase            ;
62 class ssgEntity          ;
63 class ssgLeaf            ;
64 class ssgVTable          ;
65 class ssgVtxTable        ;
66 class ssgVtxArray        ;
67 class ssgTween           ;
68 class ssgBranch          ;
69 class ssgInvisible       ;
70 class ssgBaseTransform   ;
71 class ssgTransform       ;
72 class ssgTexTrans        ;
73 class ssgCutout          ;
74 class ssgSelector        ;
75 class ssgRangeSelector   ;
76 class ssgTimedSelector   ;
77 class ssgTweenController ;
78 class ssgRoot            ;
79 
80 void  ssgDeRefDelete ( ssgBase *br ) ;
81 
82 /*
83   Think twice before assigning new type bits, it is rather complicated.
84   Perhaps some kind of automatic assignment would be good?
85  */
86 
87 #define _SSG_BACKWARDS_REFERENCE 0x0000000  /* For SSG format files */
88 
89 #define _SSG_TYPE_BASE             0x00000001
90 
91 /* ssgEntities */
92 #define _SSG_TYPE_ENTITY           0x00000002
93 #define _SSG_TYPE_LEAF             0x00000020
94 #define _SSG_TYPE_VTABLE           0x00000080
95 #define _SSG_TYPE_VTXTABLE         0x00000100
96 #define _SSG_TYPE_VTXARRAY         0x00000200
97 #define _SSG_TYPE_BRANCH           0x00000040
98 #define _SSG_TYPE_BASETRANSFORM    0x00000080
99 #define _SSG_TYPE_TRANSFORM        0x00001000
100 #define _SSG_TYPE_TEXTRANS         0x00002000
101 #define _SSG_TYPE_AXISTRANSFORM    0x00004000
102 #define _SSG_TYPE_ANIMTRANSFORM    0x00008000
103 #define _SSG_TYPE_SELECTOR         0x00000100
104 #define _SSG_TYPE_RANGESELECTOR    0x00001000
105 #define _SSG_TYPE_TIMEDSELECTOR    0x00002000
106 #define _SSG_TYPE_TWEEN            0x00008000
107 #define _SSG_TYPE_TWEENCONTROLLER  0x00010000
108 #define _SSG_TYPE_ROOT             0x00000200
109 #define _SSG_TYPE_CUTOUT           0x00000400
110 #define _SSG_TYPE_INVISIBLE        0x00000800
111 
112 /* ssgStates */
113 #define _SSG_TYPE_STATE            0x00000004
114 #define _SSG_TYPE_SIMPLESTATE      0x00000020
115 #define _SSG_TYPE_STATESELECTOR    0x00000040
116 
117 /* ssgSimpleLists */
118 #define _SSG_TYPE_SIMPLELIST       0x00000008
119 #define _SSG_TYPE_VERTEXARRAY      0x00000020
120 #define _SSG_TYPE_NORMALARRAY      0x00000040
121 #define _SSG_TYPE_TEXCOORDARRAY    0x00000080
122 #define _SSG_TYPE_COLOURARRAY      0x00000100
123 #define _SSG_TYPE_INDEXARRAY       0x00000200
124 #define _SSG_TYPE_TRANSFORMARRAY   0x00000400
125 #define _SSG_TYPE_INTERLEAVEDARRAY 0x00000800
126 
127 /* ssgTextures */
128 #define _SSG_TYPE_TEXTURE          0x00000010
129 
130 #define SSG_FILE_VERSION       0x01
131 #define SSG_FILE_MAGIC_NUMBER  (('S'<<24)+('S'<<16)+('G'<<8)+SSG_FILE_VERSION)
132 
133 
ssgTypeBase()134 inline int ssgTypeBase         () { return _SSG_TYPE_BASE ; }
135 
ssgTypeEntity()136 inline int ssgTypeEntity       () { return _SSG_TYPE_ENTITY    | ssgTypeBase    () ; }
ssgTypeLeaf()137 inline int ssgTypeLeaf         () { return _SSG_TYPE_LEAF      | ssgTypeEntity  () ; }
ssgTypeVTable()138 inline int ssgTypeVTable       () { return _SSG_TYPE_VTABLE    | ssgTypeLeaf    () ; }
ssgTypeVtxTable()139 inline int ssgTypeVtxTable     () { return _SSG_TYPE_VTXTABLE  | ssgTypeLeaf    () ; }
ssgTypeVtxArray()140 inline int ssgTypeVtxArray     () { return _SSG_TYPE_VTXARRAY  | ssgTypeVtxTable() ; }
ssgTypeTween()141 inline int ssgTypeTween        () { return _SSG_TYPE_TWEEN     | ssgTypeVtxTable() ; }
ssgTypeBranch()142 inline int ssgTypeBranch       () { return _SSG_TYPE_BRANCH    | ssgTypeEntity  () ; }
ssgTypeTweenController()143 inline int ssgTypeTweenController(){ return _SSG_TYPE_TWEENCONTROLLER | ssgTypeBranch() ; }
ssgTypeBaseTransform()144 inline int ssgTypeBaseTransform() { return _SSG_TYPE_BASETRANSFORM | ssgTypeBranch () ; }
ssgTypeTransform()145 inline int ssgTypeTransform    () { return _SSG_TYPE_TRANSFORM | ssgTypeBaseTransform () ; }
ssgTypeAnimTransform()146 inline int ssgTypeAnimTransform() { return _SSG_TYPE_ANIMTRANSFORM  | ssgTypeTransform () ; }
ssgTypeTexTrans()147 inline int ssgTypeTexTrans     () { return _SSG_TYPE_TEXTRANS  | ssgTypeBaseTransform () ; }
ssgTypeAxisTransform()148 inline int ssgTypeAxisTransform() { return _SSG_TYPE_AXISTRANSFORM  | ssgTypeTransform () ; }
ssgTypeSelector()149 inline int ssgTypeSelector     () { return _SSG_TYPE_SELECTOR  | ssgTypeBranch  () ; }
ssgTypeRangeSelector()150 inline int ssgTypeRangeSelector() { return _SSG_TYPE_RANGESELECTOR | ssgTypeSelector () ; }
ssgTypeTimedSelector()151 inline int ssgTypeTimedSelector() { return _SSG_TYPE_TIMEDSELECTOR | ssgTypeSelector () ; }
ssgTypeRoot()152 inline int ssgTypeRoot         () { return _SSG_TYPE_ROOT      | ssgTypeBranch  () ; }
ssgTypeCutout()153 inline int ssgTypeCutout       () { return _SSG_TYPE_CUTOUT    | ssgTypeBranch  () ; }
ssgTypeInvisible()154 inline int ssgTypeInvisible    () { return _SSG_TYPE_INVISIBLE | ssgTypeBranch  () ; }
155 
ssgTypeState()156 inline int ssgTypeState        () { return _SSG_TYPE_STATE     | ssgTypeBase    () ; }
ssgTypeSimpleState()157 inline int ssgTypeSimpleState  () { return _SSG_TYPE_SIMPLESTATE | ssgTypeState () ; }
ssgTypeStateSelector()158 inline int ssgTypeStateSelector() { return _SSG_TYPE_STATESELECTOR | ssgTypeSimpleState () ; }
159 
ssgTypeSimpleList()160 inline int ssgTypeSimpleList   () { return _SSG_TYPE_SIMPLELIST | ssgTypeBase   () ; }
ssgTypeVertexArray()161 inline int ssgTypeVertexArray  () { return _SSG_TYPE_VERTEXARRAY | ssgTypeSimpleList () ; }
ssgTypeNormalArray()162 inline int ssgTypeNormalArray  () { return _SSG_TYPE_NORMALARRAY | ssgTypeSimpleList () ; }
ssgTypeTexCoordArray()163 inline int ssgTypeTexCoordArray() { return _SSG_TYPE_TEXCOORDARRAY | ssgTypeSimpleList () ; }
ssgTypeColourArray()164 inline int ssgTypeColourArray  () { return _SSG_TYPE_COLOURARRAY | ssgTypeSimpleList () ; }
ssgTypeIndexArray()165 inline int ssgTypeIndexArray   () { return _SSG_TYPE_INDEXARRAY | ssgTypeSimpleList () ; }
ssgTypeTransformArray()166 inline int ssgTypeTransformArray() { return _SSG_TYPE_TRANSFORMARRAY | ssgTypeSimpleList () ; }
ssgTypeInterleavedArray()167 inline int ssgTypeInterleavedArray() { return _SSG_TYPE_INTERLEAVEDARRAY | ssgTypeSimpleList () ; }
168 
ssgTypeTexture()169 inline int ssgTypeTexture      () { return _SSG_TYPE_TEXTURE   | ssgTypeBase    () ; }
170 
171 /*
172   It's critical that these numbers don't change without
173   some pretty pressing need because significant change to
174   ssgSimpleState.cxx and ssgStateTables.cxx would be needed.
175 */
176 
177 #define SSG_GL_TEXTURE_EN        0
178 #define SSG_GL_CULL_FACE_EN      1
179 #define SSG_GL_COLOR_MATERIAL_EN 2
180 #define SSG_GL_BLEND_EN          3
181 #define SSG_GL_ALPHA_TEST_EN     4
182 #define SSG_GL_LIGHTING_EN       5
183 
184 #define SSG_GL_TEXTURE           6
185 #define SSG_GL_COLOR_MATERIAL    7
186 #define SSG_GL_DIFFUSE           8
187 #define SSG_GL_AMBIENT           9
188 #define SSG_GL_SPECULAR         10
189 #define SSG_GL_EMISSION         11
190 #define SSG_GL_SHININESS        12
191 #define SSG_GL_ALPHA_TEST       13
192 #define SSG_GL_SHADE_MODEL      14
193 
194 #define SSG_CLONE_RECURSIVE        1
195 #define SSG_CLONE_GEOMETRY         2
196 #define SSG_CLONE_USERDATA         4
197 #define SSG_CLONE_STATE            8
198 #define SSG_CLONE_STATE_RECURSIVE 16
199 #define SSG_CLONE_TEXTURE         32
200 
201 int ssgGetFrameCounter () ;
202 void ssgSetFrameCounter ( int fc ) ;
203 
204 // Returns GL_TRUE if the OpenGL Extension whose name is *extName
205 // is supported by the system, or GL_FALSE otherwise.
206 bool ssgIsExtensionSupported(char *extName);
207 
208 class ssgList
209 {
210 protected:
211   unsigned int total ;  /* The total number of entities in the list */
212   unsigned int limit ;  /* The current limit on number of entities  */
213   unsigned int next  ;  /* The next entity when we are doing getNext ops */
214 
215   ssgEntity **entity_list ;  /* The list. */
216 
217   void sizeChk (void) ;
218 
219 public:
220 
221   ssgList ( int init_max = 1 ) ;
222   virtual ~ssgList (void) ;
223 
getEntity(unsigned int n)224   ssgEntity *getEntity ( unsigned int n )
225   {
226     next = n + 1 ;
227     return ( n >= total ) ? (ssgEntity *) NULL : entity_list [ n ] ;
228   }
229 
230   virtual void addEntity ( ssgEntity *entity ) ;
231   virtual void removeEntity ( unsigned int n ) ;
232 
233   void removeAllEntities () ;
234 
removeEntity(ssgEntity * entity)235   void removeEntity ( ssgEntity *entity )
236   {
237     removeEntity ( searchForEntity ( entity ) ) ;
238   }
239 
240   virtual void replaceEntity ( unsigned int n, ssgEntity *new_entity ) ;
241 
replaceEntity(ssgEntity * old_entity,ssgEntity * new_entity)242   void replaceEntity ( ssgEntity *old_entity, ssgEntity *new_entity )
243   {
244     replaceEntity ( searchForEntity ( old_entity ), new_entity ) ;
245   }
246 
getNumEntities(void)247   int        getNumEntities    (void) { return total ; }
getNextEntity(void)248   ssgEntity *getNextEntity     (void) { return getEntity ( next ) ; }
249   int        searchForEntity   ( ssgEntity *entity ) ;
250 } ;
251 
252 
253 class ssgKidList : public ssgList
254 {
255 public:
256 
257   ssgKidList ( int init_max = 1 ) ;
258   virtual ~ssgKidList (void) ;
259 
260   void addEntity ( ssgEntity *entity ) ;
261   void removeEntity ( unsigned int n ) ;
262 
removeEntity(ssgEntity * entity)263   void removeEntity ( ssgEntity *entity )
264   {
265     removeEntity ( searchForEntity ( entity ) ) ;
266   }
267 
268   void replaceEntity ( unsigned int n, ssgEntity *new_entity ) ;
269 
replaceEntity(ssgEntity * old_entity,ssgEntity * new_entity)270   void replaceEntity ( ssgEntity *old_entity, ssgEntity *new_entity )
271   {
272     replaceEntity ( searchForEntity ( old_entity ), new_entity ) ;
273   }
274 } ;
275 
276 
277 class ssgBase
278 {
279   int   refc   ;  /* The number of references to this node */
280   int   unique ;  /* A unique number for this node */
281 
282 protected :
283 
284   int   type  ;
285   int   spare ;  /* This spare field is used in a bunch of short-term hacks */
286 
287   char    *name ;
288   ssgBase *user_data ;
289   virtual void copy_from ( ssgBase *src, int clone_flags ) ;
290 
291 public:
292   void *operator new  ( size_t size ) ;
293   void  operator delete ( void *ptr ) ;
294 
deadBeefCheck()295   void deadBeefCheck () { assert ( type != (int) 0xDeadBeef ) ; }
296 
297   virtual void zeroSpareRecursive ();
298   virtual void zeroSpare ()         ;
299   virtual void incSpare  ()         ;
300   virtual void setSpare  ( int ss ) ;
301   virtual int  getSpare  ()         ;
302 
getUnique()303   int  getUnique () { return unique ; }
304 
305   ssgBase (void) ;
306   virtual ~ssgBase (void) ;
307 
ref()308   void ref   () { refc++ ; }
deRef()309   void deRef () { assert ( refc > 0 ) ; refc-- ; }
getRef()310   int  getRef() { return refc ; }
311 
312   virtual ssgBase *clone ( int clone_flags = 0 ) ;
313 
314   /* Type checking mechanism */
315 
316   virtual const char *getTypeName(void) ;
317 
getType(void)318   int   getType    (void)     { return type ; }
isA(int ty)319   int   isA        ( int ty ) { return getType() == ty ; }
isAKindOf(int ty)320   int   isAKindOf  ( int ty ) { return ( getType() & ty ) == ty ; }
321 
322   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
323   virtual int load ( FILE *fd ) ;
324   virtual int save ( FILE *fd ) ;
325 
getUserData()326   ssgBase *getUserData () { return user_data ; }
327 
setUserData(ssgBase * s)328   void setUserData ( ssgBase *s )
329   {
330     ssgDeRefDelete ( user_data ) ;
331 
332     user_data = s ;
333     if ( s != NULL )
334       s -> ref () ;
335   }
336 
337   void  setName ( const char *nm ) ;
getName()338   char *getName () { return name ; }
getPrintableName()339   const char *getPrintableName () { return (name == NULL) ? "NoName" : name ; }
340 } ;
341 
342 
343 
344 class ssgSimpleList : public ssgBase
345 {
346 protected:
347 
348   unsigned int total   ;  /* The total number of things in the list */
349   unsigned int limit   ;  /* The current limit on number of things  */
350   unsigned int size_of ;  /* The size of each thing */
351   char         *list   ;  /* The list. */
352   bool         own_mem ;  /* Do we own the list memory ? */
353 
sizeChk(unsigned int n)354   void sizeChk ( unsigned int n )
355   {
356     if ( (total+n) > limit )
357     {
358       if ( ! own_mem )
359         ulSetError( UL_FATAL, "ssgSimpleList: Cannot resize array." );
360 
361       /* how big should we make the list? */
362       limit += limit ;  /* double it */
363 			if ( limit <= 0 )
364 				limit = 3;
365       if ( (total+n) > limit )
366         limit = (total+n) ;
367 
368       /* re-allocate the list */
369       char *nlist = new char [ limit * size_of ] ;
370       memmove ( nlist, list, total * size_of ) ;
371       delete [] list ;
372       list = nlist ;
373     }
374   }
375 
376   virtual void copy_from ( ssgSimpleList *src, int clone_flags ) ;
377 
378 _SSG_PUBLIC:
379 
ssgSimpleList()380   ssgSimpleList ()
381   {
382     type = ssgTypeSimpleList () ;
383     limit = 0 ;
384     size_of = 0 ;
385     total = 0 ;
386     list = NULL ;
387     own_mem = true ;
388   }
389 
390 public:
391 
392   ssgSimpleList ( int sz, int init = 3, char* things = 0 )
393   {
394     type = ssgTypeSimpleList () ;
395     limit = init ;
396     size_of = sz ;
397     if ( things )
398     {
399       total = init ;
400       list = things ;
401       own_mem = false ;
402     }
403     else
404     {
405       total = 0 ;
406       list = new char [ limit * size_of ] ;
407       own_mem = true ;
408     }
409   }
410 
411   virtual ssgBase *clone ( int clone_flags = 0 ) ;
412 
~ssgSimpleList(void)413   virtual ~ssgSimpleList (void)
414   {
415     if ( own_mem )
416       delete [] list ;
417     list = NULL ;
418   } ;
419 
raw_get(unsigned int n)420   char *raw_get ( unsigned int n )
421   {
422     return ( n >= total ) ? ((char *) 0) : & list [ n * size_of ] ;
423   }
424 
raw_add(char * thing)425   void raw_add ( char *thing )
426   {
427     sizeChk ( 1 ) ;
428     memcpy ( & list [ size_of * total++ ], thing, size_of ) ;
429   } ;
430 
raw_add(char * things,unsigned int n)431   void raw_add ( char *things, unsigned int n )
432   {
433     sizeChk ( n ) ;
434     memcpy ( & list [ size_of * total ], things, size_of * n ) ;
435     total += n ;
436   }
437 
raw_set(char * thing,unsigned int n)438   void raw_set ( char *thing, unsigned int n  )
439   {
440     memcpy ( & list [ size_of * n ], thing, size_of ) ;
441   } ;
442 
removeLast()443   void removeLast ()
444   {
445     if ( total > 0 )
446       total-- ;
447   }
448 
removeAll()449   void removeAll ()
450   {
451     if ( own_mem )
452       delete [] list ;
453     list = NULL ;
454     limit = total = 0 ;
455   }
456 
457 	int compare(ssgSimpleList *other, int print_result=TRUE);
getSizeOf(void)458   int getSizeOf (void) { return size_of ; }
getNum(void)459   int getNum (void) { return total ; }
460 
rawSetNum(unsigned int n)461   void rawSetNum ( unsigned int n ) /* Better know what you're doing!! */
462   {
463     total = n ;
464   }
465 
setNum(unsigned int n)466   void setNum ( unsigned int n )
467   {
468     if ( total < n )
469     {
470       sizeChk ( n ) ;
471       memset ( & list [ size_of * total ], 0, size_of * (n-total) ) ;
472       total = n ;
473     }
474   }
475 
476   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
477   virtual int load ( FILE *fd ) ;
478   virtual int save ( FILE *fd ) ;
479   virtual const char *getTypeName(void) ;
480 } ;
481 
482 
483 class ssgVertexArray : public ssgSimpleList
484 {
485 public:
486 
487   virtual ssgBase *clone ( int clone_flags = 0 ) ;
488   ssgVertexArray ( int init = 3, sgVec3* things = 0 )
489     : ssgSimpleList ( sizeof(sgVec3), init, (char*)things )
490   {
491     type = ssgTypeVertexArray () ;
492   }
get(unsigned int n)493   float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; }
add(sgVec3 thing)494   void   add ( sgVec3   thing ) { raw_add ( (char *) thing ) ; } ;
set(sgVec3 thing,unsigned int n)495   void   set ( sgVec3   thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ;
set(float x,float y,float z,unsigned int n)496   void   set ( float x, float y, float z, unsigned int n )
497   { sgVec3 tmp = { x, y, z } ; raw_set ( (char *) tmp, n ) ; } ;
add(float x,float y,float z)498   void   add ( float x, float y, float z )
499   { sgVec3 tmp = { x, y, z } ; raw_add ( (char *) tmp ) ; } ;
500   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
501   virtual const char *getTypeName(void) ;
502 } ;
503 
504 
505 class ssgNormalArray : public ssgSimpleList
506 {
507 public:
508 
509   virtual ssgBase *clone ( int clone_flags = 0 ) ;
510   ssgNormalArray ( int init = 3, sgVec3* things = 0 )
511     : ssgSimpleList ( sizeof(sgVec3), init, (char*)things )
512   {
513     type = ssgTypeNormalArray () ;
514   }
get(unsigned int n)515   float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; }
add(sgVec3 thing)516   void   add ( sgVec3   thing ) { raw_add ( (char *) thing ) ; } ;
set(sgVec3 thing,unsigned int n)517   void   set ( sgVec3   thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ;
set(float x,float y,float z,unsigned int n)518   void   set ( float x, float y, float z, unsigned int n )
519   { sgVec3 tmp = { x, y, z } ; raw_set ( (char *) tmp, n ) ; } ;
add(float x,float y,float z)520   void   add ( float x, float y, float z )
521   { sgVec3 tmp = { x, y, z } ; raw_add ( (char *) tmp ) ; } ;
522   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
523   virtual const char *getTypeName(void) ;
524 } ;
525 
526 
527 class ssgTexCoordArray : public ssgSimpleList
528 {
529 public:
530 
531   virtual ssgBase *clone ( int clone_flags = 0 ) ;
532   ssgTexCoordArray ( int init = 3, sgVec2* things = 0 )
533     : ssgSimpleList ( sizeof(sgVec2), init, (char*)things )
534   {
535     type = ssgTypeTexCoordArray () ;
536   }
get(unsigned int n)537   float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; }
add(sgVec2 thing)538   void   add ( sgVec2   thing ) { raw_add ( (char *) thing ) ; } ;
set(sgVec2 thing,unsigned int n)539   void   set ( sgVec2   thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ;
set(float u,float v,unsigned int n)540   void   set ( float u, float v, unsigned int n )
541   { sgVec2 tmp = { u, v } ; raw_set ( (char *) tmp, n ) ; } ;
add(float u,float v)542   void   add ( float u, float v )
543   { sgVec2 tmp = { u, v } ; raw_add ( (char *) tmp ) ; } ;
544   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
545   virtual const char *getTypeName(void) ;
546 } ;
547 
548 
549 class ssgColourArray : public ssgSimpleList
550 {
551 public:
552 
553   virtual ssgBase *clone ( int clone_flags = 0 ) ;
554   ssgColourArray ( int init = 3, sgVec4* things = 0 )
555     : ssgSimpleList ( sizeof(sgVec4), init, (char*)things )
556   {
557     type = ssgTypeColourArray () ;
558   }
get(unsigned int n)559   float *get ( unsigned int n ) { return (float *) raw_get ( n ) ; }
add(sgVec4 thing)560   void   add ( sgVec4   thing ) { raw_add ( (char *) thing ) ; } ;
set(sgVec4 thing,unsigned int n)561   void   set ( sgVec4   thing, unsigned int n ) { raw_set ( (char *) thing, n ) ; } ;
set(float r,float g,float b,float a,unsigned int n)562   void   set ( float r, float g, float b, float a, unsigned int n )
563   { sgVec4 tmp = { r,g,b,a } ; raw_set ( (char *) tmp, n ) ; } ;
add(float r,float g,float b,float a)564   void   add ( float r, float g, float b, float a )
565   { sgVec4 tmp = { r,g,b,a } ; raw_add ( (char *) tmp ) ; } ;
566   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
567   virtual const char *getTypeName(void) ;
568 } ;
569 
570 
571 class ssgIndexArray : public ssgSimpleList
572 {
573 public:
574 
575   virtual ssgBase *clone ( int clone_flags = 0 ) ;
576   ssgIndexArray ( int init = 3, short* things = 0 )
577     : ssgSimpleList ( sizeof(short), init, (char*)things )
578   {
579     type = ssgTypeIndexArray () ;
580   }
581   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
get(unsigned int n)582   short *get ( unsigned int n ) { return (short *) raw_get ( n ) ; }
add(short thing)583   void   add ( short    thing ) { raw_add ( (char *) &thing ) ; } ;
set(short thing,unsigned int n)584   void   set ( short    thing, unsigned int n ) { raw_set ( (char *) &thing, n ) ; } ;
585   virtual const char *getTypeName(void) ;
586 } ;
587 
588 
589 class ssgTransformArray : public ssgSimpleList
590 {
591 public:
592   int selection ;  /* used to remember last transform selected */
593 
594   ssgTransformArray ( int init = 3, sgMat4* things = 0 )
595     : ssgSimpleList ( sizeof(sgMat4), init, (char*)things )
596   {
597     type = ssgTypeTransformArray () ;
598     selection = 0 ;
599   }
get(unsigned int n)600   sgMat4 *get ( unsigned int n ) { return (sgMat4 *) raw_get ( n ) ; }
add(sgMat4 thing)601   void   add ( sgMat4  thing ) { raw_add ( (char *) thing ) ; } ;
602   virtual const char *getTypeName(void) ;
603 } ;
604 
605 
606 class ssgTexture ;
607 class ssgTextureArray : private ssgSimpleList
608 {
609 public:
610 
611   ssgTextureArray ( int init = 3 )
ssgSimpleList(sizeof (ssgTexture *),init)612     : ssgSimpleList ( sizeof(ssgTexture*), init )
613   {
614     //type = ssgTypeTextureArray () ;
615   }
616 
getNum(void)617   int getNum (void) { return total ; }
get(unsigned int n)618   ssgTexture* get ( unsigned int n )
619     { return *( (ssgTexture**) raw_get ( n ) ) ; }
620   void add ( ssgTexture* thing ) ;
621   void removeAll () ;
622   ssgTexture* findByFilename ( const char* fname ) ;
623 } ;
624 
625 
626 class ssgSimpleState ;
627 class ssgSimpleStateArray : private ssgSimpleList
628 {
629   void collect_recursive ( ssgEntity *e );
630 
631 public:
632 
633   ssgSimpleStateArray ( int init = 3 )
ssgSimpleList(sizeof (ssgSimpleState *),init)634     : ssgSimpleList ( sizeof(ssgSimpleState*), init )
635   {
636     //type = ssgTypeSimpleStateArray () ;
637   }
638 
getNum(void)639   int getNum (void) { return total ; }
get(unsigned int n)640   ssgSimpleState* get ( unsigned int n )
641   {
642     assert(n<total);
643     return *( (ssgSimpleState**) raw_get ( n ) ) ;
644   }
645   void add ( ssgSimpleState* ss ) ;
646   void removeAll () ;
647   ssgSimpleState* findMatch ( ssgSimpleState* ss ) ;
648 
649   void collect ( ssgEntity *e );
650 	int findIndex ( ssgSimpleState* st ) ;  //returns -1 if not found
651 } ;
652 
653 
654 struct ssgInterleavedArrayElement
655 {
656   sgVec2 texCoord ;
657   sgVec4 colour ;
658   sgVec3 normal ;
659   sgVec3 vertex ;
660 } ;
661 
662 
663 class ssgInterleavedArray : public ssgSimpleList
664 {
665 public:
666 
667   ssgInterleavedArray ( int init = 3, ssgInterleavedArrayElement* things = 0 )
668     : ssgSimpleList ( sizeof(ssgInterleavedArrayElement), init, (char*)things )
669   {
670     type = ssgTypeInterleavedArray () ;
671   }
get(unsigned int n)672   ssgInterleavedArrayElement *get ( unsigned int n ) { return (ssgInterleavedArrayElement *) raw_get ( n ) ; }
add(ssgInterleavedArrayElement thing)673   void add ( ssgInterleavedArrayElement  thing ) { raw_add ( (char *) &thing ) ; } ;
add(ssgInterleavedArrayElement * thing)674   void add ( ssgInterleavedArrayElement *thing ) { raw_add ( (char *)  thing ) ; } ;
set(ssgInterleavedArrayElement thing,unsigned int n)675   void set ( ssgInterleavedArrayElement  thing, unsigned int n ) { raw_set ( (char *) &thing, n ) ; } ;
set(ssgInterleavedArrayElement * thing,unsigned int n)676   void set ( ssgInterleavedArrayElement *thing, unsigned int n ) { raw_set ( (char *)  thing, n ) ; } ;
677   virtual const char *getTypeName(void) ;
678 } ;
679 
680 
681 struct ssgTextureInfo
682 {
683 	unsigned int width ;
684 	unsigned int height ;
685 	unsigned int depth ;
686 	unsigned int alpha ;
687 } ;
688 
689 
690 bool ssgLoadTexture ( const char *fname, ssgTextureInfo* info=0 ) ;
691   bool ssgLoadPNG ( const char *fname, ssgTextureInfo* info ) ;
692   bool ssgLoadSGI ( const char *fname, ssgTextureInfo* info ) ;
693   bool ssgLoadBMP ( const char *fname, ssgTextureInfo* info ) ;
694   bool ssgLoadTGA ( const char *fname, ssgTextureInfo* info ) ;
695   bool ssgLoadMDLTexture ( const char *fname, ssgTextureInfo* info ) ;
696 	bool ssgLoadPCX ( const char *fname, ssgTextureInfo* info ) ;
697 
698 void ssgAddTextureFormat ( const char* extension,
699                           bool (*) (const char*, ssgTextureInfo* info) ) ;
700 
701 int ssgGetNumTexelsLoaded () ;
702 bool ssgMakeMipMaps ( GLubyte *image, int xsize, int ysize, int zsize, bool freeData = true ) ;
703 
704 
705 class ssgTexture : public ssgBase
706 {
707 protected:
708   char *filename ;
709   int own_handle ;
710   GLuint handle ;
711 	int wrapu, wrapv, mipmap ;
712   bool has_alpha ;
713 
714   void alloc_handle () ;
715   void free_handle () ;
716 
717 protected:
718 
719   virtual void copy_from ( ssgTexture *src, int clone_flags ) ;
720 	void setDefaultGlParams(int wrapu, int wrapv, int mipmap);
721 
722 public:
723 
724   virtual ssgBase *clone ( int clone_flags = 0 ) ;
725 
726   ssgTexture () ;
727 
728   // This constructor loads the texture from file for you:
729   ssgTexture ( const char *fname, int wrapu = TRUE, int wrapv = TRUE,
730 	       int mipmap = TRUE );
731 
732   // use this constructor if you already have the texture in memory
733   ssgTexture ( const char *fname, GLubyte *image, int xsize, int ysize, int zsize,
734 		     int wrapu = TRUE, int wrapv = TRUE);
735 
736   virtual ~ssgTexture (void) ;
737 
hasAlpha()738   bool hasAlpha () const { return has_alpha ; }
739 
getHandle()740   GLuint getHandle () { return handle ; }
741 
742   /*
743     WARNING - setHandle() IS DEPRECATED
744     BECAUSE IT LEAKS texture handles!
745   */
746 
747   void setHandle ( GLuint handle ) ;
748 
getFilename(void)749   char *getFilename(void) { return filename ; }
750 
setFilename(const char * fname)751   void  setFilename(const char *fname)
752   {
753     delete [] filename ;
754 
755     if ( fname == NULL )
756       filename = NULL ;
757     else
758       filename = ulStrDup ( fname ) ;
759   }
760 
761   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
762   virtual int load ( FILE *fd ) ;
763   virtual int save ( FILE *fd ) ;
764   virtual const char *getTypeName(void) ;
765 } ;
766 
767 typedef int (*ssgCallback)( ssgEntity * ) ;
768 #define SSG_CALLBACK_PREDRAW   1
769 #define SSG_CALLBACK_POSTDRAW  2
770 
771 typedef int (*ssgTravCallback)( ssgEntity *entity, int traversal_mask ) ;
772 #define SSG_CALLBACK_PRETRAV   1
773 #define SSG_CALLBACK_POSTTRAV  2
774 
775 class ssgState ;
776 
777 typedef int (*ssgStateCallback)( ssgState *entity ) ;
778 
779 #define SSG_CALLBACK_PREAPPLY   3
780 
781 class ssgState : public ssgBase
782 {
783   int translucent ;
784 
785   int external_property_index ;
786 
787   ssgStateCallback preApplyCB ;
788   ssgStateCallback preDrawCB  ;
789   ssgStateCallback postDrawCB ;
790 
791 
792 protected:
793 
794   void preApply () ;
795   void preDraw  () ;
796 
797 public:
798 
799   virtual void copy_from ( ssgState *src, int clone_flags ) ;
800   ssgState (void) ;
801   virtual ~ssgState (void) ;
802 
803   virtual const char *getTypeName(void) ;
804 
getStateCallback(int cb_type)805   ssgStateCallback getStateCallback ( int cb_type )
806   {
807     return ( cb_type == SSG_CALLBACK_PREAPPLY ) ? preApplyCB :
808            ( cb_type == SSG_CALLBACK_PREDRAW  ) ? preDrawCB :
809                                                   postDrawCB ;
810   }
811 
setStateCallback(int cb_type,ssgStateCallback cb)812   void setStateCallback ( int cb_type, ssgStateCallback cb )
813   {
814     if ( cb_type == SSG_CALLBACK_PREAPPLY )
815       preApplyCB = cb ;
816     else
817     if ( cb_type == SSG_CALLBACK_PREDRAW )
818       preDrawCB = cb ;
819     else
820       postDrawCB = cb ;
821   }
822 
getExternalPropertyIndex(void)823   int  getExternalPropertyIndex (void) { return external_property_index ; }
setExternalPropertyIndex(int i)824   void setExternalPropertyIndex ( int i ) { external_property_index = i ; }
825 
isTranslucent(void)826   virtual int  isTranslucent (void)  { return translucent ;  }
setTranslucent(void)827   virtual void setTranslucent (void) { translucent = TRUE  ; }
setOpaque(void)828   virtual void setOpaque      (void) { translucent = FALSE ; }
829   virtual void force (void) = 0 ;
830   virtual void apply (void) = 0 ;
831 
832   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
833   virtual int load ( FILE *fd ) ;
834   virtual int save ( FILE *fd ) ;
835 } ;
836 
837 
838 class ssgSimpleState : public ssgState
839 {
840 _SSG_PUBLIC:
841 
842   int    dont_care ;
843   int    enables   ;
844   ssgTexture* texture ;
845   int    mipmap;
846 
847   int colour_material_mode ;
848   sgVec4 specular_colour ;
849   sgVec4 emission_colour ;
850   sgVec4  ambient_colour ;
851   sgVec4  diffuse_colour ;
852 
853   GLenum shade_model ;
854 
855   float  shininess ;
856   float  alpha_clamp ;
857 
858   ssgSimpleState ( int I_am_current_state ) ;
859 
860 protected:
861 
862 public:
863 
864   virtual void copy_from ( ssgSimpleState *src, int clone_flags ) ;
865   virtual ssgBase *clone ( int clone_flags = 0 ) ;
866   ssgSimpleState (void) ;
867   virtual ~ssgSimpleState (void) ;
868   virtual const char *getTypeName(void) ;
869 
870   virtual void force (void) ;
871   virtual void apply (void) ;
872 
care_about(int mode)873   virtual void      care_about ( int mode ) { dont_care &= ~(1<<mode) ; }
dont_care_about(int mode)874   virtual void dont_care_about ( int mode ) { dont_care |=  (1<<mode) ; }
getCareAbout(int mode)875   virtual int     getCareAbout ( int mode ) { return dont_care & (1<<mode) ; }
876 
877   virtual int  isEnabled ( GLenum mode ) ;
878   virtual void disable   ( GLenum mode ) ;
879   virtual void enable    ( GLenum mode ) ;
set(GLenum mode,int val)880   virtual void set       ( GLenum mode, int val )
881                                  { val ? enable(mode) : disable(mode) ; }
882 
getTextureHandle(void)883   virtual GLuint getTextureHandle (void)
884   {
885     if ( texture != NULL )
886       return texture -> getHandle () ;
887     return 0 ;
888   }
889 
getTextureFilename(void)890   virtual char *getTextureFilename(void)
891   {
892     if ( texture != NULL )
893       return texture -> getFilename () ;
894     return NULL ;
895   }
896 
getTexture(void)897   virtual ssgTexture* getTexture (void)
898   {
899     return texture ;
900   }
901 
setTexture(ssgTexture * tex)902   virtual void setTexture ( ssgTexture *tex )
903   {
904     ssgDeRefDelete ( texture ) ;
905     texture = tex ;
906     if ( texture != NULL )
907     {
908       care_about ( SSG_GL_TEXTURE ) ;
909       texture -> ref () ;
910     }
911     else
912     {
913       dont_care_about ( SSG_GL_TEXTURE ) ;
914     }
915   }
916 
917   virtual void  setTexture ( const char *fname,
918     int _wrapu = TRUE, int _wrapv = TRUE, int _mipmap = TRUE )
919   {
920     mipmap = _mipmap ;
921     setTexture ( new ssgTexture ( fname, _wrapu, _wrapv, mipmap ) ) ;
922   }
923 
924   /*
925     WARNING - THIS FORM OF setTexture IS DEPRECATED
926     BECAUSE IT PREVENTS ssgSave FROM SAVING THE
927     TEXTURE FILENAME and it LEAKS texture handles!
928   */
929 
setTexture(GLuint tex)930   virtual void setTexture ( GLuint tex )
931   {
932     if ( !texture )
933       setTexture ( new ssgTexture ) ;
934 
935     texture -> setHandle ( tex ) ;
936     texture -> setFilename ( NULL ) ;
937   }
938 
setTextureFilename(const char * fname)939   virtual void setTextureFilename ( const char *fname )
940   {
941     if ( !texture )
942       setTexture ( new ssgTexture ) ;
943 
944     texture -> setFilename ( fname ) ;
945   }
946 
getColourMaterial()947   virtual GLenum getColourMaterial ()
948   {
949     return (GLenum) colour_material_mode ;
950   }
951 
setColourMaterial(GLenum which)952   virtual void setColourMaterial ( GLenum which )
953   {
954     colour_material_mode = (int) which ;
955     care_about ( SSG_GL_COLOR_MATERIAL ) ;
956   }
957 
958   virtual void setMaterial ( GLenum which, float r, float g,
959                                            float b, float a = 1.0f )
960   {
961     sgVec4 rgba ;
962     sgSetVec4 ( rgba, r, g, b, a ) ;
963     setMaterial ( which, rgba ) ;
964   }
965 
setMaterial(GLenum which,sgVec4 rgba)966   virtual void setMaterial   ( GLenum which, sgVec4 rgba )
967   {
968     switch ( which )
969     {
970       case GL_EMISSION : sgCopyVec4 ( emission_colour, rgba ) ;
971                          care_about ( SSG_GL_EMISSION ) ;
972                          break ;
973       case GL_SPECULAR : sgCopyVec4 ( specular_colour, rgba ) ;
974                          care_about ( SSG_GL_SPECULAR ) ;
975                          break ;
976       case GL_AMBIENT  : sgCopyVec4 ( ambient_colour , rgba ) ;
977                          care_about ( SSG_GL_AMBIENT  ) ;
978                          break ;
979       case GL_DIFFUSE  : sgCopyVec4 ( diffuse_colour , rgba ) ;
980                          care_about ( SSG_GL_DIFFUSE  ) ;
981                          break ;
982       case GL_AMBIENT_AND_DIFFUSE :  // in compliance with glMaterial
983                          sgCopyVec4 ( ambient_colour , rgba ) ;
984                          sgCopyVec4 ( diffuse_colour , rgba ) ;
985                          care_about ( SSG_GL_AMBIENT | SSG_GL_DIFFUSE ) ;
986 			 break ;
987       default :          break ;
988     }
989   }
990 
getMaterial(GLenum which)991   virtual float *getMaterial ( GLenum which )
992   {
993     switch ( which )
994     {
995       case GL_EMISSION : return emission_colour ;
996       case GL_SPECULAR : return specular_colour ;
997       case GL_AMBIENT  : return ambient_colour  ;
998       case GL_DIFFUSE  : return diffuse_colour  ;
999       default: break ;
1000     }
1001 
1002     return NULL ;
1003   }
1004 
getShininess(void)1005   virtual float getShininess (void)
1006   {
1007     return shininess ;
1008   }
1009 
setShininess(float sh)1010   virtual void setShininess ( float sh )
1011   {
1012     care_about ( SSG_GL_SHININESS ) ;
1013     shininess = sh ;
1014   }
1015 
setShadeModel(GLenum model)1016   virtual void setShadeModel ( GLenum model )
1017   {
1018     care_about ( SSG_GL_SHADE_MODEL ) ;
1019     shade_model = model ;
1020   }
1021 
setAlphaClamp(float clamp)1022   virtual void setAlphaClamp ( float clamp )
1023   {
1024     care_about ( SSG_GL_ALPHA_TEST ) ;
1025     alpha_clamp = clamp ;
1026   }
1027 
1028 	/*int getWrapU();
1029   int getWrapV();*/
1030   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1031   virtual int load ( FILE *fd ) ;
1032   virtual int save ( FILE *fd ) ;
1033 } ;
1034 
1035 
1036 class ssgStateSelector : public ssgSimpleState
1037 {
1038   int              nstates   ;
1039   int              selection ;
1040 _SSG_PUBLIC:
1041   ssgSimpleState **statelist ;
1042 
1043 protected:
1044   virtual void copy_from ( ssgStateSelector *src, int clone_flags ) ;
1045 
1046 public:
1047 
1048   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1049   ssgStateSelector () ;
1050   ssgStateSelector ( int ns ) ;
1051 
1052   virtual ~ssgStateSelector (void) ;
1053   virtual const char *getTypeName(void) ;
1054 
getNumSteps(void)1055   int             getNumSteps ( void ) { return nstates ; }
1056   void            selectStep ( unsigned int s ) ;
1057   unsigned int    getSelectStep   (void) ;
1058   ssgSimpleState *getCurrentStep  (void) ;
1059   void            setStep ( int i, ssgSimpleState *step ) ;
1060   ssgSimpleState *getStep ( int i ) ;
1061 
1062   virtual int  isTranslucent (void)  ;
1063   virtual void setTranslucent (void) ;
1064   virtual void setOpaque      (void) ;
1065   void force (void) ;
1066   void apply (void) ;
1067 
1068   void      care_about ( int mode ) ;
1069   void dont_care_about ( int mode ) ;
1070 
1071   int    isEnabled ( GLenum mode ) ;
1072   void   disable   ( GLenum mode ) ;
1073   void   enable    ( GLenum mode ) ;
1074 
1075   char *getTextureFilename(void) ;
1076   void  setTextureFilename(char *fname) ;
1077 
1078   void   setTexture ( char *fname,
1079 		      int _wrapu = TRUE,
1080 		      int _wrapv = TRUE,
1081 		      int _mipmap = TRUE ) ;
1082   GLuint getTextureHandle (void)   ;
1083   void   setTexture ( ssgTexture *tex ) ;
1084 
1085   /*
1086     WARNING - THIS FORM OF setTexture IS DEPRECATED
1087     BECAUSE IT PREVENTS ssgSave FROM SAVING THE
1088     TEXTURE FILENAME and LEAKS texture handles!
1089   */
1090 
1091   void   setTexture ( GLuint      tex ) ;
1092 
1093   void   setColourMaterial(GLenum which);
1094   void   setMaterial ( GLenum which, float r, float g,
1095                                    float b, float a = 1.0f ) ;
1096 
1097   void   setMaterial   ( GLenum which, sgVec4 rgba ) ;
1098   float *getMaterial ( GLenum which ) ;
1099   float  getShininess (void) ;
1100   void   setShininess ( float sh ) ;
1101   void   setShadeModel ( GLenum model ) ;
1102   void   setAlphaClamp ( float clamp ) ;
1103   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1104   virtual int load ( FILE *fd ) ;
1105   virtual int save ( FILE *fd ) ;
1106 } ;
1107 
1108 struct ssgEntityBinding
1109 {
1110   ssgEntity **entity     ;
1111   char       *nameOrPath ;
1112 } ;
1113 
1114 
1115 class ssgEntity : public ssgBase
1116 {
1117   ssgList parents ;
1118 
1119   int traversal_mask ;
1120   ssgTravCallback  preTravCB ;
1121   ssgTravCallback postTravCB ;
1122 
1123 protected:
1124   sgSphere bsphere ;
1125   int bsphere_is_invalid ;
1126 
emptyBSphere()1127   void emptyBSphere  ()              { bsphere.empty  ()    ; }
1128   void visualiseBSphere () ;
extendBSphere(sgSphere * s)1129   void extendBSphere ( sgSphere *s ) { bsphere.extend ( s ) ; }
extendBSphere(sgBox * b)1130   void extendBSphere ( sgBox    *b ) { bsphere.extend ( b ) ; }
extendBSphere(sgVec3 v)1131   void extendBSphere ( sgVec3    v ) { bsphere.extend ( v ) ; }
1132 
1133   virtual ssgCullResult cull_test  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1134   virtual ssgCullResult isect_test ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1135   virtual ssgCullResult hot_test   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1136   virtual ssgCullResult los_test   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1137 
1138   virtual void copy_from ( ssgEntity *src, int clone_flags ) ;
1139 public:
1140 
1141   ssgEntity (void) ;
1142   virtual ~ssgEntity (void) ;
1143 
getTraversalMask()1144   int  getTraversalMask     ()        { return traversal_mask ;}
setTraversalMask(int t)1145   void setTraversalMask     ( int t ) { traversal_mask  =  t ; }
setTraversalMaskBits(int t)1146   void setTraversalMaskBits ( int t ) { traversal_mask |=  t ; }
clrTraversalMaskBits(int t)1147   void clrTraversalMaskBits ( int t ) { traversal_mask &= ~t ; }
1148 
getTravCallback(int cb_type)1149   ssgTravCallback getTravCallback ( int cb_type )
1150   {
1151     return ( cb_type == SSG_CALLBACK_PRETRAV ) ? preTravCB : postTravCB ;
1152   }
1153 
setTravCallback(int cb_type,ssgTravCallback cb)1154   void setTravCallback ( int cb_type, ssgTravCallback cb )
1155   {
1156     if ( cb_type == SSG_CALLBACK_PRETRAV )
1157       preTravCB = cb ;
1158     else
1159       postTravCB = cb ;
1160   }
1161 
1162   int preTravTests ( int *test_needed, int which ) ;
1163   void postTravTests ( int which ) ;
1164 
1165   virtual void getNetTransform     ( sgMat4 xform ) ;
1166   virtual void getLastNetTransform ( sgMat4 xform ) ;
1167 
1168   /* for backward compatibility */
1169   virtual ssgCallback getCallback ( int cb_type ) ;
1170   virtual void setCallback ( int cb_type, ssgCallback cb ) ;
1171 
1172   virtual ssgEntity* getByName  ( char *nm ) ;
1173   virtual ssgEntity* getByPath  ( char *path ) ;
1174   int  bindEntities ( ssgEntityBinding *bind ) ;
1175 
1176   virtual void recalcBSphere (void) = 0 ;
isDirtyBSphere(void)1177   int  isDirtyBSphere (void) { return bsphere_is_invalid ; }
1178   void dirtyBSphere  () ;
1179 
getBSphere()1180   sgSphere *getBSphere ()
1181   {
1182     if ( isDirtyBSphere () )
1183       recalcBSphere () ;
1184 
1185     return & bsphere ;
1186   }
1187 
getNumKids(void)1188   virtual int getNumKids (void) { return 0 ; }
getNumParents()1189   int getNumParents () { return parents.getNumEntities () ; }
getParent(int p)1190   ssgBranch *getParent ( int p ) { return (ssgBranch *) parents.getEntity ( p ) ; }
getNextParent()1191   ssgBranch *getNextParent () { return (ssgBranch *) parents.getNextEntity () ; }
addParent(ssgEntity * entity)1192   void addParent    ( ssgEntity *entity ) { parents.addEntity    ( entity ) ; }
removeParent(ssgEntity * entity)1193   void removeParent ( ssgEntity *entity ) { parents.removeEntity ( entity ) ; }
1194 
1195   virtual const char *getTypeName(void) ;
1196 
1197   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) = 0 ;
1198   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) = 0 ;
1199   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) = 0 ;
1200   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) = 0 ;
1201   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1202   virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) = 0 ;
1203   virtual int load ( FILE *fd ) ;
1204   virtual int save ( FILE *fd ) ;
1205 } ;
1206 
1207 
1208 
1209 class ssgLeaf : public ssgEntity
1210 {
1211   int cull_face ;
1212   ssgState *state ;
1213 
1214 protected:
1215   GLenum gltype ;
1216 
1217   ssgCallback  preDrawCB ;
1218   ssgCallback postDrawCB ;
1219 
1220 #ifdef _SSG_USE_DLIST
1221   GLuint dlist ;
1222 #endif
1223 
1224   virtual void draw_geometry () = 0 ;
1225 
1226   int preDraw () ;
1227 
1228   virtual void copy_from ( ssgLeaf *src, int clone_flags ) ;
1229 public:
1230   ssgLeaf (void) ;
1231   virtual ~ssgLeaf (void) ;
1232 
1233   virtual void drawHighlight ( sgVec4 colour ) = 0 ;
1234   virtual void drawHighlight ( sgVec4 colour, int i ) = 0 ;
1235   virtual void pick ( int baseName ) = 0 ;
1236 
1237 #ifdef _SSG_USE_DLIST
1238   void makeDList () ;
1239   void deleteDList () ;
getDListIndex()1240   GLuint getDListIndex () { return dlist ; }
1241 #endif
1242 
getExternalPropertyIndex()1243   int  getExternalPropertyIndex ()
1244                  { return state ? state->getExternalPropertyIndex() : 0 ; }
1245 
isTranslucent()1246   int  isTranslucent () { return state ? state->isTranslucent() : FALSE ; }
hasState()1247   int       hasState () { return state != NULL ; }
1248 
getState()1249   ssgState *getState () { return state ; }
1250   void      setState ( ssgState *st ); //~~ T.G. Body extended & moved into CXX file
1251 
getCallback(int cb_type)1252   virtual ssgCallback getCallback ( int cb_type )
1253   {
1254     return ( cb_type == SSG_CALLBACK_PREDRAW ) ? preDrawCB : postDrawCB ;
1255   }
1256 
setCallback(int cb_type,ssgCallback cb)1257   virtual void setCallback ( int cb_type, ssgCallback cb )
1258   {
1259     if ( cb_type == SSG_CALLBACK_PREDRAW )
1260       preDrawCB = cb ;
1261     else
1262       postDrawCB = cb ;
1263   }
1264 
setPrimitiveType(GLenum ty)1265   virtual void setPrimitiveType ( GLenum ty ) { gltype = ty ; }
getPrimitiveType()1266   virtual GLenum getPrimitiveType () { return gltype ; }
1267 
1268   /* For backwards compatibility only -- DEPRECATED */
getGLtype()1269   GLenum getGLtype () { return getPrimitiveType() ; }
1270 
getNumVertices()1271   virtual int getNumVertices  () { return 0 ; }
getNumNormals()1272   virtual int getNumNormals   () { return 0 ; }
getNumColours()1273   virtual int getNumColours   () { return 0 ; }
getNumTexCoords()1274   virtual int getNumTexCoords () { return 0 ; }
1275 
1276   virtual float *getVertex   ( int i ) = 0 ;
1277   virtual float *getNormal   ( int i ) = 0 ;
1278   virtual float *getColour   ( int i ) = 0 ;
1279   virtual float *getTexCoord ( int i ) = 0 ;
1280   virtual int  getNumTriangles () = 0 ;
1281   virtual void getTriangle ( int n, short *v1, short *v2, short *v3 ) = 0 ;
1282   virtual int  getNumLines () = 0 ;
1283   virtual void getLine ( int n, short *v1, short *v2 ) = 0 ;
1284 
1285   virtual void transform ( const sgMat4 m ) = 0 ;
1286 
setCullFace(int cf)1287   void setCullFace ( int cf ) { cull_face = cf ; }
getCullFace()1288   int  getCullFace () { return cull_face ; }
1289 
1290   virtual void recalcBSphere () = 0 ;
1291   virtual const char *getTypeName(void) ;
1292   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1293   virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
1294   virtual int load ( FILE *fd ) ;
1295   virtual int save ( FILE *fd ) ;
1296 
1297   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1298   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1299   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1300   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1301   virtual void isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) = 0 ;
1302   virtual void hot_triangles   ( sgVec3    s, sgMat4 m, int test_needed ) = 0 ;
1303   virtual void los_triangles   ( sgVec3    s, sgMat4 m, int test_needed ) = 0 ;
1304   virtual void draw  () = 0 ;
1305 } ;
1306 
1307 extern sgVec3 _ssgVertex000   ;
1308 extern sgVec4 _ssgColourWhite ;
1309 extern sgVec3 _ssgNormalUp    ;
1310 extern sgVec2 _ssgTexCoord00  ;
1311 extern short  _ssgIndex0      ;
1312 extern float _ssgGlobTime     ; // used by ssgAnimTransform. Has to be set by the appliation!
1313 
1314 
1315 class ssgVTable : public ssgLeaf
1316 {
1317 protected:
1318   sgBox bbox ;
1319   int indexed ;
1320 
1321   sgVec3 *vertices  ; int num_vertices  ; unsigned short *v_index ;
1322   sgVec3 *normals   ; int num_normals   ; unsigned short *n_index ;
1323   sgVec2 *texcoords ; int num_texcoords ; unsigned short *t_index ;
1324   sgVec4 *colours   ; int num_colours   ; unsigned short *c_index ;
1325 
1326   virtual void draw_geometry () ;
1327   virtual void copy_from ( ssgVTable *src, int clone_flags ) ;
1328 
1329 _SSG_PUBLIC:
isIndexed()1330   int isIndexed () { return indexed ; }
1331 
1332 public:
1333   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1334   ssgVTable () ;
1335   ssgVTable ( GLenum ty,
1336               int nv, unsigned short *vi, sgVec3 *vl,
1337               int nn, unsigned short *ni, sgVec3 *nl,
1338               int nt, unsigned short *ti, sgVec2 *tl,
1339               int nc, unsigned short *ci, sgVec4 *cl ) ;
1340 
1341   ssgVTable ( GLenum ty,
1342               int nv, sgVec3 *vl,
1343               int nn, sgVec3 *nl,
1344               int nt, sgVec2 *tl,
1345               int nc, sgVec4 *cl ) ;
1346 
1347   virtual void drawHighlight ( sgVec4 colour ) ;
1348   virtual void drawHighlight ( sgVec4 colour, int i ) ;
1349   virtual void pick ( int baseName ) ;
1350   virtual void transform ( const sgMat4 m ) ;
1351 
getNumVertices()1352   int getNumVertices  () { return num_vertices  ; }
getNumNormals()1353   int getNumNormals   () { return num_normals   ; }
getNumColours()1354   int getNumColours   () { return num_colours   ; }
getNumTexCoords()1355   int getNumTexCoords () { return num_texcoords ; }
1356   int getNumTriangles () ;
1357   void getTriangle ( int n, short *v1, short *v2, short *v3 ) ;
1358   int  getNumLines () ;
1359   void getLine ( int n, short *v1, short *v2 ) ;
1360 
getColourList(void ** list,unsigned short ** idx)1361   void getColourList ( void **list, unsigned short **idx )
1362   {
1363     *list = colours ;
1364     *idx  = c_index  ;
1365   }
1366 
getTexCoordList(void ** list,unsigned short ** idx)1367   void getTexCoordList ( void **list, unsigned short **idx )
1368   {
1369     *list = texcoords ;
1370     *idx  = t_index  ;
1371   }
1372 
getNormalList(void ** list,unsigned short ** idx)1373   void getNormalList ( void **list, unsigned short **idx )
1374   {
1375     *list = normals ;
1376     *idx  = n_index  ;
1377   }
1378 
getVertexList(void ** list,unsigned short ** idx)1379   void getVertexList ( void **list, unsigned short **idx )
1380   {
1381     *list = vertices ;
1382     *idx  = v_index  ;
1383   }
1384 
getVertex(int i)1385   float *getVertex  (int i){ if(i>=num_vertices)i=num_vertices-1;
1386                              return (num_vertices<=0) ? _ssgVertex000 :
1387                                     ((indexed)?vertices [v_index[i]]:vertices [i]);}
getColour(int i)1388   float *getColour  (int i){ if(i>=num_colours)i=num_colours-1;
1389                              return (num_colours<=0) ? _ssgColourWhite :
1390                                     ((indexed)?colours  [c_index[i]]:colours  [i]);}
getNormal(int i)1391   float *getNormal  (int i){ if(i>=num_normals)i=num_normals-1;
1392                              return (num_normals<=0) ? _ssgNormalUp :
1393                                     ((indexed)?normals  [n_index[i]]:normals  [i]);}
getTexCoord(int i)1394   float *getTexCoord(int i){ if(i>=num_texcoords)i=num_texcoords-1;
1395                              return (num_texcoords<=0) ? _ssgTexCoord00 :
1396                                     ((indexed)?texcoords[t_index[i]]:texcoords[i]);}
1397 
1398 
1399   virtual ~ssgVTable (void) ;
1400 
1401   virtual const char *getTypeName(void) ;
1402   virtual void recalcBSphere () ;
1403   virtual void draw () ;
1404 
1405   virtual void isect_triangles ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1406   virtual void hot_triangles   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1407   virtual void los_triangles   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1408   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1409   virtual int load ( FILE *fd ) ;
1410   virtual int save ( FILE *fd ) ;
1411 } ;
1412 
1413 
1414 class ssgVtxTable : public ssgLeaf
1415 {
1416 protected:
1417   sgBox bbox ;
1418 
1419   virtual void draw_geometry () ;
1420   virtual void copy_from ( ssgVtxTable *src, int clone_flags ) ;
1421 
1422 _SSG_PUBLIC:
1423 
1424   ssgVertexArray   *vertices  ;
1425   ssgNormalArray   *normals   ;
1426   ssgTexCoordArray *texcoords ;
1427   ssgColourArray   *colours   ;
1428 
1429 public:
1430 	int compare(ssgVtxTable *other, int print_result=TRUE);
1431   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1432   ssgVtxTable () ;
1433 
1434   ssgVtxTable ( GLenum ty, ssgVertexArray   *vl,
1435                            ssgNormalArray   *nl,
1436                            ssgTexCoordArray *tl,
1437                            ssgColourArray   *cl ) ;
1438 
textureMe(float uP,float vP)1439   void textureMe(float uP, float vP)
1440 	{ texcoords = new ssgTexCoordArray;
1441 	  for(int i=vertices->getNum()-1; i>=0; i--)
1442 		{ sgVec2 v;
1443 			v[0] = uP; v[1] = vP;
1444 			texcoords->add(v);
1445 		}
1446 	}
1447 	virtual void drawHighlight ( sgVec4 colour ) ;
1448   virtual void drawHighlight ( sgVec4 colour, int i ) ;
1449   virtual void pick ( int baseName ) ;
1450   virtual void transform ( const sgMat4 m ) ;
1451 
getVertices()1452   ssgVertexArray   *getVertices  () { return vertices  ; }
getNormals()1453   ssgNormalArray   *getNormals   () { return normals   ; }
getTexCoords()1454   ssgTexCoordArray *getTexCoords () { return texcoords ; }
getColours()1455   ssgColourArray   *getColours   () { return colours   ; }
1456 
1457   virtual void setVertices  ( ssgVertexArray   *vl ) ;
1458   virtual void setNormals   ( ssgNormalArray   *nl ) ;
1459   virtual void setTexCoords ( ssgTexCoordArray *tl ) ;
1460   virtual void setColours   ( ssgColourArray   *cl ) ;
1461 
getNumVertices()1462   int getNumVertices  () { return vertices  -> getNum () ; }
getNumNormals()1463   int getNumNormals   () { return normals   -> getNum () ; }
getNumColours()1464   int getNumColours   () { return colours   -> getNum () ; }
getNumTexCoords()1465   int getNumTexCoords () { return texcoords -> getNum () ; }
1466 
1467   /* Don't call this unless you know what you are doing!! */
rawSetNumVertices(unsigned int n)1468   void rawSetNumVertices ( unsigned int n ) { vertices -> rawSetNum ( n ) ; }
1469 
1470   int  getNumTriangles () ;
1471   void getTriangle ( int n, short *v1, short *v2, short *v3 ) ;
1472   int  getNumLines () ;
1473   void getLine ( int n, short *v1, short *v2 ) ;
1474 
getVertexList(void ** list)1475   void getVertexList   ( void **list ) { *list = vertices  -> get ( 0 ) ; }
getNormalList(void ** list)1476   void getNormalList   ( void **list ) { *list = normals   -> get ( 0 ) ; }
getTexCoordList(void ** list)1477   void getTexCoordList ( void **list ) { *list = texcoords -> get ( 0 ) ; }
getColourList(void ** list)1478   void getColourList   ( void **list ) { *list = colours   -> get ( 0 ) ; }
1479 
getVertex(int i)1480   float *getVertex  (int i){ int nv=getNumVertices(); if(i>=nv)i=nv-1;
1481                              return (nv<=0) ? _ssgVertex000:vertices->get(i);}
getNormal(int i)1482   float *getNormal  (int i){ int nn=getNumNormals(); if(i>=nn)i=nn-1;
1483 			     return (nn<=0) ? _ssgNormalUp:normals->get(i);}
getTexCoord(int i)1484   float *getTexCoord(int i){ int nc=getNumTexCoords(); if(i>=nc)i=nc-1;
1485                              return (nc<=0) ? _ssgTexCoord00:texcoords->get(i);}
getColour(int i)1486   float *getColour  (int i){ int nc=getNumColours(); if(i>=nc)i=nc-1;
1487 			     return (nc<=0) ? _ssgColourWhite:colours->get(i);}
1488 
1489 	ssgVtxArray *getAs_ssgVtxArray ();
1490 
1491   virtual ~ssgVtxTable (void) ;
1492 
1493   virtual const char *getTypeName(void) ;
1494   virtual void recalcBSphere () ;
1495   virtual void draw () ;
1496 
1497   virtual void isect_triangles ( sgSphere *s, sgMat4 m, int test_needed ) ;
1498   virtual void hot_triangles   ( sgVec3    s, sgMat4 m, int test_needed ) ;
1499   virtual void los_triangles   ( sgVec3    s, sgMat4 m, int test_needed ) ;
1500   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2);
1501   virtual int load ( FILE *fd ) ;
1502   virtual int save ( FILE *fd ) ;
1503 
1504 } ;
1505 
1506 
1507 class ssgTween : public ssgVtxTable
1508 {
1509   virtual void copy_from ( ssgTween *src, int clone_flags ) ;
1510   void init () ;
1511 protected:
1512 _SSG_PUBLIC:
1513 
1514   int curr_bank ;
1515 
1516   ssgVertexArray   *render_vertices  ;
1517   ssgNormalArray   *render_normals   ;
1518   ssgTexCoordArray *render_texcoords ;
1519   ssgColourArray   *render_colours   ;
1520 
1521   ulList *banked_vertices  ;
1522   ulList *banked_normals   ;
1523   ulList *banked_texcoords ;
1524   ulList *banked_colours   ;
1525 
1526 public:
1527   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1528 
1529   ssgTween () ;
1530   ssgTween ( GLenum ty ) ;
1531 
1532   virtual void setVertices  ( ssgVertexArray   *vl ) ;
1533   virtual void setNormals   ( ssgNormalArray   *nl ) ;
1534   virtual void setTexCoords ( ssgTexCoordArray *tl ) ;
1535   virtual void setColours   ( ssgColourArray   *cl ) ;
1536 
1537   virtual void recalcBSphere () ;
1538   virtual void draw () ;
1539   virtual void transform ( const sgMat4 m ) ;
1540 
1541   virtual const char *getTypeName(void) ;
1542   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2);
1543   virtual int load ( FILE *fd ) ;
1544   virtual int save ( FILE *fd ) ;
1545 
getNumBanks()1546   int getNumBanks () { return banked_vertices -> getNumEntities () ; }
1547 
1548   int  newBank ( ssgVertexArray   *vl, ssgNormalArray   *nl,
1549                  ssgTexCoordArray *tl, ssgColourArray   *cl ) ;
1550   int  newBank ( int newVertices , int newNormals,
1551                  int newTexCoords, int newColours ) ;
1552   void setBank ( int bank ) ;
1553 
1554   virtual ~ssgTween (void) ;
1555 } ;
1556 
1557 
1558 class ssgVtxArray : public ssgVtxTable
1559 {
1560 protected:
1561   ssgIndexArray      *indices;
1562 
1563   virtual void draw_geometry () ;
1564   virtual void copy_from ( ssgVtxArray *src, int clone_flags ) ;
1565 
1566 public:
1567   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1568   ssgVtxArray () ;
1569 
1570   ssgVtxArray ( GLenum ty, ssgVertexArray   *vl,
1571                            ssgNormalArray   *nl,
1572                            ssgTexCoordArray *tl,
1573                            ssgColourArray   *cl,
1574 			   ssgIndexArray    *il ) ;
1575 
1576   virtual void drawHighlight ( sgVec4 colour ) ;
1577   virtual void drawHighlight ( sgVec4 colour, int i ) ;
1578   virtual void pick ( int baseName ) ;
1579 
1580   void setIndices ( ssgIndexArray *il ) ;
addIndex(short i)1581 	void addIndex ( short i) { indices->add(i); }
1582 
getNumIndices()1583   int getNumIndices () { return indices -> getNum () ; }
1584 
1585   int getNumTriangles () ;
1586   void getTriangle ( int n, short *v1, short *v2, short *v3 ) ;
1587 
1588   int  getNumLines () ;
1589   void getLine ( int n, short *v1, short *v2 ) ;
1590 
getIndexList(void ** list)1591   void getIndexList ( void **list ) { *list = indices  -> get ( 0 ) ; }
1592 
getIndex(int i)1593   short *getIndex  (int i){ int ni=getNumIndices();if(i>=ni)i=ni-1;
1594                              return (ni<=0) ? &_ssgIndex0 : indices->get(i);}
1595 
1596 	void removeUnusedVertices();
1597   virtual ~ssgVtxArray (void) ;
1598 
1599   virtual const char *getTypeName(void) ;
1600 
1601   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1602   virtual int load ( FILE *fd ) ;
1603   virtual int save ( FILE *fd ) ;
1604 } ;
1605 
1606 
1607 // class ssgVtxInterleavedArray
1608 
1609 
1610 class ssgBranch : public ssgEntity
1611 {
1612   ssgKidList kids ;
1613 
1614 protected:
1615   virtual void copy_from ( ssgBranch *src, int clone_flags ) ;
1616 
1617 public:
1618   virtual void zeroSpareRecursive ();
1619 
1620   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1621   ssgBranch (void) ;
1622   virtual ~ssgBranch (void) ;
1623 
getNumKids(void)1624   virtual int getNumKids (void)   { return kids.getNumEntities() ; }
getKid(int n)1625   ssgEntity *getKid     ( int n ) { return kids.getEntity  ( n ) ; }
getNextKid(void)1626   ssgEntity *getNextKid (void)    { return kids.getNextEntity () ; }
searchForKid(ssgEntity * entity)1627   int        searchForKid ( ssgEntity *entity )
1628                                   { return kids.searchForEntity(entity); }
1629 
1630   void addKid        ( ssgEntity *entity ) ;
1631   void removeKid     ( int n ) ;
1632   void removeKid     ( ssgEntity *entity ) ;
1633   void removeAllKids (void) ;
1634   void replaceKid    ( int n, ssgEntity *new_entity ) ;
1635   void replaceKid    ( ssgEntity *old_entity, ssgEntity *new_entity ) ;
1636 
1637 	void mergeHNodes();
1638 
1639   virtual ssgEntity *getByName ( char *match ) ;
1640   virtual ssgEntity *getByPath ( char *path  ) ;
1641 
1642   virtual const char *getTypeName(void) ;
1643   virtual void cull          ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1644   virtual void isect         ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1645   virtual void hot           ( sgVec3     s, sgMat4 m, int test_needed ) ;
1646   virtual void los           ( sgVec3     s, sgMat4 m, int test_needed ) ;
1647   virtual void print         ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1648   virtual void getStats ( int *num_branches, int *num_leaves, int *num_tris, int *num_vertices ) ;
1649   virtual int load ( FILE *fd ) ;
1650   virtual int save ( FILE *fd ) ;
1651   virtual void recalcBSphere () ;
1652 } ;
1653 
1654 
1655 #define SSGTWEEN_STOP_AT_END    0
1656 #define SSGTWEEN_REPEAT         1
1657 
1658 class ssgTweenController : public ssgBranch
1659 {
1660   float curr_bank ;
1661   int   mode ;  /* STOP_AT_END or REPEAT */
1662 
1663 protected:
1664 
1665   virtual void copy_from ( ssgTweenController *src, int clone_flags ) ;
1666 
1667 public:
1668 
1669   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1670   ssgTweenController (void) ;
1671   virtual ~ssgTweenController (void) ;
1672 
setMode(int _mode)1673   void  setMode ( int _mode ) { mode = _mode ; }
getMode()1674   int   getMode ()            { return mode ; }
1675 
selectBank(float f)1676   void  selectBank ( float f ) { curr_bank = f ; }
getCurrBank()1677   float getCurrBank () { return curr_bank ; }
1678 
1679   virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1680   virtual const char *getTypeName(void) ;
1681   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
1682   virtual int load ( FILE *fd ) ;
1683   virtual int save ( FILE *fd ) ;
1684 } ;
1685 
1686 
1687 
1688 class ssgInvisible : public ssgBranch
1689 {
1690 protected:
1691 
1692   virtual void copy_from ( ssgInvisible *src, int clone_flags ) ;
1693 
1694 public:
1695 
1696   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1697   ssgInvisible (void) ;
1698   virtual ~ssgInvisible (void) ;
1699 
1700   virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1701   virtual int load ( FILE *fd ) ;
1702   virtual int save ( FILE *fd ) ;
1703 } ;
1704 
1705 
1706 
1707 class ssgSelector : public ssgBranch
1708 {
1709   unsigned char* selection ;
1710 
1711 protected:
1712   int max_kids ;
1713 
1714   virtual void copy_from ( ssgSelector *src, int clone_flags ) ;
1715 
1716 public:
1717 
1718   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1719   ssgSelector ( int max_kids = 32 ) ;
1720   virtual ~ssgSelector (void) ;
1721 
selectStep(unsigned int s)1722   void selectStep ( unsigned int s )
1723   {
1724     memset ( selection, 0, max_kids ) ;
1725     selection [s] = 1 ;
1726   }
1727 
select(unsigned int s)1728   void select ( unsigned int s )
1729   {
1730     for ( int i=0; i<max_kids && i<32; i++ )
1731       selection [i] = ( (1<<i) & s ) != 0 ;
1732   }
1733 
getSelect()1734   unsigned int getSelect ()
1735   {
1736     unsigned int s = 0 ;
1737     for ( int i=0; i<max_kids && i<32; i++ )
1738       if ( selection [i] ) s |= (1<<i) ;
1739     return s ;
1740   }
1741 
isSelected(unsigned int i)1742   int isSelected ( unsigned int i ) const
1743   {
1744     return (i<(unsigned int)max_kids) ? selection [ i ] : FALSE ;
1745   }
1746 
getFirstSelection()1747   int getFirstSelection ()
1748   {
1749     int res ;
1750 
1751     for ( res = 0 ; res < max_kids && ! selection[res] ; res++ )
1752       /* Look for first selection */ ;
1753 
1754     return ( res < max_kids ) ? res : -1 ;
1755   }
1756 
getFirstSelectedKid()1757   ssgEntity *getFirstSelectedKid ()
1758   {
1759     int k = getFirstSelection () ;
1760     return (k >= 0) ? getKid ( k ) : NULL ;
1761   }
1762 
getMaxKids(void)1763   int getMaxKids (void) const { return max_kids ; }
1764 
1765   virtual const char *getTypeName(void) ;
1766   virtual int load ( FILE *fd ) ;
1767   virtual int save ( FILE *fd ) ;
1768   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1769   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1770   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1771   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1772 } ;
1773 
1774 
1775 class ssgRangeSelector : public ssgSelector
1776 {
1777   int additive ;
1778   float rng_list [ 33 ] ;
1779 
1780 protected:
1781   virtual void copy_from ( ssgRangeSelector *src, int clone_flags ) ;
1782 public:
1783 
1784   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1785   ssgRangeSelector (void) ;
1786   virtual ~ssgRangeSelector (void) ;
1787 
setRanges(float * ranges,unsigned int nranges)1788   void setRanges ( float *ranges, unsigned int nranges )
1789   {
1790     for ( unsigned int i = 0 ; i < 33 ; i++ )
1791       if ( i < nranges )
1792         rng_list [ i ] = ranges [ i ] ;
1793       else
1794         rng_list [ i ] = SG_MAX ;
1795   }
1796 
setRange(unsigned int which,float range)1797   void setRange ( unsigned int which, float range )
1798   {
1799     if ( which < 33 )
1800       rng_list [ which ] = range ;
1801   }
1802 
getRanges()1803   float *getRanges ()
1804   {
1805     return rng_list ;
1806   }
1807 
getRange(unsigned int which)1808   float getRange ( unsigned int which )
1809   {
1810     return ( which < 33 ) ? rng_list[which] : SG_MAX ;
1811   }
1812 
setAdditive(int add)1813   void setAdditive ( int add ) { additive = add ; }
isAdditive()1814   int  isAdditive  () { return additive ; }
1815 
1816   virtual const char *getTypeName(void) ;
1817   virtual int load ( FILE *fd ) ;
1818   virtual int save ( FILE *fd ) ;
1819   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1820   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1821   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1822   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1823 } ;
1824 
1825 
1826 enum ssgAnimEnum
1827 {
1828   SSG_ANIM_START,
1829   SSG_ANIM_STOP,
1830   SSG_ANIM_PAUSE,
1831   SSG_ANIM_RESUME
1832 } ;
1833 
1834 enum ssgAnimDirection
1835 {
1836   SSG_ANIM_SWING,
1837   SSG_ANIM_ONESHOT,
1838   SSG_ANIM_SHUTTLE
1839 } ;
1840 
1841 enum ssgAnimTimeMode
1842 {
1843     SSG_ANIM_FRAME,
1844     SSG_ANIM_CLOCK
1845 };
1846 
1847 
1848 class ssgTimedSelector : public ssgSelector
1849 {
1850 _SSG_PUBLIC:
1851   ssgAnimEnum      running ;
1852   ssgAnimDirection mode    ;
1853 
1854   double  start_time ;
1855   double  pause_time ;
1856   double  loop_time  ;
1857   float  *times      ;
1858   int   curr  ;
1859   int   start ;
1860   int   end   ;
1861 
1862 protected:
1863   ssgAnimTimeMode time_mode ;
1864   static ulClock ck ;
1865 
compute_loop_time()1866   void compute_loop_time ()
1867   {
1868     loop_time = 0 ;
1869 
1870     for ( int k = start ; k <= end ; k++ )
1871       loop_time += times [ k ] ;
1872   }
1873 
1874   virtual void copy_from ( ssgTimedSelector *src, int clone_flags ) ;
1875 
get_time()1876   double get_time() const
1877   {
1878     if (time_mode == SSG_ANIM_FRAME)
1879       return (double) ssgGetFrameCounter() ;
1880     else
1881       return ck.update(), ck.getAbsTime();
1882   }
1883 public:
1884 
1885   virtual ssgBase *clone ( int clone_flags = 0 ) ;
1886   ssgTimedSelector ( int max_kids = 32 ) ;
1887   virtual ~ssgTimedSelector (void) ;
1888 
1889   virtual const char *getTypeName(void) ;
1890 
1891   int getStep () ;
1892 
getTimeMode()1893   ssgAnimTimeMode getTimeMode() const { return time_mode; }
1894 
1895   float getDuration ( int i = 0 ) { return times [ i ] ; }
1896 
1897   void setDuration ( float ti, int i = -1, ssgAnimTimeMode m = SSG_ANIM_FRAME )
1898   {
1899     time_mode = m;
1900     if ( i >= 0 && i < max_kids )
1901       times [ i ] = ti ;
1902     else
1903     for ( int j = 0 ; j < max_kids ; j++ )
1904       times [ j ] = ti ;
1905 
1906     compute_loop_time () ;
1907   }
1908 
control(ssgAnimEnum m)1909   void control ( ssgAnimEnum m )
1910   {
1911     compute_loop_time () ;
1912 
1913     if ( m == SSG_ANIM_PAUSE )
1914     {
1915       pause_time = get_time() ;
1916       curr = getStep () ;
1917     }
1918     else
1919     if ( m == SSG_ANIM_RESUME )
1920     {
1921       start_time += get_time () - pause_time ;
1922 
1923       if ( running != SSG_ANIM_STOP )
1924         m = SSG_ANIM_START ;
1925     }
1926     else
1927     if ( m == SSG_ANIM_START )
1928     {
1929       start_time = get_time () ;
1930       curr = getStep () ;
1931     }
1932 
1933     running = m ;
1934   }
1935 
getControl()1936   ssgAnimEnum getControl () { return running ; }
1937 
setMode(ssgAnimDirection m)1938   void setMode ( ssgAnimDirection m ) { mode = m ; }
getMode()1939   ssgAnimDirection getMode () { return mode ; }
1940 
setLimits(int st,int en)1941   void setLimits ( int st, int en )
1942   {
1943     curr  = st ;
1944     start = st ;
1945     end   = en ;
1946     compute_loop_time () ;
1947   }
1948 
getLimits(int * st,int * en)1949   void getLimits ( int *st, int *en )
1950   {
1951     if ( st != NULL ) *st = start ;
1952     if ( en != NULL ) *en = end ;
1953   }
1954 
1955   virtual int load ( FILE *fd ) ;
1956   virtual int save ( FILE *fd ) ;
1957   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
1958   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) ;
1959   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1960   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) ;
1961 } ;
1962 
1963 
1964 class ssgBaseTransform : public ssgBranch
1965 {
1966 protected:
1967 
1968   sgMat4 transform ;
1969   sgMat4 last_transform ;
1970   int    last_updated ;
1971   int    first_time ;
1972   virtual void copy_from ( ssgBaseTransform *src, int clone_flags ) ;
1973 public:
1974 
1975   ssgBaseTransform (void) ;
1976   virtual ~ssgBaseTransform (void) ;
1977 
firsttime()1978   void firsttime ()
1979   {
1980     if ( first_time )
1981     {
1982       first_time = FALSE ;
1983       updateTransform () ;
1984     }
1985   }
1986 
updateTransform()1987   void updateTransform ()
1988   {
1989     sgCopyMat4 ( last_transform, transform ) ;
1990     last_updated = ssgGetFrameCounter () ;
1991   }
1992 
getLastTransform(sgMat4 xform)1993   void getLastTransform ( sgMat4 xform )
1994   {
1995     /*
1996       If the transform was not updated this - or last frame
1997       then we need to equate the two transforms.
1998     */
1999 
2000     if ( last_updated < ssgGetFrameCounter () - 1 )
2001       updateTransform () ;
2002 
2003     sgCopyMat4 ( xform, last_transform ) ;
2004   }
2005 
getTransform(sgMat4 xform)2006   void getTransform ( sgMat4 xform )
2007   {
2008     sgCopyMat4 ( xform, transform ) ;
2009   }
2010 
2011   virtual void setTransform ( sgVec3 xyz ) = 0 ;
2012   virtual void setTransform ( sgCoord *xform ) = 0 ;
2013   virtual void setTransform ( sgCoord *xform, float sx, float sy, float sz )=0;
2014   virtual void setTransform ( sgMat4 xform ) = 0 ;
2015 
2016   virtual int load ( FILE *fd ) ;
2017   virtual int save ( FILE *fd ) ;
2018 
2019   virtual const char *getTypeName(void) ;
2020   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
2021 } ;
2022 
2023 
2024 class ssgTransform : public ssgBaseTransform
2025 {
2026 protected:
2027   virtual void copy_from ( ssgTransform *src, int clone_flags ) ;
2028 public:
2029 
2030   virtual ssgBase *clone ( int clone_flags = 0 ) ;
2031   ssgTransform (void) ;
2032   ssgTransform ( sgCoord *c ) ;
2033   virtual ~ssgTransform (void) ;
2034 
2035   virtual void setTransform ( sgVec3 xyz ) ;
2036   virtual void setTransform ( sgCoord *xform ) ;
2037   virtual void setTransform ( sgCoord *xform, float sx, float sy, float sz ) ;
2038   virtual void setTransform ( sgMat4 xform ) ;
2039 
2040   virtual void getNetTransform     ( sgMat4 xform ) ;
2041   virtual void getLastNetTransform ( sgMat4 xform ) ;
2042 
2043   virtual const char *getTypeName(void) ;
2044   virtual int load ( FILE *fd ) ;
2045   virtual int save ( FILE *fd ) ;
2046   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
2047   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) ;
2048   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) ;
2049   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) ;
2050   virtual void recalcBSphere () ;
2051 } ;
2052 
2053 class ssgAnimTransform  : public ssgTransform
2054 {
2055   float curr_bank ;
2056   int   mode ;  /* SSGTWEEN_STOP_AT_END or SSGTWEEN_REPEAT */
2057   class ssgTransformArray transformations;
2058 
2059 protected:
2060 
2061   virtual void copy_from ( ssgAnimTransform *src, int clone_flags ) ;
2062 
2063 public:
2064 
setNum(unsigned int n)2065   void setNum ( unsigned int n ) { transformations.setNum( n ); }
setATransform(sgMat4 thing,unsigned int n)2066   void setATransform ( sgMat4 thing, unsigned int n ) { transformations.raw_set ( (char *) thing, n ) ; } ;
2067 
2068 
2069   virtual ssgBase *clone ( int clone_flags = 0 ) ;
2070   ssgAnimTransform (void) ;
2071   virtual ~ssgAnimTransform (void) ;
2072 
setMode(int _mode)2073   void  setMode ( int _mode ) { mode = _mode ; }
getMode()2074   int   getMode ()            { return mode ; }
2075 
selectBank(float f)2076   void  selectBank ( float f ) { curr_bank = f ; }
getCurrBank()2077   float getCurrBank () { return curr_bank ; }
2078 
2079   virtual void cull ( sgFrustum *f, sgMat4 m, int test_needed ) ;
2080   virtual const char *getTypeName(void) ;
2081   virtual void print ( FILE *fd = stderr, char *indent = "", int how_much = 2 ) ;
2082   virtual int load ( FILE *fd ) ;
2083   virtual int save ( FILE *fd ) ;
2084 } ;
2085 
2086 
2087 class ssgAxisTransform : public ssgTransform
2088 {
2089   sgVec3 rotation_axis   ;
2090   sgVec3 rotation_center ;
2091   float  limit_low  ;
2092   float  limit_high ;
2093 protected:
2094   virtual void copy_from ( ssgAxisTransform *src, int clone_flags ) ;
2095 public:
2096 
2097   virtual ssgBase *clone ( int clone_flags = 0 ) ;
2098   ssgAxisTransform (void) ;
2099   ssgAxisTransform ( sgVec3 axis, sgVec3 center ) ;
2100   virtual ~ssgAxisTransform (void) ;
2101 
2102   virtual void  setAxis     ( sgVec3 axis   ) ;
2103   virtual float *getAxis    () ;
2104   virtual void  setCenter   ( sgVec3 center ) ;
2105   virtual float *getCenter  () ;
2106   virtual void  setRotation ( float rot ) ;
2107 
2108   virtual void setRotationLimits ( float low, float high ) ;
2109   virtual void setLinearRotation ( float rot ) ;
2110 
2111   virtual const char *getTypeName(void) ;
2112   virtual int load ( FILE *fd ) ;
2113   virtual int save ( FILE *fd ) ;
2114 };
2115 
2116 
2117 class ssgTexTrans : public ssgBaseTransform
2118 {
2119 protected:
2120   virtual void copy_from ( ssgTexTrans *src, int clone_flags ) ;
2121 public:
2122 
2123   virtual ssgBase *clone ( int clone_flags = 0 ) ;
2124   ssgTexTrans (void) ;
2125   ssgTexTrans ( sgCoord *c ) ;
2126   virtual ~ssgTexTrans (void) ;
2127 
2128   virtual void setTransform ( sgVec3 xyz ) ;
2129   virtual void setTransform ( sgCoord *xform ) ;
2130   virtual void setTransform ( sgCoord *xform, float sx, float sy, float sz ) ;
2131   virtual void setTransform ( sgMat4 xform ) ;
2132 
2133   virtual const char *getTypeName(void) ;
2134   virtual int load ( FILE *fd ) ;
2135   virtual int save ( FILE *fd ) ;
2136   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
2137 } ;
2138 
2139 
2140 class ssgCutout : public ssgBranch
2141 {
2142   int point_rotate ;
2143 protected:
2144   virtual void copy_from ( ssgCutout *src, int clone_flags ) ;
2145 public:
2146 
2147   virtual ssgBase *clone ( int clone_flags = 0 ) ;
2148   ssgCutout (int pntrot=FALSE) ;
2149   virtual ~ssgCutout (void) ;
2150 
isPointRotate(void)2151   int isPointRotate (void) { return point_rotate ; }
2152 
2153   virtual const char *getTypeName(void) ;
2154   virtual int load ( FILE *fd ) ;
2155   virtual int save ( FILE *fd ) ;
2156   virtual void cull  ( sgFrustum *f, sgMat4 m, int test_needed ) ;
2157   virtual void isect ( sgSphere  *s, sgMat4 m, int test_needed ) ;
2158   virtual void hot   ( sgVec3     s, sgMat4 m, int test_needed ) ;
2159   virtual void los   ( sgVec3     s, sgMat4 m, int test_needed ) ;
2160 } ;
2161 
2162 
2163 class ssgRoot : public ssgBranch
2164 {
2165 protected:
2166   virtual void copy_from ( ssgRoot *src, int clone_flags ) ;
2167 public:
2168 
2169   virtual ssgBase *clone ( int clone_flags = 0 ) ;
2170   ssgRoot (void) ;
2171   virtual ~ssgRoot (void) ;
2172   virtual const char *getTypeName(void) ;
2173   virtual int load ( FILE *fd ) ;
2174   virtual int save ( FILE *fd ) ;
2175 } ;
2176 
2177 
2178 class ssgLight
2179 {
2180   int id ;
2181   int is_headlight ;
2182   int is_turned_on ;
2183 
2184   sgVec4 ambient ;
2185   sgVec4 diffuse ;
2186   sgVec4 specular ;
2187 
2188   sgVec4 position ;
2189 
2190   sgVec3 direction ;
2191   float  exponent ;
2192   float  cutoff ;
2193   sgVec3 atten ;
2194 
2195 public:
2196 
ssgLight()2197   ssgLight ()
2198   {
2199     id = 0 ;
2200     is_turned_on = FALSE ;
2201     is_headlight = FALSE ;
2202     sgSetVec4 ( position, 0.0f, 0.0f, 1.0f, 0.0f ) ;
2203     sgSetVec4 ( ambient , 0.2f, 0.2f, 0.2f, 1.0f ) ;
2204     sgSetVec4 ( diffuse , 1.0f, 1.0f, 1.0f, 1.0f ) ;
2205     sgSetVec4 ( specular, 1.0f, 1.0f, 1.0f, 1.0f ) ;
2206     sgSetVec3 ( direction, 0.0f, 0.0f, -1.0f ) ;
2207     exponent = 1.0f;
2208     cutoff   = 90.0f;
2209     sgSetVec3 ( atten, 1.0f, 0.0f, 0.0f ) ;
2210   }
2211 
setID(int i)2212   void setID ( int i ) { id = i ; }
isOn()2213   int  isOn () { return is_turned_on  ; }
on()2214   void on   () { is_turned_on = TRUE  ; }
off()2215   void off  () { is_turned_on = FALSE ; }
2216 
setPosition(const sgVec3 pos)2217   void setPosition ( const sgVec3 pos ) { sgCopyVec3 ( position, pos ) ; }
getPosition(sgVec3 pos)2218   void getPosition ( sgVec3 pos )       { sgCopyVec3 ( pos, position ) ; }
setPosition(float x,float y,float z)2219   void setPosition ( float x, float y, float z ) { sgSetVec3 ( position, x, y, z ) ; }
2220 
setColour(GLenum which,const sgVec4 col)2221   void setColour   ( GLenum which, const sgVec4 col )
2222   {
2223     switch ( which )
2224     {
2225       case GL_AMBIENT  : sgCopyVec4 ( ambient , col ) ; break ;
2226       case GL_DIFFUSE  : sgCopyVec4 ( diffuse , col ) ; break ;
2227       case GL_SPECULAR : sgCopyVec4 ( specular, col ) ; break ;
2228       default : break ;
2229     }
2230   }
2231 
getColour(GLenum which,sgVec4 col)2232   void getColour   ( GLenum which, sgVec4 col )
2233   {
2234     switch ( which )
2235     {
2236       case GL_AMBIENT  : sgCopyVec4 ( col , ambient ) ; break ;
2237       case GL_DIFFUSE  : sgCopyVec4 ( col , diffuse ) ; break ;
2238       case GL_SPECULAR : sgCopyVec4 ( col, specular ) ; break ;
2239       default : break ;
2240     }
2241   }
2242 
setColour(GLenum which,float r,float g,float b)2243   void setColour   ( GLenum which, float r, float g, float b )
2244   {
2245     sgVec4 colour = { r, g, b, 1.0f };
2246     setColour(which, colour);
2247   }
2248 
setHeadlight(int head)2249   void setHeadlight ( int head ) { is_headlight = head ; }
isHeadlight()2250   int  isHeadlight () { return is_headlight ; }
2251 
setSpotlight(int spot)2252   void setSpotlight ( int spot ) { position[3] = ( spot ? 1.0f : 0.0f ) ; }
isSpotlight()2253   int  isSpotlight () { return position[3] != 0.0f; }
2254 
setSpotDirection(const sgVec3 dir)2255   void setSpotDirection ( const sgVec3 dir ) { sgCopyVec3 ( direction, dir ) ; }
getSpotDirection(sgVec3 dir)2256   void getSpotDirection ( sgVec3 dir )       { sgCopyVec3 ( dir, direction ) ; }
setSpotDirection(float x,float y,float z)2257   void setSpotDirection ( float x, float y, float z ) { sgSetVec3 ( direction, x, y, z ) ; }
2258 
2259   void setSpotDiffusion ( float exp, float cut = 90.0f )
2260   {
2261     exponent = exp;
2262     cutoff   = cut;
2263   }
2264 
2265   void getSpotDiffusion ( float *exp, float *cut = 0 )
2266   {
2267     if (exp != 0) *exp = exponent;
2268     if (cut != 0) *cut = cutoff;
2269   }
2270 
setSpotAttenuation(float constant,float linear,float quadratic)2271   void setSpotAttenuation ( float constant, float linear, float quadratic )
2272   {
2273     sgSetVec3( atten, constant, linear, quadratic );
2274   }
2275 
getSpotAttenuation(float * constant,float * linear,float * quadratic)2276   void getSpotAttenuation ( float *constant, float *linear, float *quadratic )
2277   {
2278     if (constant  != 0) *constant  = atten[0];
2279     if (linear    != 0) *linear    = atten[1];
2280     if (quadratic != 0) *quadratic = atten[2];
2281   }
2282 
setup()2283   void setup ()
2284   {
2285     if ( is_turned_on )
2286     {
2287       glEnable  ( (GLenum)(GL_LIGHT0+id) ) ;
2288       glLightfv ( (GLenum)(GL_LIGHT0+id), GL_AMBIENT , ambient  ) ;
2289       glLightfv ( (GLenum)(GL_LIGHT0+id), GL_DIFFUSE , diffuse  ) ;
2290       glLightfv ( (GLenum)(GL_LIGHT0+id), GL_SPECULAR, specular ) ;
2291       glLightfv ( (GLenum)(GL_LIGHT0+id), GL_POSITION, position ) ;
2292       if ( isSpotlight() ) {
2293 	 glLightfv ( (GLenum)(GL_LIGHT0+id), GL_SPOT_DIRECTION, direction ) ;
2294 	 glLightf  ( (GLenum)(GL_LIGHT0+id), GL_SPOT_EXPONENT,  exponent  ) ;
2295 	 glLightf  ( (GLenum)(GL_LIGHT0+id), GL_SPOT_CUTOFF,    cutoff    ) ;
2296 	 glLightf  ( (GLenum)(GL_LIGHT0+id), GL_CONSTANT_ATTENUATION,  atten[0] );
2297 	 glLightf  ( (GLenum)(GL_LIGHT0+id), GL_LINEAR_ATTENUATION,    atten[1] );
2298 	 glLightf  ( (GLenum)(GL_LIGHT0+id), GL_QUADRATIC_ATTENUATION, atten[2] );
2299       }
2300     }
2301     else
2302       glDisable ( (GLenum)(GL_LIGHT0+id) ) ;
2303   }
2304 
2305 } ;
2306 
2307 class ssgHit
2308 {
2309 _SSG_PUBLIC:
2310 
2311   int num_entries ;
2312   ssgEntity *path [ SSG_MAXPATH ] ;
2313 
2314 public:
2315   ssgLeaf *leaf ;
2316   int      triangle ;
2317   sgVec4   plane ;
2318   sgMat4   matrix ;
2319 
ssgHit()2320   ssgHit ()
2321   {
2322     leaf = NULL ;
2323     init () ;
2324   } ;
2325 
init()2326   void init () { num_entries = 0 ; }
2327 
addPath(ssgEntity * e)2328   void addPath ( ssgEntity *e )
2329   {
2330     if ( num_entries < SSG_MAXPATH )
2331       path [ num_entries++ ] = e ;
2332   }
2333 
getNumPathEntries()2334   int getNumPathEntries () { return num_entries ; }
2335 
getPathEntry(int i)2336   ssgEntity *getPathEntry ( int i )
2337   {
2338     return ( i >= 0 && i < num_entries ) ? path[i] : (ssgEntity *) NULL ;
2339   }
2340 } ;
2341 
2342 class ssgContext
2343 {
2344  protected:
2345 
2346   int enabledClipPlanes ;
2347   sgVec4 clipPlane [ 6 ] ;
2348   ssgSimpleState *currentState ;
2349   ssgSimpleState *basicState   ;
2350   sgFrustum      *frustum      ;
2351 
2352   sgMat4    cameraMatrix       ;
2353   int       cullFace           ;
2354   int       ovTexture          ;
2355   int       ovCullface         ;
2356   ssgState *ovState            ;
2357 
2358 public:
2359 
2360 
2361    ssgContext () ;
2362   ~ssgContext () ;
2363 
2364   void forceBasicState () ;
2365 
2366   void applyClipPlanes () ;
2367   void removeClipPlanes () ;
2368 
2369   void makeCurrent () ;
2370   int    isCurrent () ;
2371 
clrClipPlane(int i)2372   void clrClipPlane ( int i )
2373   {
2374     if ( i >= 0 && i < 6 )
2375       enabledClipPlanes &= ~(1<<i) ;
2376   }
2377 
setClipPlane(int i,sgVec4 plane)2378   void setClipPlane ( int i, sgVec4 plane )
2379   {
2380     if ( i >= 0 && i < 6 )
2381     {
2382       sgCopyVec4 ( clipPlane [ i ], plane ) ;
2383       enabledClipPlanes |= (1<<i) ;
2384     }
2385   }
2386 
isSetClipPlane(int i)2387   int  isSetClipPlane ( int i ) { return enabledClipPlanes & (1<<i) ; }
getClipPlane(int i)2388   float *getClipPlane ( int i )
2389   {
2390     return ((i<0)||(i>=6)) ? NULL : clipPlane [i] ;
2391   }
2392 
2393   void overrideState     ( ssgState *s ) ;
2394   void overrideTexture   ( int on_off ) ;
2395   void overrideCullface  ( int on_off ) ;
2396 
setCullface(int on_off)2397   void setCullface       ( int on_off )
2398   {
2399     if ( cullFace == on_off || ovCullface )
2400       return ;
2401 
2402     cullFace = on_off ;
2403 
2404     if ( cullFace ) glEnable  ( GL_CULL_FACE ) ;
2405                else glDisable ( GL_CULL_FACE ) ;
2406   }
2407 
overriddenState()2408   ssgState *overriddenState () { return ovState ; }
stateOverridden()2409   int  stateOverridden    () { return ovState != NULL ; }
textureOverridden()2410   int  textureOverridden  () { return ovTexture  ; }
cullfaceOverridden()2411   int  cullfaceOverridden () { return ovCullface ; }
cullfaceIsEnabled()2412   int  cullfaceIsEnabled  () { return cullFace   ; }
2413 
getFrustum()2414   sgFrustum *getFrustum () { return frustum ; }
2415 
2416   // make a perspective projection
2417   void setFrustum ( float l, float r, float b, float t, float n, float f ) ;
2418 
2419   // make an orthographic projection
2420   void setOrtho   ( float l, float r, float b, float t, float n, float f ) ;
2421 
2422   void getNearFar ( float *n, float *f ) ;
2423   void getFOV     ( float *w, float *h ) ;
2424   void getOrtho   ( float *w, float *h ) ;
2425 
2426   void setNearFar ( float  n, float  f ) ;
2427   void setOrtho   ( float  w, float  h ) ; // make orthographic
2428   void setFOV     ( float  w, float  h ) ; // make perspective
2429 
isOrtho()2430   int  isOrtho () { return frustum -> isOrtho () ; } // is orthographic
2431 
getState()2432   ssgSimpleState *getState () { return currentState ; }
2433   void cull ( ssgBranch *r ) ;
2434 
2435   void getCameraPosition ( sgVec3   pos ) ;
2436   void setCamera ( sgMat4 mat ) ;
2437   void setCamera ( const sgCoord *coord ) ;
2438   void setCameraLookAt ( const sgVec3 eye, const sgVec3 center, const sgVec3 up ) ;
2439   void setCameraLookAt ( const sgVec3 eye, const sgVec3 center ) ;
2440 
2441   void loadProjectionMatrix () ;
2442   void loadModelviewMatrix  () ;
2443 
2444   void getProjectionMatrix  ( sgMat4 dst ) ;
2445   void getModelviewMatrix   ( sgMat4 dst ) ;
2446 
2447   void pushProjectionMatrix () ;
2448   void pushProjectionMatrix ( sgFrustum *f ) ;
2449   void loadModelviewMatrix  ( sgMat4 mat ) ;
2450 
2451 } ;
2452 
2453 
2454 
2455 /* Compatibility inlines for pre-ssgContext applications */
2456 
2457 extern ssgContext *_ssgCurrentContext ;
2458 
ssgGetCurrentContext()2459 inline ssgContext *ssgGetCurrentContext () { return _ssgCurrentContext ; }
2460 
ssgGetCameraPosition(sgVec3 pos)2461 inline void ssgGetCameraPosition ( sgVec3 pos )
2462 {
2463   _ssgCurrentContext -> getCameraPosition ( pos ) ;
2464 }
2465 
ssgOverrideState(ssgState * s)2466 inline void ssgOverrideState ( ssgState *s )
2467 {
2468   _ssgCurrentContext->overrideState ( s ) ;
2469 }
2470 
ssgOverrideTexture(int on_off)2471 inline void ssgOverrideTexture ( int on_off )
2472 {
2473   _ssgCurrentContext->overrideTexture ( on_off ) ;
2474 }
2475 
ssgOverrideCullface(int on_off)2476 inline void ssgOverrideCullface ( int on_off )
2477 {
2478   _ssgCurrentContext->overrideCullface ( on_off ) ;
2479 }
2480 
ssgGetNearFar(float * n,float * f)2481 inline void ssgGetNearFar ( float *n, float *f )
2482 {
2483   _ssgCurrentContext->getNearFar ( n, f ) ;
2484 }
2485 
ssgGetFOV(float * w,float * h)2486 inline void ssgGetFOV ( float *w, float *h )
2487 {
2488   _ssgCurrentContext->getFOV ( w, h ) ;
2489 }
2490 
ssgGetOrtho(float * w,float * h)2491 inline void ssgGetOrtho ( float *w, float *h )
2492 {
2493   _ssgCurrentContext->getOrtho ( w, h ) ;
2494 }
2495 
ssgSetFrustum(float l,float r,float b,float t,float n,float f)2496 inline void ssgSetFrustum ( float l, float r, float b, float t, float n, float f )
2497 {
2498   _ssgCurrentContext->setFrustum ( l, r, b, t, n, f ) ;
2499 }
2500 
ssgSetOrtho(float l,float r,float b,float t,float n,float f)2501 inline void ssgSetOrtho ( float l, float r, float b, float t, float n, float f )
2502 {
2503   _ssgCurrentContext->setOrtho ( l, r, b, t, n, f ) ;
2504 }
2505 
ssgSetFOV(float w,float h)2506 inline void ssgSetFOV ( float w, float h )
2507 {
2508   _ssgCurrentContext->setFOV ( w, h ) ;
2509 }
2510 
ssgSetOrtho(float w,float h)2511 inline void ssgSetOrtho ( float w, float h )
2512 {
2513   _ssgCurrentContext->setOrtho ( w, h ) ;
2514 }
2515 
ssgSetNearFar(float n,float f)2516 inline void ssgSetNearFar ( float n, float f )
2517 {
2518   _ssgCurrentContext->setNearFar ( n, f ) ;
2519 }
2520 
ssgSetCamera(sgMat4 mat)2521 inline void ssgSetCamera ( sgMat4 mat )
2522 {
2523   _ssgCurrentContext-> setCamera ( mat ) ;
2524 }
2525 
ssgSetCamera(sgCoord * coord)2526 inline void ssgSetCamera ( sgCoord *coord )
2527 {
2528   _ssgCurrentContext-> setCamera ( coord ) ;
2529 }
2530 
ssgSetCameraLookAt(const sgVec3 eye,const sgVec3 center,const sgVec3 up)2531 inline void ssgSetCameraLookAt ( const sgVec3 eye, const sgVec3 center, const sgVec3 up )
2532 {
2533   _ssgCurrentContext-> setCameraLookAt ( eye, center, up ) ;
2534 }
2535 
ssgSetCameraLookAt(const sgVec3 eye,const sgVec3 center)2536 inline void ssgSetCameraLookAt ( const sgVec3 eye, const sgVec3 center )
2537 {
2538   _ssgCurrentContext-> setCameraLookAt ( eye, center ) ;
2539 }
2540 
ssgLoadProjectionMatrix()2541 inline void ssgLoadProjectionMatrix ()
2542 {
2543   _ssgCurrentContext->loadProjectionMatrix () ;
2544 }
2545 
ssgLoadProjectionMatrix(sgFrustum * f)2546 inline void ssgLoadProjectionMatrix ( sgFrustum *f )
2547 {
2548   glLoadIdentity () ;
2549   _ssgCurrentContext->pushProjectionMatrix ( f ) ;
2550 }
2551 
ssgGetProjectionMatrix(sgMat4 dst)2552 inline void ssgGetProjectionMatrix ( sgMat4 dst )
2553 {
2554   _ssgCurrentContext->getProjectionMatrix ( dst ) ;
2555 }
2556 
ssgGetModelviewMatrix(sgMat4 dst)2557 inline void ssgGetModelviewMatrix ( sgMat4 dst )
2558 {
2559   _ssgCurrentContext->getModelviewMatrix ( dst ) ;
2560 }
2561 
ssgLoadModelviewMatrix()2562 inline void ssgLoadModelviewMatrix ()
2563 {
2564   _ssgCurrentContext->loadModelviewMatrix () ;
2565 }
2566 
ssgLoadModelviewMatrix(sgMat4 mat)2567 inline void ssgLoadModelviewMatrix ( sgMat4 mat )
2568 {
2569   _ssgCurrentContext->loadModelviewMatrix ( mat ) ;
2570 }
2571 
ssgForceBasicState()2572 inline void ssgForceBasicState ()
2573 {
2574   _ssgCurrentContext -> forceBasicState () ;
2575 }
2576 
ssgGetFrustum()2577 inline  sgFrustum *ssgGetFrustum ()
2578 {
2579   return _ssgCurrentContext -> getFrustum() ;
2580 }
2581 
2582 void ssgInit () ;
2583 
2584 void ssgCullAndDraw ( ssgBranch *root ) ;
2585 void ssgCullAndPick ( ssgBranch *root, sgVec2 botleft, sgVec2 topright ) ;
2586 int  ssgIsect       ( ssgBranch *root, sgSphere*s,sgMat4 m, ssgHit **results ) ;
2587 int  ssgHOT         ( ssgBranch *root, sgVec3  s, sgMat4 m, ssgHit **results ) ;
2588 int  ssgLOS         ( ssgBranch *root, sgVec3  s, sgMat4 m, ssgHit **results ) ;
2589 
2590 /* Load/Save functions */
2591 
2592 enum {
2593 	SSG_MD2_STAND,
2594 	SSG_MD2_RUN,
2595 	SSG_MD2_ATTACK,
2596 	SSG_MD2_PAIN_1,
2597 	SSG_MD2_PAIN_2,
2598 	SSG_MD2_PAIN_3,
2599 	SSG_MD2_JUMP,
2600 	SSG_MD2_FLIPOFF,
2601 	SSG_MD2_SALUTE,
2602 	SSG_MD2_TAUNT,
2603 	SSG_MD2_WAVE,
2604 	SSG_MD2_POINT,
2605 	SSG_MD2_CROUCH_STAND,
2606 	SSG_MD2_CROUCH_WALK,
2607 	SSG_MD2_CROUCH_PAIN,
2608 	SSG_MD2_CROUCH_DEATH,
2609 	SSG_MD2_DEATH_1,
2610 	SSG_MD2_DEATH_2,
2611 	SSG_MD2_DEATH_3,
2612 	SSG_MD2_ALL,
2613 	SSG_MD2_POSE
2614 };
2615 
2616 class ssgLoaderOptions
2617 {
2618   //NOTES: we could add more later
2619   //...model scale factor...
2620   //...create normals or read them from the file?...
2621   //...cutoff angle for smooth shading where there isn`t one in the file format...
2622   //...which direction is front-facing in formats that don`t get it right...
2623   //...etc...
2624 
2625 protected:
2626 
2627 
2628   /* for backward compatibility */
2629   ssgState *(*create_state_cb)( char *) ;
2630   ssgBranch *(*create_branch_cb)(char *) ;
2631 
2632   char* model_dir ;
2633   char* texture_dir ;
2634 
2635   char* make_path ( char* path, const char* dir, const char* fname ) const ;
2636 
2637 public:
2638   ssgSimpleStateArray shared_states ;
2639   ssgTextureArray shared_textures ;
2640 
ssgLoaderOptions()2641   ssgLoaderOptions ()
2642   {
2643     model_dir = 0 ;
2644     texture_dir = 0 ;
2645 
2646     /* for backward compatibility */
2647     create_state_cb = 0 ;
2648     create_branch_cb = 0 ;
2649   }
2650 
~ssgLoaderOptions()2651   virtual ~ssgLoaderOptions()
2652   {
2653     if (model_dir)
2654     {
2655       delete [] model_dir;
2656       model_dir = 0;
2657     }
2658 
2659     if (texture_dir)
2660     {
2661       delete [] texture_dir;
2662       texture_dir = 0;
2663     }
2664   }
2665 
getModelDir(void)2666   const char* getModelDir ( void ) const { return model_dir ; }
getTextureDir(void)2667   const char* getTextureDir ( void ) const { return texture_dir ; }
2668   void setModelDir ( const char *s ) ;
2669   void setTextureDir ( const char *s ) ;
2670 
2671   //
2672   // the idea is that you derive a class from ssgLoaderOptions and
2673   // override these methods to customize how the loaders work
2674   //
2675   virtual void makeModelPath ( char* path, const char *fname ) const ;
2676   virtual void makeTexturePath ( char* path, const char *fname ) const ;
2677 
2678   virtual ssgLeaf* createLeaf ( ssgLeaf* leaf, const char* parent_name ) ;
2679   virtual ssgTexture* createTexture ( char* tfname,
2680 			      int wrapu  = TRUE, int wrapv = TRUE,
2681 			      int mipmap = TRUE ) ;
2682   virtual ssgTransform* createTransform ( ssgTransform* tr,
2683       ssgTransformArray* ta ) const ;
2684   virtual ssgSelector* createSelector ( ssgSelector* s ) const ;
createBranch(char * text)2685   virtual ssgBranch* createBranch ( char* text ) const
2686   {
2687     if ( create_branch_cb != NULL )
2688       return (*create_branch_cb)(text) ;
2689     return NULL ;
2690   }
createState(char * tfname)2691   virtual ssgState* createState ( char* tfname ) const
2692   {
2693     if ( create_state_cb != NULL )
2694       return (*create_state_cb)(tfname) ;
2695     return NULL ;
2696   }
createSimpleState(char * tfname)2697   virtual ssgSimpleState* createSimpleState ( char* tfname ) const
2698   {
2699     ssgState *st = createState ( tfname ) ;
2700     if ( st != NULL )
2701     {
2702       if ( st -> isAKindOf ( ssgTypeSimpleState() ) )
2703       {
2704         return (ssgSimpleState*) st ;
2705       }
2706       else
2707       {
2708         ulSetError(UL_WARNING, "createState() did not return simple state");
2709       }
2710     }
2711     return NULL ;
2712   }
2713 
endLoad()2714   virtual void endLoad ()
2715   {
2716     /* default behavior is to reset sharing after loading a model */
2717     shared_textures.removeAll () ;
2718     shared_states.removeAll () ;
2719   }
2720 
2721   //
2722   // *** DEPRECATED INTERFACE ***
2723   // for backward compatibility
2724   // derive and use virtual methods to override
2725   //
setCreateBranchCallback(ssgBranch * (* cb)(char *))2726   void setCreateBranchCallback ( ssgBranch *(*cb)(char *) )
2727   {
2728     create_branch_cb = cb ;
2729   }
setCreateStateCallback(ssgState * (* cb)(char *))2730   void setCreateStateCallback ( ssgState *(*cb)(char *) )
2731   {
2732     create_state_cb = cb ;
2733   }
2734 } ;
2735 
2736 
2737 int        ssgSave     ( const char *fname, ssgEntity *ent ) ;
2738 int        ssgSaveAC   ( const char *fname, ssgEntity *ent ) ;
2739 int        ssgSaveASE  ( const char *fname, ssgEntity *ent ) ;
2740 int        ssgSaveSSG  ( const char *fname, ssgEntity *ent ) ;
2741 int        ssgSaveDXF  ( const char *fname, ssgEntity *ent ) ;
2742 int        ssgSaveTRI  ( const char *fname, ssgEntity *ent ) ;
2743 int        ssgSaveOBJ  ( const char *fname, ssgEntity *ent ) ;
2744 int        ssgSaveX    ( const char *fname, ssgEntity *ent ) ;
2745 int        ssgSaveM    ( const char *fname, ssgEntity *ent ) ;
2746 int        ssgSave3ds  ( const char *fname, ssgEntity *ent ) ;
2747 int        ssgSaveFLT  ( const char *fname, ssgEntity *ent ) ;
2748 int        ssgSaveOFF  ( const char *fname, ssgEntity *ent ) ;
2749 int        ssgSaveQHI  ( const char *fname, ssgEntity *ent ) ;
2750 int        ssgSaveATG  ( const char *fname, ssgEntity *ent ) ;
2751 int        ssgSaveVRML1( const char *fname, ssgEntity *ent ) ;
2752 int        ssgSaveASC  ( const char *fname, ssgEntity *ent ) ;
2753 int        ssgSaveIV   ( const char *fname, ssgEntity *ent ) ;
2754 int				 ssgSavePOV  ( const char *fname, ssgEntity *ent ) ;
2755 
2756 
2757 ssgEntity *ssgLoad     ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2758 ssgEntity *ssgLoad3ds  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2759 ssgEntity *ssgLoadAC3D ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2760 ssgEntity *ssgLoadASC  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2761 ssgEntity *ssgLoadSSG  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2762 ssgEntity *ssgLoadASE  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2763 ssgEntity *ssgLoadDOF  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2764 ssgEntity *ssgLoadDXF  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2765 ssgEntity *ssgLoadTRI  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2766 ssgEntity *ssgLoadOBJ  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2767 ssgEntity *ssgLoadMD2  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2768 ssgEntity *ssgLoadMDL  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2769 ssgEntity *ssgLoadX    ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2770 ssgEntity *ssgLoadFLT  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2771 ssgEntity *ssgLoadM    ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2772 ssgEntity *ssgLoadStrip( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2773 ssgEntity *ssgLoadOFF  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2774 ssgEntity *ssgLoadATG  ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2775 ssgEntity *ssgLoadVRML1( const char *fname, const ssgLoaderOptions* options = NULL ) ;
2776 ssgEntity *ssgLoadIV   ( const char *fname, const ssgLoaderOptions* options = NULL ) ;
2777 ssgEntity *ssgLoadXPlaneOBJ ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2778 
2779 
2780 typedef ssgEntity *ssgLoadFunc ( const char *, const ssgLoaderOptions * ) ;
2781 typedef int        ssgSaveFunc ( const char *, ssgEntity * ) ;
2782 
2783 void ssgAddModelFormat ( const char* extension,
2784                         ssgLoadFunc *loadfunc , ssgSaveFunc  *savefunc ) ;
2785 
2786 /* current loader options */
2787 
2788 extern ssgLoaderOptions* _ssgCurrentOptions ;
2789 
ssgGetCurrentOptions()2790 inline ssgLoaderOptions* ssgGetCurrentOptions ()
2791 {
2792   return _ssgCurrentOptions ;
2793 }
2794 
ssgSetCurrentOptions(ssgLoaderOptions * options)2795 inline void ssgSetCurrentOptions ( ssgLoaderOptions* options )
2796 {
2797   if ( options != NULL )
2798     _ssgCurrentOptions = options ;
2799 }
2800 
2801 /* For backwards compatibility */
2802 
ssgLoad(char * fname,ssgBranch * (* cb)(char *))2803 inline ssgEntity *ssgLoad ( char *fname, ssgBranch *(*cb)(char *))
2804 {
2805   _ssgCurrentOptions -> setCreateBranchCallback ( cb ) ;
2806   return ssgLoad ( fname ) ;
2807 }
2808 
ssgSetAppStateCallback(ssgState * (* cb)(char *))2809 inline void ssgSetAppStateCallback ( ssgState *(*cb)(char *) )
2810 {
2811   _ssgCurrentOptions -> setCreateStateCallback ( cb ) ;
2812 }
2813 
ssgModelPath(const char * path)2814 inline void ssgModelPath   ( const char *path )
2815 {
2816   _ssgCurrentOptions -> setModelDir ( path ) ;
2817 }
2818 
ssgTexturePath(const char * path)2819 inline void ssgTexturePath ( const char *path )
2820 {
2821   _ssgCurrentOptions -> setTextureDir ( path ) ;
2822 }
2823 
2824 ssgEntity *ssgLoadAC   ( const char *fname, const ssgLoaderOptions *options = NULL ) ;
2825 
2826 
2827 void ssgGetValuesFromLastATGFile(double *x, double *y, double *z, double *r);
2828 
2829  bool ssgConvertTexture( char * fname_output, char * fname_input ) ;
2830 
2831 
2832 class ssgStatistics
2833 {
2834   int vertex_count ;
2835   int leaf_count   ;
2836 
2837 public:
2838 
2839   void reset () ;
2840 
bumpVertexCount(int i)2841   void bumpVertexCount ( int i ) { vertex_count += i ; }
bumpLeafCount(int i)2842   void bumpLeafCount   ( int i ) {   leaf_count += i ; }
2843 
getVertexCount()2844   int getVertexCount () { return vertex_count ; }
getLeafCount()2845   int getLeafCount   () { return leaf_count ; }
2846 
ssgStatistics()2847   ssgStatistics ()
2848   {
2849     reset () ;
2850   }
2851 } ;
2852 
2853 ssgStatistics *ssgGetLatestStatistics () ;
2854 
2855 /* scene walkers */
2856 
2857 void ssgFlatten  ( ssgEntity *ent ) ;
2858 void ssgStripify ( ssgEntity *ent ) ;
2859 void ssgArrayTool ( ssgEntity *ent, float* vtol = 0, bool make_normals = false ) ;
2860 void ssgTransTool ( ssgEntity *ent, const sgMat4 trans ) ;
2861 
2862 ssgLight *ssgGetLight ( int i ) ;
2863 
2864 char *ssgShowStats () ;
2865 void  ssgDelete ( ssgBranch *br ) ;
2866 const char *ssgGetVersion () ;
2867 
2868 void ssgSetLoadOFFTranslucent ( int i );
2869 
2870 void ssgRegisterType ( int type, ssgBase * ( *create_func ) () ) ;
2871 ssgBase *ssgCreateOfType ( int type ) ;
2872 
2873 #define SSG_BACKFACE_COLLISIONS_SUPPORTED 1
2874 void ssgSetBackFaceCollisions ( bool b ) ;
2875 
2876 #endif
2877 
2878