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

Comparing libgender/oct.C (file contents):
Revision 1.16 by root, Tue Oct 5 07:48:33 2004 UTC vs.
Revision 1.39 by root, Sat Oct 9 16:37:31 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 glGenQueries (1, &id);
27
28 glBeginQuery (GL_SAMPLES_PASSED, id);
29 return id;
30}
31
32#define end_occ_query() glEndQuery (GL_SAMPLES_PASSED);
33
34static GLuint occ_query_result (GLuint id)
35{
36 GLuint count;
37
38 glGetQueryObjectuiv (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::draw (draw_context &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
120 if (vs.generation != ctx.generation) 80 if (vs.generation != ctx.generation)
121 vs.visibility = visibility_state::UNKNOWN; 81 vs.visibility = visibility_state::UNKNOWN;
122 82
123 const sector &cam = ctx.v.orig; 83 if (orig <= ctx.orig && ctx.orig <= orig + extent)
124#if 0
125 if (cam.x >= orig.x && cam.x <= orig.x + extent
126 && cam.y >= orig.y && cam.y <= orig.y + extent
127 && cam.z >= orig.z && cam.z <= orig.z + extent)
128 { 84 {
129 vs.visibility = visibility_state::PARTIAL; 85 vs.visibility = visibility_state::PARTIAL;
130 vs.generation = ctx.generation; 86 vs.generation = ctx.generation;
131 } 87 }
132 else 88 else
133#endif
134 { 89 {
135 //printf ("OCTANT %d,%d,%d+%d\n", orig.x, orig.y, orig.z, extent); 90 GLfloat extent2 = 0.5F * (GLfloat)extent;
136 point center ( 91 point center = point (orig) + extent2 - point (ctx.orig);
137 orig.x + (soffs)extent / 2 - cam.x ,
138 orig.y + (soffs)extent / 2 - cam.y ,
139 orig.z + (soffs)extent / 2 - cam.z
140 );
141 92
142 GLfloat dia = (0.5 * sqrtf (3))*(GLfloat)extent; 93 GLfloat rad = ctx.diagfact * extent2;
143 94
144#if 0
145 printf ("DISTANCE %f,%f,%f TO near: %f\n",
146 center.x, center.y, center.z,
147 ctx.frustum.n.distance (center)
148 );
149#endif
150#if 0
151 printf ("DISTANCE %f,%f,%f TO far: %f\n",
152 center.x, center.y, center.z,
153 ctx.frustum.f.distance (center)
154 );
155#endif
156#if 1
157 if (ctx.frustum.t.distance (center) < -dia) return; 95 if (ctx.frustum.t.distance (center) < -rad) return;
158 if (ctx.frustum.b.distance (center) < -dia) return; 96 if (ctx.frustum.b.distance (center) < -rad) return;
159 if (ctx.frustum.l.distance (center) < -dia) return; 97 if (ctx.frustum.l.distance (center) < -rad) return;
160 if (ctx.frustum.r.distance (center) < -dia) return; 98 if (ctx.frustum.r.distance (center) < -rad) return;
161 if (ctx.frustum.n.distance (center) < -dia) return; 99 if (ctx.frustum.n.distance (center) < -rad) return;
162 if (ctx.frustum.f.distance (center) < -dia) return;
163#endif
164 100
101 GLfloat fd = ctx.frustum.f.distance (center);
102
103 if (fd < -rad)
104 {
105 if (fd < -rad * 3.F)
106 return;
107
108 ctx.farlist.push_back (this);
109 return;
110 }
165 } 111 }
166 112
113 if (vs.visibility == visibility_state::UNKNOWN)
114 vs.visibility = visibility_state::FULL;
115
116 if (size ())
117 ctx.vislist.push_back (this);
118
119 // node to start with
120 unsigned char si = ctx.d.x < 0 ? 1 : 0
121 | ctx.d.y < 0 ? 2 : 0
122 | ctx.d.z < 0 ? 4 : 0;
123
124 // bit-toggle to find next child for front-to-back order
125 static unsigned char next[8]
126 = { 0, 0^1, 1^2, 2^4, 4^3, 3^5, 5^6, 6^7 };
127
128 for (int i = 0; i < 8; i++)
129 {
130 si ^= next[i];
131
132 if (sub[si])
133 sub[si]->detect_visibility (ctx);
134 }
135
136 vs.generation = ctx.generation;
137}
138
139void octant::display (view &ctx)
140{
167#if 1 141#if 0
168 glBegin (GL_LINES); 142 glBegin (GL_LINES);
169 sector s = orig; 143 sector s = orig - ctx.orig;
170 s.x -= ctx.v.orig.x;
171 s.y -= ctx.v.orig.y;
172 s.z -= ctx.v.orig.z;
173 vec3 clr(0, 0.8, 0); 144 vec3 clr(0, 0.8, 0);
174 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, (const GLfloat*)&clr); 145 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, (const GLfloat*)&clr);
175 146
176 for (int i = 8; i--; ) 147 for (int i = 8; i--; )
177 for (int ji = 3; ji--; ) 148 for (int ji = 3; ji--; )
187 s.z + !!(j & 4) * extent); 158 s.z + !!(j & 4) * extent);
188 } 159 }
189 } 160 }
190 161
191 glEnd (); 162 glEnd ();
192 glDisable(GL_COLOR_MATERIAL);
193#endif 163#endif
194 164
195#if 0
196 if (vs.visibility == visibility_state::PARTIAL
197 && vs.generation == ctx.generation)
198#endif
199 {
200 for (iterator i = end (); i-- != begin (); ) 165 for (iterator i = end (); i != begin (); )
201#if 0
202 printf ("draw %p %d,%d,%d (%d,%d,%d - %d,%d,%d)\n", *i,
203 (*i)->orig.x,
204 (*i)->orig.y,
205 (*i)->orig.z,
206 (*i)->bbox.a.x,
207 (*i)->bbox.a.y,
208 (*i)->bbox.a.z,
209 (*i)->bbox.b.x,
210 (*i)->bbox.b.y,
211 (*i)->bbox.b.z
212 ),
213#endif
214 (*i)->display (ctx); 166 (*--i)->display (ctx);
215
216 // node to start with
217 unsigned char si = ctx.v.d.x < 0 ? 1 : 0
218 | ctx.v.d.y < 0 ? 2 : 0
219 | ctx.v.d.z < 0 ? 4 : 0;
220
221 // bit-toggle to find next child for front-to-back order
222 static unsigned char next[8]
223 = { 0, 0^1, 1^2, 2^4, 4^3, 3^5, 5^6, 6^7 };
224
225 for (int i = 0; i < 8; i++)
226 {
227 si ^= next[i];
228
229 if (sub[si])
230 sub[si]->draw (ctx);
231 }
232 }
233
234 vs.generation = ctx.generation;
235} 167}
236 168
169void octant::draw_bbox (view &ctx)
170{
171 sector s = orig - ctx.orig;
237 172
173 gl::draw_box (ctx, s, s + extent);
174}
238 175
176void octant::event (occ_query &ev)
177{
178 if (ev.r <= 5)
179 return;
180
181 //ev.v.vismap[this].visibility = visibility_state::FULL;
182 ev.v.far = ev.v.near + ev.v.frustum.n.distance (orig);
183 printf ("OCT(%x,%x,%x+%x) samples %d\n", orig.x, orig.y, orig.z, extent, ev.r);
184}
185

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines