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