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

Comparing libgender/oct.C (file contents):
Revision 1.76 by root, Tue Nov 9 22:33:18 2004 UTC vs.
Revision 1.87 by root, Thu Jan 6 03:09:24 2005 UTC

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
12enum visibility_state { FULL, PARTIAL, SMALL, OCCLUDED, SUBTREE_OCCLUDED }; 12enum visibility_state { FULL, PARTIAL, OCCLUDED };
13 13
14struct evis { 14struct evis {
15 entity *e;
15 visibility_state state; 16 visibility_state state;
16 double last; // time of last check 17 double last; // time of last check
17 evis () : last(0.), state(FULL) { }; 18
19 void clear ()
20 {
21 last = 0.;
22 state = FULL;
23 }
24
25 evis ()
26 {
27 clear ();
28 }
18}; 29};
19 30
20struct oct_visibility : visibility_base 31struct oct_visibility : visibility_base
21{ 32{
22 typedef map<entity *, evis> evismap; 33 vector<evis> vismap;
23 evismap vismap;
24 34
25 visibility_state state; 35 visibility_state state;
36
37 evis &get_visibility (int i, entity *e)
38 {
39 evis &evs = vismap [i];
40
41 if (evs.e != e)
42 {
43 evs.clear ();
44 evs.e = e;
45 }
46
47 return evs;
48 }
26 49
27 oct_visibility (octant &oct) 50 oct_visibility (octant &oct)
28 : state(FULL) 51 : state(FULL)
29 { 52 {
30 } 53 }
78void octant::add (entity *e) 101void octant::add (entity *e)
79{ 102{
80 const sector &a = e->a; 103 const sector &a = e->a;
81 const sector &b = e->b; 104 const sector &b = e->b;
82 105
106 uoffs size = max (abs (b - a));
107
108 if (size >= extent >> 4)
109 {
83 if (overlap (orig, extent, a, b)) 110 if (overlap (orig, extent, a, b))
84 {
85 uoffs extent2 = extent >> 1;
86 uoffs size = max (abs (b - a));
87
88 if (size >= extent2)
89 { 111 {
90 push_back (e); 112 push_back (e);
91 e->o.push_back (this); 113 e->o.push_back (this);
92 return;
93 } 114 }
115 }
116 else
117 {
118 uoffs extent2 = extent >> 1;
94 119
95 for (int i = 8; i--; ) 120 for (int i = 8; i--; )
96 { 121 {
97 sector s = offset (orig, i, extent2); 122 sector s = offset (orig, i, extent2);
98 123
112 137
113void octant::remove (entity *e) 138void octant::remove (entity *e)
114{ 139{
115} 140}
116 141
117bool octant::detect_visibility (view &ctx) 142bool octant::detect_visibility (view &ctx) //, bool fully_visible)
118{ 143{
144 ctx.stat1++;//D
145
119 sector centeri = orig - ctx.orig; 146 sector centeri = orig - ctx.orig;
120 point centerf = point (centeri); 147 point centerf = point (centeri);
121 148
122 GLfloat rad = ctx.diagfact * extent; 149 GLfloat rad = ctx.diagfact * extent;
123 150
124 if (!overlap (ctx.frustum.c, sphere (centerf, rad))) 151 if (!overlap (ctx.frustum.c, sphere (centerf, rad)))
125 return false; 152 return false;
126 153
127 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 154 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
128 155
156 //vs.state = FULL;//D
157
158#if 0
129 if (max (abs (centeri)) <= extent) 159 if (max (abs (centeri)) <= extent)
130 vs.state = PARTIAL; 160 ;
131 else 161 else
132 { 162 {
163#endif
164
133 if (distance (ctx.frustum.t, centerf) < -rad) return false; 165 //if (distance (ctx.frustum.t, centerf) < -rad) return false;
134 if (distance (ctx.frustum.b, centerf) < -rad) return false; 166 //if (distance (ctx.frustum.b, centerf) < -rad) return false;
135 if (distance (ctx.frustum.l, centerf) < -rad) return false; 167 //if (distance (ctx.frustum.l, centerf) < -rad) return false;
136 if (distance (ctx.frustum.r, centerf) < -rad) return false; 168 //if (distance (ctx.frustum.r, centerf) < -rad) return false;
137 if (distance (ctx.frustum.n, centerf) < -rad) return false; 169 ////if (distance (ctx.frustum.n, centerf) < -rad) return false;
138 170
139#if 0 171#if 0
140 GLfloat fd = distance (ctx.frustum.f, centerf); 172 GLfloat fd = distance (ctx.frustum.f, centerf);
141 173
142 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F) 174 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F)
143 return false; 175 return false;
144#endif 176#endif
145 }
146 177
147 // very important, optimize? 178 // very important, optimize?
148 GLfloat z = ctx.z_near + distance (ctx.frustum.n, centerf) + rad; 179 GLfloat z = length (ctx.p - centerf) + rad;
149 if (ctx.perspfact * extent / z < 1.) // very crude "too small to see" check 180 if (z < 0.F || ctx.perspfact * extent / z < 10.) // very crude "too small to see" check
150 return false; 181 return false;
151 182
152#if 0 183#if 0
153 if (vs.state == PARTIAL || vs.state == FULL) 184 if (vs.state == PARTIAL || vs.state == FULL)
154 ctx.nc_far = max (ctx.nc_far, z); 185 ctx.nc_far = max (ctx.nc_far, z);
155#endif 186#endif
156 187
157 if (vs.state == SUBTREE_OCCLUDED) 188 if (vs.state == OCCLUDED)
158 { 189 {
190#if 0
191 if (extent < ctx.z_far)
192 {
193#endif
159 ctx.vislist.push_back (this); 194 ctx.postdepthlist.push_back (this);
160 return false; 195 return false;
196#if 0
197 }
198 else
199 vs.state == PARTIAL;
200#endif
161 } 201 }
162 202
163 bool visible = size () && (vs.state == PARTIAL || vs.state == FULL); 203 bool visible = size () && vs.state == FULL;
164 204
165 // node to start with 205 // node to start with
166 unsigned char si = centeri.x > 0 ? 1 : 0 206 unsigned char si = centeri.x > 0 ? 1 : 0
167 | centeri.y > 0 ? 2 : 0 207 | centeri.y > 0 ? 2 : 0
168 | centeri.z > 0 ? 4 : 0; 208 | centeri.z > 0 ? 4 : 0;
183 223
184 if (visible) 224 if (visible)
185 { 225 {
186 if (size ()) 226 if (size ())
187 ctx.vislist.push_back (this); 227 ctx.vislist.push_back (this);
228
229 ctx.postdepthlist.push_back (this);
188 } 230 }
189 else 231 else
190 { 232 {
191 vs.state = SUBTREE_OCCLUDED; 233 //vs.state = OCCLUDED;
192 ctx.vislist.push_back (this); 234 ctx.postdepthlist.push_back (this);
193 } 235 }
194 236
195 return visible; 237 return visible;
196} 238}
197 239
198void octant::draw_depth (view &ctx) 240void octant::draw_depth (view &ctx)
199{ 241{
200 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 242 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
201 243
244 vs.vismap.resize (size ());
245
202 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED) 246 if (vs.state == PARTIAL || vs.state == OCCLUDED)
203 return; 247 return;
204 248
205 for (iterator i = begin (); i != end (); ) 249 for (int i = 0; i < size (); ++i)
206 { 250 {
207 entity *e = *i++; 251 entity *e = (*this)[i];
208 252 const evis &evs = vs.get_visibility (i, e);
209 evis &evs = vs.vismap[e];
210 253
211 if (evs.state != OCCLUDED) 254 if (evs.state != OCCLUDED)
212 { 255 {
213 if (!ctx.may_draw (e)) 256 if (!ctx.may_draw (e))
214 continue; 257 continue;
227 270
228void octant::draw_postdepth (view &ctx) 271void octant::draw_postdepth (view &ctx)
229{ 272{
230 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 273 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
231 274
232 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED) 275 if (vs.state == PARTIAL || vs.state == OCCLUDED)
233 { 276 {
234 ctx.begin_occ_query (*this, 0); 277 ctx.begin_occ_query (*this, 0);
235 sector s = orig - ctx.orig; 278 sector s = orig - ctx.orig;
236 gl::draw_bbox (s - extent, s + extent); 279 gl::draw_bbox (s - extent, s + extent);
237 ctx.end_occ_query (); 280 ctx.end_occ_query ();
238 } 281 }
239 else 282 else
240 { 283 {
241 int nvis = 0; 284 int nvis = 0;
242 285
243 for (iterator i = begin (); i != end (); ) 286 for (int i = 0; i < size (); ++i)
244 { 287 {
245 entity *e = *i++; 288 entity *e = (*this)[i];
246 289 const evis &evs = vs.get_visibility (i, e);
247 evis &evs = vs.vismap[e];
248 290
249 if (evs.state == OCCLUDED) 291 if (evs.state == OCCLUDED)
250 { 292 {
251 if (!ctx.may_draw (e)) 293 if (!ctx.may_draw (e))
252 continue; 294 continue;
257 } 299 }
258 else 300 else
259 nvis++; 301 nvis++;
260 } 302 }
261 303
304#if 0
262 if (nvis == 0 && size ()) 305 if (nvis == 0 && size ())
263 vs.state = OCCLUDED; 306 vs.state = PARTIAL;
307#endif
264 } 308 }
265} 309}
266 310
267void octant::draw_lighted (view &ctx) 311void octant::draw_lighted (view &ctx)
268{ 312{
269 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 313 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
270 314
315#if 0
271 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED) 316 if (vs.state == PARTIAL || vs.state == OCCLUDED)
317 {
318 sector s = orig - ctx.orig;
319 gl::draw_bbox (s - extent, s + extent);
320 printf ("DLP %p\n", this);//D
321 }
322#endif
323
324 if (vs.state == PARTIAL || vs.state == OCCLUDED)
272 return; 325 return;
273 326
274 for (iterator i = begin (); i != end (); ) 327#if 0
328 {
329 static vertex_buffer vb;
330 static index_buffer ib;
331
332 sector s = orig - ctx.orig;
333 sector a = s - extent, b = s + extent;
334
335 vertex_v3f vd[] = {
336 point (a.x, a.y, a.z),
337 point (b.x, a.y, a.z),
338 point (a.x, b.y, a.z),
339 point (b.x, b.y, a.z),
340 point (a.x, a.y, b.z),
341 point (b.x, a.y, b.z),
342 point (a.x, b.y, b.z),
343 point (b.x, b.y, b.z),
344 };
345
346 if (!ib)
275 { 347 {
348 static GLushort verts[4*6] = {
349 0, 4, 6, 2, // -x
350 1, 3, 7, 5, // +x
351 0, 1, 5, 4, // -y
352 7, 3, 2, 6, // +y
353 0, 2, 3, 1, // -z
354 4, 5, 7, 6, // +z
355 };
356
357 ib.set (verts, 4*6, GL_STATIC_DRAW_ARB);
358 }
359
360 vb.set (vd, 8, GL_STREAM_DRAW_ARB);
361 vb.bind ();
362 for (int i = 0; i < 6; i++)
363 ib.draw (GL_LINE_LOOP, i*4, 4);
364
365 }
366#endif
367
368 for (int i = 0; i < size (); ++i)
369 {
276 entity *e = *i++; 370 entity *e = (*this)[i];
277 371 evis &evs = vs.get_visibility (i, e);
278 evis &evs = vs.vismap[e];
279 372
280 if (evs.state != OCCLUDED) 373 if (evs.state != OCCLUDED)
281 { 374 {
282 if (!ctx.may_draw (e)) 375 if (!ctx.may_draw (e))
283 continue; 376 continue;
286 GLfloat z = length (vec3 (center)); 379 GLfloat z = length (vec3 (center));
287 ctx.pixfact = ctx.perspfact / z; 380 ctx.pixfact = ctx.perspfact / z;
288 381
289 if (ctx.pass->type != LIGHTED 382 if (ctx.pass->type != LIGHTED
290 || !ctx.first_lighted 383 || !ctx.first_lighted
291 || evs.last + 0.1 > timer.now) 384 || evs.last + 1. > timer.now)
292 e->draw (ctx); 385 e->draw (ctx);
293 else 386 else
294 { 387 {
295 evs.last = timer.now; 388 evs.last = timer.now;
296 ctx.begin_occ_query (*this, e); 389 ctx.begin_occ_query (*this, e);
306 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx); 399 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx);
307 entity *e = (entity *)ev.id; 400 entity *e = (entity *)ev.id;
308 401
309 if (e) 402 if (e)
310 { 403 {
311 evis &evs = vs.vismap[e]; 404 for (vector<evis>::iterator i = vs.vismap.begin ();
405 i != vs.vismap.end ();
406 ++i)
407 if (i->e == e)
408 {
312 evs.state = ev.count ? FULL : OCCLUDED; 409 i->state = ev.count ? FULL : OCCLUDED;
410 return;
411 }
313 } 412 }
314 else 413 else
315 vs.state = ev.count ? FULL : OCCLUDED; 414 vs.state = ev.count ? (vs.state == PARTIAL ? PARTIAL : FULL) : OCCLUDED;
316} 415}
317 416
318 417

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines