Khaotic Engine Reborn
Loading...
Searching...
No Matches
frustumclass.cpp
1#include "frustumclass.h"
2
3
4FrustumClass::FrustumClass()
5{
6}
7
8
9FrustumClass::FrustumClass(const FrustumClass& other)
10{
11}
12
13
14FrustumClass::~FrustumClass()
15{
16}
17
18void FrustumClass::ConstructFrustum(XMMATRIX viewMatrix, XMMATRIX projectionMatrix, float screenDepth)
19{
20 XMMATRIX finalMatrix;
21 XMFLOAT4X4 projMatrix, matrix;
22 float zMinimum, r, t;
23
24 // Load the projection matrix into a XMFLOAT4X4 structure.
25 XMStoreFloat4x4(&projMatrix, projectionMatrix);
26
27 // Calculate the minimum Z distance in the frustum.
28 zMinimum = -projMatrix._43 / projMatrix._33;
29 r = screenDepth / (screenDepth - zMinimum);
30 projMatrix._33 = r;
31 projMatrix._43 = -r * zMinimum;
32
33 // Load the updated XMFLOAT4X4 back into the original projection matrix.
34 projectionMatrix = XMLoadFloat4x4(&projMatrix);
35
36 // Create the frustum matrix from the view matrix and updated projection matrix.
37 finalMatrix = XMMatrixMultiply(viewMatrix, projectionMatrix);
38
39 // Load the final matrix into a XMFLOAT4X4 structure.
40 XMStoreFloat4x4(&matrix, finalMatrix);
41
42 // Get the near plane of the frustum.
43 m_planes[0].x = matrix._13;
44 m_planes[0].y = matrix._23;
45 m_planes[0].z = matrix._33;
46 m_planes[0].w = matrix._43;
47
48 // Normalize it.
49 t = (float)sqrt((m_planes[0].x * m_planes[0].x) + (m_planes[0].y * m_planes[0].y) + (m_planes[0].z * m_planes[0].z));
50 m_planes[0].x /= t;
51 m_planes[0].y /= t;
52 m_planes[0].z /= t;
53 m_planes[0].w /= t;
54
55 // Calculate the far plane of frustum.
56 m_planes[1].x = matrix._14 - matrix._13;
57 m_planes[1].y = matrix._24 - matrix._23;
58 m_planes[1].z = matrix._34 - matrix._33;
59 m_planes[1].w = matrix._44 - matrix._43;
60
61 // Normalize it.
62 t = (float)sqrt((m_planes[1].x * m_planes[1].x) + (m_planes[1].y * m_planes[1].y) + (m_planes[1].z * m_planes[1].z));
63 m_planes[1].x /= t;
64 m_planes[1].y /= t;
65 m_planes[1].z /= t;
66 m_planes[1].w /= t;
67
68 // Calculate the left plane of frustum.
69 m_planes[2].x = matrix._14 + matrix._11;
70 m_planes[2].y = matrix._24 + matrix._21;
71 m_planes[2].z = matrix._34 + matrix._31;
72 m_planes[2].w = matrix._44 + matrix._41;
73
74 // Normalize it.
75 t = (float)sqrt((m_planes[2].x * m_planes[2].x) + (m_planes[2].y * m_planes[2].y) + (m_planes[2].z * m_planes[2].z));
76 m_planes[2].x /= t;
77 m_planes[2].y /= t;
78 m_planes[2].z /= t;
79 m_planes[2].w /= t;
80
81 // Calculate the right plane of frustum.
82 m_planes[3].x = matrix._14 - matrix._11;
83 m_planes[3].y = matrix._24 - matrix._21;
84 m_planes[3].z = matrix._34 - matrix._31;
85 m_planes[3].w = matrix._44 - matrix._41;
86
87 // Normalize it.
88 t = (float)sqrt((m_planes[3].x * m_planes[3].x) + (m_planes[3].y * m_planes[3].y) + (m_planes[3].z * m_planes[3].z));
89 m_planes[3].x /= t;
90 m_planes[3].y /= t;
91 m_planes[3].z /= t;
92 m_planes[3].w /= t;
93
94 // Calculate the top plane of frustum.
95 m_planes[4].x = matrix._14 - matrix._12;
96 m_planes[4].y = matrix._24 - matrix._22;
97 m_planes[4].z = matrix._34 - matrix._32;
98 m_planes[4].w = matrix._44 - matrix._42;
99
100 // Normalize it.
101 t = (float)sqrt((m_planes[4].x * m_planes[4].x) + (m_planes[4].y * m_planes[4].y) + (m_planes[4].z * m_planes[4].z));
102 m_planes[4].x /= t;
103 m_planes[4].y /= t;
104 m_planes[4].z /= t;
105 m_planes[4].w /= t;
106
107 // Calculate the bottom plane of frustum.
108 m_planes[5].x = matrix._14 + matrix._12;
109 m_planes[5].y = matrix._24 + matrix._22;
110 m_planes[5].z = matrix._34 + matrix._32;
111 m_planes[5].w = matrix._44 + matrix._42;
112
113 // Normalize it.
114 t = (float)sqrt((m_planes[5].x * m_planes[5].x) + (m_planes[5].y * m_planes[5].y) + (m_planes[5].z * m_planes[5].z));
115 m_planes[5].x /= t;
116 m_planes[5].y /= t;
117 m_planes[5].z /= t;
118 m_planes[5].w /= t;
119
120 return;
121}
122
123bool FrustumClass::CheckPoint(float x, float y, float z)
124{
125 int i;
126
127
128 // Check if the point is inside all six planes of the view frustum.
129 for (i = 0; i < 6; i++)
130 {
131 if (((m_planes[i].x * x) + (m_planes[i].y * y) + (m_planes[i].z * z) + m_planes[i].w) < 0.0f)
132 {
133 return false;
134 }
135 }
136
137 return true;
138}
139
140bool FrustumClass::CheckCube(float xCenter, float yCenter, float zCenter, float radius)
141{
142 int i;
143
144
145 // Check if any one point of the cube is in the view frustum.
146 for (i = 0; i < 6; i++)
147 {
148 if (m_planes[i].x * (xCenter - radius) +
149 m_planes[i].y * (yCenter - radius) +
150 m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
151 {
152 continue;
153 }
154
155 if (m_planes[i].x * (xCenter + radius) +
156 m_planes[i].y * (yCenter - radius) +
157 m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
158 {
159 continue;
160 }
161
162 if (m_planes[i].x * (xCenter - radius) +
163 m_planes[i].y * (yCenter + radius) +
164 m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
165 {
166 continue;
167 }
168
169 if (m_planes[i].x * (xCenter + radius) +
170 m_planes[i].y * (yCenter + radius) +
171 m_planes[i].z * (zCenter - radius) + m_planes[i].w >= 0.0f)
172 {
173 continue;
174 }
175
176 if (m_planes[i].x * (xCenter - radius) +
177 m_planes[i].y * (yCenter - radius) +
178 m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
179 {
180 continue;
181 }
182
183 if (m_planes[i].x * (xCenter + radius) +
184 m_planes[i].y * (yCenter - radius) +
185 m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
186 {
187 continue;
188 }
189
190 if (m_planes[i].x * (xCenter - radius) +
191 m_planes[i].y * (yCenter + radius) +
192 m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
193 {
194 continue;
195 }
196
197 if (m_planes[i].x * (xCenter + radius) +
198 m_planes[i].y * (yCenter + radius) +
199 m_planes[i].z * (zCenter + radius) + m_planes[i].w >= 0.0f)
200 {
201 continue;
202 }
203
204 return false;
205 }
206
207 return true;
208}
209
210bool FrustumClass::CheckSphere(float xCenter, float yCenter, float zCenter, float radius)
211{
212 int i;
213
214
215 // Check if the radius of the sphere is inside the view frustum.
216 for (i = 0; i < 6; i++)
217 {
218 if (((m_planes[i].x * xCenter) + (m_planes[i].y * yCenter) + (m_planes[i].z * zCenter) + m_planes[i].w) < -radius)
219 {
220 return false;
221 }
222 }
223
224 return true;
225}
226
227bool FrustumClass::CheckRectangle(float xCenter, float yCenter, float zCenter, float xSize, float ySize, float zSize)
228{
229 int i;
230
231
232 // Check if any of the 6 planes of the rectangle are inside the view frustum.
233 for (i = 0; i < 6; i++)
234 {
235 if (m_planes[i].x * (xCenter - xSize) +
236 m_planes[i].y * (yCenter - ySize) +
237 m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
238 {
239 continue;
240 }
241
242 if (m_planes[i].x * (xCenter + xSize) +
243 m_planes[i].y * (yCenter - ySize) +
244 m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
245 {
246 continue;
247 }
248
249 if (m_planes[i].x * (xCenter - xSize) +
250 m_planes[i].y * (yCenter + ySize) +
251 m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
252 {
253 continue;
254 }
255
256 if (m_planes[i].x * (xCenter - xSize) +
257 m_planes[i].y * (yCenter - ySize) +
258 m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
259 {
260 continue;
261 }
262
263 if (m_planes[i].x * (xCenter + xSize) +
264 m_planes[i].y * (yCenter + ySize) +
265 m_planes[i].z * (zCenter - zSize) + m_planes[i].w >= 0.0f)
266 {
267 continue;
268 }
269
270 if (m_planes[i].x * (xCenter + xSize) +
271 m_planes[i].y * (yCenter - ySize) +
272 m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
273 {
274 continue;
275 }
276
277 if (m_planes[i].x * (xCenter - xSize) +
278 m_planes[i].y * (yCenter + ySize) +
279 m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
280 {
281 continue;
282 }
283
284 if (m_planes[i].x * (xCenter + xSize) +
285 m_planes[i].y * (yCenter + ySize) +
286 m_planes[i].z * (zCenter + zSize) + m_planes[i].w >= 0.0f)
287 {
288 continue;
289 }
290
291 return false;
292 }
293
294 return true;
295}
296