Toast Engine
Toggle main menu visibility
Loading...
Searching...
No Matches
frustum.hpp
Go to the documentation of this file.
1
4
5
#pragma once
6
7
#include <array>
8
#include <glm/glm.hpp>
9
#include <limits>
10
#include <utility>
11
12
namespace
renderer {
13
14
using
FrustumPlanes = std::array<glm::vec4, 6>;
15
16
struct
Box
{
17
glm::vec3 min {0.0f};
18
glm::vec3 max {0.0f};
19
};
20
23
[[nodiscard]]
24
inline
auto
extractFrustumPlanes
(
const
glm::mat4& view_projection,
bool
reversed_depth =
false
) -> FrustumPlanes {
25
const
auto
& m = view_projection;
26
// glm is column major
27
const
glm::vec4 row0(m[0][0], m[1][0], m[2][0], m[3][0]);
28
const
glm::vec4 row1(m[0][1], m[1][1], m[2][1], m[3][1]);
29
const
glm::vec4 row2(m[0][2], m[1][2], m[2][2], m[3][2]);
30
const
glm::vec4 row3(m[0][3], m[1][3], m[2][3], m[3][3]);
31
32
FrustumPlanes planes {row3 + row0, row3 - row0, row3 + row1, row3 - row1, row2, row3 - row2};
33
if
(reversed_depth) {
34
std::swap(planes[4], planes[5]);
35
}
36
37
for
(
auto
& plane : planes) {
38
const
float
length = glm::length(glm::vec3(plane));
39
if
(length > 0.0f) {
40
plane /= length;
41
}
42
}
43
return
planes;
44
}
45
46
[[nodiscard]]
47
inline
auto
sphereInFrustum(
const
FrustumPlanes& planes,
const
glm::vec3& center,
float
radius) ->
bool
{
48
for
(
const
auto
& plane : planes) {
49
if
(glm::dot(glm::vec3(plane), center) + plane.w < -radius) {
50
return
false
;
51
}
52
}
53
return
true
;
54
}
55
57
[[nodiscard]]
58
inline
auto
transformBox
(
const
glm::mat4& model,
const
glm::vec3& min,
const
glm::vec3& max) ->
Box
{
59
Box
out {glm::vec3(std::numeric_limits<float>::max()), glm::vec3(std::numeric_limits<float>::lowest())};
60
for
(
int
corner = 0; corner < 8; ++corner) {
61
const
glm::vec3 local(
62
(corner & 1) != 0 ? max.x : min.x, (corner & 2) != 0 ? max.y : min.y, (corner & 4) != 0 ? max.z : min.z
63
);
64
const
glm::vec3 world = glm::vec3(model * glm::vec4(local, 1.0f));
65
out.min = glm::min(out.min, world);
66
out.max = glm::max(out.max, world);
67
}
68
return
out;
69
}
70
72
[[nodiscard]]
73
inline
auto
boxTouchesLateralFrustum
(
const
FrustumPlanes& planes,
const
Box
& box) ->
bool
{
74
constexpr
size_t
k_near = 4;
75
for
(
size_t
i = 0; i < planes.size(); ++i) {
76
if
(i == k_near) {
77
continue
;
78
}
79
const
glm::vec3 normal(planes[i]);
80
const
glm::vec3 support(
81
normal.x >= 0.0f ? box.max.x : box.min.x,
82
normal.y >= 0.0f ? box.max.y : box.min.y,
83
normal.z >= 0.0f ? box.max.z : box.min.z
84
);
85
if
(glm::dot(normal, support) + planes[i].w < 0.0f) {
86
return
false
;
87
}
88
}
89
return
true
;
90
}
91
92
}
renderer::transformBox
auto transformBox(const glm::mat4 &model, const glm::vec3 &min, const glm::vec3 &max) -> Box
World axis aligned box around a box in the space model maps from.
Definition
frustum.hpp:58
renderer::boxTouchesLateralFrustum
auto boxTouchesLateralFrustum(const FrustumPlanes &planes, const Box &box) -> bool
Skips the near plane so a box in front of it still counts.
Definition
frustum.hpp:73
renderer::extractFrustumPlanes
auto extractFrustumPlanes(const glm::mat4 &view_projection, bool reversed_depth=false) -> FrustumPlanes
Definition
frustum.hpp:24
renderer::Box
Definition
frustum.hpp:16
engine
src
toast
renderer
frustum.hpp
Generated by
1.17.0