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: ssgRangeSelector.cxx 1568 2002-09-02 06:05:49Z sjbaker $
22 */
23 
24 
25 #include "ssgLocal.h"
26 
copy_from(ssgRangeSelector * src,int clone_flags)27 void ssgRangeSelector::copy_from ( ssgRangeSelector *src, int clone_flags )
28 {
29   ssgSelector::copy_from ( src, clone_flags ) ;
30 
31   additive = src -> isAdditive () ;
32 
33   for ( unsigned int i = 0 ; i < 33 ; i++ )
34     rng_list [ i ] = src -> getRange ( i ) ;
35 }
36 
37 
clone(int clone_flags)38 ssgBase *ssgRangeSelector::clone ( int clone_flags )
39 {
40   ssgRangeSelector *b = new ssgRangeSelector ;
41   b -> copy_from ( this, clone_flags ) ;
42   return b ;
43 }
44 
45 
ssgRangeSelector(void)46 ssgRangeSelector::ssgRangeSelector (void)
47 {
48   type = ssgTypeRangeSelector () ;
49   additive = FALSE ;
50   rng_list[0] = 0.0f ;
51 
52   for ( int i = 1 ; i < 33 ; i++ )
53     rng_list[i] = SG_MAX ;
54 }
55 
~ssgRangeSelector(void)56 ssgRangeSelector::~ssgRangeSelector (void)
57 {
58 }
59 
cull(sgFrustum * f,sgMat4 m,int test_needed)60 void ssgRangeSelector::cull ( sgFrustum *f, sgMat4 m, int test_needed )
61 {
62   if ( ! preTravTests ( &test_needed, SSGTRAV_CULL ) )
63     return ;
64 
65   int cull_result = cull_test ( f, m, test_needed ) ;
66 
67   if ( cull_result == SSG_OUTSIDE )
68     return ;
69 
70   float range = sgLengthVec3 ( m [ 3 ] ) ;
71 
72   if ( range < rng_list [ 0 ] )  /* Too close */
73   {
74     select ( 0 ) ;
75     return ;
76   }
77 
78   unsigned int sel = 0 ;
79 
80   for ( int i = 1 ; i < 33 ; i++ )
81   {
82     ssgEntity *e = getKid ( i-1 ) ;
83 
84     if ( e == NULL || rng_list [ i ] == SG_MAX )
85     {
86       select ( 0 ) ;
87       return ;
88     }
89 
90     if ( e != NULL && range < rng_list [ i ] )
91     {
92       e -> cull ( f, m, cull_result != SSG_INSIDE ) ;
93       sel |= 1 << (i-1) ;
94 
95       if ( ! additive )
96       {
97         selectStep ( i-1 ) ;
98         return ;
99       }
100     }
101   }
102 
103   select ( sel ) ;
104 
105   postTravTests ( SSGTRAV_CULL ) ;
106 }
107 
108 
hot(sgVec3 sp,sgMat4 m,int test_needed)109 void ssgRangeSelector::hot ( sgVec3 sp, sgMat4 m, int test_needed )
110 {
111   if ( ! preTravTests ( &test_needed, SSGTRAV_HOT ) )
112     return ;
113 
114   if ( additive )
115     ssgBranch::hot ( sp, m, test_needed ) ;
116   else
117   {
118     /* No point in testing this node since it only has one child */
119 
120     _ssgPushPath ( this ) ;
121 
122     ssgEntity *e = getKid ( 0 ) ;
123 
124     if ( e != NULL )
125       e -> hot ( sp, m, test_needed ) ;
126 
127     _ssgPopPath () ;
128   }
129 
130   postTravTests ( SSGTRAV_HOT ) ;
131 }
132 
133 
los(sgVec3 sp,sgMat4 m,int test_needed)134 void ssgRangeSelector::los ( sgVec3 sp, sgMat4 m, int test_needed )
135 {
136   if ( ! preTravTests ( &test_needed, SSGTRAV_LOS ) )
137     return ;
138 
139   if ( additive )
140     ssgBranch::los ( sp, m, test_needed ) ;
141   else
142   {
143     /* No point in testing this node since it only has one child */
144 
145     _ssgPushPath ( this ) ;
146 
147     ssgEntity *e = getKid ( 0 ) ;
148 
149     if ( e != NULL )
150       e -> los ( sp, m, test_needed ) ;
151 
152     _ssgPopPath () ;
153   }
154 
155   postTravTests ( SSGTRAV_LOS ) ;
156 }
157 
isect(sgSphere * sp,sgMat4 m,int test_needed)158 void ssgRangeSelector::isect ( sgSphere *sp, sgMat4 m, int test_needed )
159 {
160   if ( ! preTravTests ( &test_needed, SSGTRAV_ISECT ) )
161     return ;
162 
163   if ( additive )
164     ssgBranch::isect ( sp, m, test_needed ) ;
165   else
166   {
167     /* No point in testing this node since it only has one child */
168 
169     _ssgPushPath ( this ) ;
170 
171     ssgEntity *e = getKid ( 0 ) ;
172 
173     if ( e != NULL )
174       e -> isect ( sp, m, test_needed ) ;
175 
176     _ssgPopPath () ;
177   }
178 
179   postTravTests ( SSGTRAV_ISECT ) ;
180 }
181 
182 
183 
load(FILE * fd)184 int ssgRangeSelector::load ( FILE *fd )
185 {
186   _ssgReadInt   ( fd, & additive ) ;
187   _ssgReadFloat ( fd, 33, rng_list ) ;
188 
189   return ssgSelector::load(fd) ;
190 }
191 
save(FILE * fd)192 int ssgRangeSelector::save ( FILE *fd )
193 {
194   _ssgWriteInt   ( fd, additive ) ;
195   _ssgWriteFloat ( fd, 33, rng_list ) ;
196 
197   return ssgSelector::save(fd) ;
198 }
199 
200 
201