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

Comparing libgender/oct.C (file contents):
Revision 1.22 by root, Wed Oct 6 02:04:03 2004 UTC vs.
Revision 1.47 by root, Sun Oct 10 02:40:18 2004 UTC

2 2
3#include <vector> 3#include <vector>
4 4
5using namespace std; 5using namespace std;
6 6
7#define GL_GLEXT_PROTOTYPES
8#include <GL/gl.h> 7#include <GL/gl.h>
9 8
10#include "oct.h" 9#include "oct.h"
11#include "view.h" 10#include "view.h"
12#include "entity.h" 11#include "entity.h"
13
14vector<GLuint> occ_query_objects;
15
16static GLuint begin_occ_query ()
17{
18 GLuint id;
19
20 if (occ_query_objects.size ())
21 {
22 id = *(occ_query_objects.end () - 1);
23 occ_query_objects.pop_back ();
24 }
25 else
26 glGenQueriesARB (1, &id);
27
28 glBeginQueryARB (GL_SAMPLES_PASSED, id);
29 return id;
30}
31
32#define end_occ_query() glEndQueryARB (GL_SAMPLES_PASSED);
33
34static GLuint occ_query_result (GLuint id)
35{
36 GLuint count;
37
38 glGetQueryObjectuivARB (id, GL_QUERY_RESULT, &count);
39 occ_query_objects.push_back (id);
40
41 return count;
42}
43 12
44octant world(0, sector (SOFFS_MIN, SOFFS_MIN, SOFFS_MIN), MAXEXTENT); 13octant world(0, sector (SOFFS_MIN, SOFFS_MIN, SOFFS_MIN), MAXEXTENT);
45 14
46octant::octant (octant *parent, const sector &orig, uoffs extent) 15octant::octant (octant *parent, const sector &orig, uoffs extent)
47: parent(parent), orig(orig), extent(extent) 16: parent(parent), orig(orig), extent(extent)
54{ 23{
55 for (fill = 8; fill--; ) 24 for (fill = 8; fill--; )
56 delete sub[fill]; 25 delete sub[fill];
57} 26}
58 27
59static bool overlap (const sector &o1, uoffs ea, const box &bbox) 28static bool overlap (const sector &o1, uoffs ea, const sector &a, const sector &b)
60{ 29{
61 sector a2, b2;
62
63 ea /= 2; 30 ea /= 2;
64 31
65 a2.x = o1.x + ea; 32 sector center_1 = o1 + ea;
66 a2.y = o1.y + ea; 33 sector size_2 = b - a;
67 a2.z = o1.z + ea; 34 sector center_2 = a + size_2 / 2;
68
69 b2.x = (bbox.a.x + bbox.b.x) / 2;
70 b2.y = (bbox.a.y + bbox.b.y) / 2;
71 b2.z = (bbox.a.z + bbox.b.z) / 2;
72 35
73 return abs (a2.x - b2.x) <= ea + (bbox.b.x - bbox.a.x) 36 return abs (center_1 - center_2) <= ea + size_2;
74 && abs (a2.y - b2.y) <= ea + (bbox.b.y - bbox.a.y)
75 && abs (a2.z - b2.z) <= ea + (bbox.b.z - bbox.a.z);
76} 37}
77 38
78void octant::add (entity_base *e) 39void octant::add (entity *e)
79{ 40{
80 box bbox = translate (e->bbox, e->orig, sector (0, 0, 0)); 41 const sector &a = e->a;
42 const sector &b = e->b;
81 43
82 uoffs size = max (abs (bbox.b.x - bbox.a.x),
83 max (abs (bbox.b.y - bbox.a.y),
84 abs (bbox.b.z - bbox.a.z)));
85
86 if (overlap (orig, extent, bbox)) 44 if (overlap (orig, extent, a, b))
87 { 45 {
88 uoffs extent2 = extent / 2; 46 uoffs extent2 = extent / 2;
47 uoffs size = max (abs (b - a));
89 48
90 if (size > extent2 || !extent2) 49 if (size > extent2 || !extent2)
91 { 50 {
92 push_back (e); 51 push_back (e);
93 e->o.push_back (this); 52 e->o.push_back (this);
96 55
97 for (int i = 8; i--; ) 56 for (int i = 8; i--; )
98 { 57 {
99 sector s = orig; 58 sector s = orig;
100 s.offset (i, extent2); 59 s.offset (i, extent2);
60
101 if (overlap (s, extent2, bbox)) 61 if (overlap (s, extent2, a, b))
102 { 62 {
103 if (!sub[i]) 63 if (!sub[i])
104 sub[i] = new octant (this, s, extent2); 64 sub[i] = new octant (this, s, extent2);
105 65
106 sub[i]->add (e); 66 sub[i]->add (e);
107 } 67 }
108 } 68 }
109 } 69 }
110} 70}
111 71
112void octant::remove (entity_base *e) 72void octant::remove (entity *e)
113{ 73{
114} 74}
115 75
116void octant::detect_visibility (view &ctx) 76void octant::detect_visibility (view &ctx)
117{ 77{
118 visibility_state &vs = ctx.vismap[this]; 78 visibility_state &vs = ctx.vismap[this];
119 79
80 GLfloat extent2 = 0.5F * (GLfloat)extent;
81 point center = point (orig + (extent >> 1) - ctx.orig);
82 if (extent & 1) center = center + 0.5F;
83 GLfloat rad = ctx.diagfact * extent2;
84
120 if (vs.generation != ctx.generation) 85 if (vs.generation + 1 != ctx.generation)
121 vs.visibility = visibility_state::UNKNOWN; 86 vs.visibility = visibility_state::UNKNOWN;
122 87
123 const sector &cam = ctx.orig; 88 vs.generation = ctx.generation;
124 if (cam.x >= orig.x && cam.x <= orig.x + extent 89
125 && cam.y >= orig.y && cam.y <= orig.y + extent 90 if (orig <= ctx.orig && ctx.orig <= orig + extent)
126 && cam.z >= orig.z && cam.z <= orig.z + extent)
127 {
128 vs.visibility = visibility_state::PARTIAL; 91 vs.visibility = visibility_state::PARTIAL;
129 vs.generation = ctx.generation;
130 }
131 else 92 else
132 { 93 {
133 point center ( 94 if (ctx.frustum.t.distance (center) < -rad) return;
134 orig.x + (soffs)extent / 2 - cam.x, 95 if (ctx.frustum.b.distance (center) < -rad) return;
135 orig.y + (soffs)extent / 2 - cam.y, 96 if (ctx.frustum.l.distance (center) < -rad) return;
136 orig.z + (soffs)extent / 2 - cam.z 97 if (ctx.frustum.r.distance (center) < -rad) return;
137 ); 98 if (ctx.frustum.n.distance (center) < -rad) return;
138 99
139 GLfloat dia = (0.5 * sqrtf (3))*(GLfloat)extent; 100 GLfloat fd = ctx.frustum.f.distance (center);
140 101
141 if (ctx.frustum.t.distance (center) < -dia) return; 102 if (fd < -(ctx.c_far - ctx.z_far) -rad * 3.F)
142 if (ctx.frustum.b.distance (center) < -dia) return; 103 return;
143 if (ctx.frustum.l.distance (center) < -dia) return;
144 if (ctx.frustum.r.distance (center) < -dia) return;
145 if (ctx.frustum.n.distance (center) < -dia) return;
146 if (ctx.frustum.f.distance (center) < -dia) return;
147 } 104 }
148 105
106 if (vs.visibility == visibility_state::OCCLUDED
107 || vs.visibility == visibility_state::UNKNOWN)
108 {
109 ctx.farlist.push_back (this);
110 return;
111 }
112
113#if 0
114 if (vs.visibility == visibility_state::UNKNOWN)
115 vs.visibility = visibility_state::FULL;
116#endif
117
118 GLfloat z = ctx.z_near + ctx.frustum.n.distance (center) + rad;
119
120 if (vs.visibility == visibility_state::FULL)
121 ctx.nc_far = max (ctx.nc_far, z);
122
149 if (size ()) 123 if (size ()
124 && (vs.visibility == visibility_state::PARTIAL
125 || vs.visibility == visibility_state::FULL))
126 {
127 ctx.nz_far = max (ctx.nz_far, z);
150 ctx.vislist.push_back (this); 128 ctx.vislist.push_back (this);
129 }
151 130
152 // node to start with 131 // node to start with
153 unsigned char si = ctx.d.x < 0 ? 1 : 0 132 unsigned char si = ctx.d.x < 0 ? 1 : 0
154 | ctx.d.y < 0 ? 2 : 0 133 | ctx.d.y < 0 ? 2 : 0
155 | ctx.d.z < 0 ? 4 : 0; 134 | ctx.d.z < 0 ? 4 : 0;
163 si ^= next[i]; 142 si ^= next[i];
164 143
165 if (sub[si]) 144 if (sub[si])
166 sub[si]->detect_visibility (ctx); 145 sub[si]->detect_visibility (ctx);
167 } 146 }
168
169 vs.generation = ctx.generation;
170} 147}
171 148
172void octant::display (view &ctx) 149void octant::display (view &ctx)
173{ 150{
174#if 0 151#if 0
175 glBegin (GL_LINES); 152 glBegin (GL_LINES);
176 sector s = orig; 153 sector s = orig - ctx.orig;
177 s.x -= ctx.orig.x;
178 s.y -= ctx.orig.y;
179 s.z -= ctx.orig.z;
180 vec3 clr(0, 0.8, 0); 154 vec3 clr(0, 0.8, 0);
181 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, (const GLfloat*)&clr); 155 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, (const GLfloat*)&clr);
182 156
183 for (int i = 8; i--; ) 157 for (int i = 8; i--; )
184 for (int ji = 3; ji--; ) 158 for (int ji = 3; ji--; )
194 s.z + !!(j & 4) * extent); 168 s.z + !!(j & 4) * extent);
195 } 169 }
196 } 170 }
197 171
198 glEnd (); 172 glEnd ();
199 glDisable(GL_COLOR_MATERIAL);
200#endif 173#endif
201 174
202 GLuint i = begin_occ_query ();
203 for (iterator i = end (); i != begin (); ) 175 for (iterator i = end (); i != begin (); )
204 (*--i)->display (ctx); 176 (*--i)->display (ctx);
205 end_occ_query ();
206} 177}
207 178
179void octant::draw_bbox (view &ctx)
180{
181 sector s = orig - ctx.orig;
208 182
183 gl::draw_box (ctx, s, s + extent);
184}
209 185
186void octant::event (occ_query &ev)
187{
188 visibility_state &vs = ev.v.vismap[this];
189
190 vs.last = timer.now;
191 vs.visibility = ev.r <= 0
192 ? visibility_state::OCCLUDED
193 : visibility_state::FULL;
194 //if (extent > 0x16)
195 //printf ("OCT(%x,%x,%x+%x) samples %d\n", orig.x, orig.y, orig.z, extent, ev.r);
196}
197

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines