1 /*
2 * Frustum.cpp
3 * Copyright (C) 2007 by Bryan Duff <duff0097@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20 #include <cmath>
21 #include <GL/gl.h>
22
23 #include "Frustum.h"
24
GetFrustum()25 void FRUSTUM::GetFrustum()
26 {
27 float projmatrix[16];
28 float mvmatrix[16];
29 float clip[16];
30 float t;
31
32 glGetFloatv(GL_PROJECTION_MATRIX, projmatrix);
33 glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix);
34
35 // Combine the matrices
36 clip[0] =
37 mvmatrix[0] * projmatrix[0] + mvmatrix[1] * projmatrix[4] +
38 mvmatrix[2] * projmatrix[8] + mvmatrix[3] * projmatrix[12];
39 clip[1] =
40 mvmatrix[0] * projmatrix[1] + mvmatrix[1] * projmatrix[5] +
41 mvmatrix[2] * projmatrix[9] + mvmatrix[3] * projmatrix[13];
42 clip[2] =
43 mvmatrix[0] * projmatrix[2] + mvmatrix[1] * projmatrix[6] +
44 mvmatrix[2] * projmatrix[10] + mvmatrix[3] * projmatrix[14];
45 clip[3] =
46 mvmatrix[0] * projmatrix[3] + mvmatrix[1] * projmatrix[7] +
47 mvmatrix[2] * projmatrix[11] + mvmatrix[3] * projmatrix[15];
48
49 clip[4] =
50 mvmatrix[4] * projmatrix[0] + mvmatrix[5] * projmatrix[4] +
51 mvmatrix[6] * projmatrix[8] + mvmatrix[7] * projmatrix[12];
52 clip[5] =
53 mvmatrix[4] * projmatrix[1] + mvmatrix[5] * projmatrix[5] +
54 mvmatrix[6] * projmatrix[9] + mvmatrix[7] * projmatrix[13];
55 clip[6] =
56 mvmatrix[4] * projmatrix[2] + mvmatrix[5] * projmatrix[6] +
57 mvmatrix[6] * projmatrix[10] + mvmatrix[7] * projmatrix[14];
58 clip[7] =
59 mvmatrix[4] * projmatrix[3] + mvmatrix[5] * projmatrix[7] +
60 mvmatrix[6] * projmatrix[11] + mvmatrix[7] * projmatrix[15];
61
62 clip[8] =
63 mvmatrix[8] * projmatrix[0] + mvmatrix[9] * projmatrix[4] +
64 mvmatrix[10] * projmatrix[8] + mvmatrix[11] * projmatrix[12];
65 clip[9] =
66 mvmatrix[8] * projmatrix[1] + mvmatrix[9] * projmatrix[5] +
67 mvmatrix[10] * projmatrix[9] + mvmatrix[11] * projmatrix[13];
68 clip[10] =
69 mvmatrix[8] * projmatrix[2] + mvmatrix[9] * projmatrix[6] +
70 mvmatrix[10] * projmatrix[10] + mvmatrix[11] * projmatrix[14];
71 clip[11] =
72 mvmatrix[8] * projmatrix[3] + mvmatrix[9] * projmatrix[7] +
73 mvmatrix[10] * projmatrix[11] + mvmatrix[11] * projmatrix[15];
74
75 clip[12] =
76 mvmatrix[12] * projmatrix[0] + mvmatrix[13] * projmatrix[4] +
77 mvmatrix[14] * projmatrix[8] + mvmatrix[15] * projmatrix[12];
78 clip[13] =
79 mvmatrix[12] * projmatrix[1] + mvmatrix[13] * projmatrix[5] +
80 mvmatrix[14] * projmatrix[9] + mvmatrix[15] * projmatrix[13];
81 clip[14] =
82 mvmatrix[12] * projmatrix[2] + mvmatrix[13] * projmatrix[6] +
83 mvmatrix[14] * projmatrix[10] + mvmatrix[15] * projmatrix[14];
84 clip[15] =
85 mvmatrix[12] * projmatrix[3] + mvmatrix[13] * projmatrix[7] +
86 mvmatrix[14] * projmatrix[11] + mvmatrix[15] * projmatrix[15];
87
88 // Right plane
89 frustum[0][0] = clip[3] - clip[0];
90 frustum[0][1] = clip[7] - clip[4];
91 frustum[0][2] = clip[11] - clip[8];
92 frustum[0][3] = clip[15] - clip[12];
93
94 // Left plane
95 frustum[1][0] = clip[3] + clip[0];
96 frustum[1][1] = clip[7] + clip[4];
97 frustum[1][2] = clip[11] + clip[8];
98 frustum[1][3] = clip[15] + clip[12];
99
100 // Bottom plane
101 frustum[2][0] = clip[3] + clip[1];
102 frustum[2][1] = clip[7] + clip[5];
103 frustum[2][2] = clip[11] + clip[9];
104 frustum[2][3] = clip[15] + clip[13];
105
106 // Top plane
107 frustum[3][0] = clip[3] - clip[1];
108 frustum[3][1] = clip[7] - clip[5];
109 frustum[3][2] = clip[11] - clip[9];
110 frustum[3][3] = clip[15] - clip[13];
111
112 // Far plane
113 frustum[4][0] = clip[3] - clip[2];
114 frustum[4][1] = clip[7] - clip[6];
115 frustum[4][2] = clip[11] - clip[10];
116 frustum[4][3] = clip[15] - clip[14];
117
118 // Near plane
119 frustum[5][0] = clip[3] + clip[2];
120 frustum[5][1] = clip[7] + clip[6];
121 frustum[5][2] = clip[11] + clip[10];
122 frustum[5][3] = clip[15] + clip[14];
123
124 /* normalize the right plane */
125 t = sqrt(frustum[0][0] * frustum[0][0]
126 + frustum[0][1] * frustum[0][1]
127 + frustum[0][2] * frustum[0][2]);
128 frustum[0][0] /= t;
129 frustum[0][1] /= t;
130 frustum[0][2] /= t;
131 frustum[0][3] /= t;
132
133 /* calculate left plane */
134 frustum[1][0] = clip[3] + clip[0];
135 frustum[1][1] = clip[7] + clip[4];
136 frustum[1][2] = clip[11] + clip[8];
137 frustum[1][3] = clip[15] + clip[12];
138
139 /* normalize the left plane */
140 t = sqrt(frustum[1][0] * frustum[1][0]
141 + frustum[1][1] * frustum[1][1]
142 + frustum[1][2] * frustum[1][2]);
143 frustum[1][0] /= t;
144 frustum[1][1] /= t;
145 frustum[1][2] /= t;
146 frustum[1][3] /= t;
147
148 /* calculate the bottom plane */
149 frustum[2][0] = clip[3] + clip[1];
150 frustum[2][1] = clip[7] + clip[5];
151 frustum[2][2] = clip[11] + clip[9];
152 frustum[2][3] = clip[15] + clip[13];
153
154 /* normalize the bottom plane */
155 t = sqrt(frustum[2][0] * frustum[2][0]
156 + frustum[2][1] * frustum[2][1]
157 + frustum[2][2] * frustum[2][2]);
158 frustum[2][0] /= t;
159 frustum[2][1] /= t;
160 frustum[2][2] /= t;
161 frustum[2][3] /= t;
162
163 /* calculate the top plane */
164 frustum[3][0] = clip[3] - clip[1];
165 frustum[3][1] = clip[7] - clip[5];
166 frustum[3][2] = clip[11] - clip[9];
167 frustum[3][3] = clip[15] - clip[13];
168
169 /* normalize the top plane */
170 t = sqrt(frustum[3][0] * frustum[3][0]
171 + frustum[3][1] * frustum[3][1]
172 + frustum[3][2] * frustum[3][2]);
173 frustum[3][0] /= t;
174 frustum[3][1] /= t;
175 frustum[3][2] /= t;
176 frustum[3][3] /= t;
177
178 /* calculate the far plane */
179 frustum[4][0] = clip[3] - clip[2];
180 frustum[4][1] = clip[7] - clip[6];
181 frustum[4][2] = clip[11] - clip[10];
182 frustum[4][3] = clip[15] - clip[14];
183
184 /* normalize the far plane */
185 t = sqrt(frustum[4][0] * frustum[4][0]
186 + frustum[4][1] * frustum[4][1]
187 + frustum[4][2] * frustum[4][2]);
188 frustum[4][0] /= t;
189 frustum[4][1] /= t;
190 frustum[4][2] /= t;
191 frustum[4][3] /= t;
192
193 /* calculate the near plane */
194 frustum[5][0] = clip[3] + clip[2];
195 frustum[5][1] = clip[7] + clip[6];
196 frustum[5][2] = clip[11] + clip[10];
197 frustum[5][3] = clip[15] + clip[14];
198
199 /* normalize the near plane */
200 t = sqrt(frustum[5][0] * frustum[5][0]
201 + frustum[5][1] * frustum[5][1]
202 + frustum[5][2] * frustum[5][2]);
203 frustum[5][0] /= t;
204 frustum[5][1] /= t;
205 frustum[5][2] /= t;
206 frustum[5][3] /= t;
207
208 }
209
CubeInFrustum(float x,float y,float z,float size)210 int FRUSTUM::CubeInFrustum(float x, float y, float z, float size)
211 {
212 int c, c2;
213
214 c2 = 0;
215 for(int i = 0; i < 6; i++) {
216 c = 0;
217 if(frustum[i][0] * (x - size) + frustum[i][1] * (y - size) +
218 frustum[i][2] * (z - size) + frustum[i][3] > 0)
219 c++;
220 if(frustum[i][0] * (x + size) + frustum[i][1] * (y - size) +
221 frustum[i][2] * (z - size) + frustum[i][3] > 0)
222 c++;
223 if(frustum[i][0] * (x - size) + frustum[i][1] * (y + size) +
224 frustum[i][2] * (z - size) + frustum[i][3] > 0)
225 c++;
226 if(frustum[i][0] * (x + size) + frustum[i][1] * (y + size) +
227 frustum[i][2] * (z - size) + frustum[i][3] > 0)
228 c++;
229 if(frustum[i][0] * (x - size) + frustum[i][1] * (y - size) +
230 frustum[i][2] * (z + size) + frustum[i][3] > 0)
231 c++;
232 if(frustum[i][0] * (x + size) + frustum[i][1] * (y - size) +
233 frustum[i][2] * (z + size) + frustum[i][3] > 0)
234 c++;
235 if(frustum[i][0] * (x - size) + frustum[i][1] * (y + size) +
236 frustum[i][2] * (z + size) + frustum[i][3] > 0)
237 c++;
238 if(frustum[i][0] * (x + size) + frustum[i][1] * (y + size) +
239 frustum[i][2] * (z + size) + frustum[i][3] > 0)
240 c++;
241 if(c == 0)
242 return 0;
243 if(c == 8)
244 c2++;
245 }
246 if(c2 >= 6)
247 return 2;
248 else
249 return 1;
250 }
251
CubeInFrustum(float x,float y,float z,float size,float height)252 int FRUSTUM::CubeInFrustum(float x, float y, float z, float size, float height)
253 {
254 int c, c2;
255
256 c2 = 0;
257 for(int i = 0; i < 6; i++) {
258 c = 0;
259 if(frustum[i][0] * (x - size) + frustum[i][1] * (y - height) +
260 frustum[i][2] * (z - size) + frustum[i][3] > 0)
261 c++;
262 if(frustum[i][0] * (x + size) + frustum[i][1] * (y - height) +
263 frustum[i][2] * (z - size) + frustum[i][3] > 0)
264 c++;
265 if(frustum[i][0] * (x - size) + frustum[i][1] * (y + height) +
266 frustum[i][2] * (z - size) + frustum[i][3] > 0)
267 c++;
268 if(frustum[i][0] * (x + size) + frustum[i][1] * (y + height) +
269 frustum[i][2] * (z - size) + frustum[i][3] > 0)
270 c++;
271 if(frustum[i][0] * (x - size) + frustum[i][1] * (y - height) +
272 frustum[i][2] * (z + size) + frustum[i][3] > 0)
273 c++;
274 if(frustum[i][0] * (x + size) + frustum[i][1] * (y - height) +
275 frustum[i][2] * (z + size) + frustum[i][3] > 0)
276 c++;
277 if(frustum[i][0] * (x - size) + frustum[i][1] * (y + height) +
278 frustum[i][2] * (z + size) + frustum[i][3] > 0)
279 c++;
280 if(frustum[i][0] * (x + size) + frustum[i][1] * (y + height) +
281 frustum[i][2] * (z + size) + frustum[i][3] > 0)
282 c++;
283 if(c == 0)
284 return 0;
285 if(c == 8)
286 c2++;
287 }
288 if(c2 >= 6)
289 return 2;
290 else
291 return 1;
292 }
293
SphereInFrustum(float x,float y,float z,float radius)294 int FRUSTUM::SphereInFrustum(float x, float y, float z, float radius)
295 {
296 int c2;
297
298 c2 = 0;
299 for(int i = 0; i < 6; i++) {
300 if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z +
301 frustum[i][3] > -1 * radius)
302 c2++;
303 else
304 return 0;
305 }
306 if(c2 >= 6)
307 return 2;
308 else
309 return 1;
310 }
311