Antkeeper  0.0.1
view-frustum.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef ANTKEEPER_GEOM_PRIMITIVES_VIEW_FRUSTUM_HPP
21 #define ANTKEEPER_GEOM_PRIMITIVES_VIEW_FRUSTUM_HPP
22 
23 #include <engine/math/vector.hpp>
24 #include <engine/math/matrix.hpp>
28 
29 namespace geom {
30 namespace primitives {
31 
37 template <class T>
39 {
42 
45 
48 
51 
54 
56  constexpr view_frustum() noexcept = default;
57 
63  inline explicit constexpr view_frustum(const matrix_type& matrix) noexcept
64  {
65  extract(matrix);
66  }
67 
70  [[nodiscard]] inline constexpr const plane_type& left() const noexcept
71  {
72  return planes[0];
73  }
74  [[nodiscard]] inline constexpr plane_type& left() noexcept
75  {
76  return planes[0];
77  }
79 
82  [[nodiscard]] inline constexpr const plane_type& right() const noexcept
83  {
84  return planes[1];
85  }
86  [[nodiscard]] inline constexpr plane_type& right() noexcept
87  {
88  return planes[1];
89  }
91 
94  [[nodiscard]] inline constexpr const plane_type& bottom() const noexcept
95  {
96  return planes[2];
97  }
98  [[nodiscard]] inline constexpr plane_type& bottom() noexcept
99  {
100  return planes[2];
101  }
103 
106  [[nodiscard]] inline constexpr const plane_type& top() const noexcept
107  {
108  return planes[3];
109  }
110  [[nodiscard]] inline constexpr plane_type& top() noexcept
111  {
112  return planes[3];
113  }
115 
118  [[nodiscard]] inline constexpr const plane_type& near() const noexcept
119  {
120  return planes[4];
121  }
122  [[nodiscard]] inline constexpr plane_type& near() noexcept
123  {
124  return planes[4];
125  }
127 
130  [[nodiscard]] inline constexpr const plane_type& far() const noexcept
131  {
132  return planes[5];
133  }
134  [[nodiscard]] inline constexpr plane_type& far() noexcept
135  {
136  return planes[5];
137  }
139 
145  void extract(const matrix_type& matrix) noexcept
146  {
147  for (std::size_t i = 0; i < 6; ++i)
148  {
149  plane_type& plane = planes[i];
150  const std::size_t j = i >> 1;
151 
152  // Extract plane coefficients
153  if (i % 2)
154  {
155  plane.normal.x() = matrix[0][3] - matrix[0][j];
156  plane.normal.y() = matrix[1][3] - matrix[1][j];
157  plane.normal.z() = matrix[2][3] - matrix[2][j];
158  plane.constant = matrix[3][3] - matrix[3][j];
159  }
160  else
161  {
162  plane.normal.x() = matrix[0][3] + matrix[0][j];
163  plane.normal.y() = matrix[1][3] + matrix[1][j];
164  plane.normal.z() = matrix[2][3] + matrix[2][j];
165  plane.constant = matrix[3][3] + matrix[3][j];
166  }
167 
168  // Normalize plane coefficients
172  }
173  }
174 
182  [[nodiscard]] bool intersects(const box_type& box) const noexcept
183  {
184  for (const auto& plane: planes)
185  {
186  const vector_type p
187  {
188  (plane.normal.x() > T{0}) ? box.max.x() : box.min.x(),
189  (plane.normal.y() > T{0}) ? box.max.y() : box.min.y(),
190  (plane.normal.z() > T{0}) ? box.max.z() : box.min.z()
191  };
192 
193  if (plane.distance(p) < T{0})
194  {
195  return false;
196  }
197  }
198 
199  return true;
200  }
201 
209  [[nodiscard]] bool intersects(const sphere_type& sphere) const noexcept
210  {
211  for (const auto& plane: planes)
212  {
214  {
215  return false;
216  }
217  }
218 
219  return true;
220  }
221 
229  [[nodiscard]] constexpr bool contains(const vector_type& point) const noexcept
230  {
231  for (const auto& plane: planes)
232  {
233  if (plane.distance(point) < T{0})
234  {
235  return false;
236  }
237  }
238 
239  return true;
240  }
241 
249  [[nodiscard]] bool contains(const box_type& box) const noexcept
250  {
251  for (const auto& plane: planes)
252  {
253  const vector_type p
254  {
255  (plane.normal.x() > T{0}) ? box.max.x() : box.min.x(),
256  (plane.normal.y() > T{0}) ? box.max.y() : box.min.y(),
257  (plane.normal.z() > T{0}) ? box.max.z() : box.min.z()
258  };
259 
260  const vector_type n
261  {
262  (plane.normal.x() < T{0}) ? box.max.x() : box.min.x(),
263  (plane.normal.y() < T{0}) ? box.max.y() : box.min.y(),
264  (plane.normal.z() < T{0}) ? box.max.z() : box.min.z()
265  };
266 
267  if (plane.distance(p) < T{0} || plane.distance(n) < T{0})
268  {
269  return false;
270  }
271  }
272 
273  return true;
274  }
275 
283  [[nodiscard]] bool contains(const sphere_type& sphere) const noexcept
284  {
285  for (const auto& plane: planes)
286  {
288  {
289  return false;
290  }
291  }
292 
293  return true;
294  }
295 
309 };
310 
311 } // namespace primitives
312 
313 using namespace primitives;
314 
315 } // namespace geom
316 
317 #endif // ANTKEEPER_GEOM_PRIMITIVES_VIEW_FRUSTUM_HPP
Geometric algorithms.
T inv_length(const quaternion< T > &q)
Calculates the inverse length of a quaternion.
Definition: quaternion.hpp:596
n-dimensional plane.
Definition: hyperplane.hpp:36
T constant
Hyperplane constant.
Definition: hyperplane.hpp:44
constexpr T distance(const vector_type &point) const noexcept
Calculates the signed distance from the hyperplane to a point.
Definition: hyperplane.hpp:78
vector_type normal
Hyperplane normal.
Definition: hyperplane.hpp:41
n-dimensional axis-aligned rectangle.
vector_type min
Minimum extent of the hyperrectangle.
vector_type max
Maximum extent of the hyperrectangle.
n-dimensional sphere.
Definition: hypersphere.hpp:37
vector_type center
Hypersphere center.
Definition: hypersphere.hpp:42
T radius
Hypersphere radius.
Definition: hypersphere.hpp:45
constexpr plane_type & right() noexcept
Returns the right clipping plane.
constexpr const plane_type & right() const noexcept
Returns the right clipping plane.
constexpr const plane_type & far() const noexcept
Returns the far clipping plane.
bool intersects(const sphere_type &sphere) const noexcept
Tests for intersection between a sphere and the view frustum.
constexpr view_frustum() noexcept=default
Constructs a view frustum.
constexpr plane_type & near() noexcept
Returns the near clipping plane.
constexpr const plane_type & bottom() const noexcept
Returns the bottom clipping plane.
bool contains(const sphere_type &sphere) const noexcept
Checks if a sphere is completely contained within the view frustum.
void extract(const matrix_type &matrix) noexcept
Extracts the view frustum planes from a view-projection matrix.
plane_type planes[6]
View frustum clipping planes.
constexpr bool contains(const vector_type &point) const noexcept
Tests whether a point is contained within this view frustum.
constexpr plane_type & left() noexcept
Returns the left clipping plane.
constexpr plane_type & top() noexcept
Returns the top clipping plane.
bool contains(const box_type &box) const noexcept
Checks if an axis-aligned box is completely contained within the view frustum.
constexpr const plane_type & top() const noexcept
Returns the top clipping plane.
constexpr plane_type & far() noexcept
Returns the far clipping plane.
bool intersects(const box_type &box) const noexcept
Tests for intersection between an axis-aligned box and the view frustum.
constexpr const plane_type & near() const noexcept
Returns the near clipping plane.
constexpr const plane_type & left() const noexcept
Returns the left clipping plane.
constexpr plane_type & bottom() noexcept
Returns the bottom clipping plane.
n by m column-major matrix.
Definition: math/matrix.hpp:44
n-dimensional vector.
Definition: vector.hpp:44
constexpr element_type & x() noexcept
Returns a reference to the first element.
Definition: vector.hpp:164
constexpr element_type & y() noexcept
Returns a reference to the second element.
Definition: vector.hpp:180
constexpr element_type & z() noexcept
Returns a reference to the third element.
Definition: vector.hpp:196