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

Comparing libgender/oct.C (file contents):
Revision 1.74 by root, Sun Nov 7 03:28:20 2004 UTC vs.
Revision 1.75 by root, Tue Nov 9 22:24:14 2004 UTC

28 : state(FULL) 28 : state(FULL)
29 { 29 {
30 } 30 }
31}; 31};
32 32
33octant world(0, sector (SOFFS_MIN, SOFFS_MIN, SOFFS_MIN), MAXEXTENT); 33octant world(0, sector (0, 0, 0), MAXEXTENT);
34 34
35octant::octant (octant *parent, const sector &orig, uoffs extent) 35octant::octant (octant *parent, const sector &orig, uoffs extent)
36: parent(parent) 36: parent(parent)
37, orig(orig) 37, orig(orig)
38, extent(extent) 38, extent(extent)
47} 47}
48 48
49void octant::clear_visibility (visibility_base *vs) 49void octant::clear_visibility (visibility_base *vs)
50{ 50{
51 ((oct_visibility *)vs)->vismap.clear (); 51 ((oct_visibility *)vs)->vismap.clear ();
52 ((oct_visibility *)vs)->state = FULL;
52} 53}
53 54
54octant::~octant () 55octant::~octant ()
55{ 56{
56 for (fill = 8; fill--; ) 57 for (fill = 8; fill--; )
57 delete sub[fill]; 58 delete sub[fill];
58} 59}
59 60
60static bool overlap (const sector &o1, uoffs ea, const sector &a, const sector &b) 61static bool overlap (const sector &orig, uoffs extent, const sector &a, const sector &b)
61{ 62{
62 ea /= 2; 63 sector size = (b - a + 1) >> 1;
63
64 sector center_1 = o1 + ea; 64 sector center = a + size;
65 sector size_2 = b - a;
66 sector center_2 = a + (size_2 >> 1);
67 65
68 return abs (center_1 - center_2) <= ea + size_2; 66 return abs (orig - center) <= extent + size;
67}
68
69static sector offset (const sector &s, int subindex, uoffs extent)
70{
71 return sector (
72 s.x + (subindex & 1 ? extent : -extent),
73 s.y + (subindex & 2 ? extent : -extent),
74 s.z + (subindex & 4 ? extent : -extent)
75 );
69} 76}
70 77
71void octant::add (entity *e) 78void octant::add (entity *e)
72{ 79{
73 const sector &a = e->a; 80 const sector &a = e->a;
76 if (overlap (orig, extent, a, b)) 83 if (overlap (orig, extent, a, b))
77 { 84 {
78 uoffs extent2 = extent >> 1; 85 uoffs extent2 = extent >> 1;
79 uoffs size = max (abs (b - a)); 86 uoffs size = max (abs (b - a));
80 87
81 if (size >= extent2 >> 1) 88 if (size >= extent2)
82 { 89 {
83 push_back (e); 90 push_back (e);
84 e->o.push_back (this); 91 e->o.push_back (this);
85 return; 92 return;
86 } 93 }
87 94
88 for (int i = 8; i--; ) 95 for (int i = 8; i--; )
89 { 96 {
90 sector s = orig;
91 s.offset (i, extent2); 97 sector s = offset (orig, i, extent2);
92 98
93 if (overlap (s, extent2, a, b)) 99 if (overlap (s, extent2, a, b))
94 { 100 {
95 if (!sub[i]) 101 if (!sub[i])
96 { 102 {
108{ 114{
109} 115}
110 116
111bool octant::detect_visibility (view &ctx) 117bool octant::detect_visibility (view &ctx)
112{ 118{
113 GLfloat extent2 = 0.5F * (GLfloat)extent;
114 sector centeri = orig + (extent >> 1) - ctx.orig; 119 sector centeri = orig - ctx.orig;
115 point centerf = point (centeri) + ((extent & 1) ? 0.5F : 0.F); 120 point centerf = point (centeri);
116 121
117 GLfloat rad = ctx.diagfact * extent2; 122 GLfloat rad = ctx.diagfact * extent;
118 123
119 if (!overlap (ctx.frustum.c, sphere (centerf, rad))) 124 if (!overlap (ctx.frustum.c, sphere (centerf, rad)))
120 return false; 125 return false;
121 126
122 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 127 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
123 128
124 if (orig <= ctx.orig && ctx.orig <= orig + extent) 129 if (max (abs (centeri)) <= extent)
125 vs.state = PARTIAL; 130 vs.state = PARTIAL;
126 else 131 else
127 { 132 {
128 if (distance (ctx.frustum.t, centerf) < -rad) return false; 133 if (distance (ctx.frustum.t, centerf) < -rad) return false;
129 if (distance (ctx.frustum.b, centerf) < -rad) return false; 134 if (distance (ctx.frustum.b, centerf) < -rad) return false;
146 ctx.vislist.push_back (this); 151 ctx.vislist.push_back (this);
147 return false; 152 return false;
148 } 153 }
149#endif 154#endif
150 155
156 // very important, optimize?
151 GLfloat z = ctx.z_near + distance (ctx.frustum.n, centerf) + rad; 157 GLfloat z = ctx.z_near + distance (ctx.frustum.n, centerf) + rad;
152 if (ctx.perspfact * extent / z < 1.) // very crude "too small to see" check 158 if (ctx.perspfact * extent / z < 1.) // very crude "too small to see" check
153 return false; 159 return false;
154 //printf ("z %f, perspfact %f, z*p %f\n", z, ctx.perspfact, ctx.perspfact / z);
155 160
156#if 0 161#if 0
157 if (vs.state == PARTIAL || vs.state == FULL) 162 if (vs.state == PARTIAL || vs.state == FULL)
158 ctx.nc_far = max (ctx.nc_far, z); 163 ctx.nc_far = max (ctx.nc_far, z);
159#endif 164#endif
197 } 202 }
198 203
199 return visible; 204 return visible;
200} 205}
201 206
202void octant::display (view &ctx) 207void octant::draw_depth (view &ctx)
203{ 208{
204 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 209 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
205 210
206 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED) 211 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED)
212 return;
213
214 for (iterator i = begin (); i != end (); )
207 { 215 {
208 if (ctx.pass->type == POSTDEPTH) 216 entity *e = *i++;
217
218 evis &evs = vs.vismap[e];
219
220 if (evs.state != OCCLUDED)
221 {
222 if (!ctx.may_draw (e))
223 continue;
224
225 sector center = ((e->a + e->b) >> 1) - ctx.orig;
226 GLfloat z = length (vec3 (center));
227 ctx.pixfact = ctx.perspfact / z;
228
229 ctx.nz_far = max (ctx.nz_far, z + extent);
230 ctx.nz_near = min (ctx.nz_near, z - extent);
231
232 e->draw (ctx);
209 { 233 }
234 }
235}
236
237void octant::draw_postdepth (view &ctx)
238{
239 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
240
241 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED)
242 {
210 ctx.begin_occ_query (*this, 0); 243 ctx.begin_occ_query (*this, 0);
211 sector s = orig - ctx.orig; 244 sector s = orig - ctx.orig;
212 gl::draw_bbox (s, s + extent); 245 gl::draw_bbox (s - extent, s + extent);
213 ctx.end_occ_query (); 246 ctx.end_occ_query ();
214 }
215 } 247 }
216 else 248 else
217 { 249 {
218 int nvis = 0; 250 int nvis = 0;
219 251
221 { 253 {
222 entity *e = *i++; 254 entity *e = *i++;
223 255
224 evis &evs = vs.vismap[e]; 256 evis &evs = vs.vismap[e];
225 257
226 if (ctx.pass->type == POSTDEPTH) 258 if (evs.state == OCCLUDED)
227 { 259 {
228 if (evs.state == OCCLUDED) 260 if (!ctx.may_draw (e))
229 { 261 continue;
262
230 ctx.begin_occ_query (*this, e); 263 ctx.begin_occ_query (*this, e);
231 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig); 264 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig);
232 ctx.end_occ_query (); 265 ctx.end_occ_query ();
233 }
234 else
235 nvis++;
236 } 266 }
237 else 267 else
268 nvis++;
269 }
270
271 if (nvis == 0 && size ())
272 vs.state = OCCLUDED;
273 }
274}
275
276void octant::draw_lighted (view &ctx)
277{
278 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
279
280 if (vs.state == OCCLUDED || vs.state == SUBTREE_OCCLUDED)
281 return;
282
283 for (iterator i = begin (); i != end (); )
284 {
285 entity *e = *i++;
286
287 evis &evs = vs.vismap[e];
288
289 if (evs.state != OCCLUDED)
238 { 290 {
239 if (!ctx.may_draw (e)) 291 if (!ctx.may_draw (e))
240 continue; 292 continue;
241 293
242
243 if (evs.state != OCCLUDED)
244 {
245 sector center = ((e->a + e->b) >> 1) - ctx.orig; 294 sector center = ((e->a + e->b) >> 1) - ctx.orig;
246 GLfloat z = length (vec3 (center)); 295 GLfloat z = length (vec3 (center));
247 ctx.pixfact = ctx.perspfact / z; 296 ctx.pixfact = ctx.perspfact / z;
248 297
249 ctx.nz_far = max (ctx.nz_far, z + extent); 298 if (ctx.pass->type != LIGHTED
250 ctx.nz_near = min (ctx.nz_near, z - extent); 299 || !ctx.first_lighted
251 300 || evs.last + 0.1 > timer.now)
252 if (ctx.pass->type == DEPTH || evs.last + 0.1 > timer.now)
253 e->draw (ctx); 301 e->draw (ctx);
254 else 302 else
255 { 303 {
256 evs.last = timer.now; 304 evs.last = timer.now;
257 ctx.begin_occ_query (*this, e); 305 ctx.begin_occ_query (*this, e);
258 e->draw (ctx); 306 e->draw (ctx);
259 ctx.end_occ_query (); 307 ctx.end_occ_query ();
260 }
261 }
262 } 308 }
263 } 309 }
264
265#if 1
266 if (ctx.pass->type == POSTDEPTH && nvis == 0 && size ())
267 vs.state = OCCLUDED;
268#endif
269 } 310 }
270} 311}
271 312
272void octant::event (occ_query &ev) 313void octant::event (occ_query &ev)
273{ 314{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines