… | |
… | |
75 | |
75 | |
76 | void octant::detect_visibility (view &ctx) |
76 | void octant::detect_visibility (view &ctx) |
77 | { |
77 | { |
78 | visibility_state &vs = ctx.vismap[this]; |
78 | visibility_state &vs = ctx.vismap[this]; |
79 | |
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 | |
80 | if (vs.generation != ctx.generation) |
85 | if (vs.generation != ctx.generation) |
81 | vs.visibility = visibility_state::UNKNOWN; |
86 | vs.visibility = visibility_state::UNKNOWN; |
82 | |
87 | |
|
|
88 | vs.generation = ctx.generation; |
|
|
89 | |
83 | if (orig <= ctx.orig && ctx.orig <= orig + extent) |
90 | if (orig <= ctx.orig && ctx.orig <= orig + extent) |
84 | { |
|
|
85 | vs.visibility = visibility_state::PARTIAL; |
91 | vs.visibility = visibility_state::PARTIAL; |
86 | vs.generation = ctx.generation; |
|
|
87 | } |
|
|
88 | else |
92 | else |
89 | { |
93 | { |
90 | GLfloat extent2 = 0.5F * (GLfloat)extent; |
|
|
91 | point center = point (orig) + extent2 - point (ctx.orig); |
|
|
92 | |
|
|
93 | GLfloat rad = ctx.diagfact * extent2; |
|
|
94 | |
|
|
95 | if (ctx.frustum.t.distance (center) < -rad) return; |
94 | if (ctx.frustum.t.distance (center) < -rad) return; |
96 | if (ctx.frustum.b.distance (center) < -rad) return; |
95 | if (ctx.frustum.b.distance (center) < -rad) return; |
97 | if (ctx.frustum.l.distance (center) < -rad) return; |
96 | if (ctx.frustum.l.distance (center) < -rad) return; |
98 | if (ctx.frustum.r.distance (center) < -rad) return; |
97 | if (ctx.frustum.r.distance (center) < -rad) return; |
99 | if (ctx.frustum.n.distance (center) < -rad) return; |
98 | if (ctx.frustum.n.distance (center) < -rad) return; |
… | |
… | |
117 | vs.visibility = visibility_state::FULL; |
116 | vs.visibility = visibility_state::FULL; |
118 | |
117 | |
119 | if (size () |
118 | if (size () |
120 | && (vs.visibility == visibility_state::PARTIAL |
119 | && (vs.visibility == visibility_state::PARTIAL |
121 | || vs.visibility == visibility_state::FULL)) |
120 | || vs.visibility == visibility_state::FULL)) |
|
|
121 | { |
|
|
122 | ctx.nextfar = max (ctx.nextfar, ctx.near + ctx.frustum.n.distance (center) + extent); |
122 | ctx.vislist.push_back (this); |
123 | ctx.vislist.push_back (this); |
|
|
124 | } |
123 | |
125 | |
124 | // node to start with |
126 | // node to start with |
125 | unsigned char si = ctx.d.x < 0 ? 1 : 0 |
127 | unsigned char si = ctx.d.x < 0 ? 1 : 0 |
126 | | ctx.d.y < 0 ? 2 : 0 |
128 | | ctx.d.y < 0 ? 2 : 0 |
127 | | ctx.d.z < 0 ? 4 : 0; |
129 | | ctx.d.z < 0 ? 4 : 0; |
… | |
… | |
135 | si ^= next[i]; |
137 | si ^= next[i]; |
136 | |
138 | |
137 | if (sub[si]) |
139 | if (sub[si]) |
138 | sub[si]->detect_visibility (ctx); |
140 | sub[si]->detect_visibility (ctx); |
139 | } |
141 | } |
140 | |
|
|
141 | vs.generation = ctx.generation; |
|
|
142 | } |
142 | } |
143 | |
143 | |
144 | void octant::display (view &ctx) |
144 | void octant::display (view &ctx) |
145 | { |
145 | { |
146 | #if 0 |
146 | #if 0 |
… | |
… | |
178 | gl::draw_box (ctx, s, s + extent); |
178 | gl::draw_box (ctx, s, s + extent); |
179 | } |
179 | } |
180 | |
180 | |
181 | void octant::event (occ_query &ev) |
181 | void octant::event (occ_query &ev) |
182 | { |
182 | { |
|
|
183 | ev.v.vismap[this].visibility = visibility_state::FULL; |
|
|
184 | return; |
183 | ev.v.vismap[this].visibility = ev.r < 4 |
185 | ev.v.vismap[this].visibility = ev.r < 4 |
184 | ? visibility_state::OCCLUDED |
186 | ? visibility_state::OCCLUDED |
185 | : visibility_state::FULL; |
187 | : visibility_state::FULL; |
186 | ev.v.far = ev.v.near + ev.v.frustum.n.distance (orig); |
|
|
187 | printf ("OCT(%x,%x,%x+%x) samples %d\n", orig.x, orig.y, orig.z, extent, ev.r); |
188 | printf ("OCT(%x,%x,%x+%x) samples %d\n", orig.x, orig.y, orig.z, extent, ev.r); |
188 | } |
189 | } |
189 | |
190 | |