]> git.jsancho.org Git - lugaru.git/blob - Source/Math/Frustum.cpp
Empire: Restore Ash's black fur as intended by the author
[lugaru.git] / Source / Math / Frustum.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "Math/Frustum.hpp"
22
23 #include "Graphic/gamegl.hpp"
24
25 #include <math.h>
26
27 void FRUSTUM::
28     GetFrustum()
29 {
30     static float projmatrix[16];
31     static float mvmatrix[16];
32     static float clip[16];
33
34     glGetFloatv(GL_PROJECTION_MATRIX, projmatrix);
35     glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix);
36
37     // Combine the matrices
38     clip[0] = mvmatrix[0] * projmatrix[0] + mvmatrix[1] * projmatrix[4] + mvmatrix[2] * projmatrix[8] + mvmatrix[3] * projmatrix[12];
39     clip[1] = mvmatrix[0] * projmatrix[1] + mvmatrix[1] * projmatrix[5] + mvmatrix[2] * projmatrix[9] + mvmatrix[3] * projmatrix[13];
40     clip[2] = mvmatrix[0] * projmatrix[2] + mvmatrix[1] * projmatrix[6] + mvmatrix[2] * projmatrix[10] + mvmatrix[3] * projmatrix[14];
41     clip[3] = mvmatrix[0] * projmatrix[3] + mvmatrix[1] * projmatrix[7] + mvmatrix[2] * projmatrix[11] + mvmatrix[3] * projmatrix[15];
42
43     clip[4] = mvmatrix[4] * projmatrix[0] + mvmatrix[5] * projmatrix[4] + mvmatrix[6] * projmatrix[8] + mvmatrix[7] * projmatrix[12];
44     clip[5] = mvmatrix[4] * projmatrix[1] + mvmatrix[5] * projmatrix[5] + mvmatrix[6] * projmatrix[9] + mvmatrix[7] * projmatrix[13];
45     clip[6] = mvmatrix[4] * projmatrix[2] + mvmatrix[5] * projmatrix[6] + mvmatrix[6] * projmatrix[10] + mvmatrix[7] * projmatrix[14];
46     clip[7] = mvmatrix[4] * projmatrix[3] + mvmatrix[5] * projmatrix[7] + mvmatrix[6] * projmatrix[11] + mvmatrix[7] * projmatrix[15];
47
48     clip[8] = mvmatrix[8] * projmatrix[0] + mvmatrix[9] * projmatrix[4] + mvmatrix[10] * projmatrix[8] + mvmatrix[11] * projmatrix[12];
49     clip[9] = mvmatrix[8] * projmatrix[1] + mvmatrix[9] * projmatrix[5] + mvmatrix[10] * projmatrix[9] + mvmatrix[11] * projmatrix[13];
50     clip[10] = mvmatrix[8] * projmatrix[2] + mvmatrix[9] * projmatrix[6] + mvmatrix[10] * projmatrix[10] + mvmatrix[11] * projmatrix[14];
51     clip[11] = mvmatrix[8] * projmatrix[3] + mvmatrix[9] * projmatrix[7] + mvmatrix[10] * projmatrix[11] + mvmatrix[11] * projmatrix[15];
52
53     clip[12] = mvmatrix[12] * projmatrix[0] + mvmatrix[13] * projmatrix[4] + mvmatrix[14] * projmatrix[8] + mvmatrix[15] * projmatrix[12];
54     clip[13] = mvmatrix[12] * projmatrix[1] + mvmatrix[13] * projmatrix[5] + mvmatrix[14] * projmatrix[9] + mvmatrix[15] * projmatrix[13];
55     clip[14] = mvmatrix[12] * projmatrix[2] + mvmatrix[13] * projmatrix[6] + mvmatrix[14] * projmatrix[10] + mvmatrix[15] * projmatrix[14];
56     clip[15] = mvmatrix[12] * projmatrix[3] + mvmatrix[13] * projmatrix[7] + mvmatrix[14] * projmatrix[11] + mvmatrix[15] * projmatrix[15];
57
58     // Right plane
59     frustum[0][0] = clip[3] - clip[0];
60     frustum[0][1] = clip[7] - clip[4];
61     frustum[0][2] = clip[11] - clip[8];
62     frustum[0][3] = clip[15] - clip[12];
63
64     // Left plane
65     frustum[1][0] = clip[3] + clip[0];
66     frustum[1][1] = clip[7] + clip[4];
67     frustum[1][2] = clip[11] + clip[8];
68     frustum[1][3] = clip[15] + clip[12];
69
70     // Bottom plane
71     frustum[2][0] = clip[3] + clip[1];
72     frustum[2][1] = clip[7] + clip[5];
73     frustum[2][2] = clip[11] + clip[9];
74     frustum[2][3] = clip[15] + clip[13];
75
76     // Top plane
77     frustum[3][0] = clip[3] - clip[1];
78     frustum[3][1] = clip[7] - clip[5];
79     frustum[3][2] = clip[11] - clip[9];
80     frustum[3][3] = clip[15] - clip[13];
81
82     // Far plane
83     frustum[4][0] = clip[3] - clip[2];
84     frustum[4][1] = clip[7] - clip[6];
85     frustum[4][2] = clip[11] - clip[10];
86     frustum[4][3] = clip[15] - clip[14];
87
88     // Near plane
89     frustum[5][0] = clip[3] + clip[2];
90     frustum[5][1] = clip[7] + clip[6];
91     frustum[5][2] = clip[11] + clip[10];
92     frustum[5][3] = clip[15] + clip[14];
93 }
94
95 int FRUSTUM::
96     CubeInFrustum(float x, float y, float z, float size)
97 {
98     static int c, c2;
99
100     for (int i = 0; i < 6; i++) {
101         c = 0;
102         if (frustum[i][0] * (x - size) + frustum[i][1] * (y - size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
103             c++;
104         }
105         if (frustum[i][0] * (x + size) + frustum[i][1] * (y - size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
106             c++;
107         }
108         if (frustum[i][0] * (x - size) + frustum[i][1] * (y + size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
109             c++;
110         }
111         if (frustum[i][0] * (x + size) + frustum[i][1] * (y + size) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
112             c++;
113         }
114         if (frustum[i][0] * (x - size) + frustum[i][1] * (y - size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
115             c++;
116         }
117         if (frustum[i][0] * (x + size) + frustum[i][1] * (y - size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
118             c++;
119         }
120         if (frustum[i][0] * (x - size) + frustum[i][1] * (y + size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
121             c++;
122         }
123         if (frustum[i][0] * (x + size) + frustum[i][1] * (y + size) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
124             c++;
125         }
126         if (c == 0) {
127             return 0;
128         }
129         if (c == 8) {
130             c2++;
131         }
132     }
133     if (c2 >= 6) {
134         return 2;
135     } else {
136         return 1;
137     }
138 }
139
140 int FRUSTUM::
141     CubeInFrustum(float x, float y, float z, float size, float height)
142 {
143     static int c, c2;
144
145     for (int i = 0; i < 6; i++) {
146         c = 0;
147         if (frustum[i][0] * (x - size) + frustum[i][1] * (y - height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
148             c++;
149         }
150         if (frustum[i][0] * (x + size) + frustum[i][1] * (y - height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
151             c++;
152         }
153         if (frustum[i][0] * (x - size) + frustum[i][1] * (y + height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
154             c++;
155         }
156         if (frustum[i][0] * (x + size) + frustum[i][1] * (y + height) + frustum[i][2] * (z - size) + frustum[i][3] > 0) {
157             c++;
158         }
159         if (frustum[i][0] * (x - size) + frustum[i][1] * (y - height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
160             c++;
161         }
162         if (frustum[i][0] * (x + size) + frustum[i][1] * (y - height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
163             c++;
164         }
165         if (frustum[i][0] * (x - size) + frustum[i][1] * (y + height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
166             c++;
167         }
168         if (frustum[i][0] * (x + size) + frustum[i][1] * (y + height) + frustum[i][2] * (z + size) + frustum[i][3] > 0) {
169             c++;
170         }
171         if (c == 0) {
172             return 0;
173         }
174         if (c == 8) {
175             c2++;
176         }
177     }
178     if (c2 >= 6) {
179         return 2;
180     } else {
181         return 1;
182     }
183 }
184
185 int FRUSTUM::
186     SphereInFrustum(float x, float y, float z, float radius)
187 {
188     static int c2;
189
190     for (int i = 0; i < 6; i++) {
191         if (frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] > -1 * radius) {
192             c2++;
193         } else {
194             return 0;
195         }
196     }
197     if (c2 >= 6) {
198         return 2;
199     } else {
200         return 1;
201     }
202 }