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

Comparing libgender/oct.C (file contents):
Revision 1.53 by root, Sat Oct 16 14:48:48 2004 UTC vs.
Revision 1.56 by root, Sun Oct 17 09:43:07 2004 UTC

1#include <cstdlib> 1#include <cstdlib>
2 2
3#include <vector> 3#include <vector>
4
5using namespace std; 4using namespace std;
6 5
7#include "opengl.h" 6#include "opengl.h"
8 7
9#include "oct.h" 8#include "oct.h"
10#include "view.h" 9#include "view.h"
11#include "entity.h" 10#include "entity.h"
12 11
12enum visibility_state { FULL, PARTIAL, SMALL, OCCLUDED };
13
14struct evis {
15 visibility_state state;
16 double last; // time of last check
17 evis () : last(0.), state(FULL) { };
18};
19
13struct oct_visibility : visibility_base 20struct oct_visibility : visibility_base
14{ 21{
15 struct visibility {
16 enum { UNKNOWN, OCCLUDED, PARTIAL, FULL } state;
17 double last; // time of last check
18 visibility () : last(0.), state(UNKNOWN) { };
19 };
20
21 typedef map<entity *, visibility> evismap; 22 typedef map<entity *, evis> evismap;
22 evismap vismap; 23 evismap vismap;
23 24
25 visibility_state state;
26
24 oct_visibility (octant &oct) 27 oct_visibility (octant &oct)
28 : state(FULL)
25 { 29 {
26 } 30 }
27}; 31};
28 32
29octant world(0, sector (SOFFS_MIN, SOFFS_MIN, SOFFS_MIN), MAXEXTENT); 33octant world(0, sector (SOFFS_MIN, SOFFS_MIN, SOFFS_MIN), MAXEXTENT);
30 34
31octant::octant (octant *parent, const sector &orig, uoffs extent) 35octant::octant (octant *parent, const sector &orig, uoffs extent)
32: parent(parent), orig(orig), extent(extent) 36: parent(parent)
37, orig(orig)
38, extent(extent)
33{ 39{
34 for (fill = 8; fill--; ) 40 for (fill = 8; fill--; )
35 sub[fill] = 0; 41 sub[fill] = 0;
36} 42}
37 43
54{ 60{
55 ea /= 2; 61 ea /= 2;
56 62
57 sector center_1 = o1 + ea; 63 sector center_1 = o1 + ea;
58 sector size_2 = b - a; 64 sector size_2 = b - a;
59 sector center_2 = a + size_2 / 2; 65 sector center_2 = a + (size_2 >> 1);
60 66
61 return abs (center_1 - center_2) <= ea + size_2; 67 return abs (center_1 - center_2) <= ea + size_2;
62} 68}
63 69
64void octant::add (entity *e) 70void octant::add (entity *e)
66 const sector &a = e->a; 72 const sector &a = e->a;
67 const sector &b = e->b; 73 const sector &b = e->b;
68 74
69 if (overlap (orig, extent, a, b)) 75 if (overlap (orig, extent, a, b))
70 { 76 {
71 uoffs extent2 = extent / 2; 77 uoffs extent2 = extent >> 1;
72 uoffs size = max (abs (b - a)); 78 uoffs size = max (abs (b - a));
73 79
74 if (size >= extent2 / 2) 80 if (size >= extent2 >> 1)
75 { 81 {
76 push_back (e); 82 push_back (e);
77 e->o.push_back (this); 83 e->o.push_back (this);
78 return; 84 return;
79 } 85 }
99 105
100void octant::remove (entity *e) 106void octant::remove (entity *e)
101{ 107{
102} 108}
103 109
104bool octant::detect_visibility (view &ctx) 110bool octant::depth_pass (view &ctx)
105{ 111{
106 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 112 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
107 113
108 GLfloat extent2 = 0.5F * (GLfloat)extent; 114 GLfloat extent2 = 0.5F * (GLfloat)extent;
109 sector centeri = orig + (extent >> 1) - ctx.orig; 115 sector centeri = orig + (extent >> 1) - ctx.orig;
110 point centerf = point (centeri) + ((extent & 1) ? 0.5F : 0.F); 116 point centerf = point (centeri) + ((extent & 1) ? 0.5F : 0.F);
111 117
112 GLfloat rad = ctx.diagfact * extent2; 118 GLfloat rad = ctx.diagfact * extent2;
113 119
114 if (orig <= ctx.orig && ctx.orig <= orig + extent) 120 if (orig <= ctx.orig && ctx.orig <= orig + extent)
115 ;//vs.visibility = visibility_state::PARTIAL; 121 vs.state = PARTIAL;
116 else 122 else
117 { 123 {
118 if (ctx.frustum.t.distance (centerf) < -rad) return false; 124 if (ctx.frustum.t.distance (centerf) < -rad) return false;
119 if (ctx.frustum.b.distance (centerf) < -rad) return false; 125 if (ctx.frustum.b.distance (centerf) < -rad) return false;
120 if (ctx.frustum.l.distance (centerf) < -rad) return false; 126 if (ctx.frustum.l.distance (centerf) < -rad) return false;
125 131
126 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F) 132 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F)
127 return false; 133 return false;
128 } 134 }
129 135
130#if 0 136 if (vs.state == OCCLUDED)
131 if (vs.visibility == visibility_state::OCCLUDED 137 return false;
132 || vs.visibility == visibility_state::UNKNOWN)
133 {
134 ctx.farlist.push_back (this);
135 return;
136 }
137#endif
138
139#if 0
140 if (vs.visibility == visibility_state::UNKNOWN)
141 vs.visibility = visibility_state::FULL;
142#endif
143 138
144 GLfloat z = ctx.z_near + ctx.frustum.n.distance (centerf) + rad; 139 GLfloat z = ctx.z_near + ctx.frustum.n.distance (centerf) + rad;
145 //printf ("z %f, perspfact %f, z*p %f\n", z, ctx.perspfact, ctx.perspfact / z); 140 //printf ("z %f, perspfact %f, z*p %f\n", z, ctx.perspfact, ctx.perspfact / z);
146 141
147#if 0 142 if (vs.state == PARTIAL || vs.state == FULL)
148 if (vs.visibility == visibility_state::FULL)
149#endif
150 ctx.nc_far = max (ctx.nc_far, z); 143 ctx.nc_far = max (ctx.nc_far, z);
151 144
152 // node to start with 145 // node to start with
153 unsigned char si = centeri.x > 0 ? 1 : 0 146 unsigned char si = centeri.x > 0 ? 1 : 0
154 | centeri.y > 0 ? 2 : 0 147 | centeri.y > 0 ? 2 : 0
164 do 157 do
165 { 158 {
166 si ^= *next; 159 si ^= *next;
167 160
168 if (sub[si]) 161 if (sub[si])
169 sub[si]->detect_visibility (ctx); 162 sub[si]->depth_pass (ctx);
170 } 163 }
171 while (*++next); 164 while (*++next);
172 165
173 if (size () 166 if (size ()
174#if 0 167 && (vs.state == PARTIAL || vs.state == FULL))
175 && (vs.visibility == visibility_state::PARTIAL
176 || vs.visibility == visibility_state::FULL)
177#endif
178 )
179 { 168 {
180 ctx.nz_far = max (ctx.nz_far, z); 169 ctx.nz_far = max (ctx.nz_far, z);
170 display (ctx);
181 ctx.vislist.push_back (this); 171 ctx.vislist.push_back (this);
182 } 172 }
183 173
184 return true; 174 return true;
185} 175}
208 } 198 }
209 } 199 }
210 200
211 glEnd (); 201 glEnd ();
212#endif 202#endif
203 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
213 204
205 if (vs.state == OCCLUDED)
206 {
207 abort ();
208 if (ctx.pass == view::POSTDEPTH)
209 {
210 if (!vb_bbox)
211 {
212 sector s = orig - ctx.orig;
213 gl::gen_bbox (vb_bbox, s, s + extent);
214 }
215
216 ctx.begin_occ_query (*this, 0);
217 vb_bbox.draw (gl::bbox_mode, 0, gl::bbox_count);
218 ctx.end_occ_query ();
219 }
220 }
221 else
222 {
214 for (iterator i = end (); i != begin (); ) 223 for (iterator i = end (); i != begin (); )
215 { 224 {
216 entity *e = *--i; 225 entity *e = *--i;
217 226
218 sector diff = (e->a + e->b) / 2 - ctx.orig; 227 if (!ctx.may_draw (e))
219 GLfloat z = norm (vec3 ((e->a + e->b) / 2 - ctx.orig)); 228 continue;
229
230 evis &evs = vs.vismap[e];
231
232 if (ctx.pass == view::POSTDEPTH)
233 {
234 if (evs.state == OCCLUDED)
235 {
236 if (!e->vb_bbox)
237 gl::gen_bbox (e->vb_bbox, e->a - ctx.orig, e->b - ctx.orig);
238
239 ctx.begin_occ_query (*this, e);
240 e->vb_bbox.draw (gl::bbox_mode, 0, gl::bbox_count);
241 ctx.end_occ_query ();
242 }
243 }
244 else
245 {
246 if (evs.state != OCCLUDED)
247 {
248 sector center = ((e->a + e->b) >> 1) - ctx.orig;
249 GLfloat z = norm (vec3 (center));
220 ctx.pixfact = ctx.perspfact / z; 250 ctx.pixfact = ctx.perspfact / z;
221 251
222 if (ctx.mode != view::POSTDEPTH) 252 if (ctx.pass == view::DEPTH || evs.last + 1. > timer.now)
223 e->display (ctx); 253 e->draw (ctx);
254 else
255 {
256 evs.last = timer.now;
257 ctx.begin_occ_query (*this, e);
258 e->draw (ctx);
259 ctx.end_occ_query ();
260 }
261 }
262 }
263 }
224 } 264 }
225} 265}
226 266
227#if 0 267#if 0
228void octant::draw_bbox (view &ctx) 268void octant::draw_bbox (view &ctx)
233} 273}
234#endif 274#endif
235 275
236void octant::event (occ_query &ev) 276void octant::event (occ_query &ev)
237{ 277{
278 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx);
279 entity *e = (entity *)ev.id;
280
281 if (e)
282 {
283 evis &evs = vs.vismap[e];
284 evs.state = ev.count ? FULL : OCCLUDED;
285 }
286 else
287 {
288 vs.state = ev.count ? FULL : OCCLUDED;
289 }
290
238#if 0 291#if 0
239 visibility_state &vs = ev.v.vismap[this]; 292 visibility_state &vs = ev.v.vismap[this];
240 293
241 vs.last = timer.now; 294 vs.last = timer.now;
242 vs.visibility = ev.r <= 0 295 vs.state = ev.r <= 0
243 ? visibility_state::OCCLUDED 296 ? visibility_state::OCCLUDED
244 : visibility_state::FULL; 297 : visibility_state::FULL;
245#endif 298#endif
246} 299}
247 300

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines