Unravel Engine C++ Reference
Loading...
Searching...
No Matches
frustum.cpp
Go to the documentation of this file.
1#include "frustum.h"
2
3namespace math
4{
5namespace
6{
7
8auto get_transformed_bbox_vertices(const bbox& AABB, const transform& t) -> std::array<vec3, 8>
9{
10 std::array<vec3, 8> vertices;
11
12 vec3 min = AABB.min;
13 vec3 max = AABB.max;
14
15 vertices[0] = t.transform_coord(vec3(min.x, min.y, min.z));
16 vertices[1] = t.transform_coord(vec3(max.x, min.y, min.z));
17 vertices[2] = t.transform_coord(vec3(min.x, max.y, min.z));
18 vertices[3] = t.transform_coord(vec3(max.x, max.y, min.z));
19 vertices[4] = t.transform_coord(vec3(min.x, min.y, max.z));
20 vertices[5] = t.transform_coord(vec3(max.x, min.y, max.z));
21 vertices[6] = t.transform_coord(vec3(min.x, max.y, max.z));
22 vertices[7] = t.transform_coord(vec3(max.x, max.y, max.z));
23
24 return vertices;
25}
26
27} // namespace
28
30{
31 // Initialize values
32 planes.fill(vec4(0.0f, 0.0f, 0.0f, 0.0f));
33 points.fill(vec3(0.0f, 0.0f, 0.0f));
34 position = vec3(0, 0, 0);
35}
36
37frustum::frustum(const transform& View, const transform& Proj, bool homogeneousDepth)
38{
39 update(View, Proj, homogeneousDepth);
40}
41
43{
44 // Compute planes
51
52 // Compute points
53 vec3 e = AABB.get_extents();
54 vec3 p = AABB.get_center();
55 points[volume_geometry_point::left_bottom_near] = vec3(p.x - e.x, p.y - e.y, p.z + e.z);
56 points[volume_geometry_point::left_bottom_far] = vec3(p.x - e.x, p.y - e.y, p.z + e.z);
57 points[volume_geometry_point::right_bottom_near] = vec3(p.x + e.x, p.y - e.y, p.z - e.z);
58 points[volume_geometry_point::right_bottom_far] = vec3(p.x + e.x, p.y - e.y, p.z + e.z);
59 points[volume_geometry_point::left_top_near] = vec3(p.x - e.x, p.y + e.y, p.z + e.z);
60 points[volume_geometry_point::left_top_far] = vec3(p.x - e.x, p.y + e.y, p.z + e.z);
61 points[volume_geometry_point::right_top_near] = vec3(p.x + e.x, p.y + e.y, p.z - e.z);
62 points[volume_geometry_point::right_top_far] = vec3(p.x + e.x, p.y + e.y, p.z + e.z);
63 position = p;
64}
65
66void frustum::update(const transform& view, const transform& proj, bool homogeneousDepth)
67{
68 // Build a combined view & projection matrix
69 const transform m = proj * view;
70
71 // Extract frustum planes from matrix
72 // Planes are in format: normal(xyz), offset(w)
73 // Expects left handed orientation and row_major matrix layout
74 planes[volume_plane::right].data.x = m[0][3] + m[0][0];
75 planes[volume_plane::right].data.y = m[1][3] + m[1][0];
76 planes[volume_plane::right].data.z = m[2][3] + m[2][0];
77 planes[volume_plane::right].data.w = m[3][3] + m[3][0];
78
79 planes[volume_plane::left].data.x = m[0][3] - m[0][0];
80 planes[volume_plane::left].data.y = m[1][3] - m[1][0];
81 planes[volume_plane::left].data.z = m[2][3] - m[2][0];
82 planes[volume_plane::left].data.w = m[3][3] - m[3][0];
83
84 planes[volume_plane::top].data.x = m[0][3] - m[0][1];
85 planes[volume_plane::top].data.y = m[1][3] - m[1][1];
86 planes[volume_plane::top].data.z = m[2][3] - m[2][1];
87 planes[volume_plane::top].data.w = m[3][3] - m[3][1];
88
89 planes[volume_plane::bottom].data.x = m[0][3] + m[0][1];
90 planes[volume_plane::bottom].data.y = m[1][3] + m[1][1];
91 planes[volume_plane::bottom].data.z = m[2][3] + m[2][1];
92 planes[volume_plane::bottom].data.w = m[3][3] + m[3][1];
93
94 planes[volume_plane::far_plane].data.x = m[0][3] - m[0][2];
95 planes[volume_plane::far_plane].data.y = m[1][3] - m[1][2];
96 planes[volume_plane::far_plane].data.z = m[2][3] - m[2][2];
97 planes[volume_plane::far_plane].data.w = m[3][3] - m[3][2];
98
99 if(homogeneousDepth)
100 {
101 planes[volume_plane::near_plane].data.x = m[0][3] + m[0][2];
102 planes[volume_plane::near_plane].data.y = m[1][3] + m[1][2];
103 planes[volume_plane::near_plane].data.z = m[2][3] + m[2][2];
104 planes[volume_plane::near_plane].data.w = m[3][3] + m[3][2];
105 }
106 else
107 {
108 planes[volume_plane::near_plane].data.x = m[0][2];
109 planes[volume_plane::near_plane].data.y = m[1][2];
110 planes[volume_plane::near_plane].data.z = m[2][2];
111 planes[volume_plane::near_plane].data.w = m[3][2];
112 }
113
114 for(auto& plane : planes)
115 {
116 plane.data *= -1.0f;
117 }
118 // Normalize and compute additional information.
120
121 // Compute the originating position of the frustum.
122 position = vec3(view[0][0], view[1][0], view[2][0]) * -view[3][0];
123 position += vec3(view[0][1], view[1][1], view[2][1]) * -view[3][1];
124 position += vec3(view[0][2], view[1][2], view[2][2]) * -view[3][2];
125
126 // Extract the camera forward vector (assuming left-handed and row-major)
127 vec3 forward = -vec3(view[0][2], view[1][2], view[2][2]);
128
129 // Compute near distance
132 dot(vec3(planes[volume_plane::near_plane].data), forward);
133
134 // Compute far distance
137 dot(vec3(planes[volume_plane::far_plane].data), forward);
138}
139
140void frustum::set_planes(const std::array<plane, 6>& new_planes)
141{
142 planes = new_planes;
143 // Copy and normalize the planes
144 for(auto& plane : planes)
145 {
147 }
148
149 // Recompute the frustum corner points.
151}
152
154{
155 // Compute the 8 corner points
156 for(std::size_t i = 0; i < 8; ++i)
157 {
158 const plane& p0 =
162
163 // Compute the point at which the three planes intersect
164 vec3 n0(p0.data);
165 vec3 n1(p1.data);
166 vec3 n2(p2.data);
167
168 vec3 n1_n2 = glm::cross(n1, n2);
169 vec3 n2_n0 = glm::cross(n2, n0);
170 vec3 n0_n1 = glm::cross(n0, n1);
171
172 float cosTheta = glm::dot(n0, n1_n2);
173 float secTheta = 1.0f / cosTheta;
174
175 n1_n2 = n1_n2 * p0.data.w;
176 n2_n0 = n2_n0 * p1.data.w;
177 n0_n1 = n0_n1 * p2.data.w;
178
179 points[i] = -(n1_n2 + n2_n0 + n0_n1) * secTheta;
180
181 } // Next Corner
182}
183
184auto frustum::classify_vertices(const vec3* vertices, size_t count) const -> volume_query
185{
186 // Initialize the result as inside
188
189 // Loop through all the planes
190 for(const auto& plane : planes)
191 {
192 bool allOutside = true;
193 bool anyOutside = false;
194
195 // Check each vertex
196 for(size_t i = 0; i < count; ++i)
197 {
198 float distance = plane::dot_coord(plane, vertices[i]);
199
200 if(distance > 0.0f)
201 {
202 anyOutside = true;
203 }
204 else
205 {
206 allOutside = false;
207 }
208 }
209
210 // If all vertices are outside one plane, the OBB is outside the frustum
211 if(allOutside)
212 {
214 }
215
216 // If any vertex is outside one plane, the OBB intersects the frustum
217 if(anyOutside)
218 {
220 }
221 }
222
223 // Return the classification result
224 return Result;
225}
226
227auto frustum::classify_aabb(const bbox& AABB) const -> volume_query
228{
230 vec3 nearPoint, farPoint;
231
232 for(const auto& plane : planes)
233 {
234 nearPoint.x = plane.data.x > 0.0f ? AABB.min.x : AABB.max.x;
235 farPoint.x = plane.data.x > 0.0f ? AABB.max.x : AABB.min.x;
236
237 nearPoint.y = plane.data.y > 0.0f ? AABB.min.y : AABB.max.y;
238 farPoint.y = plane.data.y > 0.0f ? AABB.max.y : AABB.min.y;
239
240 nearPoint.z = plane.data.z > 0.0f ? AABB.min.z : AABB.max.z;
241 farPoint.z = plane.data.z > 0.0f ? AABB.max.z : AABB.min.z;
242
243 if(plane::dot_coord(plane, nearPoint) > 0.0f)
244 {
246 }
247
248 if(plane::dot_coord(plane, farPoint) > 0.0f)
249 {
251 }
252 }
253
254 return result;
255}
256
257auto frustum::classify_obb(const bbox& AABB, const transform& t) const -> volume_query
258{
259 auto vertices = get_transformed_bbox_vertices(AABB, t);
260 return classify_vertices(vertices.data(), vertices.size());
261}
262
263auto frustum::classify_aabb(const bbox& AABB, unsigned int& frustumBits, int& lastOutside) const -> volume_query
264{
266 vec3 nearPoint, farPoint;
267
268 if(lastOutside >= 0 && ((frustumBits >> lastOutside) & 0x1) == 0x0)
269 {
270 const plane& plane = planes[lastOutside];
271
272 nearPoint.x = plane.data.x > 0.0f ? AABB.min.x : AABB.max.x;
273 farPoint.x = plane.data.x > 0.0f ? AABB.max.x : AABB.min.x;
274
275 nearPoint.y = plane.data.y > 0.0f ? AABB.min.y : AABB.max.y;
276 farPoint.y = plane.data.y > 0.0f ? AABB.max.y : AABB.min.y;
277
278 nearPoint.z = plane.data.z > 0.0f ? AABB.min.z : AABB.max.z;
279 farPoint.z = plane.data.z > 0.0f ? AABB.max.z : AABB.min.z;
280
281 if(plane::dot_coord(plane, nearPoint) > 0.0f)
282 {
284 }
285
286 if(plane::dot_coord(plane, farPoint) > 0.0f)
287 {
289 }
290 else
291 {
292 frustumBits |= (0x1 << lastOutside);
293 }
294 }
295
296 for(size_t i = 0; i < planes.size(); i++)
297 {
298 if(((frustumBits >> i) & 0x1) == 0x1)
299 continue;
300 if(lastOutside >= 0 && lastOutside == int(i))
301 continue;
302
303 const plane& plane = planes[i];
304
305 nearPoint.x = plane.data.x > 0.0f ? AABB.min.x : AABB.max.x;
306 farPoint.x = plane.data.x > 0.0f ? AABB.max.x : AABB.min.x;
307
308 nearPoint.y = plane.data.y > 0.0f ? AABB.min.y : AABB.max.y;
309 farPoint.y = plane.data.y > 0.0f ? AABB.max.y : AABB.min.y;
310
311 nearPoint.z = plane.data.z > 0.0f ? AABB.min.z : AABB.max.z;
312 farPoint.z = plane.data.z > 0.0f ? AABB.max.z : AABB.min.z;
313
314 if(plane::dot_coord(plane, nearPoint) > 0.0f)
315 {
316 lastOutside = int(i);
318 }
319
320 if(plane::dot_coord(plane, farPoint) > 0.0f)
321 {
323 }
324 else
325 {
326 frustumBits |= (0x1 << i);
327 }
328 }
329
330 lastOutside = -1;
331 return result;
332}
333
334auto frustum::test_aabb(const bbox& AABB) const -> bool
335{
336 // Loop through all the planes
337 vec3 nearPoint;
338 for(const auto& plane : planes)
339 {
340 nearPoint.x = plane.data.x > 0.0f ? AABB.min.x : AABB.max.x;
341 nearPoint.y = plane.data.y > 0.0f ? AABB.min.y : AABB.max.y;
342 nearPoint.z = plane.data.z > 0.0f ? AABB.min.z : AABB.max.z;
343
344 // If near extreme point is outside, then the AABB is totally outside the
345 // frustum
346 if(plane::dot_coord(plane, nearPoint) > 0.0f)
347 {
348 return false;
349 }
350
351 } // Next plane
352
353 // Intersecting / inside
354 return true;
355}
356
357auto frustum::test_vertices(const vec3* vertices, size_t vert_count) const -> bool
358{
359 for(const auto& plane : planes)
360 {
361 bool allOutside = true;
362
363 for(size_t i = 0; i < vert_count; ++i)
364 {
365 if(plane::dot_coord(plane, vertices[i]) <= 0.0f)
366 {
367 // If any vertex is inside or on the plane, we are not all outside
368 allOutside = false;
369 break;
370 }
371 }
372
373 // If all vertices are outside this plane, the vertices are outside the frustum
374 if(allOutside)
375 {
376 return false;
377 }
378 }
379
380 // If none of the planes had all vertices outside, the vertices are inside or intersecting
381 return true;
382}
383
384auto frustum::test_obb(const bbox& AABB, const transform& t) const -> bool
385{
386 auto vertices = get_transformed_bbox_vertices(AABB, t);
387 return test_vertices(vertices.data(), vertices.size());
388}
389
391{
393
394 // Test frustum planes
395 for(const auto& plane : planes)
396 {
397 float fDot = plane::dot_coord(plane, sphere.position);
398
399 // Sphere entirely in front of plane
400 if(fDot >= sphere.radius)
401 {
403 }
404
405 // Sphere spans plane
406 if(fDot >= -sphere.radius)
407 {
409 }
410
411 } // Next plane
412
413 // Return the result
414 return Result;
415}
416
417auto frustum::test_sphere(const bsphere& sphere) const -> bool
418{
419 // Test frustum planes
420 for(const auto& plane : planes)
421 {
422 float fDot = plane::dot_coord(plane, sphere.position);
423
424 // Sphere entirely in front of plane
425 if(fDot >= sphere.radius)
426 {
427 return false;
428 }
429
430 } // Next plane
431
432 // Intersects
433 return true;
434}
435
436auto frustum::test_sphere(const bsphere& sphere, const transform& t) const -> bool
437{
438 return test_sphere(bsphere(t.transform_coord(sphere.position), sphere.radius));
439}
440
441auto frustum::swept_sphere_intersect_plane(float& t0,
442 float& t1,
443 const plane& plane,
444 const bsphere& sphere,
445 const vec3& vecSweepDirection) -> bool
446{
447 float b_dot_n = plane::dot_coord(plane, sphere.position);
448 float d_dot_n = plane::dot_normal(plane, vecSweepDirection);
449
450 if(d_dot_n == 0.0f)
451 {
452 if(b_dot_n <= sphere.radius)
453 {
454 // Effectively infinity
455 t0 = 0.0f;
456 t1 = std::numeric_limits<float>::max();
457 return true;
458
459 } // End if infinity
460
461 return false;
462
463 } // End if runs parallel to plane
464
465 // Compute the two possible intersections
466 float tmp0 = (sphere.radius - b_dot_n) / d_dot_n;
467 float tmp1 = (-sphere.radius - b_dot_n) / d_dot_n;
468 t0 = glm::min<float>(tmp0, tmp1);
469 t1 = glm::max<float>(tmp0, tmp1);
470 return true;
471
472 // End if intersection
473}
474
475auto frustum::test_swept_sphere(const bsphere& sphere, const vec3& vecSweepDirection) const -> bool
476{
477 unsigned int i, nCount = 0;
478 float t0, t1, fDisplacedRadius;
479 float pDisplacements[12];
480 vec3 vDisplacedCenter;
481
482 // Determine all 12 intersection points of the swept sphere with the view
483 // frustum.
484 for(const auto& plane : planes)
485 {
486 // Intersects frustum plane?
487 if(swept_sphere_intersect_plane(t0, t1, plane, sphere, vecSweepDirection))
488 {
489 // TODO: Possibly needs to be < 0?
490 if(t0 >= 0.0f)
491 {
492 pDisplacements[nCount++] = t0;
493 }
494 if(t1 >= 0.0f)
495 {
496 pDisplacements[nCount++] = t1;
497 }
498
499 } // End if intersects
500
501 } // Next plane
502
503 // For all points > 0, displace the sphere along the sweep direction. If the
504 // displaced
505 // sphere falls inside the frustum then we have an intersection.
506 for(i = 0; i < nCount; ++i)
507 {
508 vDisplacedCenter = sphere.position + (vecSweepDirection * pDisplacements[i]);
509 fDisplacedRadius = sphere.radius * 1.1f; // Tolerance.
510 if(test_sphere(bsphere(vDisplacedCenter, fDisplacedRadius)))
511 {
512 return true;
513 }
514
515 } // Next Intersection
516
517 // None of the displaced spheres intersected the frustum
518 return false;
519}
520
521auto frustum::test_point(const vec3& vecPoint) const -> bool
522{
523 return test_sphere(bsphere(vecPoint, 0.0f));
524}
525
526auto frustum::test_line(const vec3& v1, const vec3& v2) const -> bool
527{
528 int nCode1 = 0, nCode2 = 0;
529 float fDist1, fDist2, t;
530 int nSide1, nSide2;
531 vec3 vDir, vIntersect;
532 unsigned int i;
533
534 // Test each plane
535 for(i = 0; i < 6; ++i)
536 {
537 // Classify each point of the line against the plane.
538 fDist1 = plane::dot_coord(planes[i], v1);
539 fDist2 = plane::dot_coord(planes[i], v2);
540 nSide1 = (fDist1 >= 0) ? 1 : 0;
541 nSide2 = (fDist2 >= 0) ? 1 : 0;
542
543 // Accumulate the classification info to determine
544 // if the edge was spanning any of the planes.
545 nCode1 |= (nSide1 << i);
546 nCode2 |= (nSide2 << i);
547
548 // If the line is completely in front of any plane
549 // then it cannot possibly be intersecting.
550 if(nSide1 == 1 && nSide2 == 1)
551 {
552 return false;
553 }
554
555 // The line is potentially spanning?
556 if((nSide1 ^ nSide2) != 0)
557 {
558 // Compute the point at which the line intersects this plane.
559 vDir = v2 - v1;
560 t = -plane::dot_coord(planes[i], v1) / plane::dot_normal(planes[i], vDir);
561
562 // Truly spanning?
563 if((t >= 0.0f) && (t <= 1.0f))
564 {
565 vIntersect = v1 + (vDir * t);
566 if(test_sphere(bsphere(vIntersect, 0.01f)))
567 {
568 return true;
569 }
570
571 } // End if spanning
572
573 } // End if different sides
574
575 } // Next plane
576
577 // Intersecting?
578 return (nCode1 == 0) || (nCode2 == 0);
579}
580
582{
583 unsigned int nInFrontCount = 0;
584 unsigned int nBehindCount = 0;
585
586 // Test frustum points
587 for(unsigned int i = 0; i < 8; ++i)
588 {
589 float fDot = plane::dot_coord(plane, points[i]);
590 if(fDot > 0.0f)
591 {
592 nInFrontCount++;
593 }
594 else if(fDot < 0.0f)
595 {
596 nBehindCount++;
597 }
598
599 } // Next plane
600
601 // frustum entirely in front of plane
602 if(nInFrontCount == 8)
603 {
605 }
606
607 // frustum entire behind plane
608 if(nBehindCount == 8)
609 {
611 }
612
613 // Return intersection (spanning the plane)
615}
616
617auto frustum::test_frustum(const frustum& f) const -> bool
618{
619 // clang-format off
620 // A -> B
621 bool bIntersect1 =
622 test_line(f.points[volume_geometry_point::left_bottom_far],
624 test_line(f.points[volume_geometry_point::left_bottom_near],
628 test_line(f.points[volume_geometry_point::right_bottom_far],
630 test_line(f.points[volume_geometry_point::right_bottom_far],
634 test_line(f.points[volume_geometry_point::left_bottom_far],
636 test_line(f.points[volume_geometry_point::left_bottom_near],
638 test_line(f.points[volume_geometry_point::left_top_near],
640 test_line(f.points[volume_geometry_point::left_top_far],
642 test_line(f.points[volume_geometry_point::right_top_far],
644 test_line(f.points[volume_geometry_point::right_top_near],
646 // clang-format on
647
648 // Early out
649 if(bIntersect1)
650 {
651 return true;
652 }
653
654 // clang-format off
655 // B -> A
656 bool bIntersect2 =
657 f.test_line(points[volume_geometry_point::left_bottom_far],
659 f.test_line(points[volume_geometry_point::left_bottom_near],
663 f.test_line(points[volume_geometry_point::right_bottom_far],
665 f.test_line(points[volume_geometry_point::right_bottom_far],
669 f.test_line(points[volume_geometry_point::left_bottom_far],
671 f.test_line(points[volume_geometry_point::left_bottom_near],
673 f.test_line(points[volume_geometry_point::left_top_near],
675 f.test_line(points[volume_geometry_point::left_top_far],
677 f.test_line(points[volume_geometry_point::right_top_far],
679 f.test_line(points[volume_geometry_point::right_top_near],
681 // clang-format on
682
683 // Return intersection result
684 return bIntersect2;
685}
686
687auto frustum::mul(const transform& mtx) -> frustum&
688{
689 auto mtxIT = transpose(inverse(mtx.get_matrix()));
690
691 // transform planes
692 for(auto& plane : planes)
693 {
695 }
696
697 // transform points
698 for(auto& point : points)
699 {
700 point = mtx.transform_coord(point);
701 }
702
703 // transform originating position.
704 position = mtx.transform_coord(position);
705
706 // Return reference to self.
707 return *this;
708}
709
710auto frustum::operator==(const frustum& frustum) const -> bool
711{
712 // Compare planes.
713 for(size_t i = 0; i < planes.size(); ++i)
714 {
715 const plane& p1 = planes[i];
716 const plane& p2 = frustum.planes[i];
717 if(!(glm::abs<float>(p1.data.x - p2.data.x) <= glm::epsilon<float>() &&
718 glm::abs<float>(p1.data.y - p2.data.y) <= glm::epsilon<float>() &&
719 glm::abs<float>(p1.data.z - p2.data.z) <= glm::epsilon<float>() &&
720 glm::abs<float>(p1.data.w - p2.data.w) <= glm::epsilon<float>()))
721 {
722 return false;
723 }
724
725 } // Next plane
726
727 // Match
728 return true;
729}
730} // namespace math
Provides storage for common representation of spherical bounding volume, and wraps up common function...
Definition bsphere.h:18
Storage for frustum planes / values and wraps up common functionality.
Definition frustum.h:18
auto classify_aabb(const bbox &bounds) const -> volume_query
Classifies an axis-aligned bounding box (AABB) with respect to the frustum.
Definition frustum.cpp:227
auto classify_sphere(const bsphere &sphere) const -> volume_query
Classifies a sphere with respect to the frustum.
Definition frustum.cpp:390
vec3 position
Definition frustum.h:230
void recompute_points()
Recomputes the frustum's corner points based on its planes.
Definition frustum.cpp:153
frustum()
Default constructor.
Definition frustum.cpp:29
auto test_aabb(const bbox &bounds) const -> bool
Tests if an axis-aligned bounding box (AABB) is inside or intersecting the frustum.
Definition frustum.cpp:334
auto test_point(const vec3 &point) const -> bool
Tests if a point is inside or intersecting the frustum.
Definition frustum.cpp:521
float far_distance_
Definition frustum.h:233
auto test_sphere(const bsphere &sphere) const -> bool
Tests if a sphere is inside or intersecting the frustum.
Definition frustum.cpp:417
auto mul(const transform &t) -> frustum &
Multiplies the frustum by a transform.
Definition frustum.cpp:687
void update(const transform &view, const transform &proj, bool _oglNDC)
Updates the frustum based on the specified view and projection matrices.
Definition frustum.cpp:66
auto test_swept_sphere(const bsphere &sphere, const vec3 &sweepDirection) const -> bool
Determine whether or not the specified sphere, swept along the provided direction vector,...
Definition frustum.cpp:475
std::array< plane, 6 > planes
< The 6 planes of the frustum.
Definition frustum.h:226
auto test_vertices(const vec3 *vertices, size_t count) const -> bool
Tests if vertices are inside or intersect the frustum.
Definition frustum.cpp:357
void set_planes(const std::array< plane, 6 > &new_planes)
Sets the frustum planes.
Definition frustum.cpp:140
auto classify_plane(const plane &plane) const -> volume_query
Classifies a plane with respect to the frustum.
Definition frustum.cpp:581
auto test_line(const vec3 &v1, const vec3 &v2) const -> bool
Tests if a line intersects the frustum.
Definition frustum.cpp:526
auto classify_vertices(const vec3 *vertices, size_t count) const -> volume_query
Classifies vertices with respect to the frustum.
Definition frustum.cpp:184
auto classify_obb(const bbox &bounds, const transform &t) const -> volume_query
Classifies an oriented bounding box (OBB) with respect to the frustum.
Definition frustum.cpp:257
auto test_frustum(const frustum &frustum) const -> bool
Tests if another frustum intersects this frustum.
Definition frustum.cpp:617
auto operator==(const frustum &f) const -> bool
Equality operator.
Definition frustum.cpp:710
auto test_obb(const bbox &bounds, const transform &t) const -> bool
Tests if an oriented bounding box (OBB) is inside or intersecting the frustum.
Definition frustum.cpp:384
std::array< vec3, 8 > points
The originating position of the frustum.
Definition frustum.h:228
float near_distance_
Definition frustum.h:232
General purpose transformation class designed to maintain each component of the transformation separa...
Definition transform.hpp:27
Definition bbox.cpp:5
auto inverse(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
transform_t< float > transform
volume_query
Definition math_types.h:13
auto transpose(transform_t< T, Q > const &t) noexcept -> transform_t< T, Q >
@ sphere
Sphere type reflection probe.
float distance
Storage for box vector values and wraps up common functionality.
Definition bbox.h:21
plane get_plane(volume_plane::e side) const
Retrieves the plane for the specified side of the bounding box.
Definition bbox.cpp:59
vec3 get_extents() const
Returns a vector containing the extents of the bounding box (the half-dimensions)
Definition bbox.cpp:951
vec3 get_center() const
Returns a vector containing the exact center point of the box.
Definition bbox.cpp:946
Storage for infinite plane.
Definition plane.h:21
static auto normalize(const plane &p) -> plane
Normalizes the plane.
Definition plane.cpp:37
static auto dot_normal(const plane &p, const vec3 &v) -> float
Computes the dot product of the plane normal and a vec3.
Definition plane.cpp:15
static auto dot_coord(const plane &p, const vec3 &v) -> float
Computes the dot product of the plane and a vec3 (considering the plane's distance).
Definition plane.cpp:10
static auto mul(const plane &p, const mat4 &m) -> plane
Transforms a plane by a 4x4 matrix.
Definition plane.cpp:32
vec4 data
The components of the plane.
Definition plane.h:240