… | |
… | |
7 | |
7 | |
8 | #include "oct.h" |
8 | #include "oct.h" |
9 | #include "view.h" |
9 | #include "view.h" |
10 | #include "entity.h" |
10 | #include "entity.h" |
11 | |
11 | |
12 | enum visibility_state { FULL, PARTIAL, SMALL, OCCLUDED }; |
12 | enum visibility_state { FULL, PARTIAL, SMALL, OCCLUDED, SUBTREE_OCCLUDED }; |
13 | |
13 | |
14 | struct evis { |
14 | struct evis { |
15 | visibility_state state; |
15 | visibility_state state; |
16 | double last; // time of last check |
16 | double last; // time of last check |
17 | evis () : last(0.), state(FULL) { }; |
17 | evis () : last(0.), state(FULL) { }; |
… | |
… | |
156 | #if 0 |
156 | #if 0 |
157 | if (vs.state == PARTIAL || vs.state == FULL) |
157 | if (vs.state == PARTIAL || vs.state == FULL) |
158 | ctx.nc_far = max (ctx.nc_far, z); |
158 | ctx.nc_far = max (ctx.nc_far, z); |
159 | #endif |
159 | #endif |
160 | |
160 | |
|
|
161 | if (vs.state == SUBTREE_OCCLUDED) |
|
|
162 | { |
|
|
163 | ctx.vislist.push_back (this); |
|
|
164 | return false; |
|
|
165 | } |
|
|
166 | |
161 | // node to start with |
167 | // node to start with |
162 | unsigned char si = centeri.x > 0 ? 1 : 0 |
168 | unsigned char si = centeri.x > 0 ? 1 : 0 |
163 | | centeri.y > 0 ? 2 : 0 |
169 | | centeri.y > 0 ? 2 : 0 |
164 | | centeri.z > 0 ? 4 : 0; |
170 | | centeri.z > 0 ? 4 : 0; |
165 | |
171 | |
166 | // bit-toggle to find next child for front-to-back order |
172 | // bit-toggle to find next child for front-to-back order |
167 | static unsigned char toggle[8+1] |
173 | static unsigned char toggle[8+1] |
168 | = { 0, 0^1, 1^2, 2^4, 4^3, 3^5, 5^6, 6^7, 0 }; |
174 | = { 0, 0^1, 1^2, 2^4, 4^3, 3^5, 5^6, 6^7, 0 }; |
169 | |
175 | |
170 | bool visible = vs.state == PARTIAL || vs.state == FULL; |
176 | bool visible = size () && (vs.state == PARTIAL || vs.state == FULL); |
171 | |
177 | |
172 | unsigned char *next = toggle; |
178 | unsigned char *next = toggle; |
173 | do |
179 | do |
174 | { |
180 | { |
175 | si ^= *next; |
181 | si ^= *next; |
… | |
… | |
184 | if (size ()) |
190 | if (size ()) |
185 | ctx.vislist.push_back (this); |
191 | ctx.vislist.push_back (this); |
186 | } |
192 | } |
187 | else |
193 | else |
188 | { |
194 | { |
189 | vs.state = OCCLUDED; |
195 | vs.state = SUBTREE_OCCLUDED; |
190 | ctx.vislist.push_back (this); |
196 | ctx.vislist.push_back (this); |
191 | } |
197 | } |
192 | |
198 | |
193 | return visible; |
199 | return visible; |
194 | } |
200 | } |
195 | |
201 | |
196 | void octant::display (view &ctx) |
202 | void octant::display (view &ctx) |
197 | { |
203 | { |
198 | oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); |
204 | oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); |
199 | |
205 | |
200 | if (vs.state == OCCLUDED) |
206 | if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED) |
201 | { |
207 | { |
202 | if (ctx.pass_type == view::POSTDEPTH) |
208 | if (ctx.pass_type == view::POSTDEPTH) |
203 | { |
209 | { |
204 | ctx.begin_occ_query (*this, 0); |
210 | ctx.begin_occ_query (*this, 0); |
205 | sector s = orig - ctx.orig; |
211 | sector s = orig - ctx.orig; |
… | |
… | |
241 | ctx.pixfact = ctx.perspfact / z; |
247 | ctx.pixfact = ctx.perspfact / z; |
242 | |
248 | |
243 | ctx.nz_far = max (ctx.nz_far, z + extent); |
249 | ctx.nz_far = max (ctx.nz_far, z + extent); |
244 | ctx.nz_near = min (ctx.nz_near, z - extent); |
250 | ctx.nz_near = min (ctx.nz_near, z - extent); |
245 | |
251 | |
246 | if (ctx.pass_type == view::DEPTH || evs.last + 0.3 > timer.now) |
252 | if (ctx.pass_type == view::DEPTH || evs.last + 0.1 > timer.now) |
247 | e->draw (ctx); |
253 | e->draw (ctx); |
248 | else |
254 | else |
249 | { |
255 | { |
250 | evs.last = timer.now; |
256 | evs.last = timer.now; |
251 | ctx.begin_occ_query (*this, e); |
257 | ctx.begin_occ_query (*this, e); |