ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/oct.C
(Generate patch)

Comparing libgender/oct.C (file contents):
Revision 1.92 by root, Wed Aug 10 02:37:11 2005 UTC vs.
Revision 1.93 by root, Thu Aug 11 19:28:45 2005 UTC

9#include "oct.h" 9#include "oct.h"
10#include "view.h" 10#include "view.h"
11#include "entity.h" 11#include "entity.h"
12#include "material.h" //DEBUG 12#include "material.h" //DEBUG
13 13
14enum visibility_state { 14struct oct_visibility : visibility_base
15 PARTIAL, // surrounding the viewpoint 15{
16 FULL, // in frustum 16 bool subvis, evis;
17 OCCLUDED, // in frustom, but occluded 17 int occ_res;
18};
19
20struct evis {
21 entity *e;
22 visibility_state state;
23 double next; // time of next check
24 18
25 void clear () 19 void clear ()
26 { 20 {
27 next = 0.; 21 occ_res = -1;
28 state = FULL; 22 evis = true;
23 subvis = true;
29 } 24 }
30 25
31 evis () 26 oct_visibility (octant &oct)
32 { 27 {
33 clear (); 28 clear ();
34 } 29 }
35}; 30};
36 31
37struct oct_visibility : visibility_base
38{
39 vector<evis> vismap;
40
41 visibility_state state;
42 bool vis;
43
44 evis &get_visibility (int i, entity *e)
45 {
46 evis &evs = vismap [i];
47
48 if (evs.e != e)
49 {
50 evs.clear ();
51 evs.e = e;
52 }
53
54 return evs;
55 }
56
57 oct_visibility (octant &oct)
58 : state (FULL), vis (true)
59 {
60 }
61};
62
63octant world(0, sector (0, 0, 0), MAXEXTENT); 32octant world(0, sector (0, 0, 0), MAXEXTENT);
64 33
65octant::octant (octant *parent, const sector &orig, uoffs extent) 34octant::octant (octant *parent, const sector &orig, uoffs extent)
66: parent(parent) 35: parent(parent)
67, orig(orig) 36, orig(orig)
76 return new oct_visibility (*this); 45 return new oct_visibility (*this);
77} 46}
78 47
79void octant::clear_visibility (visibility_base *vs) 48void octant::clear_visibility (visibility_base *vs)
80{ 49{
81 ((oct_visibility *)vs)->vismap.clear (); 50 ((oct_visibility *)vs)->clear ();
82 ((oct_visibility *)vs)->state = FULL;
83} 51}
84 52
85octant::~octant () 53octant::~octant ()
86{ 54{
87 for (fill = 8; fill--; ) 55 for (fill = 8; fill--; )
157 return false; 125 return false;
158 126
159 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 127 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
160 128
161 if (max (centeri) < extent) 129 if (max (centeri) < extent)
162 vs.state = PARTIAL; 130 {
163 else 131 vs.evis = true;
132 vs.occ_res = -1;
164 { 133 }
165 if (distance (ctx.frustum.t, centerf) < -rad) return false; 134 else if (distance (ctx.frustum.t, centerf) < -rad
166 if (distance (ctx.frustum.b, centerf) < -rad) return false; 135 || distance (ctx.frustum.b, centerf) < -rad
167 if (distance (ctx.frustum.l, centerf) < -rad) return false; 136 || distance (ctx.frustum.l, centerf) < -rad
168 if (distance (ctx.frustum.r, centerf) < -rad) return false; 137 || distance (ctx.frustum.r, centerf) < -rad
169 if (distance (ctx.frustum.n, centerf) < -rad) return false; 138 || distance (ctx.frustum.n, centerf) < -rad)
139 {
140 vs.clear ();
141 return false;
170 } 142 }
171 143
172#if 0 144#if 0
173 GLfloat fd = distance (ctx.frustum.f, centerf); 145 GLfloat fd = distance (ctx.frustum.f, centerf);
174 146
177#endif 149#endif
178 150
179 // very important, optimize? 151 // very important, optimize?
180 GLfloat z = length (ctx.p - centerf) + rad; 152 GLfloat z = length (ctx.p - centerf) + rad;
181 if (z < 0.F || ctx.perspfact * extent / z < 10.) // very crude "too small to see" check 153 if (z < 0.F || ctx.perspfact * extent / z < 10.) // very crude "too small to see" check
154 {
155 vs.clear ();//D
182 return false; 156 return false;
157 }
183 158
184#if 0 159#if 0
185 if (vs.state == PARTIAL || vs.state == FULL) 160 if (vs.state == PARTIAL || vs.state == FULL)
186 ctx.nc_far = max (ctx.nc_far, z); 161 ctx.nc_far = max (ctx.nc_far, z);
187#endif 162#endif
188 163
189 if (vs.state == OCCLUDED) 164 if (vs.occ_res > 0)
165 {
166 vs.evis = true;
167 vs.occ_res = -1;
168 }
169
170 if (!(vs.subvis || vs.evis))
190 { 171 {
191 ctx.postdepthlist.push_back (this); 172 ctx.postdepthlist.push_back (this);
192
193 return false; 173 return false;
194 } 174 }
195 175
196 //bool visible = size () && vs.state != OCCLUDED;
197 bool visible = false; 176 bool subvis = false;
198 177
199 // node to start with 178 // node to start with
200 unsigned char si = centeri.x > 0 ? 1 : 0 179 unsigned char si = centeri.x > 0 ? 1 : 0
201 | centeri.y > 0 ? 2 : 0 180 | centeri.y > 0 ? 2 : 0
202 | centeri.z > 0 ? 4 : 0; 181 | centeri.z > 0 ? 4 : 0;
209 do 188 do
210 { 189 {
211 si ^= *next; 190 si ^= *next;
212 191
213 if (sub[si]) 192 if (sub[si])
214 visible = visible | sub[si]->detect_visibility (ctx); 193 subvis = subvis | sub[si]->detect_visibility (ctx);
215 } 194 }
216 while (*++next); 195 while (*++next);
217 196
218 if (visible) 197 vs.subvis = subvis;
198
199 if (subvis)
219 { 200 {
220 if (size ()) 201 if (size ())
221 {
222 ctx.postdepthlist.push_back (this);
223 if (vs.vis)
224 ctx.vislist.push_back (this);
225 }
226
227 vs.state = FULL;
228
229 return true;
230 }
231 else if (vs.state == OCCLUDED)
232 {
233 ctx.postdepthlist.push_back (this);
234
235 return false;
236 }
237 else if (size())
238 {
239 if (vs.vis)
240 { 202 {
241 ctx.postdepthlist.push_back (this); 203 ctx.postdepthlist.push_back (this);
242 ctx.vislist.push_back (this); 204 ctx.vislist.push_back (this);
243 } 205 }
244 else
245 vs.state = OCCLUDED;
246 206
247 return true; 207 return true;
248 } 208 }
209 else if (!vs.evis)
210 {
211 ctx.postdepthlist.push_back (this);
212 ctx.vislist.push_back (this);
213
214 return false;
215 }
249 else 216 else
250 { 217 {
251 return vs.state != PARTIAL; 218 ctx.postdepthlist.push_back (this);
219 ctx.vislist.push_back (this);
220
221 return true;
252 } 222 }
253} 223}
254 224
255void octant::draw_depth (view &ctx) 225void octant::draw_depth (view &ctx)
256{ 226{
257 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 227 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
258 228
259 vs.vismap.resize (size ()); 229 if (!(vs.subvis || vs.evis))
260
261 if (vs.state == OCCLUDED)
262 return; 230 return;
263 231
264 for (int i = 0; i < size (); ++i) 232 for (int i = 0; i < size (); ++i)
265 { 233 {
266 entity *e = (*this)[i]; 234 entity *e = (*this)[i];
267 const evis &evs = vs.get_visibility (i, e);
268 235
269 if (evs.state != OCCLUDED) 236 entity_visibility &evis = *(entity_visibility *)e->get_visibility (ctx);
237
238 if (evis.occ_res)
270 { 239 {
271 if (!ctx.may_draw (e)) 240 if (!ctx.may_draw (e))
272 continue; 241 continue;
273 242
274 sector center = ((e->a + e->b) >> 1) - ctx.orig; 243 sector center = ((e->a + e->b) >> 1) - ctx.orig;
285 254
286void octant::draw_postdepth (view &ctx) 255void octant::draw_postdepth (view &ctx)
287{ 256{
288 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 257 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
289 258
290 if (vs.state == OCCLUDED || !vs.vis) 259 if (!(vs.subvis || vs.evis))
291 { 260 {
292 ctx.begin_occ_query (*this, 0); 261 ctx.begin_occ_query (vs.occ_res);
293 sector s = orig - ctx.orig; 262 sector s = orig - ctx.orig;
294 gl::draw_bbox (s - extent, s + extent); 263 gl::draw_bbox (s - extent, s + extent);
295 ctx.end_occ_query (); 264 ctx.end_occ_query ();
296 } 265 }
297 else 266 else
298 { 267 {
299 vs.vis = false; 268 vs.evis = false;
300 269
301 for (int i = 0; i < size (); ++i) 270 for (int i = 0; i < size (); ++i)
302 { 271 {
303 entity *e = (*this)[i]; 272 entity *e = (*this)[i];
304 const evis &evs = vs.get_visibility (i, e); 273 entity_visibility &evis = *(entity_visibility *)e->get_visibility (ctx);
305 274
306 if (evs.state == OCCLUDED) 275 if (evis.occ_res)
276 vs.evis = true;
277 else
307 { 278 {
308 if (!ctx.may_draw (e)) 279 if (!ctx.may_draw (e))
309 continue; 280 continue;
310 281
282 ctx.stat1++;
311 ctx.begin_occ_query (*this, e); 283 ctx.begin_occ_query (evis.occ_res);
312 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig); 284 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig);
313 ctx.end_occ_query (); 285 ctx.end_occ_query ();
314 } 286 }
315 else
316 vs.vis = true;
317 } 287 }
318 } 288 }
319} 289}
320 290
321void octant::draw_lighted (view &ctx) 291void octant::draw_lighted (view &ctx)
332 debugmat->disable (ctx); 302 debugmat->disable (ctx);
333 //printf ("DLP %ld %ld %ld (%ld)\n", orig.x, orig.y, orig.z, extent);//D 303 //printf ("DLP %ld %ld %ld (%ld)\n", orig.x, orig.y, orig.z, extent);//D
334 } 304 }
335#endif 305#endif
336 306
337 if (vs.state == OCCLUDED)
338 return;
339
340 for (int i = 0; i < size (); ++i) 307 for (int i = 0; i < size (); ++i)
341 { 308 {
342 entity *e = (*this)[i]; 309 entity *e = (*this)[i];
343 evis &evs = vs.get_visibility (i, e); 310 entity_visibility &evis = *(entity_visibility *)e->get_visibility (ctx);
344 311
345 if (evs.state != OCCLUDED) 312 if (evis.occ_res)
346 { 313 {
347 if (!ctx.may_draw (e)) 314 if (!ctx.may_draw (e))
348 continue; 315 continue;
349 316
350 sector center = ((e->a + e->b) >> 1) - ctx.orig; 317 sector center = ((e->a + e->b) >> 1) - ctx.orig;
351 GLfloat z = length (vec3 (center)); 318 GLfloat z = length (vec3 (center));
352 ctx.pixfact = ctx.perspfact / z; 319 ctx.pixfact = ctx.perspfact / z;
353 320
354 if (!ctx.first_lighted 321 if (!ctx.first_lighted
355 || evs.next > timer.now) 322 || evis.next > timer.now)
356 e->draw (ctx); 323 e->draw (ctx);
357 else 324 else
358 { 325 {
326ctx.stat2++;//D
359 evs.next = timer.now + 0.2; 327 evis.next = timer.now + 0.2 + 1e6;
360 ctx.begin_occ_query (*this, e); 328 ctx.begin_occ_query (evis.occ_res);
361 e->draw (ctx); 329 e->draw (ctx);
362 ctx.end_occ_query (); 330 ctx.end_occ_query ();
363 } 331 }
364 } 332 }
365 } 333 }
366} 334}
367 335
368void octant::event (occ_query &ev)
369{
370 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx);
371 entity *e = (entity *)ev.id;
372
373 if (e)
374 {
375#if 1
376 for (vector<evis>::iterator i = vs.vismap.begin ();
377 i != vs.vismap.end ();
378 ++i)
379 if (i->e == e)
380 {
381 i->state = ev.count ? FULL : OCCLUDED;
382 return;
383 }
384#endif
385 }
386 else
387 {
388 vs.state = ev.count ? FULL : OCCLUDED;
389 vs.vis = ev.count ? true : false;
390 }
391}
392
393

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines