diff --git a/src/engine/geom/brep/brep-attribute.hpp b/src/engine/geom/brep/brep-attribute.hpp index fd61501..585b5d6 100644 --- a/src/engine/geom/brep/brep-attribute.hpp +++ b/src/engine/geom/brep/brep-attribute.hpp @@ -255,7 +255,7 @@ private: { auto copy = std::make_unique>(name(), 0); copy->m_values = m_values; - return std::move(copy); + return copy; } std::vector m_values; diff --git a/src/engine/math/matrix.hpp b/src/engine/math/matrix.hpp index 58b3143..968ea23 100644 --- a/src/engine/math/matrix.hpp +++ b/src/engine/math/matrix.hpp @@ -22,7 +22,9 @@ #include #include +#include #include +#include #include #include @@ -575,7 +577,7 @@ template [[nodiscard]] constexpr matrix inverse(const matrix& m) noexcept; /** - * Creates a viewing transformation matrix. + * Constructs a right-handed viewing transformation matrix. * * @param position Position of the view point. * @param target Position of the target. @@ -584,7 +586,21 @@ template * @return Viewing transformation matrix. */ template -[[nodiscard]] constexpr mat4 look_at(const vec3& position, const vec3& target, vec3 up); +[[nodiscard]] constexpr mat4 look_at_rh(const vec3& position, const vec3& target, const vec3& up); + +/** + * Constructs a right-handed viewing transformation matrix and its inverse. + * + * @param position Position of the view point. + * @param target Position of the target. + * @param up Unit vector pointing in the up direction. + * + * @return Tuple containing the viewing transformation matrix, followed by its inverse. + * + * @note Constructing the inverse viewing transformation matrix from viewing parameters is faster and more precise than inverting matrix. + */ +template +[[nodiscard]] constexpr std::tuple, mat4> look_at_rh_inv(const vec3& position, const vec3& target, const vec3& up); /** * Multiplies two matrices @@ -964,20 +980,47 @@ constexpr matrix inverse(const matrix& m) noexcept } template -constexpr mat4 look_at(const vec3& position, const vec3& target, vec3 up) +constexpr mat4 look_at_rh(const vec3& position, const vec3& target, const vec3& up) { - const auto forward = normalize(sub(target, position)); - const auto right = normalize(cross(forward, up)); - up = cross(right, forward); - const auto m = mat4 + const auto f = normalize(sub(target, position)); + const auto r = normalize(cross(f, up)); + const auto u = cross(r, f); + const auto t = vec3{dot(position, r), dot(position, u), dot(position, f)}; + + return {{ - {right[0], up[0], -forward[0], T{0}}, - {right[1], up[1], -forward[1], T{0}}, - {right[2], up[2], -forward[2], T{0}}, - {T{0}, T{0}, T{0}, T{1}} + { r.x(), u.x(), -f.x(), T{0}}, + { r.y(), u.y(), -f.y(), T{0}}, + { r.z(), u.z(), -f.z(), T{0}}, + {-t.x(), -t.y(), t.z(), T{1}} }}; +} + +template +constexpr std::tuple, mat4> look_at_rh_inv(const vec3& position, const vec3& target, const vec3& up) +{ + const auto f = normalize(sub(target, position)); + const auto r = normalize(cross(f, up)); + const auto u = cross(r, f); - return mul(m, translate(-position)); + return + { + mat4 + {{ + { r.x(), u.x(), -f.x(), T{0}}, + { r.y(), u.y(), -f.y(), T{0}}, + { r.z(), u.z(), -f.z(), T{0}}, + {-dot(position, r), -dot(position, u), dot(position, f), T{1}} + }}, + + mat4 + {{ + { r.x(), r.y(), r.z(), T{0}}, + { u.x(), u.y(), u.z(), T{0}}, + {-f.x(), -f.y(), -f.z(), T{0}}, + {position.x(), position.y(), position.z(), T{1}} + }} + }; } template @@ -1388,7 +1431,6 @@ inline constexpr matrix& operator/=(matrix& a, T b) noexcept // Bring matrix operators into global namespace using namespace math::operators; -// Structured binding support namespace std { /** @@ -1419,6 +1461,38 @@ namespace std /// Type of columns in the matrix. using type = math::matrix::column_vector_type; }; + + /** + * Specialization of std::formatter for math::matrix. + * + * @tparam T Element type. + * @tparam N Number of columns. + * @tparam M Number of rows. + */ + template + struct formatter>: formatter> + { + auto format(const math::matrix& t, format_context& fc) const + { + auto&& out = fc.out(); + format_to(out, "{{"); + + for (std::size_t i = 0; i < N; ++i) + { + formatter>::format(t[i], fc); + if (i < N - 1) + { + format_to(out, ", "); + } + } + + return format_to(out, "}}"); + } + }; } +// Ensure matrices are POD types +static_assert(std::is_standard_layout_v); +static_assert(std::is_trivial_v); + #endif // ANTKEEPER_MATH_MATRIX_HPP diff --git a/src/engine/math/projection.hpp b/src/engine/math/projection.hpp index 3ee3051..834248e 100644 --- a/src/engine/math/projection.hpp +++ b/src/engine/math/projection.hpp @@ -22,6 +22,7 @@ #include #include +#include namespace math { @@ -64,23 +65,60 @@ template * @param right Signed distance to the right clipping plane. * @param bottom Signed distance to the bottom clipping plane. * @param top Signed distance to the top clipping plane. - * @param z_near Signed distance to the near clipping plane. - * @param z_far Signed distance to the far clipping plane. + * @param near Signed distance to the near clipping plane. + * @param far Signed distance to the far clipping plane. * * @return Orthographic projection matrix. */ template -[[nodiscard]] constexpr matrix ortho(T left, T right, T bottom, T top, T z_near, T z_far) noexcept +[[nodiscard]] constexpr mat4 ortho(T left, T right, T bottom, T top, T near, T far) noexcept { return {{ {T{2} / (right - left), T{0}, T{0}, T{0}}, {T{0}, T{2} / (top - bottom), T{0}, T{0}}, - {T{0}, T{0}, T{-2} / (z_far - z_near), T{0}}, - {-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((z_far + z_near) / (z_far - z_near)), T{1}} + {T{0}, T{0}, T{-2} / (far - near), T{0}}, + {-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((far + near) / (far - near)), T{1}} }}; } +/** + * Constructs an orthographic projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively, along with its inverse. + * + * @param left Signed distance to the left clipping plane. + * @param right Signed distance to the right clipping plane. + * @param bottom Signed distance to the bottom clipping plane. + * @param top Signed distance to the top clipping plane. + * @param near Signed distance to the near clipping plane. + * @param far Signed distance to the far clipping plane. + * + * @return Tuple containing the orthographic projection matrix, followed by its inverse. + * + * @note Constructing the inverse orthographic projection matrix from projection parameters is faster and more precise than inverting matrix. + */ +template +[[nodiscard]] constexpr std::tuple, mat4> ortho_inv(T left, T right, T bottom, T top, T near, T far) noexcept +{ + return + { + mat4 + {{ + {T{2} / (right - left), T{0}, T{0}, T{0}}, + {T{0}, T{2} / (top - bottom), T{0}, T{0}}, + {T{0}, T{0}, T{-2} / (far - near), T{0}}, + {-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -((far + near) / (far - near)), T{1}} + }}, + + mat4 + {{ + {(right - left) / T{2}, T{0}, T{0}, T{0}}, + {T{0}, (top - bottom) / T{2}, T{0}, T{0}}, + {T{0}, T{0}, (-far + near) / T{2}, T{0}}, + {(right + left) / T{2}, (bottom + top) / T{2}, (-far - near) / T{2}, T{1}} + }} + }; +} + /** * Constructs an orthographic projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively. * @@ -88,35 +126,72 @@ template * @param right Signed distance to the right clipping plane. * @param bottom Signed distance to the bottom clipping plane. * @param top Signed distance to the top clipping plane. - * @param z_near Signed distance to the near clipping plane. - * @param z_far Signed distance to the far clipping plane. + * @param near Signed distance to the near clipping plane. + * @param far Signed distance to the far clipping plane. * * @return Orthographic projection matrix. */ template -[[nodiscard]] constexpr matrix ortho_half_z(T left, T right, T bottom, T top, T z_near, T z_far) noexcept +[[nodiscard]] constexpr mat4 ortho_half_z(T left, T right, T bottom, T top, T near, T far) noexcept { return {{ {T{2} / (right - left), T{0}, T{0}, T{0}}, {T{0}, T{2} / (top - bottom), T{0}, T{0}}, - {T{0}, T{0}, T{-1} / (z_far - z_near), T{0}}, - {-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -z_near / (z_far - z_near), T{1}} + {T{0}, T{0}, T{-1} / (far - near), T{0}}, + {-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -near / (far - near), T{1}} }}; } +/** + * Constructs an orthographic projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively, along with its inverse. + * + * @param left Signed distance to the left clipping plane. + * @param right Signed distance to the right clipping plane. + * @param bottom Signed distance to the bottom clipping plane. + * @param top Signed distance to the top clipping plane. + * @param near Signed distance to the near clipping plane. + * @param far Signed distance to the far clipping plane. + * + * @return Tuple containing the orthographic projection matrix, followed by its inverse. + * + * @note Constructing the inverse orthographic projection matrix from projection parameters is faster and more precise than inverting matrix. + */ +template +[[nodiscard]] constexpr std::tuple, mat4> ortho_half_z_inv(T left, T right, T bottom, T top, T near, T far) noexcept +{ + return + { + mat4 + {{ + {T{2} / (right - left), T{0}, T{0}, T{0}}, + {T{0}, T{2} / (top - bottom), T{0}, T{0}}, + {T{0}, T{0}, T{-1} / (far - near), T{0}}, + {-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -near / (far - near), T{1}} + }}, + + mat4 + {{ + {(right - left) / T{2}, T{0}, T{0}, T{0}}, + {T{0}, (top - bottom) / T{2}, T{0}, T{0}}, + {T{0}, T{0}, -far + near, T{0}}, + {(right + left) / T{2}, (bottom + top) / T{2}, -near, T{1}} + }} + }; +} + /** * Constructs a perspective projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively. * * @param vertical_fov Vertical field of view angle, in radians. * @param aspect_ratio Aspect ratio which determines the horizontal field of view. - * @param z_near Distance to the near clipping plane. - * @param z_far Distance to the far clipping plane. + * @param near Distance to the near clipping plane. + * @param far Distance to the far clipping plane. * * @return Perspective projection matrix. */ template -[[nodiscard]] matrix perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far) +[[nodiscard]] mat4 perspective(T vertical_fov, T aspect_ratio, T near, T far) { const T half_fov = vertical_fov * T{0.5}; const T f = std::cos(half_fov) / std::sin(half_fov); @@ -125,23 +200,61 @@ template {{ {f / aspect_ratio, T{0}, T{0}, T{0}}, {T{0}, f, T{0}, T{0}}, - {T{0}, T{0}, (z_far + z_near) / (z_near - z_far), T{-1}}, - {T{0}, T{0}, (T{2} * z_far * z_near) / (z_near - z_far), T{0}} + {T{0}, T{0}, (far + near) / (near - far), T{-1}}, + {T{0}, T{0}, (T{2} * far * near) / (near - far), T{0}} }}; } +/** + * Constructs a perspective projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively, along with its inverse. + * + * @param vertical_fov Vertical field of view angle, in radians. + * @param aspect_ratio Aspect ratio which determines the horizontal field of view. + * @param near Distance to the near clipping plane. + * @param far Distance to the far clipping plane. + * + * @return Arraay containing the perspective projection matrix, followed by its inverse. + * + * @note Constructing the inverse perspective projection matrix from projection parameters is faster and more precise than inverting matrix. + */ +template +[[nodiscard]] std::tuple, mat4> perspective_inv(T vertical_fov, T aspect_ratio, T near, T far) +{ + const T half_fov = vertical_fov * T{0.5}; + const T f = std::cos(half_fov) / std::sin(half_fov); + + return + { + mat4 + {{ + {f / aspect_ratio, T{0}, T{0}, T{0}}, + {T{0}, f, T{0}, T{0}}, + {T{0}, T{0}, (far + near) / (near - far), T{-1}}, + {T{0}, T{0}, (T{2} * far * near) / (near - far), T{0}} + }}, + + mat4 + {{ + {aspect_ratio / f, T{0}, T{0}, T{0}}, + {T{0}, T{1} / f, T{0}, T{0}}, + {T{0}, T{0}, T{0}, (near - far) / (T{2} * near * far)}, + {T{0}, T{0}, T{-1}, (near + far) / (T{2} * near * far)} + }} + }; +} + /** * Constructs a perspective projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively. * * @param vertical_fov Vertical field of view angle, in radians. * @param aspect_ratio Aspect ratio which determines the horizontal field of view. - * @param z_near Distance to the near clipping plane. - * @param z_far Distance to the far clipping plane. + * @param near Distance to the near clipping plane. + * @param far Distance to the far clipping plane. * * @return Perspective projection matrix. */ template -[[nodiscard]] matrix perspective_half_z(T vertical_fov, T aspect_ratio, T z_near, T z_far) +[[nodiscard]] mat4 perspective_half_z(T vertical_fov, T aspect_ratio, T near, T far) { const T half_fov = vertical_fov * T{0.5}; const T f = std::cos(half_fov) / std::sin(half_fov); @@ -150,11 +263,49 @@ template {{ {f / aspect_ratio, T{0}, T{0}, T{0}}, {T{0}, f, T{0}, T{0}}, - {T{0}, T{0}, z_far / (z_near - z_far), T{-1}}, - {T{0}, T{0}, -(z_far * z_near) / (z_far - z_near), T{0}} + {T{0}, T{0}, far / (near - far), T{-1}}, + {T{0}, T{0}, -(far * near) / (far - near), T{0}} }}; } +/** + * Constructs a perspective projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively. + * + * @param vertical_fov Vertical field of view angle, in radians. + * @param aspect_ratio Aspect ratio which determines the horizontal field of view. + * @param near Distance to the near clipping plane. + * @param far Distance to the far clipping plane. + * + * @return Tuple containing the perspective projection matrix, followed by its inverse. + * + * @note Constructing the inverse perspective projection matrix from projection parameters is faster and more precise than inverting matrix. + */ +template +[[nodiscard]] std::tuple, mat4> perspective_half_z_inv(T vertical_fov, T aspect_ratio, T near, T far) +{ + const T half_fov = vertical_fov * T{0.5}; + const T f = std::cos(half_fov) / std::sin(half_fov); + + return + { + mat4 + {{ + {f / aspect_ratio, T{0}, T{0}, T{0}}, + {T{0}, f, T{0}, T{0}}, + {T{0}, T{0}, far / (near - far), T{-1}}, + {T{0}, T{0}, -(far * near) / (far - near), T{0}} + }}, + + mat4 + {{ + {aspect_ratio / f, T{0}, T{0}, T{0}}, + {T{0}, T{1} / f, T{0}, T{0}}, + {T{0}, T{0}, T{0}, T{1} / far - T{1} / near}, + {T{0}, T{0}, T{-1}, T{1} / near} + }} + }; +} + } // namespace math #endif // ANTKEEPER_MATH_PROJECTION_HPP diff --git a/src/engine/math/vector.hpp b/src/engine/math/vector.hpp index 4c93739..2f696b0 100644 --- a/src/engine/math/vector.hpp +++ b/src/engine/math/vector.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1794,7 +1795,6 @@ inline constexpr vector& operator/=(vector& x, T y) noexcept // Bring vector operators into global namespace using namespace math::operators; -// Structured binding support namespace std { /** @@ -1823,6 +1823,33 @@ namespace std /// Type of elements in the vector. using type = math::vector::element_type; }; + + /** + * Specialization of std::formatter for math::vector. + * + * @tparam T Element type. + * @tparam N Number of elements. + */ + template + struct formatter>: formatter + { + auto format(const math::vector& t, format_context& fc) const + { + auto&& out = fc.out(); + format_to(out, "{{"); + + for (std::size_t i = 0; i < N; ++i) + { + formatter::format(t[i], fc); + if (i < N - 1) + { + format_to(out, ", "); + } + } + + return format_to(out, "}}"); + } + }; } // Ensure vectors are POD types diff --git a/src/engine/render/passes/shadow-map-pass.cpp b/src/engine/render/passes/shadow-map-pass.cpp index 539984e..c07bddf 100644 --- a/src/engine/render/passes/shadow-map-pass.cpp +++ b/src/engine/render/passes/shadow-map-pass.cpp @@ -120,7 +120,7 @@ void shadow_map_pass::render_csm(scene::directional_light& light, render::contex // Get light layer mask const auto light_layer_mask = light.get_layer_mask(); - if (!light_layer_mask & ctx.camera->get_layer_mask()) + if (!(light_layer_mask & ctx.camera->get_layer_mask())) { return; } @@ -232,7 +232,7 @@ void shadow_map_pass::render_csm(scene::directional_light& light, render::contex subfrustum_bounds.center = light.get_rotation() * subfrustum_bounds.center; // Construct light view matrix - const auto light_view = math::look_at(subfrustum_bounds.center, subfrustum_bounds.center + light.get_direction(), light.get_rotation() * math::fvec3{0, 1, 0}); + const auto light_view = math::look_at_rh(subfrustum_bounds.center, subfrustum_bounds.center + light.get_direction(), light.get_rotation() * math::fvec3{0, 1, 0}); // Construct light projection matrix (reversed half-z) const auto light_projection = math::ortho_half_z diff --git a/src/engine/scene/camera.cpp b/src/engine/scene/camera.cpp index ed825b2..4df6324 100644 --- a/src/engine/scene/camera.cpp +++ b/src/engine/scene/camera.cpp @@ -20,17 +20,15 @@ #include #include #include -#include namespace scene { geom::ray camera::pick(const math::fvec2& ndc) const { - const math::fvec4 near = m_inverse_view_projection * math::fvec4{ndc[0], ndc[1], 1.0f, 1.0f}; - const math::fvec4 far = m_inverse_view_projection * math::fvec4{ndc[0], ndc[1], 0.0f, 1.0f}; - - const math::fvec3 origin = math::fvec3{near[0], near[1], near[2]} / near[3]; - const math::fvec3 direction = math::normalize(math::fvec3{far[0], far[1], far[2]} / far[3] - origin); + const auto near = m_inv_view_projection * math::fvec4{ndc[0], ndc[1], 1.0f, 1.0f}; + const auto far = m_inv_view_projection * math::fvec4{ndc[0], ndc[1], 0.0f, 1.0f}; + const auto origin = math::fvec3{near[0], near[1], near[2]} / near[3]; + const auto direction = math::normalize(math::fvec3{far[0], far[1], far[2]} / far[3] - origin); return {origin, direction}; } @@ -58,13 +56,14 @@ math::fvec3 camera::unproject(const math::fvec3& window, const math::fvec4& view result[2] = 1.0f - window[2]; // z: [1, 0] result[3] = 1.0f; - result = m_inverse_view_projection * result; + result = m_inv_view_projection * result; return math::fvec3(result) * (1.0f / result[3]); } void camera::set_perspective(float vertical_fov, float aspect_ratio, float clip_near, float clip_far) { + // Set projection mode to perspective m_orthographic = false; // Update perspective projection parameters @@ -73,12 +72,12 @@ void camera::set_perspective(float vertical_fov, float aspect_ratio, float clip_ m_clip_near = clip_near; m_clip_far = clip_far; - // Recalculate projection matrix - m_projection = math::perspective_half_z(m_vertical_fov, m_aspect_ratio, m_clip_far, m_clip_near); + // Recalculate projection matrix and its inverse + std::tie(m_projection, m_inv_projection) = math::perspective_half_z_inv(m_vertical_fov, m_aspect_ratio, m_clip_far, m_clip_near); // Recalculate view-projection matrix m_view_projection = m_projection * m_view; - m_inverse_view_projection = math::inverse(m_view_projection); + m_inv_view_projection = m_inv_view * m_inv_projection; // Recalculate view frustum update_frustum(); @@ -86,26 +85,15 @@ void camera::set_perspective(float vertical_fov, float aspect_ratio, float clip_ void camera::set_vertical_fov(float vertical_fov) { - if (m_orthographic) + if (!m_orthographic) { - return; + set_perspective(vertical_fov, m_aspect_ratio, m_clip_near, m_clip_far); } - - m_vertical_fov = vertical_fov; - - // Recalculate projection matrix - m_projection = math::perspective_half_z(m_vertical_fov, m_aspect_ratio, m_clip_far, m_clip_near); - - // Recalculate view-projection matrix - m_view_projection = m_projection * m_view; - m_inverse_view_projection = math::inverse(m_view_projection); - - // Recalculate view frustum - update_frustum(); } void camera::set_orthographic(float clip_left, float clip_right, float clip_bottom, float clip_top, float clip_near, float clip_far) { + // Set projection mode to orthographic m_orthographic = true; // Update signed distances to clipping planes @@ -116,14 +104,14 @@ void camera::set_orthographic(float clip_left, float clip_right, float clip_bott m_clip_near = clip_near; m_clip_far = clip_far; - // Update projection matrix - m_projection = math::ortho_half_z(m_clip_left, m_clip_right, m_clip_bottom, m_clip_top, m_clip_far, m_clip_near); + // Recalculate projection matrix and its inverse + std::tie(m_projection, m_inv_projection) = math::ortho_half_z_inv(m_clip_left, m_clip_right, m_clip_bottom, m_clip_top, m_clip_far, m_clip_near); - // Recalculate view-projection matrix + // Update view-projection matrix and its inverse m_view_projection = m_projection * m_view; - m_inverse_view_projection = math::inverse(m_view_projection); + m_inv_view_projection = m_inv_view * m_inv_projection; - // Recalculate view frustum + // Update view frustum update_frustum(); } @@ -136,13 +124,18 @@ void camera::set_exposure_value(float ev100) void camera::transformed() { - // Recalculate view and view-projection matrices + // Update basis vectors m_forward = get_rotation() * math::fvec3{0.0f, 0.0f, -1.0f}; m_up = get_rotation() * math::fvec3{0.0f, 1.0f, 0.0f}; - m_view = math::look_at(get_translation(), get_translation() + m_forward, m_up); + + // Recalculate view matrix and its inverse + std::tie(m_view, m_inv_view) = math::look_at_rh_inv(get_translation(), get_translation() + m_forward, m_up); + + // Update view-projection matrix and its inverse m_view_projection = m_projection * m_view; - m_inverse_view_projection = math::inverse(m_view_projection); + m_inv_view_projection = m_inv_view * m_inv_projection; + // Update view frustum update_frustum(); } @@ -168,7 +161,7 @@ void camera::update_frustum() m_bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < 8; ++i) { - const math::fvec4 frustum_corner = m_inverse_view_projection * clip_space_cube[i]; + const math::fvec4 frustum_corner = m_inv_view_projection * clip_space_cube[i]; m_bounds.extend(math::fvec3(frustum_corner) / frustum_corner[3]); } } diff --git a/src/engine/scene/camera.hpp b/src/engine/scene/camera.hpp index 1cfedec..21b012d 100644 --- a/src/engine/scene/camera.hpp +++ b/src/engine/scene/camera.hpp @@ -125,139 +125,151 @@ public: * Returns the camera's compositor. */ /// @{ - [[nodiscard]] inline const render::compositor* get_compositor() const noexcept + [[nodiscard]] inline constexpr const render::compositor* get_compositor() const noexcept { return m_compositor; } - [[nodiscard]] inline render::compositor* get_compositor() noexcept + [[nodiscard]] inline constexpr render::compositor* get_compositor() noexcept { return m_compositor; } /// @} /// Returns the composite index of the camera. - [[nodiscard]] inline int get_composite_index() const noexcept + [[nodiscard]] inline constexpr int get_composite_index() const noexcept { return m_composite_index; } - [[nodiscard]] inline const aabb_type& get_bounds() const noexcept override + [[nodiscard]] inline constexpr const aabb_type& get_bounds() const noexcept override { return m_bounds; } /// Returns `true` if the camera uses an orthographic projection matrix, `false` otherwise. - [[nodiscard]] inline bool is_orthographic() const noexcept + [[nodiscard]] inline constexpr bool is_orthographic() const noexcept { return m_orthographic; } /// Returns the signed distance to the camera's left clipping plane. - [[nodiscard]] inline float get_clip_left() const noexcept + [[nodiscard]] inline constexpr float get_clip_left() const noexcept { return m_clip_left; } /// Returns the signed distance to the camera's right clipping plane. - [[nodiscard]] inline float get_clip_right() const noexcept + [[nodiscard]] inline constexpr float get_clip_right() const noexcept { return m_clip_right; } /// Returns the signed distance to the camera's bottom clipping plane. - [[nodiscard]] inline float get_clip_bottom() const noexcept + [[nodiscard]] inline constexpr float get_clip_bottom() const noexcept { return m_clip_bottom; } /// Returns the signed distance to the camera's top clipping plane. - [[nodiscard]] inline float get_clip_top() const noexcept + [[nodiscard]] inline constexpr float get_clip_top() const noexcept { return m_clip_top; } /// Returns the signed distance to the camera's near clipping plane. - [[nodiscard]] inline float get_clip_near() const noexcept + [[nodiscard]] inline constexpr float get_clip_near() const noexcept { return m_clip_near; } /// Returns the signed distance to the camera's far clipping plane. - [[nodiscard]] inline float get_clip_far() const noexcept + [[nodiscard]] inline constexpr float get_clip_far() const noexcept { return m_clip_far; } /// Returns the camera's vertical field of view, in radians. - [[nodiscard]] inline float get_vertical_fov() const noexcept + [[nodiscard]] inline constexpr float get_vertical_fov() const noexcept { return m_vertical_fov; } /// Returns the camera's aspect ratio. - [[nodiscard]] inline float get_aspect_ratio() const noexcept + [[nodiscard]] inline constexpr float get_aspect_ratio() const noexcept { return m_aspect_ratio; } /// Returns the camera's ISO 100 exposure value. - [[nodiscard]] inline float get_exposure_value() const noexcept + [[nodiscard]] inline constexpr float get_exposure_value() const noexcept { return m_exposure_value; } /// Returns the camera's exposure normalization factor. - [[nodiscard]] inline float get_exposure_normalization() const noexcept + [[nodiscard]] inline constexpr float get_exposure_normalization() const noexcept { return m_exposure_normalization; } /// Returns the camera's view matrix. - [[nodiscard]] inline const math::fmat4& get_view() const noexcept + [[nodiscard]] inline constexpr const math::fmat4& get_view() const noexcept { return m_view; } + /// Returns the inverse of the camera's view matrix. + [[nodiscard]] inline constexpr const math::fmat4& get_inv_view() const noexcept + { + return m_inv_view; + } + /// Returns the camera's projection matrix. - [[nodiscard]] inline const math::fmat4& get_projection() const noexcept + [[nodiscard]] inline constexpr const math::fmat4& get_projection() const noexcept { return m_projection; } + /// Returns the inverse of the camera's projection matrix. + [[nodiscard]] inline constexpr const math::fmat4& get_inv_projection() const noexcept + { + return m_inv_projection; + } + /// Returns the camera's view-projection matrix. - [[nodiscard]] inline const math::fmat4& get_view_projection() const noexcept + [[nodiscard]] inline constexpr const math::fmat4& get_view_projection() const noexcept { return m_view_projection; } - /// Returns the camera's inverse view-projection matrix. - [[nodiscard]] inline const math::fmat4& get_inverse_view_projection() const noexcept + /// Returns the inverse of the camera's view-projection matrix. + [[nodiscard]] inline constexpr const math::fmat4& get_inv_view_projection() const noexcept { - return m_inverse_view_projection; + return m_inv_view_projection; } /// Returns the camera's forward vector. - [[nodiscard]] inline const math::fvec3& get_forward() const noexcept + [[nodiscard]] inline constexpr const math::fvec3& get_forward() const noexcept { return m_forward; } /// Returns the camera's up vector. - [[nodiscard]] inline const math::fvec3& get_up() const noexcept + [[nodiscard]] inline constexpr const math::fvec3& get_up() const noexcept { return m_up; } /// Returns the camera's view frustum. - [[nodiscard]] inline const view_frustum_type& get_view_frustum() const noexcept + [[nodiscard]] inline constexpr const view_frustum_type& get_view_frustum() const noexcept { return m_view_frustum; } private: - virtual void transformed(); + void transformed() override; void update_frustum(); - + render::compositor* m_compositor{nullptr}; int m_composite_index{0}; @@ -272,19 +284,20 @@ private: float m_vertical_fov{math::half_pi}; float m_aspect_ratio{1.0f}; float m_exposure_value{0.0f}; - float m_exposure_normalization{1.0f / 1.2f}; + float m_exposure_normalization{1.0f}; + + math::fvec3 m_forward{0.0f, 0.0f, -1.0f}; + math::fvec3 m_up{0.0f, 1.0f, 0.0f}; math::fmat4 m_view{math::fmat4::identity()}; + math::fmat4 m_inv_view{math::fmat4::identity()}; math::fmat4 m_projection{math::fmat4::identity()}; + math::fmat4 m_inv_projection{math::fmat4::identity()}; math::fmat4 m_view_projection{math::fmat4::identity()}; - math::fmat4 m_inverse_view_projection{math::fmat4::identity()}; - - math::fvec3 m_forward{0.0f, 0.0f, -1.0f}; - math::fvec3 m_up{0.0f, 1.0f, 0.0f}; + math::fmat4 m_inv_view_projection{math::fmat4::identity()}; view_frustum_type m_view_frustum; - - aabb_type m_bounds{{0, 0, 0}, {0, 0, 0}}; + aabb_type m_bounds{{}, {}}; }; } // namespace scene diff --git a/src/game/states/experiments/treadmill-experiment-state.cpp b/src/game/states/experiments/treadmill-experiment-state.cpp index 7025192..8686e9c 100644 --- a/src/game/states/experiments/treadmill-experiment-state.cpp +++ b/src/game/states/experiments/treadmill-experiment-state.cpp @@ -96,7 +96,7 @@ treadmill_experiment_state::treadmill_experiment_state(::game& ctx): game_state(ctx) { - debug::log::trace("Entering nest view state..."); + debug::log::trace("Entering nest view state..."); ctx.active_scene = ctx.surface_scene.get();