2#ifndef LIBSBX_SCENES_COMPONENTS_CAMERA_HPP_
3#define LIBSBX_SCENES_COMPONENTS_CAMERA_HPP_
10#include <libsbx/utility/enum.hpp>
12#include <libsbx/math/vector3.hpp>
13#include <libsbx/math/matrix3x3.hpp>
14#include <libsbx/math/matrix4x4.hpp>
15#include <libsbx/math/volume.hpp>
16#include <libsbx/math/sphere.hpp>
17#include <libsbx/math/plane.hpp>
20#include <libsbx/containers/static_vector.hpp>
22#include <libsbx/core/engine.hpp>
27#include <libsbx/graphics/graphics_module.hpp>
29namespace sbx::scenes {
33 inline static constexpr auto left_plane = std::size_t{0u};
34 inline static constexpr auto right_plane = std::size_t{0u};
35 inline static constexpr auto top_plane = std::size_t{1u};
36 inline static constexpr auto bottom_plane = std::size_t{1u};
37 inline static constexpr auto near_plane = std::size_t{2u};
38 inline static constexpr auto far_plane = std::size_t{2u};
40 inline static constexpr auto margin = std::float_t{0.5f};
45 :
math::box{_extract_planes(view_projection)} { }
48 const auto world_volume = math::volume::transformed(aabb, model);
52 (
plane.normal().x() >= 0 ? world_volume.max().x() : world_volume.min().x()),
53 (
plane.normal().y() >= 0 ? world_volume.max().y() : world_volume.min().y()),
54 (
plane.normal().z() >= 0 ? world_volume.max().z() : world_volume.min().z())
57 const auto distance =
plane.distance_to_point(positive);
59 if (distance < -margin) {
69 static auto _extract_planes(
const math::matrix4x4& matrix) -> std::array<math::plane, 6u> {
70 return std::array<math::plane, 6u>{
71 _extract_plane<right_plane>(matrix),
72 _extract_plane<left_plane>(matrix),
73 _extract_plane<bottom_plane>(matrix),
74 _extract_plane<top_plane>(matrix),
75 _extract_plane<far_plane>(matrix),
76 _extract_plane<near_plane>(matrix)
80 template<std::
size_t S
ide>
82 constexpr auto sign = (Side == right_plane || Side == top_plane || Side == far_plane) ? -1.0f : 1.0f;
85 matrix[0][3] + sign * matrix[0][Side],
86 matrix[1][3] + sign * matrix[1][Side],
87 matrix[2][3] + sign * matrix[2][Side],
88 matrix[3][3] + sign * matrix[3][Side]
100 camera(
const math::angle& field_of_view, std::float_t aspect_ratio, std::float_t near_plane, std::float_t far_plane)
101 : _field_of_view{field_of_view},
102 _aspect_ratio{aspect_ratio},
103 _near_plane{near_plane},
104 _far_plane{far_plane} {
105 _update_projection();
107 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
109 graphics_module.connect_on_viewport_changed([
this](
const math::vector2u& event) {
110 set_aspect_ratio(
static_cast<std::float_t
>(event.x()) /
static_cast<std::float_t
>(event.y()));
115 auto field_of_view()
const noexcept ->
const math::angle& {
116 return _field_of_view;
119 auto set_field_of_view(
const math::angle& field_of_view) ->
void {
120 if (field_of_view == _field_of_view) {
124 _field_of_view = field_of_view;
125 _update_projection();
128 auto aspect_ratio()
const noexcept -> std::float_t {
129 return _aspect_ratio;
132 auto set_aspect_ratio(std::float_t aspect_ratio)
noexcept ->
void {
133 if (aspect_ratio != _aspect_ratio) {
134 _aspect_ratio = aspect_ratio;
135 _update_projection();
139 auto near_plane()
const noexcept -> std::float_t {
143 auto far_plane()
const noexcept -> std::float_t {
151 auto projection(
const std::float_t near,
const std::float_t far)
const noexcept ->
math::matrix4x4 {
152 return math::matrix4x4::perspective(_field_of_view, _aspect_ratio, near, far);
156 return frustum{_projection * view};
161 auto _update_projection() ->
void {
162 _projection = math::matrix4x4::perspective(_field_of_view, _aspect_ratio, _near_plane, _far_plane);
166 std::float_t _aspect_ratio;
167 std::float_t _near_plane;
168 std::float_t _far_plane;
Box / frustum-style volume intersection helpers.
Unified angle type stored internally in radians.
Definition: angle.hpp:591
Plane-based box represented by six clipping planes.
Definition: box.hpp:46
auto plane(const size_type index) const noexcept -> const plane_type &
Returns the plane at a given index.
Definition: box.ipp:39
auto planes() const noexcept -> const std::array< plane_type, 6u > &
Returns the plane array backing this box.
Definition: box.ipp:33
Definition: matrix4x4.hpp:26
A vector in two-dimensional space.
Definition: vector2.hpp:28
Definition: vector3.hpp:23
Definition: vector4.hpp:24
Definition: volume.hpp:14
Definition: camera.hpp:96
Definition: camera.hpp:31