… | |
… | |
55 | { |
55 | { |
56 | for (fill = 8; fill--; ) |
56 | for (fill = 8; fill--; ) |
57 | delete sub[fill]; |
57 | delete sub[fill]; |
58 | } |
58 | } |
59 | |
59 | |
60 | static bool overlap (const sector &o1, uoffs ea, const box &bbox) |
60 | static bool overlap (const sector &o1, uoffs ea, const sector &a, const sector &b) |
61 | { |
61 | { |
62 | sector a2, b2; |
62 | sector a2, b2; |
63 | |
63 | |
64 | ea /= 2; |
64 | ea /= 2; |
65 | |
65 | |
66 | a2.x = o1.x + ea; |
66 | a2.x = o1.x + ea; |
67 | a2.y = o1.y + ea; |
67 | a2.y = o1.y + ea; |
68 | a2.z = o1.z + ea; |
68 | a2.z = o1.z + ea; |
69 | |
69 | |
70 | b2.x = (bbox.a.x + bbox.b.x) / 2; |
70 | b2.x = (a.x + b.x) / 2; |
71 | b2.y = (bbox.a.y + bbox.b.y) / 2; |
71 | b2.y = (a.y + b.y) / 2; |
72 | b2.z = (bbox.a.z + bbox.b.z) / 2; |
72 | b2.z = (a.z + b.z) / 2; |
73 | |
73 | |
74 | return abs (a2.x - b2.x) <= ea + (bbox.b.x - bbox.a.x) |
74 | return abs (a2.x - b2.x) <= ea + (b.x - a.x) |
75 | && abs (a2.y - b2.y) <= ea + (bbox.b.y - bbox.a.y) |
75 | && abs (a2.y - b2.y) <= ea + (b.y - a.y) |
76 | && abs (a2.z - b2.z) <= ea + (bbox.b.z - bbox.a.z); |
76 | && abs (a2.z - b2.z) <= ea + (b.z - a.z); |
77 | } |
77 | } |
78 | |
78 | |
79 | void octant::add (entity_base *e) |
79 | void octant::add (entity *e) |
80 | { |
80 | { |
81 | box bbox = translate (e->bbox, e->orig, sector (0, 0, 0)); |
81 | const sector &a = e->a; |
|
|
82 | const sector &b = e->b; |
82 | |
83 | |
83 | uoffs size = max (abs (bbox.b.x - bbox.a.x), |
|
|
84 | max (abs (bbox.b.y - bbox.a.y), |
|
|
85 | abs (bbox.b.z - bbox.a.z))); |
|
|
86 | |
|
|
87 | if (overlap (orig, extent, bbox)) |
84 | if (overlap (orig, extent, a, b)) |
88 | { |
85 | { |
89 | uoffs extent2 = extent / 2; |
86 | uoffs extent2 = extent / 2; |
|
|
87 | |
|
|
88 | uoffs size = max (abs (b.x - a.x), |
|
|
89 | max (abs (b.y - a.y), |
|
|
90 | abs (b.z - a.z))); |
90 | |
91 | |
91 | if (size > extent2 || !extent2) |
92 | if (size > extent2 || !extent2) |
92 | { |
93 | { |
93 | push_back (e); |
94 | push_back (e); |
94 | e->o.push_back (this); |
95 | e->o.push_back (this); |
… | |
… | |
97 | |
98 | |
98 | for (int i = 8; i--; ) |
99 | for (int i = 8; i--; ) |
99 | { |
100 | { |
100 | sector s = orig; |
101 | sector s = orig; |
101 | s.offset (i, extent2); |
102 | s.offset (i, extent2); |
|
|
103 | |
102 | if (overlap (s, extent2, bbox)) |
104 | if (overlap (s, extent2, a, b)) |
103 | { |
105 | { |
104 | if (!sub[i]) |
106 | if (!sub[i]) |
105 | sub[i] = new octant (this, s, extent2); |
107 | sub[i] = new octant (this, s, extent2); |
106 | |
108 | |
107 | sub[i]->add (e); |
109 | sub[i]->add (e); |
108 | } |
110 | } |
109 | } |
111 | } |
110 | } |
112 | } |
111 | } |
113 | } |
112 | |
114 | |
113 | void octant::remove (entity_base *e) |
115 | void octant::remove (entity *e) |
114 | { |
116 | { |
115 | } |
117 | } |
116 | |
118 | |
117 | void octant::detect_visibility (view &ctx) |
119 | void octant::detect_visibility (view &ctx) |
118 | { |
120 | { |
… | |
… | |
135 | orig.x + (soffs)extent / 2 - cam.x, |
137 | orig.x + (soffs)extent / 2 - cam.x, |
136 | orig.y + (soffs)extent / 2 - cam.y, |
138 | orig.y + (soffs)extent / 2 - cam.y, |
137 | orig.z + (soffs)extent / 2 - cam.z |
139 | orig.z + (soffs)extent / 2 - cam.z |
138 | ); |
140 | ); |
139 | |
141 | |
140 | GLfloat dia = (0.5 * sqrtf (3))*(GLfloat)extent; |
142 | GLfloat dia = (2. * sqrtf (3))*(GLfloat)extent; |
141 | |
143 | |
142 | if (ctx.frustum.t.distance (center) < -dia) return; |
144 | if (ctx.frustum.t.distance (center) < -dia) return; |
143 | if (ctx.frustum.b.distance (center) < -dia) return; |
145 | if (ctx.frustum.b.distance (center) < -dia) return; |
144 | if (ctx.frustum.l.distance (center) < -dia) return; |
146 | if (ctx.frustum.l.distance (center) < -dia) return; |
145 | if (ctx.frustum.r.distance (center) < -dia) return; |
147 | if (ctx.frustum.r.distance (center) < -dia) return; |
… | |
… | |
152 | if (fd < -dia * 2) |
154 | if (fd < -dia * 2) |
153 | return; |
155 | return; |
154 | |
156 | |
155 | // cull, but do check for potential visibility |
157 | // cull, but do check for potential visibility |
156 | if (size ()) |
158 | if (size ()) |
|
|
159 | { |
157 | ctx.farlist.push_back (this); |
160 | ctx.farlist.push_back (this); |
|
|
161 | return; |
|
|
162 | } |
158 | } |
163 | } |
159 | } |
164 | } |
160 | |
165 | |
161 | if (size ()) |
166 | if (size ()) |
162 | ctx.vislist.push_back (this); |
167 | ctx.vislist.push_back (this); |