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

Comparing libgender/oct.C (file contents):
Revision 1.59 by root, Mon Oct 18 12:01:14 2004 UTC vs.
Revision 1.71 by root, Sun Nov 7 02:28:18 2004 UTC

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} 52}
53
53octant::~octant () 54octant::~octant ()
54{ 55{
55 for (fill = 8; fill--; ) 56 for (fill = 8; fill--; )
56 delete sub[fill]; 57 delete sub[fill];
57} 58}
105 106
106void octant::remove (entity *e) 107void octant::remove (entity *e)
107{ 108{
108} 109}
109 110
110bool octant::depth_pass (view &ctx) 111bool octant::detect_visibility (view &ctx)
111{ 112{
112 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
113
114 GLfloat extent2 = 0.5F * (GLfloat)extent; 113 GLfloat extent2 = 0.5F * (GLfloat)extent;
115 sector centeri = orig + (extent >> 1) - ctx.orig; 114 sector centeri = orig + (extent >> 1) - ctx.orig;
116 point centerf = point (centeri) + ((extent & 1) ? 0.5F : 0.F); 115 point centerf = point (centeri) + ((extent & 1) ? 0.5F : 0.F);
117 116
118 GLfloat rad = ctx.diagfact * extent2; 117 GLfloat rad = ctx.diagfact * extent2;
119 118
120 if (!overlap (ctx.frustum.c, sphere (centerf, rad))) 119 if (!overlap (ctx.frustum.c, sphere (centerf, rad)))
121 return false; 120 return false;
121
122 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
122 123
123 if (orig <= ctx.orig && ctx.orig <= orig + extent) 124 if (orig <= ctx.orig && ctx.orig <= orig + extent)
124 vs.state = PARTIAL; 125 vs.state = PARTIAL;
125 else 126 else
126 { 127 {
136 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F) 137 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F)
137 return false; 138 return false;
138#endif 139#endif
139 } 140 }
140 141
142#if 0
141 if (vs.state == OCCLUDED) 143 if (vs.state == OCCLUDED && size ())
144 {
145 if (size ())
146 ctx.vislist.push_back (this);
142 return false; 147 return false;
148 }
149#endif
143 150
144 GLfloat z = ctx.z_near + distance (ctx.frustum.n, centerf) + rad; 151 GLfloat z = ctx.z_near + distance (ctx.frustum.n, centerf) + rad;
145 if (ctx.perspfact * extent / z < 1.) // very crude "too small to see" check 152 if (ctx.perspfact * extent / z < 1.) // very crude "too small to see" check
146 return false; 153 return false;
147 //printf ("z %f, perspfact %f, z*p %f\n", z, ctx.perspfact, ctx.perspfact / z); 154 //printf ("z %f, perspfact %f, z*p %f\n", z, ctx.perspfact, ctx.perspfact / z);
154 // node to start with 161 // node to start with
155 unsigned char si = centeri.x > 0 ? 1 : 0 162 unsigned char si = centeri.x > 0 ? 1 : 0
156 | centeri.y > 0 ? 2 : 0 163 | centeri.y > 0 ? 2 : 0
157 | centeri.z > 0 ? 4 : 0; 164 | centeri.z > 0 ? 4 : 0;
158 165
159 //printf ("si %d C %Ld,%Ld,%Ld\n", si, centeri.x, centeri.y, centeri.z);
160
161 // bit-toggle to find next child for front-to-back order 166 // bit-toggle to find next child for front-to-back order
162 static unsigned char toggle[8+1] 167 static unsigned char toggle[8+1]
163 = { 0, 0^1, 1^2, 2^4, 4^3, 3^5, 5^6, 6^7, 0 }; 168 = { 0, 0^1, 1^2, 2^4, 4^3, 3^5, 5^6, 6^7, 0 };
164 169
170 bool visible = vs.state == PARTIAL || vs.state == FULL;
171
165 unsigned char *next = toggle; 172 unsigned char *next = toggle;
166 do 173 do
167 { 174 {
168 si ^= *next; 175 si ^= *next;
169 176
170 if (sub[si]) 177 if (sub[si])
171 sub[si]->depth_pass (ctx); 178 visible = visible | sub[si]->detect_visibility (ctx);
172 } 179 }
173 while (*++next); 180 while (*++next);
174 181
182 if (visible)
183 {
175 if (size () 184 if (size ())
176 && (vs.state == PARTIAL || vs.state == FULL)) 185 ctx.vislist.push_back (this);
177 { 186 }
178 display (ctx); 187 else
188 {
189 vs.state = OCCLUDED;
179 ctx.vislist.push_back (this); 190 ctx.vislist.push_back (this);
180 } 191 }
181 192
182 return true; 193 return visible;
183} 194}
184 195
185void octant::display (view &ctx) 196void octant::display (view &ctx)
186{ 197{
187#if 0
188 sector s = orig - ctx.orig;
189
190 glBegin (GL_LINES);
191 vec3 clr(0, 0.8, 0);
192 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, (const GLfloat*)&clr);
193
194 for (int i = 8; i--; )
195 for (int ji = 3; ji--; )
196 {
197 int j = i | (1 << ji);
198 if (i < j)
199 {
200 glVertex3i (s.x + !!(i & 1) * extent,
201 s.y + !!(i & 2) * extent,
202 s.z + !!(i & 4) * extent);
203 glVertex3i (s.x + !!(j & 1) * extent,
204 s.y + !!(j & 2) * extent,
205 s.z + !!(j & 4) * extent);
206 }
207 }
208
209 glEnd ();
210#endif
211 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx); 198 oct_visibility &vs = *(oct_visibility *)get_visibility (ctx);
212 199
213 if (vs.state == OCCLUDED) 200 if (vs.state == OCCLUDED)
214 { 201 {
215 abort ();
216 if (ctx.pass == view::POSTDEPTH) 202 if (ctx.pass_type == view::POSTDEPTH)
217 { 203 {
218 ctx.begin_occ_query (*this, 0); 204 ctx.begin_occ_query (*this, 0);
219 sector s = orig - ctx.orig; 205 sector s = orig - ctx.orig;
220 gl::draw_bbox (vb_bbox, s, s + extent); 206 gl::draw_bbox (s, s + extent);
221 ctx.end_occ_query (); 207 ctx.end_occ_query ();
222 } 208 }
223 } 209 }
224 else 210 else
225 { 211 {
212 int nvis = 0;
213
226 for (iterator i = begin (); i != end (); ) 214 for (iterator i = begin (); i != end (); )
227 { 215 {
228 entity *e = *i++; 216 entity *e = *i++;
229 217
230 if (!ctx.may_draw (e))
231 continue;
232
233 evis &evs = vs.vismap[e]; 218 evis &evs = vs.vismap[e];
234 219
235 if (ctx.pass == view::POSTDEPTH) 220 if (ctx.pass_type == view::POSTDEPTH)
236 { 221 {
237 if (evs.state == OCCLUDED) 222 if (evs.state == OCCLUDED)
238 { 223 {
239 ctx.begin_occ_query (*this, e); 224 ctx.begin_occ_query (*this, e);
240 gl::draw_bbox (vb_bbox, e->a - ctx.orig, e->b - ctx.orig); 225 gl::draw_bbox (e->a - ctx.orig, e->b - ctx.orig);
241 ctx.end_occ_query (); 226 ctx.end_occ_query ();
242 } 227 }
228 else
229 nvis++;
243 } 230 }
244 else 231 else
245 { 232 {
233 if (!ctx.may_draw (e))
234 continue;
235
236
246 if (evs.state != OCCLUDED) 237 if (evs.state != OCCLUDED)
247 { 238 {
248 sector center = ((e->a + e->b) >> 1) - ctx.orig; 239 sector center = ((e->a + e->b) >> 1) - ctx.orig;
249 GLfloat z = length (vec3 (center)); 240 GLfloat z = length (vec3 (center));
250 ctx.pixfact = ctx.perspfact / z; 241 ctx.pixfact = ctx.perspfact / z;
251 242
252 ctx.nz_far = max (ctx.nz_far, z); 243 ctx.nz_far = max (ctx.nz_far, z + extent);
244 ctx.nz_near = min (ctx.nz_near, z - extent);
253 245
254 if (ctx.pass == view::DEPTH || evs.last + 1. > timer.now) 246 if (ctx.pass_type == view::DEPTH || evs.last + 0.3 > timer.now)
255 e->draw (ctx); 247 e->draw (ctx);
256 else 248 else
257 { 249 {
258 evs.last = timer.now; 250 evs.last = timer.now;
259 ctx.begin_occ_query (*this, e); 251 ctx.begin_occ_query (*this, e);
261 ctx.end_occ_query (); 253 ctx.end_occ_query ();
262 } 254 }
263 } 255 }
264 } 256 }
265 } 257 }
266 }
267}
268 258
269#if 0 259#if 1
270void octant::draw_bbox (view &ctx) 260 if (ctx.pass_type == view::POSTDEPTH && nvis == 0 && size ())
271{ 261 vs.state = OCCLUDED;
272 sector s = orig - ctx.orig;
273
274 gl::draw_bbox (ctx, s, s + extent);
275}
276#endif 262#endif
263 }
264}
277 265
278void octant::event (occ_query &ev) 266void octant::event (occ_query &ev)
279{ 267{
280 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx); 268 oct_visibility &vs = *(oct_visibility *)get_visibility (ev.ctx);
281 entity *e = (entity *)ev.id; 269 entity *e = (entity *)ev.id;
284 { 272 {
285 evis &evs = vs.vismap[e]; 273 evis &evs = vs.vismap[e];
286 evs.state = ev.count ? FULL : OCCLUDED; 274 evs.state = ev.count ? FULL : OCCLUDED;
287 } 275 }
288 else 276 else
289 {
290 //vs.state = ev.count ? FULL : OCCLUDED; 277 vs.state = ev.count ? FULL : OCCLUDED;
291 }
292
293#if 0
294 visibility_state &vs = ev.v.vismap[this];
295
296 vs.last = timer.now;
297 vs.state = ev.r <= 0
298 ? visibility_state::OCCLUDED
299 : visibility_state::FULL;
300#endif
301} 278}
302 279
303 280

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines