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: ssgSelector.cxx 1568 2002-09-02 06:05:49Z sjbaker $
22 */
23 
24 
25 #include "ssgLocal.h"
26 
copy_from(ssgSelector * src,int clone_flags)27 void ssgSelector::copy_from ( ssgSelector *src, int clone_flags )
28 {
29   ssgBranch::copy_from ( src, clone_flags ) ;
30 
31   max_kids = src -> max_kids ;
32   selection = new unsigned char [ max_kids ] ;
33   memcpy ( selection, src -> selection, max_kids ) ;
34 }
35 
36 
clone(int clone_flags)37 ssgBase *ssgSelector::clone ( int clone_flags )
38 {
39   ssgSelector *b = new ssgSelector ;
40   b -> copy_from ( this, clone_flags ) ;
41   return b ;
42 }
43 
44 
ssgSelector(int _max_kids)45 ssgSelector::ssgSelector ( int _max_kids )
46 {
47   type = ssgTypeSelector () ;
48 
49   max_kids = _max_kids ;
50   selection = new unsigned char [ max_kids ] ;
51   memset ( selection, 1, max_kids ) ;
52 }
53 
~ssgSelector(void)54 ssgSelector::~ssgSelector (void)
55 {
56   delete [] selection ;
57 }
58 
cull(sgFrustum * f,sgMat4 m,int test_needed)59 void ssgSelector::cull ( sgFrustum *f, sgMat4 m, int test_needed )
60 {
61   if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
62     return ;
63 
64   int cull_result = cull_test ( f, m, test_needed ) ;
65 
66   if ( cull_result == SSG_OUTSIDE )
67     return ;
68 
69   int s = 0 ;
70 
71   for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ )
72     if ( selection [s] )
73       e -> cull ( f, m, cull_result != SSG_INSIDE ) ;
74 
75   postTravTests ( SSGTRAV_CULL ) ;
76 }
77 
hot(sgVec3 sp,sgMat4 m,int test_needed)78 void ssgSelector::hot ( sgVec3 sp, sgMat4 m, int test_needed )
79 {
80   if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
81     return ;
82 
83   int hot_result = hot_test ( sp, m, test_needed ) ;
84 
85   if ( hot_result == SSG_OUTSIDE )
86     return ;
87 
88   int s = 0 ;
89 
90   _ssgPushPath ( this ) ;
91 
92   for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ )
93     if ( selection [s] )
94       e -> hot ( sp, m, hot_result != SSG_INSIDE ) ;
95 
96   _ssgPopPath () ;
97 
98   postTravTests ( SSGTRAV_HOT ) ;
99 }
100 
101 
los(sgVec3 sp,sgMat4 m,int test_needed)102 void ssgSelector::los ( sgVec3 sp, sgMat4 m, int test_needed )
103 {
104   if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
105     return ;
106 
107   int los_result = los_test ( sp, m, test_needed ) ;
108 
109   if ( los_result == SSG_OUTSIDE )
110     return ;
111 
112   int s = 0 ;
113 
114   _ssgPushPath ( this ) ;
115 
116   for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ )
117     if ( selection [s] )
118       e -> los ( sp, m, los_result != SSG_INSIDE ) ;
119 
120   _ssgPopPath () ;
121 
122   postTravTests ( SSGTRAV_LOS ) ;
123 }
124 
125 
isect(sgSphere * sp,sgMat4 m,int test_needed)126 void ssgSelector::isect ( sgSphere *sp, sgMat4 m, int test_needed )
127 {
128   if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
129     return ;
130 
131   int isect_result = isect_test ( sp, m, test_needed ) ;
132 
133   if ( isect_result == SSG_OUTSIDE )
134     return ;
135 
136   int s = 0 ;
137 
138   _ssgPushPath ( this ) ;
139 
140   for ( ssgEntity *e = getKid ( 0 ) ; e != NULL ; e = getNextKid(), s++ )
141     if ( selection [s] )
142       e -> isect ( sp, m, isect_result != SSG_INSIDE ) ;
143 
144   _ssgPopPath () ;
145 
146   postTravTests ( SSGTRAV_ISECT ) ;
147 }
148 
149 
load(FILE * fd)150 int ssgSelector::load ( FILE *fd )
151 {
152   _ssgReadInt ( fd, & max_kids ) ;
153   delete [] selection ;
154   selection = new unsigned char [ max_kids ] ;
155   for ( int i=0; i<max_kids; i++ )
156   {
157     int temp ;
158     _ssgReadInt ( fd, & temp ) ;
159     selection [i] = (unsigned char)temp ;
160   }
161   return ssgBranch::load(fd) ;
162 }
163 
save(FILE * fd)164 int ssgSelector::save ( FILE *fd )
165 {
166   _ssgWriteInt ( fd, max_kids ) ;
167   for ( int i=0; i<max_kids; i++ )
168     _ssgWriteInt ( fd, (int)selection [i] ) ;
169   return ssgBranch::save(fd) ;
170 }
171 
172 
173