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