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

Comparing libgender/oct.C (file contents):
Revision 1.87 by root, Thu Jan 6 03:09:24 2005 UTC vs.
Revision 1.95 by root, Thu Aug 11 20:42:19 2005 UTC

1#include <cstdlib> 1#include <cstdlib>
2 2
3#include <vector> 3#include <vector>
4
4using namespace std; 5using namespace std;
5 6
6#include "opengl.h" 7#include "opengl.h"
7 8
8#include "oct.h" 9#include "oct.h"
9#include "view.h" 10#include "view.h"
10#include "entity.h" 11#include "entity.h"
12#include "material.h" //DEBUG
11 13
12enum visibility_state { FULL, PARTIAL, OCCLUDED }; 14struct oct_visibility : visibility_base
13 15{
14struct evis { 16 bool subvis, evis;
15 entity *e; 17 int occ_res;
16 visibility_state state;
17 double last; // time of last check
18 18
19 void clear () 19 void clear ()
20 { 20 {
21 last = 0.; 21 occ_res = -1;
22 state = FULL; 22 evis = true;
23 subvis = true;
23 } 24 }
24 25
25 evis () 26 oct_visibility (octant &oct)
26 { 27 {
27 clear (); 28 clear ();
28 } 29 }
29}; 30};
30 31
31struct oct_visibility : visibility_base
32{
33 vector<evis> vismap;
34
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 }
49
50 oct_visibility (octant &oct)
51 : state(FULL)
52 {
53 }
54};
55
56octant world(0, sector (0, 0, 0), MAXEXTENT); 32octant world(0, sector (0, 0, 0), MAXEXTENT);
57 33
58octant::octant (octant *parent, const sector &orig, uoffs extent) 34octant::octant (octant *parent, const sector &orig, uoffs extent)
59: parent(parent) 35: parent(parent)
60, orig(orig) 36, orig(orig)
69 return new oct_visibility (*this); 45 return new oct_visibility (*this);
70} 46}
71 47
72void octant::clear_visibility (visibility_base *vs) 48void octant::clear_visibility (visibility_base *vs)
73{ 49{
74 ((oct_visibility *)vs)->vismap.clear (); 50 ((oct_visibility *)vs)->clear ();
75 ((oct_visibility *)vs)->state = FULL;
76} 51}
77 52
78octant::~octant () 53octant::~octant ()
79{ 54{
80 for (fill = 8; fill--; ) 55 for (fill = 8; fill--; )
139{ 114{
140} 115}
141 116
142bool octant::detect_visibility (view &ctx) //, bool fully_visible) 117bool octant::detect_visibility (view &ctx) //, bool fully_visible)
143{ 118{
144 ctx.stat1++;//D
145
146 sector centeri = orig - ctx.orig; 119 sector centeri = orig - ctx.orig;
147 point centerf = point (centeri); 120 point centerf = point (centeri);
148 121
149 GLfloat rad = ctx.diagfact * extent; 122 GLfloat rad = ctx.diagfact * extent;
150 123
151 if (!overlap (ctx.frustum.c, sphere (centerf, rad))) 124 if (!overlap (ctx.frustum.c, sphere (centerf, rad)))
152 return false; 125 return false;
153 126
154 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 127 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
155 128
156 //vs.state = FULL;//D 129 if (max (centeri) < extent)
130 {
131 vs.evis = true;
132 vs.occ_res = -1;
133 }
134 else if (distance (ctx.frustum.t, centerf) < -rad
135 || distance (ctx.frustum.b, centerf) < -rad
136 || distance (ctx.frustum.l, centerf) < -rad
137 || distance (ctx.frustum.r, centerf) < -rad
138 || distance (ctx.frustum.n, centerf) < -rad)
139 {
140 vs.clear ();
141 return false;
142 }
157 143
158#if 0 144#if 0
159 if (max (abs (centeri)) <= extent)
160 ;
161 else
162 {
163#endif
164
165 //if (distance (ctx.frustum.t, centerf) < -rad) return false;
166 //if (distance (ctx.frustum.b, centerf) < -rad) return false;
167 //if (distance (ctx.frustum.l, centerf) < -rad) return false;
168 //if (distance (ctx.frustum.r, centerf) < -rad) return false;
169 ////if (distance (ctx.frustum.n, centerf) < -rad) return false;
170
171#if 0
172 GLfloat fd = distance (ctx.frustum.f, centerf); 145 GLfloat fd = distance (ctx.frustum.f, centerf);
173 146
174 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F) 147 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F)
175 return false; 148 return false;
176#endif 149#endif
177 150
178 // very important, optimize? 151 // very important, optimize?
179 GLfloat z = length (ctx.p - centerf) + rad; 152 GLfloat z = length (ctx.p - centerf) + rad;
180 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
181 return false; 156 return false;
157 }
182 158
183#if 0 159#if 0
184 if (vs.state == PARTIAL || vs.state == FULL) 160 if (vs.state == PARTIAL || vs.state == FULL)
185 ctx.nc_far = max (ctx.nc_far, z); 161 ctx.nc_far = max (ctx.nc_far, z);
186#endif 162#endif
187 163
188 if (vs.state == OCCLUDED) 164 if (vs.occ_res > 0)
165 vs.evis = true;
166 else if (!(vs.subvis || vs.evis))
189 { 167 {
190#if 0
191 if (extent < ctx.z_far)
192 {
193#endif
194 ctx.postdepthlist.push_back (this); 168 ctx.postdepthlist.push_back (this);
195 return false; 169 return false;
196#if 0
197 }
198 else
199 vs.state == PARTIAL;
200#endif
201 } 170 }
202 171
203 bool visible = size () && vs.state == FULL; 172 bool subvis = false;
204 173
205 // node to start with 174 // node to start with
206 unsigned char si = centeri.x > 0 ? 1 : 0 175 unsigned char si = centeri.x > 0 ? 1 : 0
207 | centeri.y > 0 ? 2 : 0 176 | centeri.y > 0 ? 2 : 0
208 | centeri.z > 0 ? 4 : 0; 177 | centeri.z > 0 ? 4 : 0;
215 do 184 do
216 { 185 {
217 si ^= *next; 186 si ^= *next;
218 187
219 if (sub[si]) 188 if (sub[si])
220 visible = visible | sub[si]->detect_visibility (ctx); 189 subvis = subvis | sub[si]->detect_visibility (ctx);
221 } 190 }
222 while (*++next); 191 while (*++next);
223 192
224 if (visible) 193 vs.subvis = subvis;
194
195 if (subvis)
225 { 196 {
226 if (size ()) 197 if (size ())
198 {
199 ctx.postdepthlist.push_back (this);
227 ctx.vislist.push_back (this); 200 ctx.vislist.push_back (this);
201 }
228 202
203 return true;
204 }
205 else
206 {
229 ctx.postdepthlist.push_back (this); 207 ctx.postdepthlist.push_back (this);
230 }
231 else
232 {
233 //vs.state = OCCLUDED;
234 ctx.postdepthlist.push_back (this); 208 ctx.vislist.push_back (this);
235 }
236 209
237 return visible; 210 return vs.evis || vs.occ_res > 0;
211 }
238} 212}
239 213
240void octant::draw_depth (view &ctx) 214void octant::draw_depth (view &ctx)
241{ 215{
242 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 216 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
243 217
244 vs.vismap.resize (size ()); 218 if (!vs.occ_res)
245
246 if (vs.state == PARTIAL || vs.state == OCCLUDED)
247 return; 219 return;
248 220
249 for (int i = 0; i < size (); ++i) 221 for (int i = 0; i < size (); ++i)
250 { 222 {
251 entity *e = (*this)[i]; 223 entity *e = (*this)[i];
252 const evis &evs = vs.get_visibility (i, e);
253 224
254 if (evs.state != OCCLUDED) 225 entity_visibility &evis = *(entity_visibility *)e->get_visibility (ctx);
226
227 if (evis.occ_res)
255 { 228 {
256 if (!ctx.may_draw (e)) 229 if (!ctx.may_draw (e))
257 continue; 230 continue;
258 231
259 sector center = ((e->a + e->b) >> 1) - ctx.orig; 232 sector center = ((e->a + e->b) >> 1) - ctx.orig;
270 243
271void octant::draw_postdepth (view &ctx) 244void octant::draw_postdepth (view &ctx)
272{ 245{
273 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 246 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
274 247
275 if (vs.state == PARTIAL || vs.state == OCCLUDED) 248 if (!vs.evis)
276 { 249 {
277 ctx.begin_occ_query (*this, 0); 250 ctx.begin_occ_query (vs.occ_res);
278 sector s = orig - ctx.orig; 251 sector s = orig - ctx.orig;
279 gl::draw_bbox (s - extent, s + extent); 252 gl::draw_bbox (s - extent, s + extent);
280 ctx.end_occ_query (); 253 ctx.end_occ_query ();
281 } 254 }
282 else 255 else
283 { 256 {
284 int nvis = 0; 257 vs.evis = false;
285 258
286 for (int i = 0; i < size (); ++i) 259 for (int i = 0; i < size (); ++i)
287 { 260 {
288 entity *e = (*this)[i]; 261 entity *e = (*this)[i];
289 const evis &evs = vs.get_visibility (i, e); 262 entity_visibility &evis = *(entity_visibility *)e->get_visibility (ctx);
290 263
291 if (evs.state == OCCLUDED) 264 if (evis.occ_res)
265 vs.evis = true;
266 else
292 { 267 {
293 if (!ctx.may_draw (e)) 268 if (!ctx.may_draw (e))
294 continue; 269 continue;
295 270
271 ctx.stat1++;
296 ctx.begin_occ_query (*this, e); 272 ctx.begin_occ_query (evis.occ_res);
297 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig); 273 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig);
298 ctx.end_occ_query (); 274 ctx.end_occ_query ();
299 } 275 }
300 else
301 nvis++;
302 } 276 }
277 }
278}
279
280void octant::draw_lighted (view &ctx)
281{
282 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
283
284 if (!vs.occ_res)
285 return;
303 286
304#if 0 287#if 0
305 if (nvis == 0 && size ())
306 vs.state = PARTIAL;
307#endif
308 }
309}
310
311void octant::draw_lighted (view &ctx)
312{
313 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
314
315#if 0
316 if (vs.state == PARTIAL || vs.state == OCCLUDED) 288 if (vs.state == FULL || vs.state == OCCLUDED)
317 { 289 {
318 sector s = orig - ctx.orig; 290 sector s = orig - ctx.orig;
291 debugmat->enable (ctx);
292 if (max (s) >= extent)
319 gl::draw_bbox (s - extent, s + extent); 293 gl::draw_bbox (s - extent, s + extent);
320 printf ("DLP %p\n", this);//D 294 debugmat->disable (ctx);
295 //printf ("DLP %ld %ld %ld (%ld)\n", orig.x, orig.y, orig.z, extent);//D
321 } 296 }
322#endif 297#endif
323 298
324 if (vs.state == PARTIAL || vs.state == OCCLUDED)
325 return;
326
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)
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) 299 for (int i = 0; i < size (); ++i)
369 { 300 {
370 entity *e = (*this)[i]; 301 entity *e = (*this)[i];
371 evis &evs = vs.get_visibility (i, e); 302 entity_visibility &evis = *(entity_visibility *)e->get_visibility (ctx);
372 303
373 if (evs.state != OCCLUDED) 304 if (evis.occ_res)
374 { 305 {
375 if (!ctx.may_draw (e)) 306 if (!ctx.may_draw (e))
376 continue; 307 continue;
377 308
378 sector center = ((e->a + e->b) >> 1) - ctx.orig; 309 sector center = ((e->a + e->b) >> 1) - ctx.orig;
379 GLfloat z = length (vec3 (center)); 310 GLfloat z = length (vec3 (center));
380 ctx.pixfact = ctx.perspfact / z; 311 ctx.pixfact = ctx.perspfact / z;
381 312
382 if (ctx.pass->type != LIGHTED
383 || !ctx.first_lighted 313 if (!ctx.first_lighted
384 || evs.last + 1. > timer.now) 314 || evis.next > timer.now)
385 e->draw (ctx); 315 e->draw (ctx);
386 else 316 else
387 { 317 {
388 evs.last = timer.now; 318 evis.next = timer.now + 0.2;
389 ctx.begin_occ_query (*this, e); 319 ctx.begin_occ_query (evis.occ_res);
390 e->draw (ctx); 320 e->draw (ctx);
391 ctx.end_occ_query (); 321 ctx.end_occ_query ();
392 } 322 }
393 } 323 }
394 } 324 }
395} 325}
396 326
397void octant::event (occ_query &ev)
398{
399 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx);
400 entity *e = (entity *)ev.id;
401
402 if (e)
403 {
404 for (vector<evis>::iterator i = vs.vismap.begin ();
405 i != vs.vismap.end ();
406 ++i)
407 if (i->e == e)
408 {
409 i->state = ev.count ? FULL : OCCLUDED;
410 return;
411 }
412 }
413 else
414 vs.state = ev.count ? (vs.state == PARTIAL ? PARTIAL : FULL) : OCCLUDED;
415}
416
417

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines