diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ca183..73e1a79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.25) + option(APPLICATION_NAME "Application name" "Antkeeper") option(APPLICATION_VERSION "Application version string" "0.0.0") option(APPLICATION_AUTHOR "Application author" "C. J. Howard") diff --git a/src/engine/ai/steering/agent.hpp b/src/engine/ai/steering/agent.hpp index 32a649e..9b2169e 100644 --- a/src/engine/ai/steering/agent.hpp +++ b/src/engine/ai/steering/agent.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_AI_STEERING_AGENT_HPP #define ANTKEEPER_AI_STEERING_AGENT_HPP -#include +#include #include namespace ai { @@ -35,13 +35,13 @@ struct agent float mass; /// Cartesian position vector. - float3 position; + math::fvec3 position; /// Velocity vector. - float3 velocity; + math::fvec3 velocity; /// Acceleration vector. - float3 acceleration; + math::fvec3 acceleration; /// Maximum force. float max_force; @@ -53,13 +53,13 @@ struct agent float max_speed_squared; /// Orientation quaternion. - math::quaternion orientation; + math::fquat orientation; /// Orthonormal basis forward direction vector. - float3 forward; + math::fvec3 forward; /// Orthonormal basis up direction vector. - float3 up; + math::fvec3 up; }; } // namespace steering diff --git a/src/engine/ai/steering/behavior/flee.cpp b/src/engine/ai/steering/behavior/flee.cpp index 9e00cb3..2de1885 100644 --- a/src/engine/ai/steering/behavior/flee.cpp +++ b/src/engine/ai/steering/behavior/flee.cpp @@ -23,10 +23,10 @@ namespace ai { namespace steering { namespace behavior { -float3 flee(const agent& agent, const float3& target) +math::fvec3 flee(const agent& agent, const math::fvec3& target) { - float3 force = {0, 0, 0}; - const float3 difference = target - agent.position; + math::fvec3 force = {0, 0, 0}; + const math::fvec3 difference = target - agent.position; const float sqr_distance = math::dot(difference, difference); if (sqr_distance) diff --git a/src/engine/ai/steering/behavior/flee.hpp b/src/engine/ai/steering/behavior/flee.hpp index 91490f3..3c290a7 100644 --- a/src/engine/ai/steering/behavior/flee.hpp +++ b/src/engine/ai/steering/behavior/flee.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_AI_STEERING_BEHAVIOR_FLEE_HPP #include -#include +#include namespace ai { namespace steering { @@ -34,7 +34,7 @@ namespace behavior { * @param target Target position. * @return Flee force. */ -float3 flee(const agent& agent, const float3& target); +math::fvec3 flee(const agent& agent, const math::fvec3& target); } // namespace behavior } // namespace steering diff --git a/src/engine/ai/steering/behavior/seek.cpp b/src/engine/ai/steering/behavior/seek.cpp index 9adba2c..7573e04 100644 --- a/src/engine/ai/steering/behavior/seek.cpp +++ b/src/engine/ai/steering/behavior/seek.cpp @@ -23,10 +23,10 @@ namespace ai { namespace steering { namespace behavior { -float3 seek(const agent& agent, const float3& target) +math::fvec3 seek(const agent& agent, const math::fvec3& target) { - float3 force = {0, 0, 0}; - const float3 difference = target - agent.position; + math::fvec3 force = {0, 0, 0}; + const math::fvec3 difference = target - agent.position; const float sqr_distance = math::dot(difference, difference); if (sqr_distance) diff --git a/src/engine/ai/steering/behavior/seek.hpp b/src/engine/ai/steering/behavior/seek.hpp index 03b8621..7768afd 100644 --- a/src/engine/ai/steering/behavior/seek.hpp +++ b/src/engine/ai/steering/behavior/seek.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_AI_STEERING_BEHAVIOR_SEEK_HPP #include -#include +#include namespace ai { namespace steering { @@ -34,7 +34,7 @@ namespace behavior { * @param target Target position. * @return Seek force. */ -float3 seek(const agent& agent, const float3& target); +[[nodiscard]] math::fvec3 seek(const agent& agent, const math::fvec3& target); } // namespace behavior } // namespace steering diff --git a/src/engine/ai/steering/behavior/wander.cpp b/src/engine/ai/steering/behavior/wander.cpp index 4c86f6f..05c5a9b 100644 --- a/src/engine/ai/steering/behavior/wander.cpp +++ b/src/engine/ai/steering/behavior/wander.cpp @@ -26,37 +26,37 @@ namespace ai { namespace steering { namespace behavior { -float3 wander_2d(const agent& agent, float noise, float distance, float radius, float& angle) +math::fvec3 wander_2d(const agent& agent, float noise, float distance, float radius, float& angle) { // Shift wander angle angle += math::random(-noise, noise); // Calculate center of wander circle - const float3 center = agent.position + agent.forward * distance; + const math::fvec3 center = agent.position + agent.forward * distance; // Decompose orientation into swing and twist rotations - math::quaternion swing, twist; + math::fquat swing, twist; math::swing_twist(agent.orientation, agent.up, swing, twist); // Calculate offset to point on wander circle - const float3 offset = math::conjugate(twist) * (math::angle_axis(angle, agent.up) * agent.forward * radius); + const math::fvec3 offset = math::conjugate(twist) * (math::angle_axis(angle, agent.up) * agent.forward * radius); // Seek toward point on wander circle return seek(agent, center + offset); } -float3 wander_3d(const agent& agent, float noise, float distance, float radius, float& theta, float& phi) +math::fvec3 wander_3d(const agent& agent, float noise, float distance, float radius, float& theta, float& phi) { // Shift wander angles theta += math::random(-noise, noise); phi += math::random(-noise, noise); // Calculate center of wander sphere - const float3 center = agent.position + agent.forward * distance; + const math::fvec3 center = agent.position + agent.forward * distance; // Convert spherical coordinates to Cartesian point on wander sphere const float r_cos_theta = radius * std::cos(theta); - const float3 offset = + const math::fvec3 offset = { r_cos_theta * std::cos(phi), r_cos_theta * std::sin(phi), diff --git a/src/engine/ai/steering/behavior/wander.hpp b/src/engine/ai/steering/behavior/wander.hpp index eab4ea7..84ef58a 100644 --- a/src/engine/ai/steering/behavior/wander.hpp +++ b/src/engine/ai/steering/behavior/wander.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_AI_STEERING_BEHAVIOR_WANDER_HPP #include -#include +#include namespace ai { namespace steering { @@ -38,7 +38,7 @@ namespace behavior { * * @return Wander force. */ -float3 wander_2d(const agent& agent, float noise, float distance, float radius, float& angle); +math::fvec3 wander_2d(const agent& agent, float noise, float distance, float radius, float& angle); /** * Steers an agent in a continuously shifting random direction. @@ -52,7 +52,7 @@ float3 wander_2d(const agent& agent, float noise, float distance, float radius, * * @return Wander force. */ -float3 wander_3d(const agent& agent, float noise, float distance, float radius, float& theta, float& phi); +math::fvec3 wander_3d(const agent& agent, float noise, float distance, float radius, float& theta, float& phi); } // namespace behavior } // namespace steering diff --git a/src/engine/animation/ik/constraints/euler-ik-constraint.cpp b/src/engine/animation/ik/constraints/euler-ik-constraint.cpp index 4fe8088..1a8c1fb 100644 --- a/src/engine/animation/ik/constraints/euler-ik-constraint.cpp +++ b/src/engine/animation/ik/constraints/euler-ik-constraint.cpp @@ -21,7 +21,7 @@ #include #include -void euler_ik_constraint::solve(math::quaternion& q) +void euler_ik_constraint::solve(math::fquat& q) { // Derive XYZ angles from quaternion const auto x = std::atan2(2.0f * (q.w() * q.x() + q.y() * q.z()), 1.0f - 2.0f * (q.x() * q.x() + q.y() * q.y())); @@ -42,7 +42,7 @@ void euler_ik_constraint::solve(math::quaternion& q) const auto sz = std::sin(half_constrained_z); q = math::normalize ( - math::quaternion + math::fquat { cx * cy * cz + sx * sy * sz, sx * cy * cz - cx * sy * sz, diff --git a/src/engine/animation/ik/constraints/euler-ik-constraint.hpp b/src/engine/animation/ik/constraints/euler-ik-constraint.hpp index 1901d3a..bda4aa2 100644 --- a/src/engine/animation/ik/constraints/euler-ik-constraint.hpp +++ b/src/engine/animation/ik/constraints/euler-ik-constraint.hpp @@ -29,7 +29,7 @@ class euler_ik_constraint: public ik_constraint { public: - void solve(math::quaternion& q) override; + void solve(math::fquat& q) override; /** * Sets the angular limits. @@ -37,15 +37,15 @@ public: * @param min Minimum angles of the x-, y-, and z-axes, in radians. * @param max Maximum angles of the x-, y-, and z-axes, in radians. */ - inline void set_limits(const math::vector& min, const math::vector& max) noexcept + inline void set_limits(const math::fvec3& min, const math::fvec3& max) noexcept { m_min = min; m_max = max; } private: - math::vector m_min{-math::pi, -math::pi, -math::pi}; - math::vector m_max{ math::pi, math::pi, math::pi}; + math::fvec3 m_min{-math::pi, -math::pi, -math::pi}; + math::fvec3 m_max{ math::pi, math::pi, math::pi}; }; #endif // ANTKEEPER_ANIMATION_EULER_IK_CONSTRAINT_HPP diff --git a/src/engine/animation/ik/constraints/swing-twist-ik-constraint.cpp b/src/engine/animation/ik/constraints/swing-twist-ik-constraint.cpp index 87c2aab..3004843 100644 --- a/src/engine/animation/ik/constraints/swing-twist-ik-constraint.cpp +++ b/src/engine/animation/ik/constraints/swing-twist-ik-constraint.cpp @@ -28,13 +28,13 @@ void swing_twist_ik_constraint::set_twist_limit(float angle_min, float angle_max m_sin_half_twist_max = std::sin(angle_max * 0.5f); } -void swing_twist_ik_constraint::solve(math::quaternion& q) +void swing_twist_ik_constraint::solve(math::fquat& q) { - constexpr math::vector twist_axis{0.0f, 0.0f, 1.0f}; + constexpr math::fvec3 twist_axis{0.0f, 0.0f, 1.0f}; // Decompose rotation into swing and twist components - math::quaternion swing; - math::quaternion twist; + math::fquat swing; + math::fquat twist; math::swing_twist(q, twist_axis, swing, twist); // Limit twist diff --git a/src/engine/animation/ik/constraints/swing-twist-ik-constraint.hpp b/src/engine/animation/ik/constraints/swing-twist-ik-constraint.hpp index 16a1068..9513209 100644 --- a/src/engine/animation/ik/constraints/swing-twist-ik-constraint.hpp +++ b/src/engine/animation/ik/constraints/swing-twist-ik-constraint.hpp @@ -29,7 +29,7 @@ class swing_twist_ik_constraint: public ik_constraint { public: - void solve(math::quaternion& q) override; + void solve(math::fquat& q) override; /** * Sets the twist rotation limit. diff --git a/src/engine/animation/ik/ik-constraint.hpp b/src/engine/animation/ik/ik-constraint.hpp index 555eeaf..a46a9ce 100644 --- a/src/engine/animation/ik/ik-constraint.hpp +++ b/src/engine/animation/ik/ik-constraint.hpp @@ -33,7 +33,7 @@ public: * * @param[in,out] q Unit quaternion representing the rotation of a joint. */ - virtual void solve(math::quaternion& q) = 0; + virtual void solve(math::fquat& q) = 0; }; #endif // ANTKEEPER_ANIMATION_IK_CONSTRAINT_HPP diff --git a/src/engine/animation/ik/solvers/ccd-ik-solver.hpp b/src/engine/animation/ik/solvers/ccd-ik-solver.hpp index 930e071..fcf0dfd 100644 --- a/src/engine/animation/ik/solvers/ccd-ik-solver.hpp +++ b/src/engine/animation/ik/solvers/ccd-ik-solver.hpp @@ -83,13 +83,13 @@ public: * * @param position Position of the end effector, relative to the tip bone. */ - inline void set_effector_position(const math::vector& position) noexcept + inline void set_effector_position(const math::fvec3& position) noexcept { m_effector_position = position; } /// Returns the position of the end effector, relative to the tip bone. - [[nodiscard]] inline const math::vector& get_effector_position() const + [[nodiscard]] inline const math::fvec3& get_effector_position() const { return m_effector_position; } @@ -104,13 +104,13 @@ public: * * @param position IK goal position, in world-space. */ - inline void set_goal_position(const math::vector& position) noexcept + inline void set_goal_position(const math::fvec3& position) noexcept { m_goal_position = position; } /// Returns the position of goal, in world-space. - [[nodiscard]] inline const math::vector& get_goal_position() const + [[nodiscard]] inline const math::fvec3& get_goal_position() const { return m_goal_position; } @@ -121,8 +121,8 @@ private: ik_rig* m_ik_rig{nullptr}; std::size_t m_max_iterations{10}; std::vector m_bone_indices; - math::vector m_effector_position{0.0f, 0.0f, 0.0f}; - math::vector m_goal_position{0.0f, 0.0f, 0.0f}; + math::fvec3 m_effector_position{0.0f, 0.0f, 0.0f}; + math::fvec3 m_goal_position{0.0f, 0.0f, 0.0f}; float m_sqr_distance_tolerance{1e-5f}; }; diff --git a/src/engine/animation/screen-transition.cpp b/src/engine/animation/screen-transition.cpp index fd6f454..1ee4ef9 100644 --- a/src/engine/animation/screen-transition.cpp +++ b/src/engine/animation/screen-transition.cpp @@ -23,7 +23,7 @@ screen_transition::screen_transition() { - progress = std::make_shared(1, 0.0f); + progress = std::make_shared(1, 0.0f); // Setup material material = std::make_shared(); diff --git a/src/engine/animation/screen-transition.hpp b/src/engine/animation/screen-transition.hpp index 3a6f139..80331b3 100644 --- a/src/engine/animation/screen-transition.hpp +++ b/src/engine/animation/screen-transition.hpp @@ -44,7 +44,7 @@ public: private: scene::billboard billboard; std::shared_ptr material; - std::shared_ptr progress; + std::shared_ptr progress; ::animation animation; ::animation::channel* channel; std::function callback; diff --git a/src/engine/app/sdl/sdl-window-manager.cpp b/src/engine/app/sdl/sdl-window-manager.cpp index 82f972b..8f86ac4 100644 --- a/src/engine/app/sdl/sdl-window-manager.cpp +++ b/src/engine/app/sdl/sdl-window-manager.cpp @@ -95,8 +95,8 @@ sdl_window_manager::~sdl_window_manager() std::shared_ptr sdl_window_manager::create_window ( const std::string& title, - const math::vector& windowed_position, - const math::vector& windowed_size, + const math::ivec2& windowed_position, + const math::ivec2& windowed_size, bool maximized, bool fullscreen, bool v_sync diff --git a/src/engine/app/sdl/sdl-window-manager.hpp b/src/engine/app/sdl/sdl-window-manager.hpp index c7a237b..32123e1 100644 --- a/src/engine/app/sdl/sdl-window-manager.hpp +++ b/src/engine/app/sdl/sdl-window-manager.hpp @@ -52,8 +52,8 @@ public: [[nodiscard]] virtual std::shared_ptr create_window ( const std::string& title, - const math::vector& windowed_position, - const math::vector& windowed_size, + const math::ivec2& windowed_position, + const math::ivec2& windowed_size, bool maximized, bool fullscreen, bool v_sync diff --git a/src/engine/app/sdl/sdl-window.cpp b/src/engine/app/sdl/sdl-window.cpp index c16ba16..ffe2447 100644 --- a/src/engine/app/sdl/sdl-window.cpp +++ b/src/engine/app/sdl/sdl-window.cpp @@ -28,8 +28,8 @@ namespace app { sdl_window::sdl_window ( const std::string& title, - const math::vector& windowed_position, - const math::vector& windowed_size, + const math::ivec2& windowed_position, + const math::ivec2& windowed_size, bool maximized, bool fullscreen, bool v_sync @@ -200,23 +200,23 @@ void sdl_window::set_title(const std::string& title) this->m_title = title; } -void sdl_window::set_position(const math::vector& position) +void sdl_window::set_position(const math::ivec2& position) { SDL_SetWindowPosition(m_internal_window, position.x(), position.y()); } -void sdl_window::set_size(const math::vector& size) +void sdl_window::set_size(const math::ivec2& size) { SDL_SetWindowSize(m_internal_window, size.x(), size.y()); } -void sdl_window::set_minimum_size(const math::vector& size) +void sdl_window::set_minimum_size(const math::ivec2& size) { SDL_SetWindowMinimumSize(m_internal_window, size.x(), size.y()); this->m_minimum_size = size; } -void sdl_window::set_maximum_size(const math::vector& size) +void sdl_window::set_maximum_size(const math::ivec2& size) { SDL_SetWindowMaximumSize(m_internal_window, size.x(), size.y()); this->m_maximum_size = size; diff --git a/src/engine/app/sdl/sdl-window.hpp b/src/engine/app/sdl/sdl-window.hpp index 01fd2f1..fad71cb 100644 --- a/src/engine/app/sdl/sdl-window.hpp +++ b/src/engine/app/sdl/sdl-window.hpp @@ -35,8 +35,8 @@ public: sdl_window ( const std::string& title, - const math::vector& windowed_position, - const math::vector& windowed_size, + const math::ivec2& windowed_position, + const math::ivec2& windowed_size, bool maximized, bool fullscreen, bool v_sync @@ -49,10 +49,10 @@ public: virtual ~sdl_window(); virtual void set_title(const std::string& title); - virtual void set_position(const math::vector& position); - virtual void set_size(const math::vector& size); - virtual void set_minimum_size(const math::vector& size); - virtual void set_maximum_size(const math::vector& size); + virtual void set_position(const math::ivec2& position); + virtual void set_size(const math::ivec2& size); + virtual void set_minimum_size(const math::ivec2& size); + virtual void set_maximum_size(const math::ivec2& size); virtual void set_maximized(bool maximized); virtual void set_fullscreen(bool fullscreen); virtual void set_v_sync(bool v_sync); diff --git a/src/engine/app/window-events.hpp b/src/engine/app/window-events.hpp index 8074663..6dd4b39 100644 --- a/src/engine/app/window-events.hpp +++ b/src/engine/app/window-events.hpp @@ -56,7 +56,7 @@ struct window_moved_event window* window{nullptr}; /// Position of the window, in display units. - math::vector position{0, 0}; + math::ivec2 position{0, 0}; }; /** @@ -95,7 +95,7 @@ struct window_resized_event window* window{nullptr}; /// Window size, in display units. - math::vector size{0, 0}; + math::ivec2 size{0, 0}; }; } // namespace app diff --git a/src/engine/app/window-manager.hpp b/src/engine/app/window-manager.hpp index 3e80b59..3788553 100644 --- a/src/engine/app/window-manager.hpp +++ b/src/engine/app/window-manager.hpp @@ -60,8 +60,8 @@ public: [[nodiscard]] virtual std::shared_ptr create_window ( const std::string& title, - const math::vector& windowed_position, - const math::vector& windowed_size, + const math::ivec2& windowed_position, + const math::ivec2& windowed_size, bool maximized, bool fullscreen, bool v_sync diff --git a/src/engine/app/window.hpp b/src/engine/app/window.hpp index 398f248..eab5306 100644 --- a/src/engine/app/window.hpp +++ b/src/engine/app/window.hpp @@ -48,28 +48,28 @@ public: * * @param position Position of the window, in display units. */ - virtual void set_position(const math::vector& position) = 0; + virtual void set_position(const math::ivec2& position) = 0; /** * Changes the size of the window. * * @param size Size of the window, in display units. */ - virtual void set_size(const math::vector& size) = 0; + virtual void set_size(const math::ivec2& size) = 0; /** * Sets the minimum size of the window. * * @param size Minimum size of the window, in display units. */ - virtual void set_minimum_size(const math::vector& size) = 0; + virtual void set_minimum_size(const math::ivec2& size) = 0; /** * Sets the maximum size of the window. * * @param size Maximum size of the window, in display units. */ - virtual void set_maximum_size(const math::vector& size) = 0; + virtual void set_maximum_size(const math::ivec2& size) = 0; /** * Maximizes or unmaximizes the window. @@ -109,43 +109,43 @@ public: } /// Returns the windowed (non-maximized, non-fullscreen) position of the window, in display units. - [[nodiscard]] inline const math::vector& get_windowed_position() const noexcept + [[nodiscard]] inline const math::ivec2& get_windowed_position() const noexcept { return m_windowed_position; } /// Returns the current position of the window, in display units. - [[nodiscard]] inline const math::vector& get_position() const noexcept + [[nodiscard]] inline const math::ivec2& get_position() const noexcept { return m_position; } /// Returns the windowed (non-maximized, non-fullscreen) size of the window, in display units. - [[nodiscard]] inline const math::vector& get_windowed_size() const noexcept + [[nodiscard]] inline const math::ivec2& get_windowed_size() const noexcept { return m_windowed_size; } /// Returns the current size of the window, in display units. - [[nodiscard]] inline const math::vector& get_size() const noexcept + [[nodiscard]] inline const math::ivec2& get_size() const noexcept { return m_size; } /// Returns the minimum size of the window, in display units. - [[nodiscard]] inline const math::vector& get_minimum_size() const noexcept + [[nodiscard]] inline const math::ivec2& get_minimum_size() const noexcept { return m_minimum_size; } /// Returns the maximum size of the window, in display units. - [[nodiscard]] inline const math::vector& get_maximum_size() const noexcept + [[nodiscard]] inline const math::ivec2& get_maximum_size() const noexcept { return m_minimum_size; } /// Returns the current size of the window's drawable viewport, in pixels. - [[nodiscard]] inline const math::vector& get_viewport_size() const noexcept + [[nodiscard]] inline const math::ivec2& get_viewport_size() const noexcept { return m_viewport_size; } @@ -217,13 +217,13 @@ protected: friend class window_manager; std::string m_title; - math::vector m_windowed_position{0, 0}; - math::vector m_position{0, 0}; - math::vector m_windowed_size{0, 0}; - math::vector m_size{0, 0}; - math::vector m_minimum_size{0, 0}; - math::vector m_maximum_size{0, 0}; - math::vector m_viewport_size{0, 0}; + math::ivec2 m_windowed_position{0, 0}; + math::ivec2 m_position{0, 0}; + math::ivec2 m_windowed_size{0, 0}; + math::ivec2 m_size{0, 0}; + math::ivec2 m_minimum_size{0, 0}; + math::ivec2 m_maximum_size{0, 0}; + math::ivec2 m_viewport_size{0, 0}; bool m_maximized{false}; bool m_fullscreen{false}; bool m_v_sync{false}; diff --git a/src/engine/color/aces.hpp b/src/engine/color/aces.hpp index f24f5b8..2981f4d 100644 --- a/src/engine/color/aces.hpp +++ b/src/engine/color/aces.hpp @@ -31,7 +31,7 @@ namespace aces { /// CIE xy chromaticity coordinates of the ACES white point (~D60). template -constexpr math::vector2 white_point = {T{0.32168}, T{0.33767}}; +constexpr math::vec2 white_point = {T{0.32168}, T{0.33767}}; /// ACES AP0 color space. template @@ -66,10 +66,10 @@ constexpr rgb::color_space ap1 * @return Saturation adjustment matrix. */ template -[[nodiscard]] constexpr math::matrix adjust_saturation(T s, const math::vector3& to_y) noexcept +[[nodiscard]] constexpr math::mat3 adjust_saturation(T s, const math::vec3& to_y) noexcept { - const math::vector3 v = to_y * (T{1} - s); - return math::matrix + const math::vec3 v = to_y * (T{1} - s); + return math::mat3 { v[0] + s, v[0], v[0], v[1], v[1] + s, v[1], @@ -79,11 +79,11 @@ template /// ACES AP1 RRT saturation adjustment matrix. template -constexpr math::matrix ap1_rrt_sat = aces::adjust_saturation(T{0.96}, ap1.to_y); +constexpr math::mat3 ap1_rrt_sat = aces::adjust_saturation(T{0.96}, ap1.to_y); /// ACES AP1 ODT saturation adjustment matrix. template -constexpr math::matrix ap1_odt_sat = aces::adjust_saturation(T{0.93}, ap1.to_y); +constexpr math::mat3 ap1_odt_sat = aces::adjust_saturation(T{0.93}, ap1.to_y); } // namespace aces diff --git a/src/engine/color/cat.hpp b/src/engine/color/cat.hpp index ab85005..07d5435 100644 --- a/src/engine/color/cat.hpp +++ b/src/engine/color/cat.hpp @@ -35,7 +35,7 @@ namespace cat { * @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html */ template -constexpr math::matrix bradford = +constexpr math::mat3 bradford = { T{ 0.8951}, T{-0.7502}, T{ 0.0389}, T{ 0.2664}, T{ 1.7135}, T{-0.0685}, @@ -48,7 +48,7 @@ constexpr math::matrix bradford = * @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html */ template -constexpr math::matrix von_kries = +constexpr math::mat3 von_kries = { T{ 0.40024}, T{-0.22630}, T{0.00000}, T{ 0.70760}, T{ 1.16532}, T{0.00000}, @@ -61,7 +61,7 @@ constexpr math::matrix von_kries = * @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html */ template -constexpr math::matrix xyz_scaling = +constexpr math::mat3 xyz_scaling = { T{1}, T{0}, T{0}, T{0}, T{1}, T{0}, @@ -81,17 +81,17 @@ constexpr math::matrix xyz_scaling = * @see http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html */ template -[[nodiscard]] constexpr math::matrix matrix(const math::vector2& w0, const math::vector2& w1, const math::matrix& cone_response = bradford) noexcept +[[nodiscard]] constexpr math::mat3 matrix(const math::vec2& w0, const math::vec2& w1, const math::mat3& cone_response = bradford) noexcept { // Convert CIE xy chromaticity coordinates to CIE XYZ colors - const math::vector3 w0_xyz = {w0[0] / w0[1], T{1}, (T{1} - w0[0] - w0[1]) / w0[1]}; - const math::vector3 w1_xyz = {w1[0] / w1[1], T{1}, (T{1} - w1[0] - w1[1]) / w1[1]}; + const math::vec3 w0_xyz = {w0[0] / w0[1], T{1}, (T{1} - w0[0] - w0[1]) / w0[1]}; + const math::vec3 w1_xyz = {w1[0] / w1[1], T{1}, (T{1} - w1[0] - w1[1]) / w1[1]}; // Calculate cone response of CIE XYZ colors - const math::vector3 w0_cone_response = cone_response * w0_xyz; - const math::vector3 w1_cone_response = cone_response * w1_xyz; + const math::vec3 w0_cone_response = cone_response * w0_xyz; + const math::vec3 w1_cone_response = cone_response * w1_xyz; - const math::matrix scale = + const math::mat3 scale = { w1_cone_response[0] / w0_cone_response[0], T{0}, T{0}, T{0}, w1_cone_response[1] / w0_cone_response[1], T{0}, diff --git a/src/engine/color/cct.hpp b/src/engine/color/cct.hpp index 0e85c55..7bcc410 100644 --- a/src/engine/color/cct.hpp +++ b/src/engine/color/cct.hpp @@ -38,10 +38,10 @@ namespace cct { * @see Krystek, M. (1985), An algorithm to calculate correlated colour temperature. Color Res. Appl., 10: 38-40. */ template -[[nodiscard]] math::vector2 to_ucs(T t) noexcept +[[nodiscard]] math::vec2 to_ucs(T t) noexcept { const T tt = t * t; - return math::vector2 + return math::vec2 { (T{0.860117757} + T{1.54118254e-4} * t + T{1.28641212e-7} * tt) / (T{1} + T{8.42420235e-4} * t + T{7.08145163e-7} * tt), (T{0.317398726} + T{4.22806245e-5} * t + T{4.20481691e-8} * tt) / (T{1} - T{2.89741816e-5} * t + T{1.61456053e-7} * tt) @@ -55,7 +55,7 @@ template * @return CIE xyY color with `Y = 1`. */ template -math::vector3 to_xyy(T t) +math::vec3 to_xyy(T t) { return ucs::to_xyy(to_ucs(t), T{1}); } @@ -67,7 +67,7 @@ math::vector3 to_xyy(T t) * @return CIE XYZ color with `Y = 1`. */ template -math::vector3 to_xyz(T t) +math::vec3 to_xyz(T t) { return xyy::to_xyz(to_xyy(t)); } diff --git a/src/engine/color/illuminant.hpp b/src/engine/color/illuminant.hpp index b0c1558..633b424 100644 --- a/src/engine/color/illuminant.hpp +++ b/src/engine/color/illuminant.hpp @@ -35,65 +35,65 @@ namespace illuminant { namespace deg2 { template - constexpr math::vector2 a = {T{0.44757}, T{0.40745}}; + constexpr math::vec2 a = {T{0.44757}, T{0.40745}}; template - constexpr math::vector2 b = {T{0.34842}, T{0.35161}}; + constexpr math::vec2 b = {T{0.34842}, T{0.35161}}; template - constexpr math::vector2 c = {T{0.31006}, T{0.31616}}; + constexpr math::vec2 c = {T{0.31006}, T{0.31616}}; template - constexpr math::vector2 d50 = {T{0.34567}, T{0.35850}}; + constexpr math::vec2 d50 = {T{0.34567}, T{0.35850}}; template - constexpr math::vector2 d55 = {T{0.33242}, T{0.34743}}; + constexpr math::vec2 d55 = {T{0.33242}, T{0.34743}}; template - constexpr math::vector2 d65 = {T{0.31271}, T{0.32902}}; + constexpr math::vec2 d65 = {T{0.31271}, T{0.32902}}; template - constexpr math::vector2 d75 = {T{0.29902}, T{0.31485}}; + constexpr math::vec2 d75 = {T{0.29902}, T{0.31485}}; template - constexpr math::vector2 d93 = {T{0.28315}, T{0.29711}}; + constexpr math::vec2 d93 = {T{0.28315}, T{0.29711}}; template - constexpr math::vector2 e = {T{0.33333}, T{0.33333}}; + constexpr math::vec2 e = {T{0.33333}, T{0.33333}}; template - constexpr math::vector2 f1 = {T{0.31310}, T{0.33727}}; + constexpr math::vec2 f1 = {T{0.31310}, T{0.33727}}; template - constexpr math::vector2 f2 = {T{0.37208}, T{0.37529}}; + constexpr math::vec2 f2 = {T{0.37208}, T{0.37529}}; template - constexpr math::vector2 f3 = {T{0.40910}, T{0.39430}}; + constexpr math::vec2 f3 = {T{0.40910}, T{0.39430}}; template - constexpr math::vector2 f4 = {T{0.44018}, T{0.40329}}; + constexpr math::vec2 f4 = {T{0.44018}, T{0.40329}}; template - constexpr math::vector2 f5 = {T{0.31379}, T{0.34531}}; + constexpr math::vec2 f5 = {T{0.31379}, T{0.34531}}; template - constexpr math::vector2 f6 = {T{0.37790}, T{0.38835}}; + constexpr math::vec2 f6 = {T{0.37790}, T{0.38835}}; template - constexpr math::vector2 f7 = {T{0.31292}, T{0.32933}}; + constexpr math::vec2 f7 = {T{0.31292}, T{0.32933}}; template - constexpr math::vector2 f8 = {T{0.34588}, T{0.35875}}; + constexpr math::vec2 f8 = {T{0.34588}, T{0.35875}}; template - constexpr math::vector2 f9 = {T{0.37417}, T{0.37281}}; + constexpr math::vec2 f9 = {T{0.37417}, T{0.37281}}; template - constexpr math::vector2 f10 = {T{0.34609}, T{0.35986}}; + constexpr math::vec2 f10 = {T{0.34609}, T{0.35986}}; template - constexpr math::vector2 f11 = {T{0.38052}, T{0.37713}}; + constexpr math::vec2 f11 = {T{0.38052}, T{0.37713}}; template - constexpr math::vector2 f12 = {T{0.43695}, T{0.40441}}; + constexpr math::vec2 f12 = {T{0.43695}, T{0.40441}}; template - constexpr math::vector2 led_b1 = {T{0.4560}, T{0.4078}}; + constexpr math::vec2 led_b1 = {T{0.4560}, T{0.4078}}; template - constexpr math::vector2 led_b2 = {T{0.4357}, T{0.4012}}; + constexpr math::vec2 led_b2 = {T{0.4357}, T{0.4012}}; template - constexpr math::vector2 led_b3 = {T{0.3756}, T{0.3723}}; + constexpr math::vec2 led_b3 = {T{0.3756}, T{0.3723}}; template - constexpr math::vector2 led_b4 = {T{0.3422}, T{0.3502}}; + constexpr math::vec2 led_b4 = {T{0.3422}, T{0.3502}}; template - constexpr math::vector2 led_b5 = {T{0.3118}, T{0.3236}}; + constexpr math::vec2 led_b5 = {T{0.3118}, T{0.3236}}; template - constexpr math::vector2 led_bh1 = {T{0.4474}, T{0.4066}}; + constexpr math::vec2 led_bh1 = {T{0.4474}, T{0.4066}}; template - constexpr math::vector2 led_rgb1 = {T{0.4557}, T{0.4211}}; + constexpr math::vec2 led_rgb1 = {T{0.4557}, T{0.4211}}; template - constexpr math::vector2 led_v1 = {T{0.4560}, T{0.4548}}; + constexpr math::vec2 led_v1 = {T{0.4560}, T{0.4548}}; template - constexpr math::vector2 led_v2 = {T{0.3781}, T{0.3775}}; + constexpr math::vec2 led_v2 = {T{0.3781}, T{0.3775}}; } // deg2 @@ -101,47 +101,47 @@ namespace deg2 { namespace deg10 { template - constexpr math::vector2 a = {T{0.45117}, T{0.40594}}; + constexpr math::vec2 a = {T{0.45117}, T{0.40594}}; template - constexpr math::vector2 b = {T{0.34980}, T{0.35270}}; + constexpr math::vec2 b = {T{0.34980}, T{0.35270}}; template - constexpr math::vector2 c = {T{0.31039}, T{0.31905}}; + constexpr math::vec2 c = {T{0.31039}, T{0.31905}}; template - constexpr math::vector2 d50 = {T{0.34773}, T{0.35952}}; + constexpr math::vec2 d50 = {T{0.34773}, T{0.35952}}; template - constexpr math::vector2 d55 = {T{0.33411}, T{0.34877}}; + constexpr math::vec2 d55 = {T{0.33411}, T{0.34877}}; template - constexpr math::vector2 d65 = {T{0.31382}, T{0.33100}}; + constexpr math::vec2 d65 = {T{0.31382}, T{0.33100}}; template - constexpr math::vector2 d75 = {T{0.29968}, T{0.31740}}; + constexpr math::vec2 d75 = {T{0.29968}, T{0.31740}}; template - constexpr math::vector2 d93 = {T{0.28327}, T{0.30043}}; + constexpr math::vec2 d93 = {T{0.28327}, T{0.30043}}; template - constexpr math::vector2 e = {T{0.33333}, T{0.33333}}; + constexpr math::vec2 e = {T{0.33333}, T{0.33333}}; template - constexpr math::vector2 f1 = {T{0.31811}, T{0.33559}}; + constexpr math::vec2 f1 = {T{0.31811}, T{0.33559}}; template - constexpr math::vector2 f2 = {T{0.37925}, T{0.36733}}; + constexpr math::vec2 f2 = {T{0.37925}, T{0.36733}}; template - constexpr math::vector2 f3 = {T{0.41761}, T{0.38324}}; + constexpr math::vec2 f3 = {T{0.41761}, T{0.38324}}; template - constexpr math::vector2 f4 = {T{0.44920}, T{0.39074}}; + constexpr math::vec2 f4 = {T{0.44920}, T{0.39074}}; template - constexpr math::vector2 f5 = {T{0.31975}, T{0.34246}}; + constexpr math::vec2 f5 = {T{0.31975}, T{0.34246}}; template - constexpr math::vector2 f6 = {T{0.38660}, T{0.37847}}; + constexpr math::vec2 f6 = {T{0.38660}, T{0.37847}}; template - constexpr math::vector2 f7 = {T{0.31569}, T{0.32960}}; + constexpr math::vec2 f7 = {T{0.31569}, T{0.32960}}; template - constexpr math::vector2 f8 = {T{0.34902}, T{0.35939}}; + constexpr math::vec2 f8 = {T{0.34902}, T{0.35939}}; template - constexpr math::vector2 f9 = {T{0.37829}, T{0.37045}}; + constexpr math::vec2 f9 = {T{0.37829}, T{0.37045}}; template - constexpr math::vector2 f10 = {T{0.35090}, T{0.35444}}; + constexpr math::vec2 f10 = {T{0.35090}, T{0.35444}}; template - constexpr math::vector2 f11 = {T{0.38541}, T{0.37123}}; + constexpr math::vec2 f11 = {T{0.38541}, T{0.37123}}; template - constexpr math::vector2 f12 = {T{0.44256}, T{0.39717}}; + constexpr math::vec2 f12 = {T{0.44256}, T{0.39717}}; } // namespace deg10 diff --git a/src/engine/color/rgb.hpp b/src/engine/color/rgb.hpp index 1752286..d897150 100644 --- a/src/engine/color/rgb.hpp +++ b/src/engine/color/rgb.hpp @@ -43,18 +43,18 @@ namespace rgb { * @see https://mina86.com/2019/srgb-xyz-matrix/ */ template -[[nodiscard]] constexpr math::matrix to_xyz(const math::vector2& r, const math::vector2& g, const math::vector2& b, const math::vector2& w) +[[nodiscard]] constexpr math::mat3 to_xyz(const math::vec2& r, const math::vec2& g, const math::vec2& b, const math::vec2& w) { - const math::matrix m = + const math::mat3 m = { r[0], r[1], T{1} - (r[0] + r[1]), g[0], g[1], T{1} - (g[0] + g[1]), b[0], b[1], T{1} - (b[0] + b[1]) }; - const math::vector3 scale = math::inverse(m) * math::vector3{w[0] / w[1], T{1}, (T{1} - (w[0] + w[1])) / w[1]}; + const math::vec3 scale = math::inverse(m) * math::vec3{w[0] / w[1], T{1}, (T{1} - (w[0] + w[1])) / w[1]}; - return math::matrix + return math::mat3 { m[0][0] * scale[0], m[0][1] * scale[0], m[0][2] * scale[0], m[1][0] * scale[1], m[1][1] * scale[1], m[1][2] * scale[1], @@ -69,19 +69,19 @@ template struct color_space { /// Transfer function function pointer type. - typedef math::vector3 (*transfer_function_type)(const math::vector3&); + typedef math::vec3 (*transfer_function_type)(const math::vec3&); /// CIE xy chromaticity coordinates of the red primary. - const math::vector2 r; + const math::vec2 r; /// CIE xy chromaticity coordinates of the green primary. - const math::vector2 g; + const math::vec2 g; /// CIE xy chromaticity coordinates of the blue primary. - const math::vector2 b; + const math::vec2 b; /// CIE xy chromaticity coordinates of the white point. - const math::vector2 w; + const math::vec2 w; /// Function pointer to the electro-optical transfer function. const transfer_function_type eotf; @@ -90,13 +90,13 @@ struct color_space const transfer_function_type oetf; /// Matrix which transforms an RGB color to a CIE XYZ color. - const math::matrix3x3 to_xyz; + const math::mat3 to_xyz; /// Matrix which transforms a CIE XYZ color to an RGB color. - const math::matrix3x3 from_xyz; + const math::mat3 from_xyz; /// Vector which gives the luminance of an RGB color via dot product. - const math::vector3 to_y; + const math::vec3 to_y; /** * Constructs an RGB color space. @@ -106,7 +106,7 @@ struct color_space * @param b CIE xy chromaticity coordinates of the blue primary. * @param w CIE xy chromaticity coordinates of the white point. */ - constexpr color_space(const math::vector2& r, const math::vector2& g, const math::vector2& b, const math::vector2& w, transfer_function_type eotf, transfer_function_type oetf): + constexpr color_space(const math::vec2& r, const math::vec2& g, const math::vec2& b, const math::vec2& w, transfer_function_type eotf, transfer_function_type oetf): r(r), g(g), b(b), @@ -124,7 +124,7 @@ struct color_space * @param x Linear RGB color. * @return return Luminance of @p x. */ - [[nodiscard]] inline constexpr T luminance(const math::vector3& x) const noexcept + [[nodiscard]] inline constexpr T luminance(const math::vec3& x) const noexcept { return math::dot(x, to_y); } @@ -140,7 +140,7 @@ struct color_space * @return Color space transformation matrix. */ template -[[nodiscard]] constexpr math::matrix3x3 to_rgb(const color_space& s0, const color_space& s1, const math::matrix3x3& cone_response = color::cat::bradford) +[[nodiscard]] constexpr math::mat3 to_rgb(const color_space& s0, const color_space& s1, const math::mat3& cone_response = color::cat::bradford) { return s1.from_xyz * color::cat::matrix(s0.w, s1.w, cone_response) * s0.to_xyz; } diff --git a/src/engine/color/srgb.hpp b/src/engine/color/srgb.hpp index 2d34a5d..4f670ea 100644 --- a/src/engine/color/srgb.hpp +++ b/src/engine/color/srgb.hpp @@ -37,7 +37,7 @@ namespace color { * @see IEC 61966-2-1:1999 */ template -[[nodiscard]] math::vector3 srgb_oetf(const math::vector3& x) +[[nodiscard]] math::vec3 srgb_oetf(const math::vec3& x) { auto f = [](T x) -> T { @@ -57,7 +57,7 @@ template * @see IEC 61966-2-1:1999 */ template -[[nodiscard]] math::vector3 srgb_eotf(const math::vector3& x) +[[nodiscard]] math::vec3 srgb_eotf(const math::vec3& x) { auto f = [](T x) -> T { diff --git a/src/engine/color/ucs.hpp b/src/engine/color/ucs.hpp index 44c0d03..9c29852 100644 --- a/src/engine/color/ucs.hpp +++ b/src/engine/color/ucs.hpp @@ -35,10 +35,10 @@ namespace ucs { * @return CIE xyY color. */ template -[[nodiscard]] constexpr math::vector3 to_xyy(const math::vector2& uv, T y = T{1}) noexcept +[[nodiscard]] constexpr math::vec3 to_xyy(const math::vec2& uv, T y = T{1}) noexcept { const T d = T{1} / (T{2} * uv[0] - T{8} * uv[1] + T{4}); - return math::vector3{(T{3} * uv[0]) * d, (T{2} * uv[1]) * d, y}; + return math::vec3{(T{3} * uv[0]) * d, (T{2} * uv[1]) * d, y}; } } // namespace ucs diff --git a/src/engine/color/xyy.hpp b/src/engine/color/xyy.hpp index 990d27a..4fa8391 100644 --- a/src/engine/color/xyy.hpp +++ b/src/engine/color/xyy.hpp @@ -34,7 +34,7 @@ namespace xyy { * @return return Luminance of @p x. */ template -[[nodiscard]] inline constexpr T luminance(const math::vector3& x) noexcept +[[nodiscard]] inline constexpr T luminance(const math::vec3& x) noexcept { return x[2]; } @@ -46,10 +46,10 @@ template * @return CIE 1960 UCS color. */ template -[[nodiscard]] constexpr math::vector2 to_ucs(const math::vector3& x) noexcept +[[nodiscard]] constexpr math::vec2 to_ucs(const math::vec3& x) noexcept { const T d = (T{1} / (T{-2} * x[0] + T{12} * x[1] + T{3})); - return math::vector2{(T{4} * x[0]) * d, (T{6} * x[1]) * d}; + return math::vec2{(T{4} * x[0]) * d, (T{6} * x[1]) * d}; } /** @@ -59,9 +59,9 @@ template * @return CIE XYZ color. */ template -[[nodiscard]] constexpr math::vector3 to_xyz(const math::vector3& x) noexcept +[[nodiscard]] constexpr math::vec3 to_xyz(const math::vec3& x) noexcept { - return math::vector3{(x[0] * x[2]) / x[1], x[2], ((T{1} - x[0] - x[1]) * x[2]) / x[1]}; + return math::vec3{(x[0] * x[2]) / x[1], x[2], ((T{1} - x[0] - x[1]) * x[2]) / x[1]}; } } // namespace xyy diff --git a/src/engine/color/xyz.hpp b/src/engine/color/xyz.hpp index c6a56cd..614c1b0 100644 --- a/src/engine/color/xyz.hpp +++ b/src/engine/color/xyz.hpp @@ -38,7 +38,7 @@ namespace xyz { * @return return Luminance of @p x. */ template -[[nodiscard]] inline constexpr T luminance(const math::vector3& x) noexcept +[[nodiscard]] inline constexpr T luminance(const math::vec3& x) noexcept { return x[1]; } @@ -50,10 +50,10 @@ template * @return CIE xyY color. */ template -[[nodiscard]] constexpr math::vector3 to_xyy(const math::vector3& x) noexcept +[[nodiscard]] constexpr math::vec3 to_xyy(const math::vec3& x) noexcept { const T sum = x[0] + x[1] + x[2]; - return math::vector3{x[0] / sum, x[1] / sum, x[1]}; + return math::vec3{x[0] / sum, x[1] / sum, x[1]}; } /** @@ -131,9 +131,9 @@ template * @see Wyman, C., Sloan, P.J., & Shirley, P. (2013). Simple Analytic Approximations to the CIE XYZ Color Matching Functions. */ template -[[nodiscard]] math::vector3 match(T lambda) +[[nodiscard]] math::vec3 match(T lambda) { - return math::vector3 + return math::vec3 { match_x(lambda), match_y(lambda), diff --git a/src/engine/geom/brep/brep-attribute-map.hpp b/src/engine/geom/brep/brep-attribute-map.hpp new file mode 100644 index 0000000..ea6229f --- /dev/null +++ b/src/engine/geom/brep/brep-attribute-map.hpp @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_ATTRIBUTE_MAP_HPP +#define ANTKEEPER_GEOM_BREP_ATTRIBUTE_MAP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace geom { + +/** + * Maps names to B-rep attributes. + */ +class brep_attribute_map +{ +public: + template + class iterator_template + { + public: + using iterator_type = Iter; + using iterator_category = std::bidirectional_iterator_tag; + using iterator_concept = std::bidirectional_iterator_tag; + using difference_type = std::iter_difference_t; + using value_type = brep_attribute_base; + using pointer = std::conditional::type; + using reference = std::conditional::type; + + [[nodiscard]] inline constexpr reference operator*() const noexcept + { + return *m_it->second; + } + + [[nodiscard]] inline constexpr pointer operator->() const noexcept + { + return &(*m_it->second); + } + + [[nodiscard]] inline constexpr reference operator[](difference_type i) const noexcept + { + return *(m_it[i]); + } + + inline iterator_template& operator++() noexcept + { + ++m_it; + return *this; + } + + [[nodiscard]] inline iterator_template operator++(int) noexcept + { + iterator_template tmp = *this; + ++(*this); + return tmp; + } + + inline iterator_template& operator--() noexcept + { + --m_it; + return *this; + } + + [[nodiscard]] inline iterator_template operator--(int) noexcept + { + iterator_template tmp = *this; + --(*this); + return tmp; + } + + inline iterator_template& operator+=(difference_type n) noexcept + { + m_it += n; + return *this; + } + + inline iterator_template& operator-=(difference_type n) noexcept + { + m_it -= n; + return *this; + } + + [[nodiscard]] inline bool operator==(const iterator_template& other) const noexcept + { + return m_it == other.m_it; + }; + + [[nodiscard]] inline std::weak_ordering operator<=>(const iterator_template& other) const noexcept + { + return m_it <=> other.m_it; + } + + [[nodiscard]] inline difference_type operator-(const iterator_template& rhs) const noexcept + { + return m_it - rhs.m_it; + } + + [[nodiscard]] inline iterator_template operator+(difference_type n) const noexcept + { + return iterator_template{m_it + n}; + } + + [[nodiscard]] inline iterator_template operator-(difference_type n) const noexcept + { + return iterator_template{m_it - n}; + } + + [[nodiscard]] friend iterator_template operator+(difference_type lhs, const iterator_template& rhs) noexcept + { + return iterator_template{lhs + rhs.m_it}; + } + + [[nodiscard]] friend iterator_template operator-(difference_type lhs, const iterator_template& rhs) noexcept + { + return iterator_template{lhs - rhs.m_it}; + } + + private: + friend class brep_attribute_map; + + iterator_type m_it; + }; + + using iterator = iterator_template>::iterator, false>; + using const_iterator = iterator_template>::const_iterator, true>; + + /// @name Iterators + /// @{ + + /// Returns an iterator to the first attribute. + /// @{ + [[nodiscard]] inline const_iterator begin() const noexcept + { + const_iterator it; + it.m_it = m_attributes.begin(); + return it; + } + [[nodiscard]] inline iterator begin() noexcept + { + iterator it; + it.m_it = m_attributes.begin(); + return it; + } + [[nodiscard]] inline const_iterator cbegin() const noexcept + { + return begin(); + } + /// @} + + /// Returns an iterator to the attribute following the last attribute. + /// @{ + [[nodiscard]] inline const_iterator end() const noexcept + { + const_iterator it; + it.m_it = m_attributes.end(); + return it; + } + [[nodiscard]] inline iterator end() noexcept + { + iterator it; + it.m_it = m_attributes.end(); + return it; + } + [[nodiscard]] inline const_iterator cend() const noexcept + { + return end(); + } + /// @} + + /// @} + /// @name Capacity + /// @{ + + /// Returns `true` if the container is empty, `false` otherwise. + [[nodiscard]] inline bool empty() const noexcept + { + return m_attributes.empty(); + } + + /// Returns the number of attributes in the container. + [[nodiscard]] inline std::size_t size() const noexcept + { + return m_attributes.size(); + } + + /// @} + /// @name Modifiers + /// @{ + + /** + * Removes all attributes from the container. + */ + inline void clear() noexcept + { + m_attributes.clear(); + } + + /** + * Constructs a new attribute. If an attribute with the given name exists, it will be replaced. + * + * @tparam T Attribute data type. + * + * @param name Name of the new attribute. + * + * @return Iterator to the new attribute. + */ + template + iterator emplace(hash::fnv1a32_t name) + { + if (auto i = m_attributes.find(name); i != m_attributes.end()) + { + i->second.reset(); + i->second = std::make_unique>(name, m_element_count); + + iterator it; + it.m_it = i; + return it; + } + + iterator it; + it.m_it = m_attributes.emplace(name, std::make_unique>(name, m_element_count)).first; + return it; + } + + /** + * Removes an attribute from the container. + * + * @param pos Iterator to the attribute to remove. + * + * @return Iterator following the erased attribute. + */ + inline iterator erase(iterator pos) + { + iterator it; + it.m_it = m_attributes.erase(pos.m_it); + return it; + } + + /** + * Removes an attribute from the container. + * + * @param name Name of the attribute to remove. + * + * @return Number of attributes removed (0 or 1). + */ + inline std::size_t erase(hash::fnv1a32_t name) + { + return m_attributes.erase(name); + } + + /** + * Constructs a new attribute if an attribute with the given name does not exist. + * + * @tparam T Attribute data type. + * + * @param name Name of the new attribute. + * + * @return Pair consisting of an iterator to the new or pre-existing attribute, and a Boolean value that's `true` if the new attribute was constructed, or `false` if an attribute with the given name pre-existed. + */ + template + std::pair try_emplace(hash::fnv1a32_t name) + { + if (auto i = m_attributes.find(name); i != m_attributes.end()) + { + iterator it; + it.m_it = i; + return {it, false}; + } + + auto pair = m_attributes.emplace(name, std::make_unique>(name, m_element_count)); + iterator it; + it.m_it = pair.first; + return {it, pair.second}; + } + + /// @} + /// @name Lookup + /// @{ + + /** + * Returns a reference to the attribute with the given name. If no such attribute exists, an exception of type std::out_of_range is thrown. + * + * @tparam T Attribute data type. + * + * @return Reference to the attribute with the given name. + * + * @except std::out_of_range B-rep attribute not found. + */ + /// @{ + template + [[nodiscard]] const brep_attribute& at(hash::fnv1a32_t name) const + { + auto it = find(name); + if (it == end()) + { + throw std::out_of_range("B-rep attribute not found"); + } + + return static_cast&>(*it); + } + template + [[nodiscard]] brep_attribute& at(hash::fnv1a32_t name) + { + auto it = find(name); + if (it == end()) + { + throw std::out_of_range("B-rep attribute not found"); + } + + return static_cast&>(*it); + } + /// @} + + /** + * Finds an attribute with the given name. + * + * @param name Name of an attribute. + * + * @return Iterator to the attribute with the given name. If no such attribute is found, an end iterator is returned. + */ + /// @{ + [[nodiscard]] inline const_iterator find(hash::fnv1a32_t name) const + { + const_iterator it; + it.m_it = m_attributes.find(name); + return it; + } + [[nodiscard]] inline iterator find(hash::fnv1a32_t name) + { + iterator it; + it.m_it = m_attributes.find(name); + return it; + } + /// @} + + /** + * Checks if there is an attribute with a given name in the container. + * + * @param name Attribute name. + * + * @return `true` if an attribute with the given name was found, `false` otherwise. + */ + [[nodiscard]] inline bool contains(hash::fnv1a32_t name) const + { + return m_attributes.contains(name); + } + + /// @} + +private: + template + friend class brep_element_container; + friend class brep_mesh; + + brep_attribute_map& operator=(const brep_attribute_map& other) + { + m_element_count = other.m_element_count; + m_attributes.clear(); + for (const auto& [key, value]: other.m_attributes) + { + m_attributes.emplace(key, value->clone()); + } + + return *this; + } + + std::size_t m_element_count{}; + std::unordered_map> m_attributes; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_ATTRIBUTE_MAP_HPP diff --git a/src/engine/geom/brep/brep-attribute.hpp b/src/engine/geom/brep/brep-attribute.hpp new file mode 100644 index 0000000..fd61501 --- /dev/null +++ b/src/engine/geom/brep/brep-attribute.hpp @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_ATTRIBUTE_HPP +#define ANTKEEPER_GEOM_BREP_ATTRIBUTE_HPP + +#include +#include +#include + +namespace geom { + +/** + * Abstract base class for B-rep element attributes. + */ +class brep_attribute_base +{ +public: + /// Returns the name of the attribute. + [[nodiscard]] inline constexpr hash::fnv1a32_t name() const noexcept + { + return m_name; + } + +protected: + inline explicit constexpr brep_attribute_base(hash::fnv1a32_t name) noexcept: + m_name(name) + {} + +private: + friend class brep_attribute_map; + template + friend class brep_element_container; + + /** + * Erases the attribute value of an element with the given index. + * + * @param i Index of an element. + */ + virtual void erase(std::size_t i) = 0; + + /** + * Appends a new attribute value to the end of the container. + */ + virtual void emplace_back() = 0; + + /// Returns a copy of this attribute. + [[nodiscard]] virtual std::unique_ptr clone() const = 0; + + hash::fnv1a32_t m_name; +}; + +/** + * Per-element B-rep data. + * + * @tparam T Data type. + */ +template +class brep_attribute: public brep_attribute_base +{ +public: + using value_type = T; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + using reverse_iterator = std::vector::reverse_iterator; + using const_reverse_iterator = std::vector::const_reverse_iterator; + + /** + * Constructs an attribute. + * + * @param name Name of the attribute. + * @param element_count Number of elements. + */ + brep_attribute(hash::fnv1a32_t name, std::size_t element_count): + brep_attribute_base(name), + m_values(element_count) + {} + + /// @name Attribute access + /// @{ + + /** + * Returns a reference to the attribute value of an element. + * + * @param i Index of an element. + * + * @return Reference to the attribute value of the element at index @p i. + */ + /// @{ + [[nodiscard]] inline constexpr const_reference operator[](std::size_t i) const + { + return m_values[i]; + } + [[nodiscard]] inline constexpr reference operator[](std::size_t i) + { + return m_values[i]; + } + /// @} + + /// Returns a reference to the attribute value of the first element. + /// @{ + [[nodiscard]] inline constexpr const_reference front() const + { + return m_values.front(); + } + [[nodiscard]] inline constexpr reference front() + { + return m_values.front(); + } + /// @} + + /// Returns a reference to the attribute value of the last element. + /// @{ + [[nodiscard]] inline constexpr const_reference back() const + { + return m_values.back(); + } + [[nodiscard]] inline constexpr reference back() + { + return m_values.back(); + } + /// @} + + /// Returns a pointer to the underlying array serving as attribute value storage. + /// @{ + [[nodiscard]] inline constexpr const value_type* data() const noexcept + { + return m_values.data(); + } + [[nodiscard]] inline constexpr value_type* data() noexcept + { + return m_values.data(); + } + /// @} + + /// @} + /// @name Iterators + /// @{ + + /// Returns an iterator to the attribute value of the first element. + /// @{ + [[nodiscard]] inline constexpr const_iterator begin() const noexcept + { + return m_values.begin(); + } + [[nodiscard]] inline constexpr iterator begin() noexcept + { + return m_values.begin(); + } + [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept + { + return m_values.begin(); + } + /// @} + + /// Returns an iterator to the attribute value of the element following the last element. + /// @{ + [[nodiscard]] inline constexpr const_iterator end() const noexcept + { + return m_values.end(); + } + [[nodiscard]] inline constexpr iterator end() noexcept + { + return m_values.end(); + } + [[nodiscard]] inline constexpr const_iterator cend() const noexcept + { + return m_values.end(); + } + /// @} + + /// Returns a reverse iterator to the attribute value of the first element of the reversed container. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept + { + return m_values.rbegin(); + } + [[nodiscard]] inline constexpr reverse_iterator rbegin() noexcept + { + return m_values.rbegin(); + } + [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept + { + return m_values.rbegin(); + } + /// @} + + /// Returns a reverse iterator to the attribute value of the element following the last element of the reversed container. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept + { + return m_values.rend(); + } + [[nodiscard]] inline constexpr reverse_iterator rend() noexcept + { + return m_values.rend(); + } + [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept + { + return m_values.rend(); + } + /// @} + + /// @} + /// @name Capacity + /// @{ + + /// Returns `true` if the container is empty, `false` otherwise. + [[nodiscard]] inline constexpr bool empty() const noexcept + { + return m_values.empty(); + } + + /// Returns the number of attribute values in the container. + [[nodiscard]] inline constexpr std::size_t size() const noexcept + { + return m_values.size(); + } + + /// @} + +private: + void erase(std::size_t i) override + { + m_values[i] = std::move(m_values.back()); + m_values.pop_back(); + } + + void emplace_back() override + { + m_values.emplace_back(); + } + + [[nodiscard]] std::unique_ptr clone() const override + { + auto copy = std::make_unique>(name(), 0); + copy->m_values = m_values; + return std::move(copy); + } + + std::vector m_values; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_ATTRIBUTE_HPP diff --git a/src/engine/geom/brep/brep-edge.cpp b/src/engine/geom/brep/brep-edge.cpp new file mode 100644 index 0000000..b69df02 --- /dev/null +++ b/src/engine/geom/brep/brep-edge.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include +#include +#include + +namespace geom { + +void brep_edge_loop_list::push_back(brep_loop* loop) +{ + if (empty()) + { + // List empty, initialize + m_head = loop; + loop->m_edge_next = loop; + loop->m_edge_previous = loop; + } + else + { + // Append loop + loop->m_edge_next = m_head; + loop->m_edge_previous = m_head->m_edge_previous; + m_head->m_edge_previous->m_edge_next = loop; + m_head->m_edge_previous = loop; + } + + ++m_size; +} + +void brep_edge_loop_list::remove(brep_loop* loop) +{ + // Directly link next and previous loops + loop->m_edge_next->m_edge_previous = loop->m_edge_previous; + loop->m_edge_previous->m_edge_next = loop->m_edge_next; + + // If loop was the list head, update head + if (m_head == loop) + { + m_head = loop->m_edge_next; + } + + --m_size; +} + +brep_edge* brep_edge_container::emplace_back(brep_vertex* a, brep_vertex* b) +{ + if (a == b) + { + return nullptr; + } + + brep_edge* ab = brep_element_container::emplace_back(); + ab->m_index = size() - 1; + ab->m_vertices[0] = a; + ab->m_vertices[1] = b; + + // Append edge AB to the edge lists of vertices A and B + a->m_edges.push_back(ab); + b->m_edges.push_back(ab); + + return ab; +}; + +void brep_edge_container::erase(brep_edge* edge) +{ + // Kill all loops and faces bounded by this edge + while (!edge->loops().empty()) + { + m_mesh->faces().erase(edge->loops().back()->face()); + } + + // Remove this edge from its vertices' lists of edges + edge->vertices().front()->m_edges.remove(edge); + edge->vertices().back()->m_edges.remove(edge); + + // Erase edge + brep_element_container::erase(edge); +} + +void brep_edge_container::clear() noexcept +{ + while (!empty()) + { + erase(back()); + } +} + +brep_edge* brep_edge_container::find(brep_vertex* a, brep_vertex* b) const +{ + if (!a->edges().empty() && !b->edges().empty() && a != b) + { + brep_edge* ea = a->edges().front(); + brep_edge* eb = b->edges().front(); + const std::size_t n = std::min(a->edges().size(), b->edges().size()); + for (std::size_t i = 0; i < n; ++i) + { + if (ea->vertices()[1] == b || ea->vertices()[0] == b) + { + return ea; + } + + if (eb->vertices()[1] == a || eb->vertices()[0] == a) + { + return eb; + } + + ea = ea->m_vertex_next[ea->vertices()[1] == a]; + eb = eb->m_vertex_next[eb->vertices()[1] == b]; + } + } + + return nullptr; +} + +} // namespace geom diff --git a/src/engine/geom/brep/brep-edge.hpp b/src/engine/geom/brep/brep-edge.hpp new file mode 100644 index 0000000..141e482 --- /dev/null +++ b/src/engine/geom/brep/brep-edge.hpp @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_EDGE_HPP +#define ANTKEEPER_GEOM_BREP_EDGE_HPP + +#include +#include +#include +#include +#include + +namespace geom { + +class brep_vertex; +class brep_loop; +template +class brep_element_container; + +/** + * List of B-rep loops that share a common edge. + */ +class brep_edge_loop_list +{ +public: + friend class brep_mesh; + friend class brep_face_container; + + struct const_iterator + { + public: + friend class brep_edge_loop_list; + + using iterator_category = std::bidirectional_iterator_tag; + using iterator_concept = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = brep_loop*; + using pointer = const value_type*; + using reference = const value_type&; + + [[nodiscard]] inline constexpr value_type operator*() const noexcept + { + return m_loop; + } + + [[nodiscard]] inline constexpr value_type operator->() const noexcept + { + return m_loop; + } + + inline const_iterator& operator++() noexcept + { + m_loop = m_loop->m_edge_next; + ++m_position; + return *this; + } + + [[nodiscard]] inline const_iterator operator++(int) noexcept + { + const_iterator tmp = *this; + ++(*this); + return tmp; + } + + inline const_iterator& operator--() noexcept + { + m_loop = m_loop->m_edge_previous; + --m_position; + return *this; + } + + [[nodiscard]] inline const_iterator operator--(int) noexcept + { + const_iterator tmp = *this; + --(*this); + return tmp; + } + + [[nodiscard]] inline bool operator==(const const_iterator& other) const noexcept + { + return m_position == other.m_position; + }; + + [[nodiscard]] inline std::weak_ordering operator<=>(const const_iterator& other) const noexcept + { + return m_position <=> other.m_position; + } + + [[nodiscard]] inline difference_type operator-(const const_iterator& rhs) const noexcept + { + return m_position - rhs.m_position; + } + + private: + brep_loop* m_loop; + std::ptrdiff_t m_position; + }; + + using const_reverse_iterator = std::reverse_iterator; + + /// @name Element access + /// @{ + + /// Returns the first loop. + [[nodiscard]] inline brep_loop* front() const noexcept + { + return m_head; + } + + /// Returns the last loop. + [[nodiscard]] inline brep_loop* back() const noexcept + { + return m_head->m_edge_previous; + } + + /// @} + /// @name Iterators + /// @{ + + /// Returns an iterator to the first loop. + /// @{ + [[nodiscard]] inline constexpr const_iterator begin() const noexcept + { + const_iterator it; + it.m_loop = m_head; + it.m_position = 0; + + return it; + } + [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept + { + return begin(); + } + /// @} + + /// Returns an iterator to the loop following the last loop. + /// @{ + [[nodiscard]] inline constexpr const_iterator end() const noexcept + { + const_iterator it; + it.m_loop = m_head; + it.m_position = static_cast(m_size); + + return it; + } + [[nodiscard]] inline constexpr const_iterator cend() const noexcept + { + return end(); + } + /// @} + + /// Returns a reverse iterator to the first loop of the reversed list. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept + { + return std::make_reverse_iterator(end()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept + { + return rbegin(); + } + /// @} + + /// Returns a reverse iterator to the loop following the last loop of the reversed list. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept + { + return std::make_reverse_iterator(begin()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept + { + return rend(); + } + /// @} + + /// @} + /// @name Capacity + /// @{ + + /// Returns `true` if the list is empty, `false` otherwise. + [[nodiscard]] inline constexpr bool empty() const noexcept + { + return !m_size; + } + + /// Returns the number of loops in the list. + [[nodiscard]] inline constexpr std::size_t size() const noexcept + { + return m_size; + } + + /// @} + /// @name Modifiers + /// @{ + + /** + * Appends a loop to the end of the list. + * + * @param loop Pointer to the loop to append. + */ + void push_back(brep_loop* loop); + + /** + * Removes an loop from the list. + * + * @param loop Pointer to the loop to remove. + */ + void remove(brep_loop* loop); + + /// @} + +private: + brep_loop* m_head{}; + std::size_t m_size{}; +}; + +/** + * Curve segment bounded by two vertices. + */ +class brep_edge +{ +public: + friend class brep_mesh; + friend class brep_vertex_edge_list; + friend class brep_element_container; + friend class brep_edge_container; + friend class brep_face_container; + + /** + * Returns the index of this edge in the mesh edge array. + * + * @warning This index may change if any edges are removed from the mesh. + */ + [[nodiscard]] inline constexpr std::size_t index() const noexcept + { + return m_index; + } + + /// Returns the pair of vertices that bound this edge. + [[nodiscard]] inline constexpr const std::array& vertices() const noexcept + { + return m_vertices; + } + + /// Returns the list of loops that share this edge. + [[nodiscard]] inline constexpr const brep_edge_loop_list& loops() const noexcept + { + return m_loops; + } + +private: + std::size_t m_index; + std::array m_vertices; + std::array m_vertex_next; + std::array m_vertex_previous; + brep_edge_loop_list m_loops; +}; + +/** + * B-rep edge container. + */ +class brep_edge_container: public brep_element_container +{ +public: + /** + * Appends a new edge to the end of the container. + * + * @param a First bounding vertex of the edge. + * @param b Second bounding vertex of the edge. + * + * @return Pointer to the new edge. + */ + brep_edge* emplace_back(brep_vertex* a, brep_vertex* b); + + /** + * Erases an edge and all dependent loops and faces. + * + * @param edge Pointer to the edge to erase. + * + * @warning Invalidates iterators and indices of edges, loops, and faces. + */ + void erase(brep_edge* edge) override; + + /** + * Erases all edges and their dependent loops and faces. + */ + void clear() noexcept; + + /** + * Finds an edge bounded by vertices @p a and @p b (in any order). + * + * @param a First (or second) bounding vertex of the edge. + * @param b Second (or first) bounding vertex of the edge. + * + * @return Pointer to an edge bounded by vertices @p a and @p b, or `nullptr` if no such edge was found. + */ + [[nodiscard]] brep_edge* find(brep_vertex* a, brep_vertex* b) const; + +private: + friend class brep_mesh; + + /** + * Constructs a B-rep edge container. + * + * @param mesh Pointer to the parent mesh. + */ + inline explicit brep_edge_container(brep_mesh* mesh) noexcept: + brep_element_container(mesh) + {} +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_EDGE_HPP diff --git a/src/engine/geom/brep/brep-element-container.hpp b/src/engine/geom/brep/brep-element-container.hpp new file mode 100644 index 0000000..a06b463 --- /dev/null +++ b/src/engine/geom/brep/brep-element-container.hpp @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_ELEMENT_CONTAINER_HPP +#define ANTKEEPER_GEOM_BREP_ELEMENT_CONTAINER_HPP + +#include +#include +#include +#include +#include +#include + +namespace geom { +/** + * Container for B-rep elements. + * + * @tparam T Element type. + */ +template +class brep_element_container +{ +public: + friend class brep_mesh; + + using element_type = T; + + struct const_iterator + { + public: + using iterator_category = std::random_access_iterator_tag; + using iterator_concept = std::random_access_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = element_type*; + using pointer = const value_type*; + using reference = const value_type&; + + [[nodiscard]] inline constexpr value_type operator*() const noexcept + { + return m_it->get(); + } + + [[nodiscard]] inline constexpr value_type operator->() const noexcept + { + return m_it->get(); + } + + [[nodiscard]] inline constexpr value_type operator[](difference_type i) const noexcept + { + return m_it[i]->get(); + } + + inline const_iterator& operator++() noexcept + { + ++m_it; + return *this; + } + + [[nodiscard]] inline const_iterator operator++(int) noexcept + { + const_iterator tmp = *this; + ++(*this); + return tmp; + } + + inline const_iterator& operator--() noexcept + { + --m_it; + return *this; + } + + [[nodiscard]] inline const_iterator operator--(int) noexcept + { + const_iterator tmp = *this; + --(*this); + return tmp; + } + + inline const_iterator& operator+=(difference_type n) noexcept + { + m_it += n; + return *this; + } + + inline const_iterator& operator-=(difference_type n) noexcept + { + m_it -= n; + return *this; + } + + [[nodiscard]] inline bool operator==(const const_iterator& other) const noexcept + { + return m_it == other.m_it; + }; + + [[nodiscard]] inline std::weak_ordering operator<=>(const const_iterator& other) const noexcept + { + return m_it <=> other.m_it; + } + + [[nodiscard]] inline difference_type operator-(const const_iterator& rhs) const noexcept + { + return m_it - rhs.m_it; + } + + [[nodiscard]] inline const_iterator operator+(difference_type n) const noexcept + { + return const_iterator{m_it + n}; + } + + [[nodiscard]] inline const_iterator operator-(difference_type n) const noexcept + { + return const_iterator{m_it - n}; + } + + [[nodiscard]] friend const_iterator operator+(difference_type lhs, const const_iterator& rhs) noexcept + { + return const_iterator{lhs + rhs.m_it}; + } + + [[nodiscard]] friend const_iterator operator-(difference_type lhs, const const_iterator& rhs) noexcept + { + return const_iterator{lhs - rhs.m_it}; + } + + private: + friend class brep_element_container; + + std::vector>::const_iterator m_it; + }; + + using const_reverse_iterator = std::reverse_iterator; + + /// @name Element access + /// @{ + + /** + * Returns a pointer to the element at the specified index. + * + * @param i Index of an element. + * + * @return Pointer to the element at index @p i. + */ + [[nodiscard]] inline constexpr element_type* operator[](std::size_t i) const + { + return m_elements[i].get(); + } + + /// Returns the first element. + [[nodiscard]] inline constexpr element_type* front() const noexcept + { + return m_elements.front().get(); + } + + /// Returns the last element. + [[nodiscard]] inline constexpr element_type* back() const noexcept + { + return m_elements.back().get(); + } + + /// @} + /// @name Iterators + /// @{ + + /// Returns an iterator to the first element. + /// @{ + [[nodiscard]] inline constexpr const_iterator begin() const noexcept + { + const_iterator it; + it.m_it = m_elements.begin(); + return it; + } + [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept + { + return begin(); + } + /// @} + + /// Returns an iterator to the element following the last element. + /// @{ + [[nodiscard]] inline constexpr const_iterator end() const noexcept + { + const_iterator it; + it.m_it = m_elements.end(); + return it; + } + [[nodiscard]] inline constexpr const_iterator cend() const noexcept + { + return end(); + } + /// @} + + /// Returns a reverse iterator to the first element of the reversed container. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept + { + return std::make_reverse_iterator(end()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept + { + return rbegin(); + } + /// @} + + /// Returns a reverse iterator to the element following the last element of the reversed container. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept + { + return std::make_reverse_iterator(begin()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept + { + return rend(); + } + /// @} + + /// @} + /// @name Capacity + /// @{ + + /// Returns `true` if the container is empty, `false` otherwise. + [[nodiscard]] inline constexpr bool empty() const noexcept + { + return m_elements.empty(); + } + + /// Returns the number of elements in the container. + [[nodiscard]] inline constexpr std::size_t size() const noexcept + { + return m_elements.size(); + } + + /// @} + /// @name Attributes + /// @{ + + /// Returns the element attribute map. + /// @{ + [[nodiscard]] const brep_attribute_map& attributes() const noexcept + { + return m_attribute_map; + } + [[nodiscard]] brep_attribute_map& attributes() noexcept + { + return m_attribute_map; + } + /// @} + + /// @} + +protected: + friend class brep_mesh; + + /** + * Constructs a B-rep element container. + * + * @param mesh Pointer to the parent mesh. + */ + inline explicit brep_element_container(brep_mesh* mesh) noexcept: + m_mesh(mesh) + {} + + /// @name Modifiers + /// @{ + + /** + * Erases an element from the container. + * + * @param element Pointer to the element to erase. + */ + virtual void erase(element_type* element) + { + const auto index = element->m_index; + + for (auto& [key, values]: m_attribute_map.m_attributes) + { + values->erase(index); + } + --m_attribute_map.m_element_count; + + m_elements.back()->m_index = index; + m_elements[index] = std::move(m_elements.back()); + m_elements.pop_back(); + } + + /** + * Appends a new element to the end of the container. + * + * @return Pointer to the new element. + */ + virtual element_type* emplace_back() + { + for (auto& [key, values]: m_attribute_map.m_attributes) + { + values->emplace_back(); + } + ++m_attribute_map.m_element_count; + + return m_elements.emplace_back(std::make_unique()).get(); + } + + /// @} + + brep_mesh* m_mesh; + +private: + std::vector> m_elements; + brep_attribute_map m_attribute_map; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_ELEMENT_CONTAINER_HPP diff --git a/src/engine/geom/brep/brep-face.cpp b/src/engine/geom/brep/brep-face.cpp new file mode 100644 index 0000000..824b2ce --- /dev/null +++ b/src/engine/geom/brep/brep-face.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include +#include +#include +#include + +namespace geom { + +void brep_face_loop_list::push_back(brep_loop* loop) +{ + if (empty()) + { + // List empty, initialize + m_head = loop; + loop->m_face_next = loop; + loop->m_face_previous = loop; + } + else + { + // Append loop + loop->m_face_next = m_head; + loop->m_face_previous = m_head->m_face_previous; + m_head->m_face_previous->m_face_next = loop; + m_head->m_face_previous = loop; + } + + ++m_size; +} + +void brep_face_loop_list::insert(brep_loop* next, brep_loop* loop) +{ + loop->m_face_next = next; + loop->m_face_previous = next->m_face_previous; + next->m_face_previous->m_face_next = loop; + next->m_face_previous = loop; + + ++m_size; +} + +void brep_face_loop_list::remove(brep_loop* loop) +{ + // Directly link next and previous loops + loop->m_face_next->m_face_previous = loop->m_face_previous; + loop->m_face_previous->m_face_next = loop->m_face_next; + + // If loop was the list head, update head + if (m_head == loop) + { + m_head = loop->m_face_next; + } + + --m_size; +} + +brep_face* brep_face_container::emplace_back(const std::span vertices) +{ + if (vertices.size() < 3) + { + return nullptr; + } + + // Find or make edges + std::vector edges(vertices.size()); + std::size_t i = vertices.size() - 1; + for (std::size_t j = 0; j < vertices.size(); ++j) + { + edges[i] = m_mesh->edges().find(vertices[i], vertices[j]); + if (!edges[i]) + { + edges[i] = m_mesh->edges().emplace_back(vertices[i], vertices[j]); + } + + i = j; + } + + // Allocate face + brep_face* face = brep_element_container::emplace_back(); + face->m_index = size() - 1; + + // Make face loops + for (std::size_t i = 0; i < vertices.size(); ++i) + { + brep_loop* loop = m_mesh->loops().emplace_back(); + + loop->m_vertex = vertices[i]; + loop->m_edge = edges[i]; + loop->m_face = face; + + // Append loop to its edge's list of loops + loop->m_edge->m_loops.push_back(loop); + + // Append loop to its face's list of loops + face->m_loops.push_back(loop); + } + + return face; +}; + +void brep_face_container::erase(brep_face* face) +{ + brep_loop* loop = face->loops().front(); + do + { + // Remove loop from its edge's list of loops + loop->m_edge->m_loops.remove(loop); + + brep_loop* next_loop = loop->m_face_next; + + // Erase loop + m_mesh->loops().erase(loop); + + loop = next_loop; + } + while (loop != face->loops().front()); + + // Erase face + brep_element_container::erase(face); +} + +void brep_face_container::clear() noexcept +{ + while (!empty()) + { + erase(back()); + } +} + +void brep_face_container::reverse(brep_face* face) +{ + for (brep_loop* loop: face->loops()) + { + // Swap order of loop vertices + loop->m_vertex = loop->edge()->vertices()[loop->edge()->vertices()[0] == loop->vertex()]; + + // Swap pointers to next and previous face loops + std::swap(loop->m_face_next, loop->m_face_previous); + } +} + +} // namespace geom diff --git a/src/engine/geom/brep/brep-face.hpp b/src/engine/geom/brep/brep-face.hpp new file mode 100644 index 0000000..9973527 --- /dev/null +++ b/src/engine/geom/brep/brep-face.hpp @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_FACE_HPP +#define ANTKEEPER_GEOM_BREP_FACE_HPP + +#include +#include +#include +#include +#include + +namespace geom { + +class brep_vertex; +class brep_loop; +template +class brep_element_container; + +/** + * List of B-rep loops that bound a common face. + */ +class brep_face_loop_list +{ +public: + friend class brep_mesh; + + struct const_iterator + { + public: + friend class brep_face_loop_list; + + using iterator_category = std::bidirectional_iterator_tag; + using iterator_concept = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = brep_loop*; + using pointer = const value_type*; + using reference = const value_type&; + + [[nodiscard]] inline constexpr value_type operator*() const noexcept + { + return m_loop; + } + + [[nodiscard]] inline constexpr value_type operator->() const noexcept + { + return m_loop; + } + + inline const_iterator& operator++() noexcept + { + m_loop = m_loop->m_face_next; + ++m_position; + return *this; + } + + [[nodiscard]] inline const_iterator operator++(int) noexcept + { + const_iterator tmp = *this; + ++(*this); + return tmp; + } + + inline const_iterator& operator--() noexcept + { + m_loop = m_loop->m_face_previous; + --m_position; + return *this; + } + + [[nodiscard]] inline const_iterator operator--(int) noexcept + { + const_iterator tmp = *this; + --(*this); + return tmp; + } + + [[nodiscard]] inline bool operator==(const const_iterator& other) const noexcept + { + return m_position == other.m_position; + }; + + [[nodiscard]] inline std::weak_ordering operator<=>(const const_iterator& other) const noexcept + { + return m_position <=> other.m_position; + } + + [[nodiscard]] inline difference_type operator-(const const_iterator& rhs) const noexcept + { + return m_position - rhs.m_position; + } + + private: + brep_loop* m_loop; + std::ptrdiff_t m_position; + }; + + using const_reverse_iterator = std::reverse_iterator; + + /// @name Element access + /// @{ + + /// Returns the first loop. + [[nodiscard]] inline brep_loop* front() const noexcept + { + return m_head; + } + + /// Returns the last loop. + [[nodiscard]] inline brep_loop* back() const noexcept + { + return m_head->m_face_previous; + } + + /// @} + /// @name Iterators + /// @{ + + /// Returns an iterator to the first loop. + /// @{ + [[nodiscard]] inline constexpr const_iterator begin() const noexcept + { + const_iterator it; + it.m_loop = m_head; + it.m_position = 0; + + return it; + } + [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept + { + return begin(); + } + /// @} + + /// Returns an iterator to the loop following the last loop. + /// @{ + [[nodiscard]] inline constexpr const_iterator end() const noexcept + { + const_iterator it; + it.m_loop = m_head; + it.m_position = static_cast(m_size); + + return it; + } + [[nodiscard]] inline constexpr const_iterator cend() const noexcept + { + return end(); + } + /// @} + + /// Returns a reverse iterator to the first loop of the reversed list. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept + { + return std::make_reverse_iterator(end()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept + { + return rbegin(); + } + /// @} + + /// Returns a reverse iterator to the loop following the last loop of the reversed list. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept + { + return std::make_reverse_iterator(begin()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept + { + return rend(); + } + /// @} + + /// @} + /// @name Capacity + /// @{ + + /// Returns `true` if the list is empty, `false` otherwise. + [[nodiscard]] inline constexpr bool empty() const noexcept + { + return !m_size; + } + + /// Returns the number of loops in the list. + [[nodiscard]] inline constexpr std::size_t size() const noexcept + { + return m_size; + } + + /// @} + /// @name Modifiers + /// @{ + + /** + * Appends a loop to the end of the list. + * + * @param loop Pointer to the loop to append. + */ + void push_back(brep_loop* loop); + + /** + * Inserts a loop before a given loop. + * + * @param next Loop before which this loop should be inserted. + * @param loop Pointer to the loop to insert. + */ + void insert(brep_loop* next, brep_loop* loop); + + /** + * Removes an loop from the list. + * + * @param loop Pointer to the loop to remove. + */ + void remove(brep_loop* loop); + + /// @} + +private: + brep_loop* m_head{}; + std::size_t m_size{}; +}; + +/** + * Portion of a shell bounded by loops. + */ +class brep_face +{ +public: + friend class brep_mesh; + friend class brep_element_container; + friend class brep_face_container; + + /** + * Returns the index of this face in the mesh face array. + * + * @warning This index may change if any faces are removed from the mesh. + */ + [[nodiscard]] inline constexpr std::size_t index() const noexcept + { + return m_index; + } + + /// Returns the list of loops associated with this face. + [[nodiscard]] inline constexpr const brep_face_loop_list& loops() const noexcept + { + return m_loops; + } + +private: + std::size_t m_index; + brep_face_loop_list m_loops; +}; + +/** + * B-rep face container. + */ +class brep_face_container: public brep_element_container +{ +public: + /** + * Appends a new face to the end of the container. + * + * @param vertices Ordered vertices of the face. + * + * @return Pointer to the new face. + */ + brep_face* emplace_back(const std::span vertices); + + /** + * Erases a face and all of its loops. + * + * @param face Pointer to the face to erase. + * + * @warning Invalidates iterators and indices of loops and faces. + */ + void erase(brep_face* face) override; + + /** + * Erases all faces and their loops. + */ + void clear() noexcept; + + /** + * Reverses the direction of a face's bounding loops. + * + * @param face Face bounded by the loops to reverse. + */ + void reverse(brep_face* face); + +private: + friend class brep_mesh; + + /** + * Constructs a B-rep face container. + * + * @param mesh Pointer to the parent mesh. + */ + inline explicit brep_face_container(brep_mesh* mesh) noexcept: + brep_element_container(mesh) + {} +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_FACE_HPP diff --git a/src/engine/geom/brep/brep-loop.cpp b/src/engine/geom/brep/brep-loop.cpp new file mode 100644 index 0000000..31c69bd --- /dev/null +++ b/src/engine/geom/brep/brep-loop.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include + +namespace geom { + +brep_loop* brep_loop_container::emplace_back() +{ + brep_loop* loop = brep_element_container::emplace_back(); + loop->m_index = size() - 1; + + return loop; +}; + +} // namespace geom diff --git a/src/engine/geom/brep/brep-loop.hpp b/src/engine/geom/brep/brep-loop.hpp new file mode 100644 index 0000000..ebf2f11 --- /dev/null +++ b/src/engine/geom/brep/brep-loop.hpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_LOOP_HPP +#define ANTKEEPER_GEOM_BREP_LOOP_HPP + +#include +#include + +namespace geom { + +class brep_vertex; +class brep_edge; +class brep_face; +template +class brep_element_container; + +/** + * Connected boundary of a single face. + */ +class brep_loop +{ +public: + friend class brep_mesh; + friend class brep_edge_loop_list; + friend class brep_face_loop_list; + friend class brep_element_container; + friend class brep_loop_container; + friend class brep_face_container; + + /** + * Returns the index of this loop in the mesh loop array. + * + * @warning This index may change if any loops are removed from the mesh. + */ + [[nodiscard]] inline constexpr std::size_t index() const noexcept + { + return m_index; + } + + /// Returns a pointer to the loop vertex. + [[nodiscard]] inline constexpr brep_vertex* vertex() const noexcept + { + return m_vertex; + } + + /// Returns a pointer to the loop edge. + [[nodiscard]] inline constexpr brep_edge* edge() const noexcept + { + return m_edge; + } + + /// Returns a pointer to the loop face. + [[nodiscard]] inline constexpr brep_face* face() const noexcept + { + return m_face; + } + +private: + std::size_t m_index; + brep_vertex* m_vertex; + brep_edge* m_edge; + brep_face* m_face; + brep_loop* m_edge_next; + brep_loop* m_edge_previous; + brep_loop* m_face_next; + brep_loop* m_face_previous; +}; + +/** + * B-rep loop container. + */ +class brep_loop_container: public brep_element_container +{ +private: + friend class brep_mesh; + friend class brep_face_container; + + /** + * Constructs a B-rep face container. + * + * @param mesh Pointer to the parent mesh. + */ + inline explicit brep_loop_container(brep_mesh* mesh) noexcept: + brep_element_container(mesh) + {} + + /** + * Appends a new loop to the end of the container. + * + * @return Pointer to the new loop. + */ + brep_loop* emplace_back() override; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_LOOP_HPP diff --git a/src/engine/geom/brep/brep-mesh.cpp b/src/engine/geom/brep/brep-mesh.cpp new file mode 100644 index 0000000..aa298fa --- /dev/null +++ b/src/engine/geom/brep/brep-mesh.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +namespace geom { + +brep_mesh::brep_mesh() noexcept: + m_vertices(this), + m_edges(this), + m_loops(this), + m_faces(this) +{} + +brep_mesh::brep_mesh(const brep_mesh& other): + brep_mesh() +{ + *this = other; +} + +brep_mesh& brep_mesh::operator=(const brep_mesh& other) +{ + // Allocate containers + m_vertices.m_elements.resize(other.m_vertices.m_elements.size()); + m_edges.m_elements.resize(other.m_edges.m_elements.size()); + m_loops.m_elements.resize(other.m_loops.m_elements.size()); + m_faces.m_elements.resize(other.m_faces.m_elements.size()); + + // Copy-construct elements + for (std::size_t i = 0; i < m_vertices.m_elements.size(); ++i) + { + m_vertices.m_elements[i] = std::make_unique(*other.m_vertices.m_elements[i]); + } + for (std::size_t i = 0; i < m_edges.m_elements.size(); ++i) + { + m_edges.m_elements[i] = std::make_unique(*other.m_edges.m_elements[i]); + } + for (std::size_t i = 0; i < m_loops.m_elements.size(); ++i) + { + m_loops.m_elements[i] = std::make_unique(*other.m_loops.m_elements[i]); + } + for (std::size_t i = 0; i < m_faces.m_elements.size(); ++i) + { + m_faces.m_elements[i] = std::make_unique(*other.m_faces.m_elements[i]); + } + + // Copy per-element attributes + m_vertices.m_attribute_map = other.m_vertices.m_attribute_map; + m_edges.m_attribute_map = other.m_edges.m_attribute_map; + m_loops.m_attribute_map = other.m_loops.m_attribute_map; + m_faces.m_attribute_map = other.m_faces.m_attribute_map; + + // Reassign element pointers + for (const auto& vertex: m_vertices.m_elements) + { + if (!vertex->edges().empty()) + { + vertex->m_edges.m_head = m_edges.m_elements[vertex->m_edges.m_head->m_index].get(); + } + } + for (const auto& edge: m_edges.m_elements) + { + edge->m_vertices[0] = m_vertices.m_elements[edge->m_vertices[0]->m_index].get(); + edge->m_vertices[1] = m_vertices.m_elements[edge->m_vertices[1]->m_index].get(); + edge->m_vertex_next[0] = m_edges.m_elements[edge->m_vertex_next[0]->m_index].get(); + edge->m_vertex_next[1] = m_edges.m_elements[edge->m_vertex_next[1]->m_index].get(); + edge->m_vertex_previous[0] = m_edges.m_elements[edge->m_vertex_previous[0]->m_index].get(); + edge->m_vertex_previous[1] = m_edges.m_elements[edge->m_vertex_previous[1]->m_index].get(); + + if (!edge->loops().empty()) + { + edge->m_loops.m_head = m_loops.m_elements[edge->m_loops.m_head->m_index].get(); + } + } + for (const auto& loop: m_loops.m_elements) + { + loop->m_vertex = m_vertices.m_elements[loop->m_vertex->m_index].get(); + loop->m_edge = m_edges.m_elements[loop->m_edge->m_index].get(); + loop->m_face = m_faces.m_elements[loop->m_face->m_index].get(); + loop->m_edge_next = m_loops.m_elements[loop->m_edge_next->m_index].get(); + loop->m_edge_previous = m_loops.m_elements[loop->m_edge_previous->m_index].get(); + loop->m_face_next = m_loops.m_elements[loop->m_face_next->m_index].get(); + loop->m_face_previous = m_loops.m_elements[loop->m_face_previous->m_index].get(); + } + for (const auto& face: m_faces.m_elements) + { + face->m_loops.m_head = m_loops.m_elements[face->m_loops.m_head->m_index].get(); + } + + return *this; +} + +void brep_mesh::clear() noexcept +{ + m_vertices.clear(); +} + +} // namespace geom + +/** + * Deserializes a mesh. + * + * @param[out] mesh Mesh to deserialize. + * @param[in,out] ctx Deserialize context. + * + * @throw deserialize_error Read error. + */ +template <> +void deserializer::deserialize(geom::brep_mesh& mesh, deserialize_context& ctx) +{ + // Read vertex, edge, and face counts + std::uint32_t vertex_count = 0; + std::uint32_t edge_count = 0; + std::uint32_t face_count = 0; + ctx.read32(reinterpret_cast(&vertex_count), 1); + ctx.read32(reinterpret_cast(&edge_count), 1); + ctx.read32(reinterpret_cast(&face_count), 1); + + // Make vertices + for (std::size_t i = 0; i < vertex_count; ++i) + { + mesh.vertices().emplace_back(); + } + + // Read edge vertex indices into buffer + std::vector> edges(edge_count); + ctx.read32(reinterpret_cast(edges.data()), edge_count * 2); + + // Make edges + for (const auto& e: edges) + { + mesh.edges().emplace_back(mesh.vertices()[e[0]], mesh.vertices()[e[1]]); + } + edges.clear(); + + // Read face vertex indices into buffer + std::vector> faces(face_count); + ctx.read32(reinterpret_cast(faces.data()), face_count * 3); + + // Make faces + for (const auto& f: faces) + { + geom::brep_vertex* vertices[3] = {mesh.vertices()[f[0]], mesh.vertices()[f[1]], mesh.vertices()[f[2]]}; + mesh.faces().emplace_back(vertices); + } + faces.clear(); + + // Make vertex attributes + auto& vertex_positions = static_cast&>(*mesh.vertices().attributes().emplace("position")); + + // Read vertex attributes + ctx.read32(reinterpret_cast(vertex_positions.data()), vertex_count * 3); +} + +template <> +std::unique_ptr resource_loader::load(::resource_manager& resource_manager, deserialize_context& ctx) +{ + auto resource = std::make_unique(); + deserializer().deserialize(*resource, ctx); + return resource; +} diff --git a/src/engine/geom/brep/brep-mesh.hpp b/src/engine/geom/brep/brep-mesh.hpp new file mode 100644 index 0000000..4864243 --- /dev/null +++ b/src/engine/geom/brep/brep-mesh.hpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_MESH_HPP +#define ANTKEEPER_GEOM_BREP_MESH_HPP + +#include +#include +#include +#include + +namespace geom { + +/** + * Boundary representation (B-rep) of a mesh. + */ +class brep_mesh +{ +public: + /** + * Constructs an empty mesh. + */ + brep_mesh() noexcept; + + /** + * Constructs a copy of another mesh. + * + * @param other Mesh to copy. + */ + brep_mesh(const brep_mesh& other); + + /** + * Copies another mesh into this mesh. + * + * @param other Mesh to copy. + * + * @return Reference to this mesh. + */ + brep_mesh& operator=(const brep_mesh& other); + + /// @name Modifiers + /// @{ + + /// Erases all vertices, edges, loops, and faces. + void clear() noexcept; + + /// @} + /// @name Element access + /// @{ + + /// Returns the mesh vertices. + /// @{ + [[nodiscard]] inline const brep_vertex_container& vertices() const noexcept + { + return m_vertices; + } + [[nodiscard]] inline brep_vertex_container& vertices() noexcept + { + return m_vertices; + } + ///@} + + /// Returns the mesh edges. + /// @{ + [[nodiscard]] inline const brep_edge_container& edges() const noexcept + { + return m_edges; + } + [[nodiscard]] inline brep_edge_container& edges() noexcept + { + return m_edges; + } + /// @} + + /// Returns the mesh loops. + /// @{ + [[nodiscard]] inline const brep_loop_container& loops() const noexcept + { + return m_loops; + } + [[nodiscard]] inline brep_loop_container& loops() noexcept + { + return m_loops; + } + /// @} + + /// Returns the mesh faces. + /// @{ + [[nodiscard]] inline const brep_face_container& faces() const noexcept + { + return m_faces; + } + [[nodiscard]] inline brep_face_container& faces() noexcept + { + return m_faces; + } + /// @} + + /// @} + +private: + brep_vertex_container m_vertices; + brep_edge_container m_edges; + brep_loop_container m_loops; + brep_face_container m_faces; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_MESH_HPP diff --git a/src/engine/geom/brep/brep-operations.cpp b/src/engine/geom/brep/brep-operations.cpp new file mode 100644 index 0000000..53485e3 --- /dev/null +++ b/src/engine/geom/brep/brep-operations.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include +#include +#include + +namespace geom { + +void generate_face_normals(brep_mesh& mesh) +{ + const auto& vertex_positions = mesh.vertices().attributes().at("position"); + auto& face_normals = static_cast&>(*mesh.faces().attributes().try_emplace("normal").first); + + for (brep_face* face: mesh.faces()) + { + auto loop = face->loops().begin(); + const auto& a = vertex_positions[loop->vertex()->index()]; + const auto& b = vertex_positions[(++loop)->vertex()->index()]; + const auto& c = vertex_positions[(++loop)->vertex()->index()]; + + face_normals[face->index()] = math::normalize(math::cross(b - a, c - a)); + } +} + +void generate_vertex_normals(brep_mesh& mesh) +{ + const auto& vertex_positions = mesh.vertices().attributes().at("position"); + auto& vertex_normals = static_cast&>(*mesh.vertices().attributes().try_emplace("normal").first); + + // Init vertex normals to zero + std::fill(vertex_normals.begin(), vertex_normals.end(), math::fvec3::zero()); + + if (auto face_normals_it = mesh.faces().attributes().find("normals"); face_normals_it != mesh.faces().attributes().end()) + { + const auto& face_normals = static_cast&>(*face_normals_it); + + for (brep_face* face: mesh.faces()) + { + // Get face normal from face normal attribute + const auto& face_normal = face_normals[face->index()]; + + // Accumulate vertex normals + for (brep_loop* loop: face->loops()) + { + vertex_normals[loop->vertex()->index()] += face_normal; + } + } + } + else + { + for (brep_face* face: mesh.faces()) + { + // Calculate face normal + auto loop = face->loops().begin(); + const auto& a = vertex_positions[loop->vertex()->index()]; + const auto& b = vertex_positions[(++loop)->vertex()->index()]; + const auto& c = vertex_positions[(++loop)->vertex()->index()]; + const auto face_normal = math::normalize(math::cross(b - a, c - a)); + + // Accumulate vertex normals + for (brep_loop* loop: face->loops()) + { + vertex_normals[loop->vertex()->index()] += face_normal; + } + } + } + + // Normalize vertex normals + for (auto& vertex_normal: vertex_normals) + { + vertex_normal = math::normalize(vertex_normal); + } +} + +void generate_loop_barycentric(brep_mesh& mesh) +{ + const auto& vertex_positions = mesh.vertices().attributes().at("position"); + auto& loop_barycentric = static_cast&>(*mesh.loops().attributes().try_emplace("barycentric").first); + + for (brep_face* face: mesh.faces()) + { + auto loop = face->loops().begin(); + loop_barycentric[loop->index()] = {1.0f, 0.0f, 0.0f}; + loop_barycentric[(++loop)->index()] = {0.0f, 1.0f, 0.0f}; + loop_barycentric[(++loop)->index()] = {0.0f, 0.0f, 1.0f}; + } +} + +} // namespace geom diff --git a/src/engine/geom/brep/brep-operations.hpp b/src/engine/geom/brep/brep-operations.hpp new file mode 100644 index 0000000..47a830a --- /dev/null +++ b/src/engine/geom/brep/brep-operations.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_OPERATIONS_HPP +#define ANTKEEPER_GEOM_BREP_OPERATIONS_HPP + +#include + +namespace geom { + +/** + * Generates the math::fvec3 face attribute "normal" for a B-rep mesh. + * + * @param mesh Mesh for which to generate normals. + * + * @warning Requires the math::fvec3 vertex attribute "position". + */ +void generate_face_normals(brep_mesh& mesh); + +/** + * Generates the math::fvec3 vertex attribute "normal" for a B-rep mesh. + * + * @param mesh Mesh for which to generate normals. + * + * @warning Requires the math::fvec3 vertex attribute "position". + */ +void generate_vertex_normals(brep_mesh& mesh); + +/** + * Generates the math::fvec3 loop attribute "barycentric" for a B-rep mesh. + * + * @param mesh Mesh for which to generate barycentric coordinates. + */ +void generate_loop_barycentric(brep_mesh& mesh); + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_OPERATIONS_HPP diff --git a/src/engine/geom/brep/brep-vertex.cpp b/src/engine/geom/brep/brep-vertex.cpp new file mode 100644 index 0000000..c80e4a6 --- /dev/null +++ b/src/engine/geom/brep/brep-vertex.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include +#include + +namespace geom { + +void brep_vertex_edge_list::push_back(brep_edge* edge) +{ + // Determine index of vertex in new edge vertex array + const std::size_t i = (edge->m_vertices[1] == m_vertex); + + if (empty()) + { + // List empty, initialize + m_head = edge; + edge->m_vertex_next[i] = edge; + edge->m_vertex_previous[i] = edge; + } + else + { + // Determine index of vertex in head edge vertex array + const std::size_t j = (m_head->m_vertices[1] == m_vertex); + + // Append edge + edge->m_vertex_next[i] = m_head; + edge->m_vertex_previous[i] = m_head->m_vertex_previous[j]; + edge->m_vertex_previous[i]->m_vertex_next[edge->m_vertex_previous[i]->m_vertices[1] == m_vertex] = edge; + m_head->m_vertex_previous[j] = edge; + } + + ++m_size; +} + +void brep_vertex_edge_list::remove(brep_edge* edge) +{ + // Determine index of vertex in edge vertex array + const std::size_t i = (edge->m_vertices[1] == m_vertex); + + // Get pointers to the next and previous edges + brep_edge* next = edge->m_vertex_next[i]; + brep_edge* previous = edge->m_vertex_previous[i]; + + // Directly link next and previous edges + next->m_vertex_previous[next->m_vertices[1] == m_vertex] = previous; + previous->m_vertex_next[previous->m_vertices[1] == m_vertex] = next; + + // If edge was the list head, update head + if (m_head == edge) + { + m_head = next; + } + + --m_size; +} + +brep_vertex* brep_vertex_container::emplace_back() +{ + brep_vertex* vertex = brep_element_container::emplace_back(); + vertex->m_index = size() - 1; + vertex->m_edges.m_vertex = vertex; + return vertex; +}; + +void brep_vertex_container::erase(brep_vertex* vertex) +{ + // Erase all edges bounded by this vertex + while (!vertex->edges().empty()) + { + m_mesh->edges().erase(vertex->edges().back()); + } + + // Erase vertex + brep_element_container::erase(vertex); +} + +void brep_vertex_container::clear() noexcept +{ + while (!empty()) + { + erase(back()); + } +} + +} // namespace geom diff --git a/src/engine/geom/brep/brep-vertex.hpp b/src/engine/geom/brep/brep-vertex.hpp new file mode 100644 index 0000000..8b44eeb --- /dev/null +++ b/src/engine/geom/brep/brep-vertex.hpp @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BREP_VERTEX_HPP +#define ANTKEEPER_GEOM_BREP_VERTEX_HPP + +#include +#include +#include +#include + +namespace geom { + +class brep_mesh; +class brep_edge; +class brep_vertex; +template +class brep_element_container; + +/** + * List of B-rep edges bounded by a common vertex. + */ +class brep_vertex_edge_list +{ +public: + friend class brep_mesh; + friend class brep_vertex_container; + friend class brep_edge_container; + + struct const_iterator + { + public: + friend class brep_vertex_edge_list; + + using iterator_category = std::bidirectional_iterator_tag; + using iterator_concept = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = brep_edge*; + using pointer = const value_type*; + using reference = const value_type&; + + [[nodiscard]] inline constexpr value_type operator*() const noexcept + { + return m_edge; + } + + [[nodiscard]] inline constexpr value_type operator->() const noexcept + { + return m_edge; + } + + inline const_iterator& operator++() noexcept + { + m_edge = m_edge->m_vertex_next[m_edge->vertices()[1] == m_vertex]; + ++m_position; + return *this; + } + + [[nodiscard]] inline const_iterator operator++(int) noexcept + { + const_iterator tmp = *this; + ++(*this); + return tmp; + } + + inline const_iterator& operator--() noexcept + { + m_edge = m_edge->m_vertex_previous[m_edge->vertices()[1] == m_vertex]; + --m_position; + return *this; + } + + [[nodiscard]] inline const_iterator operator--(int) noexcept + { + const_iterator tmp = *this; + --(*this); + return tmp; + } + + [[nodiscard]] inline bool operator==(const const_iterator& other) const noexcept + { + return m_position == other.m_position; + }; + + [[nodiscard]] inline std::weak_ordering operator<=>(const const_iterator& other) const noexcept + { + return m_position <=> other.m_position; + } + + [[nodiscard]] inline difference_type operator-(const const_iterator& rhs) const noexcept + { + return m_position - rhs.m_position; + } + + private: + brep_vertex* m_vertex; + brep_edge* m_edge; + std::ptrdiff_t m_position; + }; + + using const_reverse_iterator = std::reverse_iterator; + + /// @name Element access + /// @{ + + /// Returns the first edge. + [[nodiscard]] inline brep_edge* front() const noexcept + { + return m_head; + } + + /// Returns the last edge. + [[nodiscard]] inline brep_edge* back() const noexcept + { + return m_head->m_vertex_previous[m_head->vertices()[1] == m_vertex]; + } + + /// @} + /// @name Iterators + /// @{ + + /// Returns an iterator to the first edge. + /// @{ + [[nodiscard]] inline constexpr const_iterator begin() const noexcept + { + const_iterator it; + it.m_vertex = m_vertex; + it.m_edge = m_head; + it.m_position = 0; + + return it; + } + [[nodiscard]] inline constexpr const_iterator cbegin() const noexcept + { + return begin(); + } + /// @} + + /// Returns an iterator to the edge following the last edge. + /// @{ + [[nodiscard]] inline constexpr const_iterator end() const noexcept + { + const_iterator it; + it.m_vertex = m_vertex; + it.m_edge = m_head; + it.m_position = static_cast(m_size); + + return it; + } + [[nodiscard]] inline constexpr const_iterator cend() const noexcept + { + return end(); + } + /// @} + + /// Returns a reverse iterator to the first edge of the reversed list. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rbegin() const noexcept + { + return std::make_reverse_iterator(end()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crbegin() const noexcept + { + return rbegin(); + } + /// @} + + /// Returns a reverse iterator to the edge following the last edge of the reversed list. + /// @{ + [[nodiscard]] inline constexpr const_reverse_iterator rend() const noexcept + { + return std::make_reverse_iterator(begin()); + } + [[nodiscard]] inline constexpr const_reverse_iterator crend() const noexcept + { + return rend(); + } + /// @} + + /// @} + /// @name Capacity + /// @{ + + /// Returns `true` if the list is empty, `false` otherwise. + [[nodiscard]] inline constexpr bool empty() const noexcept + { + return !m_size; + } + + /// Returns the number of edges in the list. + [[nodiscard]] inline constexpr std::size_t size() const noexcept + { + return m_size; + } + + /// @} + /// @name Modifiers + /// @{ + + /** + * Appends an edge to the end of the list. + * + * @param edge Pointer to the edge to append. + */ + void push_back(brep_edge* edge); + + /** + * Removes an edge from the list. + * + * @param edge Pointer to the edge to remove. + */ + void remove(brep_edge* edge); + + /// @} + +private: + brep_vertex* m_vertex{}; + brep_edge* m_head{}; + std::size_t m_size{}; +}; + +/** + * A point in space. + */ +class brep_vertex +{ +public: + friend class brep_mesh; + friend class brep_element_container; + friend class brep_vertex_container; + friend class brep_edge_container; + + /** + * Returns the index of this vertex in the mesh vertex array. + * + * @warning This index may change if any vertices are removed from the mesh. + */ + [[nodiscard]] inline constexpr std::size_t index() const noexcept + { + return m_index; + } + + /// Returns the list of edges bounded by this vertex. + [[nodiscard]] inline constexpr const brep_vertex_edge_list& edges() const noexcept + { + return m_edges; + } + +private: + std::size_t m_index; + brep_vertex_edge_list m_edges; +}; + +/** + * B-rep vertex container. + */ +class brep_vertex_container: public brep_element_container +{ +public: + /** + * Appends a new vertex to the end of the container. + * + * @return Pointer to the new vertex. + */ + brep_vertex* emplace_back() override; + + /** + * Erases a vertex and all dependent edges, loops, and faces. + * + * @param vertex Pointer to the vertex to erase. + * + * @warning Invalidates iterators and indices of vertices, edges, loops, and faces. + */ + void erase(brep_vertex* vertex) override; + + /** + * Erases all vertices and their dependent edges, loops, and faces. + */ + void clear() noexcept; + +private: + friend class brep_mesh; + + /** + * Constructs a B-rep vertex container. + * + * @param mesh Pointer to the parent mesh. + */ + inline explicit brep_vertex_container(brep_mesh* mesh) noexcept: + brep_element_container(mesh) + {} +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BREP_VERTEX_HPP diff --git a/src/engine/geom/bvh/bvh-node.hpp b/src/engine/geom/bvh/bvh-node.hpp new file mode 100644 index 0000000..ae7736f --- /dev/null +++ b/src/engine/geom/bvh/bvh-node.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BVH_NODE_HPP +#define ANTKEEPER_GEOM_BVH_NODE_HPP + +#include +#include + +namespace geom { + +/** + * Single node in a bounding volume hierarchy. + */ +struct bvh_node +{ + /// Returns `true` if the node is a leaf node, `false` otherwise. + [[nodiscard]] inline constexpr bool is_leaf() const noexcept + { + return size; + } + + /// Node bounds. + geom::box bounds; + + /// Number of primitives in the node. + std::uint32_t size; + + /// Offset to the first child node (non-leaf) or primitive (leaf). + std::uint32_t offset; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BVH_NODE_HPP diff --git a/src/engine/geom/meshes/grid.hpp b/src/engine/geom/bvh/bvh-primitive.hpp similarity index 58% rename from src/engine/geom/meshes/grid.hpp rename to src/engine/geom/bvh/bvh-primitive.hpp index 59a92c6..8eb2c6a 100644 --- a/src/engine/geom/meshes/grid.hpp +++ b/src/engine/geom/bvh/bvh-primitive.hpp @@ -17,26 +17,26 @@ * along with Antkeeper source code. If not, see . */ -#ifndef ANTKEEPER_GEOM_MESHES_GRID_HPP -#define ANTKEEPER_GEOM_MESHES_GRID_HPP +#ifndef ANTKEEPER_GEOM_BVH_PRIMITIVE_HPP +#define ANTKEEPER_GEOM_BVH_PRIMITIVE_HPP -#include -#include +#include +#include namespace geom { -namespace meshes { /** - * Generates a grid mesh on the XY plane. - * - * @param length Side length of the grid. - * @param subdivisions_x Number of subdivisions on the x-axis. - * @param subdivisions_y Number of subdivisions on the y-axis. - * @return Grid mesh on the XY plane. + * BVH primitive. */ -[[nodiscard]] std::unique_ptr grid_xy(float length, std::size_t subdivisions_x, std::size_t subdivisions_y); +struct bvh_primitive +{ + /// Geometric center of the primitive. + math::fvec3 centroid; + + /// Axis-aligned bounding box containing the primitive. + geom::box bounds; +}; -} // namespace meshes } // namespace geom -#endif // ANTKEEPER_GEOM_MESHES_GRID_HPP +#endif // ANTKEEPER_GEOM_BVH_PRIMITIVE_HPP diff --git a/src/engine/geom/bvh/bvh.cpp b/src/engine/geom/bvh/bvh.cpp new file mode 100644 index 0000000..90d8bbb --- /dev/null +++ b/src/engine/geom/bvh/bvh.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +namespace geom { + +bvh::bvh(std::span primitives) +{ + build(primitives); +} + +bvh::bvh(const brep_mesh& mesh) +{ + build(mesh); +} + +void bvh::build(std::span primitives) +{ + if (primitives.empty()) + { + m_primitive_indices.clear(); + m_nodes.clear(); + m_node_count = 0; + } + else + { + // Allocate and fill primitive index array + m_primitive_indices.resize(primitives.size()); + std::iota(m_primitive_indices.begin(), m_primitive_indices.end(), 0); + + // Allocate nodes + m_nodes.resize(primitives.size() << 1); + + // Init root node + m_node_count = 1; + auto& root = m_nodes.front(); + root.size = static_cast(primitives.size()); + root.offset = 0; + update_bounds(root, primitives); + + // Recursively build BVH + subdivide(root, primitives); + } +} + +void bvh::build(const brep_mesh& mesh) +{ + // Get mesh vertex positions attribute + const auto& vertex_positions = mesh.vertices().attributes().at("position"); + + // Allocate BVH primitives for mesh faces + std::vector primitives(mesh.faces().size()); + + // Calculate bounding boxes + for (brep_face* face: mesh.faces()) + { + auto& primitive = primitives[face->index()]; + primitive.centroid = {}; + primitive.bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; + + for (brep_loop* loop: face->loops()) + { + const auto& vertex_position = vertex_positions[loop->vertex()->index()]; + + primitive.centroid += vertex_position; + primitive.bounds.extend(vertex_position); + } + + primitive.centroid /= static_cast(face->loops().size()); + } + + // Build BVH from the bounding boxes of the mesh faces + build(primitives); +} + +void bvh::update_bounds(bvh_node& node, const std::span& primitives) +{ + node.bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; + for (std::uint32_t i = 0; i < node.size; ++i) + { + const auto& primitive = primitives[m_primitive_indices[node.offset + i]]; + node.bounds.extend(primitive.bounds); + }; +} + +void bvh::subdivide(bvh_node& node, const std::span& primitives) +{ + if (node.size <= 2) + { + return; + } + + // Determine index of split axis + const auto extents = node.bounds.size(); + std::uint8_t split_axis = 0; + if (extents.y() > extents.x()) + { + split_axis = 1; + } + if (extents.z() > extents[split_axis]) + { + split_axis = 2; + } + + // Determine split coordinate + const float split_coord = node.bounds.min[split_axis] + extents[split_axis] * 0.5f; + + std::uint32_t i = node.offset; + std::uint32_t j = (node.size) ? i + node.size - 1 : i; + while (i <= j) + { + const auto& primitive = primitives[m_primitive_indices[i]]; + + if (primitive.centroid[split_axis] < split_coord) + // if (primitive.bounds.center()[split_axis] < split_coord) + { + ++i; + } + else + { + std::swap(m_primitive_indices[i], m_primitive_indices[j]); + if (!j) + { + break; + } + --j; + } + } + + const std::uint32_t left_size = i - node.offset; + if (!left_size || left_size == node.size) + { + return; + } + + const std::uint32_t left_index = m_node_count++; + auto& left_child = m_nodes[left_index]; + left_child.offset = node.offset; + left_child.size = left_size; + update_bounds(left_child, primitives); + + const std::uint32_t right_index = m_node_count++; + auto& right_child = m_nodes[right_index]; + right_child.offset = i; + right_child.size = node.size - left_size; + update_bounds(right_child, primitives); + + node.offset = left_index; + node.size = 0; + subdivide(left_child, primitives); + subdivide(right_child, primitives); +} + +void bvh::visit(const bvh_node& node, const geom::ray& ray, const visitor_type& f) const +{ + if (!geom::intersection(ray, node.bounds)) + { + return; + } + + if (node.is_leaf()) + { + // Visit leaf node primitives + for (std::uint32_t i = 0; i < node.size; ++i) + { + f(m_primitive_indices[node.offset + i]); + } + } + else + { + // Recursively visit node children + visit(m_nodes[node.offset], ray, f); + visit(m_nodes[node.offset + 1], ray, f); + } +} + +} // namespace geom diff --git a/src/engine/geom/bvh/bvh.hpp b/src/engine/geom/bvh/bvh.hpp new file mode 100644 index 0000000..24a693a --- /dev/null +++ b/src/engine/geom/bvh/bvh.hpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GEOM_BVH_HPP +#define ANTKEEPER_GEOM_BVH_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace geom { + +class brep_mesh; + +/** + * Bounding volume hierarchy (BVH). + */ +class bvh +{ +public: + using visitor_type = std::function; + + /** + * Constructs a BVH from a set of primitives. + * + * @param primitives Axis-aligned bounding boxes. + */ + explicit bvh(std::span primitives); + + /** + * Constructs a BVH from a B-rep mesh. + * + * @param mesh B-rep mesh from which to build the BVH. + */ + explicit bvh(const brep_mesh& mesh); + + /// Constructs an empty BVH. + constexpr bvh() noexcept = default; + + /** + * Constructs a BVH from a set of primitives. + * + * @param primitives BVH primitives. + */ + void build(std::span primitives); + + /** + * Constructs a BVH from a B-rep mesh. + * + * @param mesh B-rep mesh from which to build the BVH. + */ + void build(const brep_mesh& mesh); + + /** + * Visits the primitive indices of all BVH nodes that intersect a ray. + * + * @param ray Query ray. + * @param f Unary visitor function which operates on a BVH primitive index. + */ + inline void visit(const geom::ray& ray, const visitor_type& f) const + { + if (m_node_count) + { + visit(m_nodes.front(), ray, f); + } + } + + /// Returns the BVH nodes. + [[nodiscard]] inline constexpr const std::vector& nodes() const noexcept + { + return m_nodes; + } + +private: + void update_bounds(bvh_node& node, const std::span& primitives); + + /** + * Builds the BVH through recursive subdivision. + * + * @param node Current node. + * @param primitives BVH primitives. + */ + void subdivide(bvh_node& node, const std::span& primitives); + void visit(const bvh_node& node, const geom::ray& ray, const visitor_type& f) const; + + std::vector m_primitive_indices; + std::vector m_nodes; + std::uint32_t m_node_count{}; +}; + +} // namespace geom + +#endif // ANTKEEPER_GEOM_BVH_HPP diff --git a/src/engine/geom/cartesian.hpp b/src/engine/geom/cartesian.hpp index eab9df8..c4effe0 100644 --- a/src/engine/geom/cartesian.hpp +++ b/src/engine/geom/cartesian.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GEOM_CARTESIAN_HPP #define ANTKEEPER_GEOM_CARTESIAN_HPP -#include +#include #include namespace geom { @@ -37,14 +37,14 @@ namespace cartesian { * @see geom::coordinates::spherical */ template -math::vector3 to_spherical(const math::vector3& v); +math::vec3 to_spherical(const math::vec3& v); template -math::vector3 to_spherical(const math::vector3& v) +math::vec3 to_spherical(const math::vec3& v) { const T xx_yy = v.x() * v.x() + v.y() * v.y(); - return math::vector3 + return math::vec3 { std::sqrt(xx_yy + v.z() * v.z()), std::atan2(v.z(), std::sqrt(xx_yy)), diff --git a/src/engine/geom/intersection.hpp b/src/engine/geom/intersection.hpp index ff5dc2c..821a770 100644 --- a/src/engine/geom/intersection.hpp +++ b/src/engine/geom/intersection.hpp @@ -144,51 +144,55 @@ template * * @return Tuple containing the distance along the ray to the point of intersection, followed by two barycentric coordinates of the point of intersection, or `std::nullopt` if no intersection occurred. */ +/// @{ template -[[nodiscard]] std::optional> intersection(const ray& ray, const math::vector& a, const math::vector& b, const math::vector& c) +[[nodiscard]] constexpr std::optional> intersection(const ray& ray, const math::vec3& a, const math::vec3& b, const math::vec3& c) noexcept { // Find edges - const math::vector edge10 = b - a; - const math::vector edge20 = c - a; - + const math::vec3 edge_ab = b - a; + const math::vec3 edge_ac = c - a; + // Calculate determinant - const math::vector pv = math::cross(ray.direction, edge20); - const T det = math::dot(edge10, pv); + const math::vec3 pv = math::cross(ray.direction, edge_ac); + const T det = math::dot(edge_ab, pv); if (!det) { return std::nullopt; } - + const T inverse_det = T{1} / det; - + // Calculate u - const math::vector tv = ray.origin - a; + const math::vec3 tv = ray.origin - a; const T u = math::dot(tv, pv) * inverse_det; - if (u < T{0} || u > T{1}) { return std::nullopt; } - + // Calculate v - const math::vector qv = math::cross(tv, edge10); + const math::vec3 qv = math::cross(tv, edge_ab); const T v = math::dot(ray.direction, qv) * inverse_det; - if (v < T{0} || u + v > T{1}) { return std::nullopt; } - + // Calculate t - const T t = math::dot(edge20, qv) * inverse_det; - - if (t > T{0}) + const T t = math::dot(edge_ac, qv) * inverse_det; + if (t < T{0}) { - return std::tuple{t, u, v}; + return std::nullopt; } - - return std::nullopt; + + return std::tuple{t, u, v}; } +template +[[nodiscard]] inline constexpr std::optional> intersection(const math::vec3& a, const math::vec3& b, const math::vec3& c, const ray& ray) noexcept +{ + return intersection(ray, a, b, c); +} +/// @} /** * Hyperrectangle-hyperrectangle intersection test. diff --git a/src/engine/geom/mesh-accelerator.cpp b/src/engine/geom/mesh-accelerator.cpp deleted file mode 100644 index cf2918b..0000000 --- a/src/engine/geom/mesh-accelerator.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include -#include -#include -#include - -namespace geom { - -mesh_accelerator::mesh_accelerator() -{} - -void mesh_accelerator::build(const mesh& mesh) -{ - // Clear octree and face map - octree.clear(); - face_map.clear(); - - // Calculate mesh dimensions - box bounds = calculate_bounds(mesh); - float3 mesh_dimensions = bounds.max - bounds.min; - center_offset = mesh_dimensions * 0.5f - (bounds.min + bounds.max) * 0.5f; - - // Calculate node dimensions at each octree depth - for (auto i = 0; i <= octree_type::max_depth; ++i) - { - node_dimensions[i] = mesh_dimensions * static_cast((1.0f / std::pow(2, i))); - } - - // Add faces to octree - for (mesh::face* face: mesh.get_faces()) - { - // Calculate face bounds - float3 min_point = reinterpret_cast(face->edge->vertex->position); - float3 max_point = min_point; - mesh::edge* edge = face->edge; - do - { - const auto& position = edge->vertex->position; - for (int i = 0; i < 3; ++i) - { - min_point[i] = std::min(min_point[i], position[i]); - max_point[i] = std::max(max_point[i], position[i]); - } - - edge = edge->next; - } - while (edge != face->edge); - - // 1. Find max depth node of aabb min - // 2. Find max depth node of aabb max - // 3. Find common ancestor of the two nodes--that's the containing node. - typename octree_type::node_type min_node = find_node(min_point); - typename octree_type::node_type max_node = find_node(max_point); - typename octree_type::node_type containing_node = octree_type::common_ancestor(min_node, max_node); - - // Insert containing node into octree - octree.insert(containing_node); - - // Add face to face map - face_map[containing_node].push_back(face); - } -} - -std::optional mesh_accelerator::query_nearest(const ray& ray) const -{ - ray_query_result result; - result.t = std::numeric_limits::infinity(); - result.face = nullptr; - - query_nearest_recursive(result.t, result.face, octree.root, ray); - - if (result.face) - return std::optional{result}; - return std::nullopt; -} - -void mesh_accelerator::query_nearest_recursive(float& nearest_t, geom::mesh::face*& nearest_face, typename octree_type::node_type node, const ray& ray) const -{ - // Get node bounds - const box node_bounds = get_node_bounds(node); - - // If ray passed through this node - if (intersection(ray, node_bounds)) - { - // Test all triangles in the node - if (auto it = face_map.find(node); it != face_map.end()) - { - const std::list& faces = it->second; - - for (mesh::face* face: faces) - { - // Get triangle coordinates - const float3& a = reinterpret_cast(face->edge->vertex->position); - const float3& b = reinterpret_cast(face->edge->next->vertex->position); - const float3& c = reinterpret_cast(face->edge->previous->vertex->position); - - // Test for intersection with triangle - auto triangle_intersection = intersection(ray, a, b, c); - if (triangle_intersection) - { - const float t = std::get<0>(*triangle_intersection); - if (t < nearest_t) - { - nearest_t = t; - nearest_face = face; - } - } - } - } - - // Test all child nodes - if (!octree.is_leaf(node)) - { - for (int i = 0; i < 8; ++i) - { - query_nearest_recursive(nearest_t, nearest_face, octree.child(node, i), ray); - } - } - } -} - -box mesh_accelerator::get_node_bounds(typename octree_type::node_type node) const -{ - // Decode Morton location of node - std::uint32_t x, y, z; - morton::decode(octree_type::location(node), x, y, z); - float3 node_location = float3{static_cast(x), static_cast(y), static_cast(z)}; - - // Get node dimensions at node depth - const float3& dimensions = node_dimensions[octree_type::depth(node)]; - - // Calculate AABB - float3 min_point = (node_location * dimensions) - center_offset; - return box{min_point, min_point + dimensions}; -} - -typename mesh_accelerator::octree_type::node_type mesh_accelerator::find_node(const float3& point) const -{ - // Transform point to octree space - float3 transformed_point = (point + center_offset); - - // Account for floating-point tolerance - const float epsilon = 0.00001f; - transformed_point.x() = std::max(0.0f, std::min(node_dimensions[0].x() - epsilon, transformed_point.x())); - transformed_point.y() = std::max(0.0f, std::min(node_dimensions[0].y() - epsilon, transformed_point.y())); - transformed_point.z() = std::max(0.0f, std::min(node_dimensions[0].z() - epsilon, transformed_point.z())); - - // Transform point to max-depth node space - transformed_point = transformed_point / node_dimensions[octree_type::max_depth]; - - // Encode transformed point as a Morton location code - std::uint32_t location = morton::encode( - static_cast(transformed_point.x()), - static_cast(transformed_point.y()), - static_cast(transformed_point.z())); - - // Return max depth node at the determined location - return octree_type::node(octree_type::max_depth, location); -} - -} // namespace geom diff --git a/src/engine/geom/mesh-accelerator.hpp b/src/engine/geom/mesh-accelerator.hpp deleted file mode 100644 index 273a57a..0000000 --- a/src/engine/geom/mesh-accelerator.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_GEOM_MESH_ACCELERATOR_HPP -#define ANTKEEPER_GEOM_MESH_ACCELERATOR_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace geom { - -/** - * Acceleration structure for querying mesh geometry. - */ -class mesh_accelerator -{ -public: - struct ray_query_result - { - float t; - geom::mesh::face* face; - }; - - mesh_accelerator(); - - /** - * Builds the acceleration structure. - */ - void build(const mesh& mesh); - - /** - * Finds the first intersection between a ray and a triangle in the mesh. - * - * @param ray Ray to test for intersection. - * @return Ray query result on intersection, and `std::nullopt` if no intersection occurred. - */ - std::optional query_nearest(const ray& ray) const; - -private: - typedef unordered_octree32 octree_type; - - box get_node_bounds(typename octree_type::node_type node) const; - - void query_nearest_recursive(float& nearest_t, geom::mesh::face*& nearest_face, typename octree_type::node_type node, const ray& ray) const; - - /// Returns the max-depth node in which the point is located - typename octree_type::node_type find_node(const float3& point) const; - - octree_type octree; - float3 node_dimensions[octree_type::max_depth + 1]; - float3 center_offset; - std::unordered_map> face_map; -}; - -} // namespace geom - -#endif // ANTKEEPER_GEOM_MESH_ACCELERATOR_HPP - diff --git a/src/engine/geom/mesh-functions.cpp b/src/engine/geom/mesh-functions.cpp deleted file mode 100644 index b19c735..0000000 --- a/src/engine/geom/mesh-functions.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include -#include -#include -#include - -namespace geom { - -struct edge_hasher -{ - std::size_t operator()(const std::array& v) const noexcept - { - std::size_t hash = std::hash()(v[0]); - return hash ^ (std::hash()(v[1]) + 0x9e3779b9 + (hash << 6) + (hash >> 2)); - } -}; - -void create_triangle_mesh(mesh& mesh, const std::vector& vertices, const std::vector>& triangles) -{ - for (const auto& vertex: vertices) - mesh.add_vertex(vertex); - - std::unordered_map, geom::mesh::edge*, edge_hasher> edge_map; - const std::vector& mesh_vertices = mesh.get_vertices(); - std::vector loop(3); - - for (const auto& triangle: triangles) - { - geom::mesh::vertex* triangle_vertices[3] = - { - mesh_vertices[triangle[0]], - mesh_vertices[triangle[1]], - mesh_vertices[triangle[2]] - }; - - for (int j = 0; j < 3; ++j) - { - geom::mesh::vertex* start = triangle_vertices[j]; - geom::mesh::vertex* end = triangle_vertices[(j + 1) % 3]; - - if (auto it = edge_map.find({start->index, end->index}); it != edge_map.end()) - { - loop[j] = it->second; - } - else - { - loop[j] = mesh.add_edge(start, end); - edge_map[{start->index, end->index}] = loop[j]; - edge_map[{end->index, start->index}] = loop[j]->symmetric; - } - - } - - mesh.add_face(loop); - } -} - -void calculate_face_normals(float3* normals, const mesh& mesh) -{ - const std::vector& faces = mesh.get_faces(); - - for (std::size_t i = 0; i < faces.size(); ++i) - { - const mesh::face& face = *(faces[i]); - const float3& a = face.edge->vertex->position; - const float3& b = face.edge->next->vertex->position; - const float3& c = face.edge->previous->vertex->position; - - normals[i] = math::normalize(math::cross(b - a, c - a)); - } -} - -float3 calculate_face_normal(const mesh::face& face) -{ - const float3& a = face.edge->vertex->position; - const float3& b = face.edge->next->vertex->position; - const float3& c = face.edge->previous->vertex->position; - return math::normalize(math::cross(b - a, c - a)); -} - -void calculate_vertex_tangents(float4* tangents, const float2* texcoords, const float3* normals, const mesh& mesh) -{ - const std::vector& faces = mesh.get_faces(); - const std::vector& vertices = mesh.get_vertices(); - - // Allocate tangent and bitangent buffers - std::vector tangent_buffer(vertices.size(), float3{0.0f, 0.0f, 0.0f}); - std::vector bitangent_buffer(vertices.size(), float3{0.0f, 0.0f, 0.0f}); - - // Accumulate tangents and bitangents - for (std::size_t i = 0; i < faces.size(); ++i) - { - const mesh::face& face = *(faces[i]); - std::size_t ia = face.edge->vertex->index; - std::size_t ib = face.edge->next->vertex->index; - std::size_t ic = face.edge->previous->vertex->index; - const float3& a = vertices[ia]->position; - const float3& b = vertices[ib]->position; - const float3& c = vertices[ic]->position; - const float2& uva = texcoords[ia]; - const float2& uvb = texcoords[ib]; - const float2& uvc = texcoords[ic]; - - float3 ba = b - a; - float3 ca = c - a; - float2 uvba = uvb - uva; - float2 uvca = uvc - uva; - - float f = 1.0f / (uvba.x() * uvca.y() - uvca.x() * uvba.y()); - float3 tangent = (ba * uvca.y() - ca * uvba.y()) * f; - float3 bitangent = (ba * -uvca.x() + ca * uvba.x()) * f; - - tangent_buffer[ia] += tangent; - tangent_buffer[ib] += tangent; - tangent_buffer[ic] += tangent; - bitangent_buffer[ia] += bitangent; - bitangent_buffer[ib] += bitangent; - bitangent_buffer[ic] += bitangent; - } - - // Orthogonalize tangents - for (std::size_t i = 0; i < vertices.size(); ++i) - { - const float3& n = normals[i]; - const float3& t = tangent_buffer[i]; - const float3& b = bitangent_buffer[i]; - - // Gram-Schmidt orthogonalize tangent - float3 tangent = math::normalize(t - n * math::dot(n, t)); - - // Calculate bitangent sign - float bitangent_sign = (math::dot(math::cross(n, t), b) < 0.0f) ? -1.0f : 1.0f; - - tangents[i] = {tangent.x(), tangent.y(), tangent.z(), bitangent_sign}; - } -} - -box calculate_bounds(const mesh& mesh) -{ - box bounds; - for (int i = 0; i < 3; ++i) - { - bounds.min[i] = std::numeric_limits::infinity(); - bounds.max[i] = -std::numeric_limits::infinity(); - } - - for (const mesh::vertex* vertex: mesh.get_vertices()) - { - const auto& position = vertex->position; - bounds.extend(position); - } - - return bounds; -} - -mesh::vertex* poke_face(mesh& mesh, std::size_t index) -{ - mesh::face* face = mesh.get_faces()[index]; - - // Collect face edges and sum edge vertex positions - mesh::loop loop = {face->edge}; - float3 sum_positions = face->edge->vertex->position; - for (mesh::edge* edge = face->edge->next; edge != face->edge; edge = edge->next) - { - loop.push_back(edge); - sum_positions += edge->vertex->position; - } - - if (loop.size() <= 2) - return nullptr; - - // Remove face - mesh.remove_face(face); - - // Add vertex in center - mesh::vertex* center = mesh.add_vertex(sum_positions / static_cast(loop.size())); - - // Create first triangle - geom::mesh::edge* ab = loop[0]; - geom::mesh::edge* bc = mesh.add_edge(ab->next->vertex, center); - geom::mesh::edge* ca = mesh.add_edge(center, ab->vertex); - mesh.add_face({ab, bc, ca}); - - // Save first triangle CA edge - geom::mesh::edge* first_triangle_ca = ca; - - // Create remaining triangles - for (std::size_t i = 1; i < loop.size(); ++i) - { - ab = loop[i]; - ca = bc->symmetric; - - if (i == loop.size() - 1) - bc = first_triangle_ca->symmetric; - else - bc = mesh.add_edge(ab->next->vertex, center); - - mesh.add_face({ab, bc, ca}); - } - - return center; -} - -} // namespace geom diff --git a/src/engine/geom/mesh-functions.hpp b/src/engine/geom/mesh-functions.hpp deleted file mode 100644 index dc027fa..0000000 --- a/src/engine/geom/mesh-functions.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_GEOM_MESH_FUNCTIONS_HPP -#define ANTKEEPER_GEOM_MESH_FUNCTIONS_HPP - -#include -#include -#include -#include -#include - -namespace geom { - -/** - * Creates a triangle mesh from a list of vertices and indices. - * - * @param[out] mesh Mesh to which vertices, edges, and faces will be added. - * @param vertices Vertex positions - * @param triangles Triangle indices - * @return Newly created triangle mesh. - */ -void create_triangle_mesh(mesh& mesh, const std::vector& vertices, const std::vector>& triangles); - -/** - * Calculates normals for each face. - * - * @param[out] Array in which faceted normals will be stored. - */ -void calculate_face_normals(float3* normals, const mesh& mesh); - -float3 calculate_face_normal(const mesh::face& face); - -/** - * Calculates smooth tangents per-vertex. - * - * @param[out] tangents Array in which vertex tangents will be stored. A bitangent sign is stored in each tangent vector's fourth component. - * @param[in] texcoords Array containing vertex texture coordinates. - * @param[in] normals Array containing vertex normals. - */ -void calculate_vertex_tangents(float4* tangents, const float2* texcoords, const float3* normals, const mesh& mesh); - -/** - * Calculates the AABB bounds of a mesh. - */ -box calculate_bounds(const mesh& mesh); - -/** - * Triangulates a face by adding a new vertex in the center, then creating triangles between the edges of the original face and the new vertex. - * - * @param mesh Mesh containing the face to poke. - * @param index Index of the face to poke. - * @return Pointer to the newly-created vertex in the center of the face, or `nullptr` if the face could not be poked. - */ -mesh::vertex* poke_face(mesh& mesh, std::size_t index); - -} // namespace geom - -#endif // ANTKEEPER_GEOM_MESH_FUNCTIONS_HPP - diff --git a/src/engine/geom/mesh.cpp b/src/engine/geom/mesh.cpp deleted file mode 100644 index e20a5c9..0000000 --- a/src/engine/geom/mesh.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include -#include - -namespace geom { - -mesh::mesh(const mesh& other) -{ - *this = other; -} - -mesh::~mesh() -{ - clear(); -} - -mesh& mesh::operator=(const mesh& other) -{ - // Clear the mesh - clear(); - - // Resize vertices, edges, and faces - vertices.resize(other.vertices.size()); - edges.resize(other.edges.size()); - faces.resize(other.faces.size()); - - // Allocate vertices - for (std::size_t i = 0; i < vertices.size(); ++i) - vertices[i] = new vertex(); - - // Allocate edges - for (std::size_t i = 0; i < edges.size(); ++i) - { - edges[i] = new edge(); - edges[i]->symmetric = new edge(); - edges[i]->symmetric->symmetric = edges[i]; - } - - // Allocate faces - for (std::size_t i = 0; i < faces.size(); ++i) - faces[i] = new face(); - - // Copy vertices - for (std::size_t i = 0; i < vertices.size(); ++i) - { - vertex* va = vertices[i]; - const vertex* vb = other.vertices[i]; - - va->index = vb->index; - va->position = vb->position; - va->edge = nullptr; - - if (vb->edge) - { - va->edge = edges[vb->edge->index]; - if (vb->edge != other.edges[vb->edge->index]) - va->edge = va->edge->symmetric; - } - } - - // Copy edges - for (std::size_t i = 0; i < edges.size(); ++i) - { - edge* ea = edges[i]; - const edge* eb = other.edges[i]; - - for (std::size_t j = 0; j < 2; ++j) - { - ea->index = eb->index; - ea->vertex = vertices[eb->vertex->index]; - - ea->face = nullptr; - if (eb->face) - ea->face = faces[eb->face->index]; - - ea->previous = edges[eb->previous->index]; - if (eb->previous != other.edges[eb->previous->index]) - ea->previous = ea->previous->symmetric; - - ea->next = edges[eb->next->index]; - if (eb->next != other.edges[eb->next->index]) - ea->next = ea->next->symmetric; - - ea = ea->symmetric; - eb = eb->symmetric; - } - } - - // Copy faces - for (std::size_t i = 0; i < faces.size(); ++i) - { - face* fa = faces[i]; - const face* fb = other.faces[i]; - - fa->index = fb->index; - - fa->edge = edges[fb->edge->index]; - if (fb->edge != other.edges[fb->edge->index]) - fa->edge = fa->edge->symmetric; - } - - return *this; -} - -void mesh::clear() noexcept -{ - // Deallocate vertices - for (mesh::vertex* vertex: vertices) - delete vertex; - - // Deallocate edges - for (mesh::edge* edge: edges) - { - delete edge->symmetric; - delete edge; - } - - // Deallocate faces - for (mesh::face* face: faces) - delete face; - - vertices.clear(); - edges.clear(); - faces.clear(); -} - -mesh::vertex* mesh::add_vertex(const float3& position) -{ - mesh::vertex* vertex = new mesh::vertex - { - vertices.size(), - nullptr, - position - }; - - vertices.push_back(vertex); - - return vertex; -} - -mesh::edge* mesh::add_edge(mesh::vertex* a, mesh::vertex* b) -{ - mesh::edge* ab = new mesh::edge(); - mesh::edge* ba = new mesh::edge(); - - ab->index = edges.size(); - ab->vertex = a; - ab->face = nullptr; - ab->previous = ba; - ab->next = ba; - ab->symmetric = ba; - - ba->index = edges.size(); - ba->vertex = b; - ba->face = nullptr; - ba->previous = ab; - ba->next = ab; - ba->symmetric = ab; - - if (!a->edge) - { - a->edge = ab; - } - else - { - mesh::edge* a_in = find_free_incident(a); - mesh::edge* a_out = a_in->next; - a_in->next = ab; - ab->previous = a_in; - ba->next = a_out; - a_out->previous = ba; - } - - if (!b->edge) - { - b->edge = ba; - } - else - { - mesh::edge* b_in = find_free_incident(b); - mesh::edge* b_out = b_in->next; - b_in->next = ba; - ba->previous = b_in; - ab->next = b_out; - b_out->previous = ab; - } - - // Add edge - edges.push_back(ab); - - return ab; -} - -mesh::face* mesh::add_face(const loop& loop) -{ - if (loop.empty()) - { - throw std::runtime_error("Empty edge loop"); - } - - // Validate edge loop - for (std::size_t i = 0; i < loop.size(); ++i) - { - mesh::edge* current = loop[i]; - mesh::edge* next = loop[(i + 1) % loop.size()]; - - if (current->symmetric->vertex != next->vertex) - { - // Disconnected edge loop - throw std::runtime_error("Disconnected edge loop"); - } - - if (current->face) - { - // This edge already has a face - throw std::runtime_error("Non-manifold mesh 1"); - } - } - - // Make edges adjacent - for (std::size_t i = 0; i < loop.size(); ++i) - { - if (!make_adjacent(loop[i], loop[(i + 1) % loop.size()])) - { - throw std::runtime_error("Non-manifold mesh 2"); - } - } - - // Create face - mesh::face* face = new mesh::face(); - face->edge = loop[0]; - face->index = faces.size(); - - // Add face - faces.push_back(face); - - // Connect edges to the face - for (mesh::edge* edge: loop) - { - edge->face = face; - } - - return face; -} - -void mesh::remove_face(mesh::face* face) -{ - // Nullify pointers to this face - mesh::edge* edge = face->edge; - do - { - edge->face = nullptr; - edge = edge->next; - } - while (edge != face->edge); - - // Adjust indices of faces after this face - for (std::size_t i = face->index + 1; i < faces.size(); ++i) - { - --faces[i]->index; - } - - // Remove face from the faces vector - faces.erase(faces.begin() + face->index); - - // Deallocate face - delete face; -} - -void mesh::remove_edge(mesh::edge* edge) -{ - mesh::edge* ab = edge; - mesh::edge* ba = edge->symmetric; - mesh::vertex* a = ab->vertex; - mesh::edge* a_in = ab->previous; - mesh::edge* a_out = ba->next; - mesh::vertex* b = ba->vertex; - mesh::edge* b_in = ba->previous; - mesh::edge* b_out = ab->next; - - // Remove dependent faces - if (ab->face) - remove_face(ab->face); - if (ba->face) - remove_face(ba->face); - - // Re-link edges - if (a->edge == ab) - a->edge = (a_out == ab) ? nullptr : a_out; - if (b->edge == ba) - b->edge = (b_out == ba) ? nullptr : b_out; - a_in->next = a_out; - a_out->previous = a_in; - b_in->next = b_out; - b_out->previous = b_in; - - // Adjust indices of edges after this edge - for (std::size_t i = edge->index + 1; i < edges.size(); ++i) - { - --edges[i]->index; - --edges[i]->symmetric->index; - } - - // Remove edge from the edges vector - edges.erase(edges.begin() + edge->index); - - // Deallocate edge - delete edge->symmetric; - delete edge; -} - -void mesh::remove_vertex(mesh::vertex* vertex) -{ - // Remove connected edges - if (vertex->edge) - { - mesh::edge* current = nullptr; - mesh::edge* next = vertex->edge; - - do - { - current = next; - - next = next->symmetric->next; - if (next == current) - { - next = next->symmetric->next; - } - - remove_edge(current); - } - while (current != next); - } - - // Adjust indices of vertices after this vertex - for (std::size_t i = vertex->index + 1; i < vertices.size(); ++i) - { - --vertices[i]->index; - } - - // Remove vertex from the vertices vector - vertices.erase(vertices.begin() + vertex->index); - - // Deallocate vertex - delete vertex; -} - -mesh::edge* mesh::find_free_incident(mesh::vertex* vertex) const -{ - mesh::edge* begin = vertex->edge->symmetric; - mesh::edge* current = begin; - - do - { - if (!current->face) - { - return current; - } - - current = current->next->symmetric; - } - while (current != begin); - - return nullptr; -} - -mesh::edge* mesh::find_free_incident(mesh::edge* start_edge, mesh::edge* end_edge) const -{ - if (start_edge == end_edge) - { - return nullptr; - } - - mesh::edge* current = start_edge; - do - { - if (!current->face) - { - return current; - } - - current = current->next->symmetric; - } - while (current != end_edge); - - return nullptr; -} - -bool mesh::make_adjacent(mesh::edge* in, mesh::edge* out) -{ - if (in->next == out) - { - return true; - } - - mesh::edge* b = in->next; - mesh::edge* d = out->previous; - mesh::edge* g = find_free_incident(out->symmetric, in); - if (!g) - { - return false; - } - - mesh::edge* h = g->next; - - in->next = out; - out->previous = in; - - g->next = b; - b->previous = g; - - d->next = h; - h->previous = d; - - return true; -} - -} // namespace geom diff --git a/src/engine/geom/mesh.hpp b/src/engine/geom/mesh.hpp deleted file mode 100644 index 7138cdd..0000000 --- a/src/engine/geom/mesh.hpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_GEOM_MESH_HPP -#define ANTKEEPER_GEOM_MESH_HPP - -#include -#include - -namespace geom { - -/** - * Half-edge mesh. - * - * @see http://kaba.hilvi.org/homepage/blog/halfedge/halfedge.htm - */ -class mesh -{ -public: - struct vertex; - struct edge; - struct face; - - /** - * Half-edge mesh vertex, containing its index, a pointer to its parent edge, and its position vector. - */ - struct vertex - { - /// Index of this vertex. - std::size_t index; - - /// Pointer to the edge to which this vertex belongs. - mesh::edge* edge; - - /// Vertex position. - float3 position; - }; - - /** - * Half-edge mesh edge, containing its index and pointers to its starting vertex, parent face, and related edges. - */ - struct edge - { - /// Index of this edge. - std::size_t index; - - /// Pointer to the vertex at which the edge starts. - mesh::vertex* vertex; - - /// Pointer to the face on the left of this edge. - mesh::face* face; - - /// Pointer to the previous edge in the parent face. - mesh::edge* previous; - - /// Pointer to the next edge in the parent face. - mesh::edge* next; - - /// Pointer to the symmetric edge. - mesh::edge* symmetric; - }; - - /** - * Half-edge mesh face, containing its index and a pointer to its first edge. - */ - struct face - { - /// Index of this face. - std::size_t index; - - /// Pointer to the first edge in this face. - mesh::edge* edge; - }; - - /** - * List of edges which form a face. - */ - typedef std::vector loop; - - /** - * Constructs a mesh. - */ - constexpr mesh() noexcept = default; - - /** - * Copy-constructs a mesh. - */ - mesh(const mesh& other); - - /** - * Destructs a mesh. - */ - ~mesh() noexcept; - - /** - * Copies another mesh into this mesh. - * - * @param other Mesh to copy. - * - * @return Reference to this mesh. - */ - mesh& operator=(const mesh& other); - - /** - * Removes all vertices, edges, and faces from the mesh. - */ - void clear() noexcept; - - /** - * Adds a vertex to the mesh. - * - * @param position Position of the vertex. - * - * @return Pointer to the added vertex. - * - * @warning The added vertex will initially have a null edge. - */ - mesh::vertex* add_vertex(const float3& position); - - /** - * Adds two half edges to the mesh. - * - * @param a Vertex from which the edge originates. - * @param b Vertex at which the edge ends. - * - * @return Pointer to the half edge `ab`. The symmetric half edge `ba` can be accessed through `ab->symmetric`. - */ - mesh::edge* add_edge(mesh::vertex* a, mesh::vertex* b); - - /** - * Adds a face to the mesh. - * - * @param loop List of edges which form the face. - * @return Pointer to the added face. - * - * @exception std::runtime_error Empty edge loop. - * @exception std::runtime_error Disconnected edge loop. - * @exception std::runtime_error Non-manifold mesh 1. - * @exception std::runtime_error Non-manifold mesh 2. - */ - mesh::face* add_face(const loop& loop); - - /** - * Removes a face from the mesh. - * - * @param face Face to be removed. This face will be deallocated after removal. - */ - void remove_face(mesh::face* face); - - /** - * Removes an edge and all dependent faces from the mesh. - * - * @param edge Edge to be removed. This edge will be deallocated after removal. - */ - void remove_edge(mesh::edge* edge); - - /** - * Removes a vertex, all dependent edges, and all dependent faces from the mesh. - * - * @param vertex Vertex to be removed. This vertex will be deallocated after removal. - */ - void remove_vertex(mesh::vertex* vertex); - - /// Returns the mesh vertices. - const std::vector& get_vertices() const; - - /// Returns the mesh edges. - const std::vector& get_edges() const; - - /// Returns the mesh faces. - const std::vector& get_faces() const; - -private: - mesh::edge* find_free_incident(mesh::vertex* vertex) const; - mesh::edge* find_free_incident(mesh::edge* start_edge, mesh::edge* end_edge) const; - bool make_adjacent(mesh::edge* in_edge, mesh::edge* out_edge); - - std::vector vertices; - std::vector edges; - std::vector faces; -}; - -inline const std::vector& mesh::get_vertices() const -{ - return vertices; -} - -inline const std::vector& mesh::get_edges() const -{ - return edges; -} - -inline const std::vector& mesh::get_faces() const -{ - return faces; -} - -} // namespace geom - -#endif // ANTKEEPER_GEOM_MESH_HPP diff --git a/src/engine/geom/meshes/grid.cpp b/src/engine/geom/meshes/grid.cpp deleted file mode 100644 index b39c185..0000000 --- a/src/engine/geom/meshes/grid.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include -#include -#include -#include - -namespace geom { -namespace meshes { - -std::unique_ptr grid_xy(float length, std::size_t subdivisions_x, std::size_t subdivisions_y) -{ - // Allocate new mesh - std::unique_ptr mesh = std::make_unique(); - - // Determine vertex count and placement - std::size_t columns = subdivisions_x + 1; - std::size_t rows = subdivisions_y + 1; - float column_length = length / static_cast(columns); - float row_length = length / static_cast(rows); - - // Generate mesh vertices - float3 position; - position.z() = 0.0f; - position.y() = -length * 0.5f; - for (std::size_t i = 0; i <= rows; ++i) - { - position.x() = -length * 0.5f; - for (std::size_t j = 0; j <= columns; ++j) - { - mesh->add_vertex(position); - - position.x() += column_length; - } - - position.y() += row_length; - } - - // Function to eliminate duplicate edges - std::map, geom::mesh::edge*> edge_map; - auto add_or_find_edge = [&](geom::mesh::vertex* start, geom::mesh::vertex* end) -> geom::mesh::edge* - { - geom::mesh::edge* edge; - if (auto it = edge_map.find({start->index, end->index}); it != edge_map.end()) - { - edge = it->second; - } - else - { - edge = mesh->add_edge(start, end); - edge_map[{start->index, end->index}] = edge; - edge_map[{end->index, start->index}] = edge->symmetric; - } - - return edge; - }; - - // Connect vertices with edges and faces - const std::vector& vertices = mesh->get_vertices(); - for (std::size_t i = 0; i < rows; ++i) - { - for (std::size_t j = 0; j < columns; ++j) - { - geom::mesh::vertex* a = vertices[i * (columns + 1) + j]; - geom::mesh::vertex* b = vertices[(i + 1) * (columns + 1) + j]; - geom::mesh::vertex* c = vertices[i * (columns + 1) + j + 1]; - geom::mesh::vertex* d = vertices[(i + 1) * (columns + 1) + j + 1]; - - // a---c - // | | - // b---d - geom::mesh::edge* ab = add_or_find_edge(a, b); - geom::mesh::edge* bd = add_or_find_edge(b, d); - geom::mesh::edge* dc = add_or_find_edge(d, c); - geom::mesh::edge* ca = add_or_find_edge(c, a); - - mesh->add_face({ab, bd, dc, ca}); - } - } - - return mesh; -} - -} // namespace meshes -} // namespace geom diff --git a/src/engine/geom/morton.hpp b/src/engine/geom/morton.hpp index c4a04f3..dd040d3 100644 --- a/src/engine/geom/morton.hpp +++ b/src/engine/geom/morton.hpp @@ -24,9 +24,6 @@ namespace geom { -/// Morton location code encoding and decoding functions. -namespace morton { - /** * Encodes 2D coordinates as a Morton location code. * @@ -36,18 +33,24 @@ namespace morton { * @return Morton location code. */ template -constexpr T encode(T x, T y) noexcept +constexpr T morton_encode(T x, T y) noexcept { auto expand = [](T x) -> T { x &= (1 << (sizeof(T) << 2)) - 1; if constexpr(sizeof(T) >= 8) + { x = (x ^ (x << 16)) & T(0x0000ffff0000ffff); + } if constexpr(sizeof(T) >= 4) + { x = (x ^ (x << 8)) & T(0x00ff00ff00ff00ff); + } if constexpr(sizeof(T) >= 2) + { x = (x ^ (x << 4)) & T(0x0f0f0f0f0f0f0f0f); + } x = (x ^ (x << 2)) & T(0x3333333333333333); x = (x ^ (x << 1)) & T(0x5555555555555555); @@ -68,38 +71,38 @@ constexpr T encode(T x, T y) noexcept * @return Morton location code. */ template -constexpr T encode(T x, T y, T z) noexcept +constexpr T morton_encode(T x, T y, T z) noexcept { auto expand = [](T x) -> T { if constexpr(sizeof(T) == 1) { - x &= 0x3; - x = (x | x << 2) & 0x9; + x &= T(0x3); + x = (x | x << 2) & T(0x9); } else if constexpr(sizeof(T) == 2) { - x &= 0x001f; - x = (x | x << 8) & 0x100f; - x = (x | x << 4) & 0x10c3; - x = (x | x << 2) & 0x1249; + x &= T(0x001f); + x = (x | x << 8) & T(0x100f); + x = (x | x << 4) & T(0x10c3); + x = (x | x << 2) & T(0x1249); } else if constexpr(sizeof(T) == 4) { - x &= 0x00003ff; - x = (x | x << 16) & 0x30000ff; - x = (x | x << 8) & 0x300f00f; - x = (x | x << 4) & 0x30c30c3; - x = (x | x << 2) & 0x9249249; + x &= T(0x00003ff); + x = (x | x << 16) & T(0x30000ff); + x = (x | x << 8) & T(0x300f00f); + x = (x | x << 4) & T(0x30c30c3); + x = (x | x << 2) & T(0x9249249); } else if constexpr(sizeof(T) == 8) { - x &= 0x00000000001fffff; - x = (x | x << 32) & 0x001f00000000ffff; - x = (x | x << 16) & 0x001f0000ff0000ff; - x = (x | x << 8) & 0x100f00f00f00f00f; - x = (x | x << 4) & 0x10c30c30c30c30c3; - x = (x | x << 2) & 0x1249249249249249; + x &= T(0x00000000001fffff); + x = (x | x << 32) & T(0x001f00000000ffff); + x = (x | x << 16) & T(0x001f0000ff0000ff); + x = (x | x << 8) & T(0x100f00f00f00f00f); + x = (x | x << 4) & T(0x10c30c30c30c30c3); + x = (x | x << 2) & T(0x1249249249249249); } return x; @@ -116,21 +119,26 @@ constexpr T encode(T x, T y, T z) noexcept * @param[out] y Decoded y-coordinate. */ template -void decode(T code, T& x, T& y) noexcept +void morton_decode(T code, T& x, T& y) noexcept { auto compress = [](T x) -> T { - x &= T(0x5555555555555555); - + x &= T(0x5555555555555555); x = (x ^ (x >> 1)) & T(0x3333333333333333); x = (x ^ (x >> 2)) & T(0x0f0f0f0f0f0f0f0f); if constexpr(sizeof(T) >= 2) + { x = (x ^ (x >> 4)) & T(0x00ff00ff00ff00ff); + } if constexpr(sizeof(T) >= 4) + { x = (x ^ (x >> 8)) & T(0x0000ffff0000ffff); + } if constexpr(sizeof(T) >= 8) + { x = (x ^ (x >> 16)) & T(0x00000000ffffffff); + } return x; }; @@ -148,38 +156,38 @@ void decode(T code, T& x, T& y) noexcept * @param[out] z Decoded z-coordinate. */ template -void decode(T code, T& x, T& y, T& z) noexcept +void morton_decode(T code, T& x, T& y, T& z) noexcept { auto compress = [](T x) -> T { if constexpr(sizeof(T) == 1) { - x &= 0x9; - x = (x ^ x >> 2) & 0x3; + x &= T(0x9); + x = (x ^ x >> 2) & T(0x3); } else if constexpr(sizeof(T) == 2) { - x &= 0x1249; - x = (x ^ x >> 2) & 0x10c3; - x = (x ^ x >> 4) & 0x100f; - x = (x ^ x >> 8) & 0x001f; + x &= T(0x1249); + x = (x ^ x >> 2) & T(0x10c3); + x = (x ^ x >> 4) & T(0x100f); + x = (x ^ x >> 8) & T(0x001f); } else if constexpr(sizeof(T) == 4) { - x &= 0x9249249; - x = (x ^ x >> 2) & 0x30c30c3; - x = (x ^ x >> 4) & 0x300f00f; - x = (x ^ x >> 8) & 0x30000ff; - x = (x ^ x >> 16) & 0x00003ff; + x &= T(0x9249249); + x = (x ^ x >> 2) & T(0x30c30c3); + x = (x ^ x >> 4) & T(0x300f00f); + x = (x ^ x >> 8) & T(0x30000ff); + x = (x ^ x >> 16) & T(0x00003ff); } else if constexpr(sizeof(T) == 8) { - x &= 0x1249249249249249; - x = (x ^ x >> 2) & 0x10c30c30c30c30c3; - x = (x ^ x >> 4) & 0x100f00f00f00f00f; - x = (x ^ x >> 8) & 0x001f0000ff0000ff; - x = (x ^ x >> 16) & 0x001f00000000ffff; - x = (x ^ x >> 32) & 0x00000000001fffff; + x &= T(0x1249249249249249); + x = (x ^ x >> 2) & T(0x10c30c30c30c30c3); + x = (x ^ x >> 4) & T(0x100f00f00f00f00f); + x = (x ^ x >> 8) & T(0x001f0000ff0000ff); + x = (x ^ x >> 16) & T(0x001f00000000ffff); + x = (x ^ x >> 32) & T(0x00000000001fffff); } return x; @@ -190,7 +198,6 @@ void decode(T code, T& x, T& y, T& z) noexcept z = compress(code >> 2); } -} // namespace morton } // namespace geom #endif // ANTKEEPER_GEOM_MORTON_HPP diff --git a/src/engine/geom/primitives/hyperrectangle.hpp b/src/engine/geom/primitives/hyperrectangle.hpp index 0644ab9..68e13bd 100644 --- a/src/engine/geom/primitives/hyperrectangle.hpp +++ b/src/engine/geom/primitives/hyperrectangle.hpp @@ -22,7 +22,6 @@ #include #include -#include namespace geom { namespace primitives { @@ -156,18 +155,19 @@ struct hyperrectangle } /** - * Returns `false` if any coordinates of `min` are greater than `max`. + * Returns `true` if any coordinates of `min` are greater than `max`, `false` otherwise. */ - [[nodiscard]] constexpr bool valid() const noexcept + [[nodiscard]] constexpr bool degenerate() const noexcept { for (std::size_t i = 0; i < N; ++i) { if (min[i] > max[i]) { - return false; + return true; } } - return true; + + return false; } /// Calculates the volume of the hyperrectangle. diff --git a/src/engine/geom/primitives/view-frustum.hpp b/src/engine/geom/primitives/view-frustum.hpp index 0610c29..6a5123b 100644 --- a/src/engine/geom/primitives/view-frustum.hpp +++ b/src/engine/geom/primitives/view-frustum.hpp @@ -38,13 +38,13 @@ template struct view_frustum { /// Vector type. - using vector_type = math::vector; + using vector_type = math::vec3; /// Plane type. using plane_type = geom::plane; /// View-projection matrix type. - using matrix_type = math::matrix; + using matrix_type = math::mat4; /// Box type. using box_type = geom::box; diff --git a/src/engine/geom/projection.hpp b/src/engine/geom/projection.hpp index d49c476..e368246 100644 --- a/src/engine/geom/projection.hpp +++ b/src/engine/geom/projection.hpp @@ -25,7 +25,7 @@ namespace geom { template -math::vector project_on_plane(const math::vector& v, const math::vector& p, const math::vector& n) +math::vec3 project_on_plane(const math::vec3& v, const math::vec3& p, const math::vec3& n) { return v - n * math::dot(v - p, n); } diff --git a/src/engine/geom/sdf.hpp b/src/engine/geom/sdf.hpp index 525b806..0e4551a 100644 --- a/src/engine/geom/sdf.hpp +++ b/src/engine/geom/sdf.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GEOM_SDF_HPP #define ANTKEEPER_GEOM_SDF_HPP -#include +#include #include namespace geom { @@ -28,21 +28,21 @@ namespace geom { /// Signed distance functions. namespace sdf { -inline float3 translate(const float3& sample, const float3& offset) +inline math::fvec3 translate(const math::fvec3& sample, const math::fvec3& offset) { return sample - offset; } -inline float sphere(const float3& p, float r) +inline float sphere(const math::fvec3& p, float r) { return math::length(p) - r; } -inline float cylinder(const float3& p, float r, float h) +inline float cylinder(const math::fvec3& p, float r, float h) { float dx = std::abs(math::length(math::swizzle<0, 2>(p))) - r; float dy = std::abs(p[1]) - h; - return std::min(std::max(dx, dy), 0.0f) + math::length(float2{std::max(dx, 0.0f), std::max(dy, 0.0f)}); + return std::min(std::max(dx, dy), 0.0f) + math::length(math::fvec2{std::max(dx, 0.0f), std::max(dy, 0.0f)}); } inline float op_union(float a, float b) diff --git a/src/engine/geom/spherical.hpp b/src/engine/geom/spherical.hpp index 3881665..36d387d 100644 --- a/src/engine/geom/spherical.hpp +++ b/src/engine/geom/spherical.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GEOM_SPHERICAL_HPP #define ANTKEEPER_GEOM_SPHERICAL_HPP -#include +#include #include namespace geom { @@ -37,14 +37,14 @@ namespace spherical { * @see geom::coordinates::cartesian */ template -math::vector3 to_cartesian(const math::vector3& v); +math::vec3 to_cartesian(const math::vec3& v); template -math::vector3 to_cartesian(const math::vector3& v) +math::vec3 to_cartesian(const math::vec3& v) { const T x = v[0] * std::cos(v[1]); - return math::vector3 + return math::vec3 { x * std::cos(v[2]), x * std::sin(v[2]), diff --git a/src/engine/gl/opengl/gl-shader-variables.cpp b/src/engine/gl/opengl/gl-shader-variables.cpp index e2b7034..0cde5bb 100644 --- a/src/engine/gl/opengl/gl-shader-variables.cpp +++ b/src/engine/gl/opengl/gl-shader-variables.cpp @@ -52,23 +52,23 @@ void gl_shader_bool::update(std::span values, std::size_t index) con glUniform1iv(gl_uniform_location + static_cast(index), static_cast(values.size()), ivalues.data()); } -gl_shader_bool2::gl_shader_bool2(std::size_t size, GLint gl_uniform_location): +gl_shader_bvec2::gl_shader_bvec2(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location}, ivalues(size * 2) {} -void gl_shader_bool2::update(const bool2& value) const noexcept +void gl_shader_bvec2::update(const math::bvec2& value) const noexcept { glUniform2i(gl_uniform_location, static_cast(value[0]), static_cast(value[1])); } -void gl_shader_bool2::update(const bool2& value, std::size_t index) const +void gl_shader_bvec2::update(const math::bvec2& value, std::size_t index) const { glUniform2i(gl_uniform_location + static_cast(index), static_cast(value[0]), static_cast(value[1])); } -void gl_shader_bool2::update(std::span values, std::size_t index) const +void gl_shader_bvec2::update(std::span values, std::size_t index) const { GLint* ivalue = ivalues.data(); for (const auto& value: values) @@ -80,23 +80,23 @@ void gl_shader_bool2::update(std::span values, std::size_t index) c glUniform2iv(gl_uniform_location + static_cast(index), static_cast(values.size()), ivalues.data()); } -gl_shader_bool3::gl_shader_bool3(std::size_t size, GLint gl_uniform_location): +gl_shader_bvec3::gl_shader_bvec3(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location}, ivalues(size * 3) {} -void gl_shader_bool3::update(const bool3& value) const noexcept +void gl_shader_bvec3::update(const math::bvec3& value) const noexcept { glUniform3i(gl_uniform_location, static_cast(value[0]), static_cast(value[1]), static_cast(value[2])); } -void gl_shader_bool3::update(const bool3& value, std::size_t index) const +void gl_shader_bvec3::update(const math::bvec3& value, std::size_t index) const { glUniform3i(gl_uniform_location + static_cast(index), static_cast(value[0]), static_cast(value[1]), static_cast(value[2])); } -void gl_shader_bool3::update(std::span values, std::size_t index) const +void gl_shader_bvec3::update(std::span values, std::size_t index) const { GLint* ivalue = ivalues.data(); for (const auto& value: values) @@ -109,23 +109,23 @@ void gl_shader_bool3::update(std::span values, std::size_t index) c glUniform3iv(gl_uniform_location + static_cast(index), static_cast(values.size()), ivalues.data()); } -gl_shader_bool4::gl_shader_bool4(std::size_t size, GLint gl_uniform_location): +gl_shader_bvec4::gl_shader_bvec4(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location}, ivalues(size * 4) {} -void gl_shader_bool4::update(const bool4& value) const noexcept +void gl_shader_bvec4::update(const math::bvec4& value) const noexcept { glUniform4i(gl_uniform_location, static_cast(value[0]), static_cast(value[1]), static_cast(value[2]), static_cast(value[3])); } -void gl_shader_bool4::update(const bool4& value, std::size_t index) const +void gl_shader_bvec4::update(const math::bvec4& value, std::size_t index) const { glUniform4i(gl_uniform_location + static_cast(index), static_cast(value[0]), static_cast(value[1]), static_cast(value[2]), static_cast(value[3])); } -void gl_shader_bool4::update(std::span values, std::size_t index) const +void gl_shader_bvec4::update(std::span values, std::size_t index) const { GLint* ivalue = ivalues.data(); for (const auto& value: values) @@ -159,62 +159,62 @@ void gl_shader_int::update(std::span values, std::size_t index) const glUniform1iv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()); } -gl_shader_int2::gl_shader_int2(std::size_t size, GLint gl_uniform_location): +gl_shader_ivec2::gl_shader_ivec2(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_int2::update(const int2& value) const noexcept +void gl_shader_ivec2::update(const math::ivec2& value) const noexcept { glUniform2iv(gl_uniform_location, 1, value.data()); } -void gl_shader_int2::update(const int2& value, std::size_t index) const +void gl_shader_ivec2::update(const math::ivec2& value, std::size_t index) const { glUniform2iv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_int2::update(std::span values, std::size_t index) const +void gl_shader_ivec2::update(std::span values, std::size_t index) const { glUniform2iv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_int3::gl_shader_int3(std::size_t size, GLint gl_uniform_location): +gl_shader_ivec3::gl_shader_ivec3(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_int3::update(const int3& value) const noexcept +void gl_shader_ivec3::update(const math::ivec3& value) const noexcept { glUniform3iv(gl_uniform_location, 1, value.data()); } -void gl_shader_int3::update(const int3& value, std::size_t index) const +void gl_shader_ivec3::update(const math::ivec3& value, std::size_t index) const { glUniform3iv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_int3::update(std::span values, std::size_t index) const +void gl_shader_ivec3::update(std::span values, std::size_t index) const { glUniform3iv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_int4::gl_shader_int4(std::size_t size, GLint gl_uniform_location): +gl_shader_ivec4::gl_shader_ivec4(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_int4::update(const int4& value) const noexcept +void gl_shader_ivec4::update(const math::ivec4& value) const noexcept { glUniform4iv(gl_uniform_location, 1, value.data()); } -void gl_shader_int4::update(const int4& value, std::size_t index) const +void gl_shader_ivec4::update(const math::ivec4& value, std::size_t index) const { glUniform4iv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_int4::update(std::span values, std::size_t index) const +void gl_shader_ivec4::update(std::span values, std::size_t index) const { glUniform4iv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } @@ -239,62 +239,62 @@ void gl_shader_uint::update(std::span values, std::size_t in glUniform1uiv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()); } -gl_shader_uint2::gl_shader_uint2(std::size_t size, GLint gl_uniform_location): +gl_shader_uvec2::gl_shader_uvec2(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_uint2::update(const uint2& value) const noexcept +void gl_shader_uvec2::update(const math::uvec2& value) const noexcept { glUniform2uiv(gl_uniform_location, 1, value.data()); } -void gl_shader_uint2::update(const uint2& value, std::size_t index) const +void gl_shader_uvec2::update(const math::uvec2& value, std::size_t index) const { glUniform2uiv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_uint2::update(std::span values, std::size_t index) const +void gl_shader_uvec2::update(std::span values, std::size_t index) const { glUniform2uiv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_uint3::gl_shader_uint3(std::size_t size, GLint gl_uniform_location): +gl_shader_uvec3::gl_shader_uvec3(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_uint3::update(const uint3& value) const noexcept +void gl_shader_uvec3::update(const math::uvec3& value) const noexcept { glUniform3uiv(gl_uniform_location, 1, value.data()); } -void gl_shader_uint3::update(const uint3& value, std::size_t index) const +void gl_shader_uvec3::update(const math::uvec3& value, std::size_t index) const { glUniform3uiv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_uint3::update(std::span values, std::size_t index) const +void gl_shader_uvec3::update(std::span values, std::size_t index) const { glUniform3uiv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_uint4::gl_shader_uint4(std::size_t size, GLint gl_uniform_location): +gl_shader_uvec4::gl_shader_uvec4(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_uint4::update(const uint4& value) const noexcept +void gl_shader_uvec4::update(const math::uvec4& value) const noexcept { glUniform4uiv(gl_uniform_location, 1, value.data()); } -void gl_shader_uint4::update(const uint4& value, std::size_t index) const +void gl_shader_uvec4::update(const math::uvec4& value, std::size_t index) const { glUniform4uiv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_uint4::update(std::span values, std::size_t index) const +void gl_shader_uvec4::update(std::span values, std::size_t index) const { glUniform4uiv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } @@ -319,122 +319,122 @@ void gl_shader_float::update(std::span values, std::size_t index) c glUniform1fv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()); } -gl_shader_float2::gl_shader_float2(std::size_t size, GLint gl_uniform_location): +gl_shader_fvec2::gl_shader_fvec2(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_float2::update(const float2& value) const noexcept +void gl_shader_fvec2::update(const math::fvec2& value) const noexcept { glUniform2fv(gl_uniform_location, 1, value.data()); } -void gl_shader_float2::update(const float2& value, std::size_t index) const +void gl_shader_fvec2::update(const math::fvec2& value, std::size_t index) const { glUniform2fv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_float2::update(std::span values, std::size_t index) const +void gl_shader_fvec2::update(std::span values, std::size_t index) const { glUniform2fv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_float3::gl_shader_float3(std::size_t size, GLint gl_uniform_location): +gl_shader_fvec3::gl_shader_fvec3(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_float3::update(const float3& value) const noexcept +void gl_shader_fvec3::update(const math::fvec3& value) const noexcept { glUniform3fv(gl_uniform_location, 1, value.data()); } -void gl_shader_float3::update(const float3& value, std::size_t index) const +void gl_shader_fvec3::update(const math::fvec3& value, std::size_t index) const { glUniform3fv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_float3::update(std::span values, std::size_t index) const +void gl_shader_fvec3::update(std::span values, std::size_t index) const { glUniform3fv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_float4::gl_shader_float4(std::size_t size, GLint gl_uniform_location): +gl_shader_fvec4::gl_shader_fvec4(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_float4::update(const float4& value) const noexcept +void gl_shader_fvec4::update(const math::fvec4& value) const noexcept { glUniform4fv(gl_uniform_location, 1, value.data()); } -void gl_shader_float4::update(const float4& value, std::size_t index) const +void gl_shader_fvec4::update(const math::fvec4& value, std::size_t index) const { glUniform4fv(gl_uniform_location + static_cast(index), 1, value.data()); } -void gl_shader_float4::update(std::span values, std::size_t index) const +void gl_shader_fvec4::update(std::span values, std::size_t index) const { glUniform4fv(gl_uniform_location + static_cast(index), static_cast(values.size()), values.data()->data()); } -gl_shader_float2x2::gl_shader_float2x2(std::size_t size, GLint gl_uniform_location): +gl_shader_fmat2::gl_shader_fmat2(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_float2x2::update(const float2x2& value) const noexcept +void gl_shader_fmat2::update(const math::fmat2& value) const noexcept { glUniformMatrix2fv(gl_uniform_location, 1, GL_FALSE, value.data()); } -void gl_shader_float2x2::update(const float2x2& value, std::size_t index) const +void gl_shader_fmat2::update(const math::fmat2& value, std::size_t index) const { glUniformMatrix2fv(gl_uniform_location + static_cast(index) * 2, 1, GL_FALSE, value.data()); } -void gl_shader_float2x2::update(std::span values, std::size_t index) const +void gl_shader_fmat2::update(std::span values, std::size_t index) const { glUniformMatrix2fv(gl_uniform_location + static_cast(index) * 2, static_cast(values.size()), GL_FALSE, values.data()->data()); } -gl_shader_float3x3::gl_shader_float3x3(std::size_t size, GLint gl_uniform_location): +gl_shader_fmat3::gl_shader_fmat3(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_float3x3::update(const float3x3& value) const noexcept +void gl_shader_fmat3::update(const math::fmat3& value) const noexcept { glUniformMatrix3fv(gl_uniform_location, 1, GL_FALSE, value.data()); } -void gl_shader_float3x3::update(const float3x3& value, std::size_t index) const +void gl_shader_fmat3::update(const math::fmat3& value, std::size_t index) const { glUniformMatrix3fv(gl_uniform_location + static_cast(index) * 3, 1, GL_FALSE, value.data()); } -void gl_shader_float3x3::update(std::span values, std::size_t index) const +void gl_shader_fmat3::update(std::span values, std::size_t index) const { glUniformMatrix3fv(gl_uniform_location + static_cast(index) * 3, static_cast(values.size()), GL_FALSE, values.data()->data()); } -gl_shader_float4x4::gl_shader_float4x4(std::size_t size, GLint gl_uniform_location): +gl_shader_fmat4::gl_shader_fmat4(std::size_t size, GLint gl_uniform_location): shader_variable(size), gl_uniform_location{gl_uniform_location} {} -void gl_shader_float4x4::update(const float4x4& value) const noexcept +void gl_shader_fmat4::update(const math::fmat4& value) const noexcept { glUniformMatrix4fv(gl_uniform_location, 1, GL_FALSE, value.data()); } -void gl_shader_float4x4::update(const float4x4& value, std::size_t index) const +void gl_shader_fmat4::update(const math::fmat4& value, std::size_t index) const { glUniformMatrix4fv(gl_uniform_location + static_cast(index) * 4, 1, GL_FALSE, value.data()); } -void gl_shader_float4x4::update(std::span values, std::size_t index) const +void gl_shader_fmat4::update(std::span values, std::size_t index) const { glUniformMatrix4fv(gl_uniform_location + static_cast(index) * 4, static_cast(values.size()), GL_FALSE, values.data()->data()); } diff --git a/src/engine/gl/opengl/gl-shader-variables.hpp b/src/engine/gl/opengl/gl-shader-variables.hpp index b1f3a80..0b555f5 100644 --- a/src/engine/gl/opengl/gl-shader-variables.hpp +++ b/src/engine/gl/opengl/gl-shader-variables.hpp @@ -36,7 +36,7 @@ public: [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::bool1; + return shader_variable_type::bvec1; } void update(bool value) const noexcept override; @@ -51,19 +51,19 @@ private: /** * 2-dimensional boolean vector shader variable implementation using OpenGL. */ -class gl_shader_bool2: public shader_variable +class gl_shader_bvec2: public shader_variable { public: - gl_shader_bool2(std::size_t size, GLint gl_uniform_location); + gl_shader_bvec2(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::bool2; + return shader_variable_type::bvec2; } - void update(const bool2& value) const noexcept override; - void update(const bool2& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::bvec2& value) const noexcept override; + void update(const math::bvec2& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -73,19 +73,19 @@ private: /** * 3-dimensional boolean vector shader variable implementation using OpenGL. */ -class gl_shader_bool3: public shader_variable +class gl_shader_bvec3: public shader_variable { public: - gl_shader_bool3(std::size_t size, GLint gl_uniform_location); + gl_shader_bvec3(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::bool3; + return shader_variable_type::bvec3; } - void update(const bool3& value) const noexcept override; - void update(const bool3& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::bvec3& value) const noexcept override; + void update(const math::bvec3& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -95,19 +95,19 @@ private: /** * 4-dimensional boolean vector shader variable implementation using OpenGL. */ -class gl_shader_bool4: public shader_variable +class gl_shader_bvec4: public shader_variable { public: - gl_shader_bool4(std::size_t size, GLint gl_uniform_location); + gl_shader_bvec4(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::bool4; + return shader_variable_type::bvec4; } - void update(const bool4& value) const noexcept override; - void update(const bool4& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::bvec4& value) const noexcept override; + void update(const math::bvec4& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -124,7 +124,7 @@ public: [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::int1; + return shader_variable_type::ivec1; } void update(int value) const noexcept override; @@ -138,19 +138,19 @@ private: /** * 2-dimensional signed integer vector shader variable implementation using OpenGL. */ -class gl_shader_int2: public shader_variable +class gl_shader_ivec2: public shader_variable { public: - gl_shader_int2(std::size_t size, GLint gl_uniform_location); + gl_shader_ivec2(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::int2; + return shader_variable_type::ivec2; } - void update(const int2& value) const noexcept override; - void update(const int2& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::ivec2& value) const noexcept override; + void update(const math::ivec2& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -159,19 +159,19 @@ private: /** * 3-dimensional signed integer vector shader variable implementation using OpenGL. */ -class gl_shader_int3: public shader_variable +class gl_shader_ivec3: public shader_variable { public: - gl_shader_int3(std::size_t size, GLint gl_uniform_location); + gl_shader_ivec3(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::int3; + return shader_variable_type::ivec3; } - void update(const int3& value) const noexcept override; - void update(const int3& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::ivec3& value) const noexcept override; + void update(const math::ivec3& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -180,19 +180,19 @@ private: /** * 4-dimensional signed integer vector shader variable implementation using OpenGL. */ -class gl_shader_int4: public shader_variable +class gl_shader_ivec4: public shader_variable { public: - gl_shader_int4(std::size_t size, GLint gl_uniform_location); + gl_shader_ivec4(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::int4; + return shader_variable_type::ivec4; } - void update(const int4& value) const noexcept override; - void update(const int4& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::ivec4& value) const noexcept override; + void update(const math::ivec4& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -208,7 +208,7 @@ public: [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::uint1; + return shader_variable_type::uvec1; } void update(unsigned int value) const noexcept override; @@ -222,19 +222,19 @@ private: /** * 2-dimensional unsigned integer vector shader variable implementation using OpenGL. */ -class gl_shader_uint2: public shader_variable +class gl_shader_uvec2: public shader_variable { public: - gl_shader_uint2(std::size_t size, GLint gl_uniform_location); + gl_shader_uvec2(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::uint2; + return shader_variable_type::uvec2; } - void update(const uint2& value) const noexcept override; - void update(const uint2& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::uvec2& value) const noexcept override; + void update(const math::uvec2& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -243,19 +243,19 @@ private: /** * 3-dimensional unsigned integer vector shader variable implementation using OpenGL. */ -class gl_shader_uint3: public shader_variable +class gl_shader_uvec3: public shader_variable { public: - gl_shader_uint3(std::size_t size, GLint gl_uniform_location); + gl_shader_uvec3(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::uint3; + return shader_variable_type::uvec3; } - void update(const uint3& value) const noexcept override; - void update(const uint3& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::uvec3& value) const noexcept override; + void update(const math::uvec3& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -264,19 +264,19 @@ private: /** * 4-dimensional unsigned integer vector shader variable implementation using OpenGL. */ -class gl_shader_uint4: public shader_variable +class gl_shader_uvec4: public shader_variable { public: - gl_shader_uint4(std::size_t size, GLint gl_uniform_location); + gl_shader_uvec4(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::uint4; + return shader_variable_type::uvec4; } - void update(const uint4& value) const noexcept override; - void update(const uint4& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::uvec4& value) const noexcept override; + void update(const math::uvec4& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -292,7 +292,7 @@ public: [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float1; + return shader_variable_type::fvec1; } void update(float value) const noexcept override; @@ -306,19 +306,19 @@ private: /** * 2-dimensional floating-point vector shader variable implementation using OpenGL. */ -class gl_shader_float2: public shader_variable +class gl_shader_fvec2: public shader_variable { public: - gl_shader_float2(std::size_t size, GLint gl_uniform_location); + gl_shader_fvec2(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float2; + return shader_variable_type::fvec2; } - void update(const float2& value) const noexcept override; - void update(const float2& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::fvec2& value) const noexcept override; + void update(const math::fvec2& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -327,19 +327,19 @@ private: /** * 3-dimensional floating-point vector shader variable implementation using OpenGL. */ -class gl_shader_float3: public shader_variable +class gl_shader_fvec3: public shader_variable { public: - gl_shader_float3(std::size_t size, GLint gl_uniform_location); + gl_shader_fvec3(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float3; + return shader_variable_type::fvec3; } - void update(const float3& value) const noexcept override; - void update(const float3& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::fvec3& value) const noexcept override; + void update(const math::fvec3& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -348,19 +348,19 @@ private: /** * 4-dimensional floating-point vector shader variable implementation using OpenGL. */ -class gl_shader_float4: public shader_variable +class gl_shader_fvec4: public shader_variable { public: - gl_shader_float4(std::size_t size, GLint gl_uniform_location); + gl_shader_fvec4(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float4; + return shader_variable_type::fvec4; } - void update(const float4& value) const noexcept override; - void update(const float4& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::fvec4& value) const noexcept override; + void update(const math::fvec4& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -369,19 +369,19 @@ private: /** * 2x2 floating-point matrix shader variable implementation using OpenGL. */ -class gl_shader_float2x2: public shader_variable +class gl_shader_fmat2: public shader_variable { public: - gl_shader_float2x2(std::size_t size, GLint gl_uniform_location); + gl_shader_fmat2(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float2x2; + return shader_variable_type::fmat2; } - void update(const float2x2& value) const noexcept override; - void update(const float2x2& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::fmat2& value) const noexcept override; + void update(const math::fmat2& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -390,19 +390,19 @@ private: /** * 3x3 floating-point matrix shader variable implementation using OpenGL. */ -class gl_shader_float3x3: public shader_variable +class gl_shader_fmat3: public shader_variable { public: - gl_shader_float3x3(std::size_t size, GLint gl_uniform_location); + gl_shader_fmat3(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float3x3; + return shader_variable_type::fmat3; } - void update(const float3x3& value) const noexcept override; - void update(const float3x3& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::fmat3& value) const noexcept override; + void update(const math::fmat3& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; @@ -411,19 +411,19 @@ private: /** * 4x4 floating-point matrix shader variable implementation using OpenGL. */ -class gl_shader_float4x4: public shader_variable +class gl_shader_fmat4: public shader_variable { public: - gl_shader_float4x4(std::size_t size, GLint gl_uniform_location); + gl_shader_fmat4(std::size_t size, GLint gl_uniform_location); [[nodiscard]] inline constexpr shader_variable_type type() const noexcept override { - return shader_variable_type::float4x4; + return shader_variable_type::fmat4; } - void update(const float4x4& value) const noexcept override; - void update(const float4x4& value, std::size_t index) const override; - void update(std::span values, std::size_t index = 0) const override; + void update(const math::fmat4& value) const noexcept override; + void update(const math::fmat4& value, std::size_t index) const override; + void update(std::span values, std::size_t index = 0) const override; private: GLint gl_uniform_location; diff --git a/src/engine/gl/shader-program.cpp b/src/engine/gl/shader-program.cpp index d61c807..ed2fdef 100644 --- a/src/engine/gl/shader-program.cpp +++ b/src/engine/gl/shader-program.cpp @@ -234,62 +234,62 @@ void shader_program::load_variables() variable = std::make_unique(variable_size, uniform_location); break; case GL_BOOL_VEC2: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_BOOL_VEC3: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_BOOL_VEC4: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_INT: variable = std::make_unique(variable_size, uniform_location); break; case GL_INT_VEC2: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_INT_VEC3: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_INT_VEC4: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_UNSIGNED_INT: variable = std::make_unique(variable_size, uniform_location); break; case GL_UNSIGNED_INT_VEC2: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_UNSIGNED_INT_VEC3: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_UNSIGNED_INT_VEC4: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT: variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT_VEC2: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT_VEC3: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT_VEC4: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT_MAT2: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT_MAT3: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_FLOAT_MAT4: - variable = std::make_unique(variable_size, uniform_location); + variable = std::make_unique(variable_size, uniform_location); break; case GL_SAMPLER_1D: diff --git a/src/engine/gl/shader-variable-type.hpp b/src/engine/gl/shader-variable-type.hpp index 76287bc..49e564a 100644 --- a/src/engine/gl/shader-variable-type.hpp +++ b/src/engine/gl/shader-variable-type.hpp @@ -29,25 +29,25 @@ namespace gl { */ enum class shader_variable_type: std::uint8_t { - bool1, - bool2, - bool3, - bool4, - int1, - int2, - int3, - int4, - uint1, - uint2, - uint3, - uint4, - float1, - float2, - float3, - float4, - float2x2, - float3x3, - float4x4, + bvec1, + bvec2, + bvec3, + bvec4, + ivec1, + ivec2, + ivec3, + ivec4, + uvec1, + uvec2, + uvec3, + uvec4, + fvec1, + fvec2, + fvec3, + fvec4, + fmat2, + fmat3, + fmat4, texture_1d, texture_2d, texture_3d, diff --git a/src/engine/gl/shader-variable.cpp b/src/engine/gl/shader-variable.cpp index 6f238e8..dd5db2f 100644 --- a/src/engine/gl/shader-variable.cpp +++ b/src/engine/gl/shader-variable.cpp @@ -33,17 +33,17 @@ void shader_variable::update(bool value) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const bool2& value) const +void shader_variable::update(const math::bvec2& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const bool3& value) const +void shader_variable::update(const math::bvec3& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const bool4& value) const +void shader_variable::update(const math::bvec4& value) const { throw std::invalid_argument(type_mismatch_error); } @@ -53,17 +53,17 @@ void shader_variable::update(int value) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const int2& value) const +void shader_variable::update(const math::ivec2& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const int3& value) const +void shader_variable::update(const math::ivec3& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const int4& value) const +void shader_variable::update(const math::ivec4& value) const { throw std::invalid_argument(type_mismatch_error); } @@ -73,17 +73,17 @@ void shader_variable::update(unsigned int value) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const uint2& value) const +void shader_variable::update(const math::uvec2& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const uint3& value) const +void shader_variable::update(const math::uvec3& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const uint4& value) const +void shader_variable::update(const math::uvec4& value) const { throw std::invalid_argument(type_mismatch_error); } @@ -93,32 +93,32 @@ void shader_variable::update(float value) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float2& value) const +void shader_variable::update(const math::fvec2& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float3& value) const +void shader_variable::update(const math::fvec3& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float4& value) const +void shader_variable::update(const math::fvec4& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float2x2& value) const +void shader_variable::update(const math::fmat2& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float3x3& value) const +void shader_variable::update(const math::fmat3& value) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float4x4& value) const +void shader_variable::update(const math::fmat4& value) const { throw std::invalid_argument(type_mismatch_error); } @@ -148,17 +148,17 @@ void shader_variable::update(bool value, std::size_t index) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const bool2& value, std::size_t index) const +void shader_variable::update(const math::bvec2& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const bool3& value, std::size_t index) const +void shader_variable::update(const math::bvec3& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const bool4& value, std::size_t index) const +void shader_variable::update(const math::bvec4& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -168,17 +168,17 @@ void shader_variable::update(int value, std::size_t index) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const int2& value, std::size_t index) const +void shader_variable::update(const math::ivec2& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const int3& value, std::size_t index) const +void shader_variable::update(const math::ivec3& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const int4& value, std::size_t index) const +void shader_variable::update(const math::ivec4& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -188,17 +188,17 @@ void shader_variable::update(unsigned int value, std::size_t index) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const uint2& value, std::size_t index) const +void shader_variable::update(const math::uvec2& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const uint3& value, std::size_t index) const +void shader_variable::update(const math::uvec3& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const uint4& value, std::size_t index) const +void shader_variable::update(const math::uvec4& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -208,32 +208,32 @@ void shader_variable::update(float value, std::size_t index) const throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float2& value, std::size_t index) const +void shader_variable::update(const math::fvec2& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float3& value, std::size_t index) const +void shader_variable::update(const math::fvec3& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float4& value, std::size_t index) const +void shader_variable::update(const math::fvec4& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float2x2& value, std::size_t index) const +void shader_variable::update(const math::fmat2& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float3x3& value, std::size_t index) const +void shader_variable::update(const math::fmat3& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(const float4x4& value, std::size_t index) const +void shader_variable::update(const math::fmat4& value, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -263,17 +263,17 @@ void shader_variable::update(std::span values, std::size_t index) co throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -283,17 +283,17 @@ void shader_variable::update(std::span values, std::size_t index) con throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -303,17 +303,17 @@ void shader_variable::update(std::span values, std::size_t i throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } @@ -323,32 +323,32 @@ void shader_variable::update(std::span values, std::size_t index) c throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } -void shader_variable::update(std::span values, std::size_t index) const +void shader_variable::update(std::span values, std::size_t index) const { throw std::invalid_argument(type_mismatch_error); } diff --git a/src/engine/gl/shader-variable.hpp b/src/engine/gl/shader-variable.hpp index e5dde56..5215924 100644 --- a/src/engine/gl/shader-variable.hpp +++ b/src/engine/gl/shader-variable.hpp @@ -20,7 +20,8 @@ #ifndef ANTKEEPER_GL_SHADER_INPUT_HPP #define ANTKEEPER_GL_SHADER_INPUT_HPP -#include +#include +#include #include #include #include @@ -61,28 +62,28 @@ public: */ ///@{ virtual void update(bool value) const; - virtual void update(const bool2& value) const; - virtual void update(const bool3& value) const; - virtual void update(const bool4& value) const; + virtual void update(const math::bvec2& value) const; + virtual void update(const math::bvec3& value) const; + virtual void update(const math::bvec4& value) const; virtual void update(int value) const; - virtual void update(const int2& value) const; - virtual void update(const int3& value) const; - virtual void update(const int4& value) const; + virtual void update(const math::ivec2& value) const; + virtual void update(const math::ivec3& value) const; + virtual void update(const math::ivec4& value) const; virtual void update(unsigned int value) const; - virtual void update(const uint2& value) const; - virtual void update(const uint3& value) const; - virtual void update(const uint4& value) const; + virtual void update(const math::uvec2& value) const; + virtual void update(const math::uvec3& value) const; + virtual void update(const math::uvec4& value) const; virtual void update(float value) const; - virtual void update(const float2& value) const; - virtual void update(const float3& value) const; - virtual void update(const float4& value) const; + virtual void update(const math::fvec2& value) const; + virtual void update(const math::fvec3& value) const; + virtual void update(const math::fvec4& value) const; - virtual void update(const float2x2& value) const; - virtual void update(const float3x3& value) const; - virtual void update(const float4x4& value) const; + virtual void update(const math::fmat2& value) const; + virtual void update(const math::fmat3& value) const; + virtual void update(const math::fmat4& value) const; virtual void update(const texture_1d& value) const; virtual void update(const texture_2d& value) const; @@ -100,28 +101,28 @@ public: */ /// @{ virtual void update(bool value, std::size_t index) const; - virtual void update(const bool2& value, std::size_t index) const; - virtual void update(const bool3& value, std::size_t index) const; - virtual void update(const bool4& value, std::size_t index) const; + virtual void update(const math::bvec2& value, std::size_t index) const; + virtual void update(const math::bvec3& value, std::size_t index) const; + virtual void update(const math::bvec4& value, std::size_t index) const; virtual void update(int value, std::size_t index) const; - virtual void update(const int2& value, std::size_t index) const; - virtual void update(const int3& value, std::size_t index) const; - virtual void update(const int4& value, std::size_t index) const; + virtual void update(const math::ivec2& value, std::size_t index) const; + virtual void update(const math::ivec3& value, std::size_t index) const; + virtual void update(const math::ivec4& value, std::size_t index) const; virtual void update(unsigned int value, std::size_t index) const; - virtual void update(const uint2& value, std::size_t index) const; - virtual void update(const uint3& value, std::size_t index) const; - virtual void update(const uint4& value, std::size_t index) const; + virtual void update(const math::uvec2& value, std::size_t index) const; + virtual void update(const math::uvec3& value, std::size_t index) const; + virtual void update(const math::uvec4& value, std::size_t index) const; virtual void update(float value, std::size_t index) const; - virtual void update(const float2& value, std::size_t index) const; - virtual void update(const float3& value, std::size_t index) const; - virtual void update(const float4& value, std::size_t index) const; + virtual void update(const math::fvec2& value, std::size_t index) const; + virtual void update(const math::fvec3& value, std::size_t index) const; + virtual void update(const math::fvec4& value, std::size_t index) const; - virtual void update(const float2x2& value, std::size_t index) const; - virtual void update(const float3x3& value, std::size_t index) const; - virtual void update(const float4x4& value, std::size_t index) const; + virtual void update(const math::fmat2& value, std::size_t index) const; + virtual void update(const math::fmat3& value, std::size_t index) const; + virtual void update(const math::fmat4& value, std::size_t index) const; virtual void update(const texture_1d& value, std::size_t index) const; virtual void update(const texture_2d& value, std::size_t index) const; @@ -139,28 +140,28 @@ public: */ ///@{ virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; - virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; + virtual void update(std::span values, std::size_t index = 0) const; virtual void update(std::span values, std::size_t index = 0) const; virtual void update(std::span values, std::size_t index = 0) const; diff --git a/src/engine/input/mouse-events.hpp b/src/engine/input/mouse-events.hpp index a0aecad..8b10950 100644 --- a/src/engine/input/mouse-events.hpp +++ b/src/engine/input/mouse-events.hpp @@ -39,10 +39,10 @@ struct mouse_moved_event mouse* mouse{nullptr}; /// Mouse position, in pixels, relative to the window. - math::vector position{0, 0}; + math::vec2 position{0, 0}; /// Relative movement of the mouse, in pixels. - math::vector difference{0, 0}; + math::vec2 difference{0, 0}; }; /** @@ -54,7 +54,7 @@ struct mouse_button_pressed_event mouse* mouse{nullptr}; /// Mouse position, in pixels, relative to the window, when the button was pressed. - math::vector position{0, 0}; + math::vec2 position{0, 0}; /// Mouse button being pressed. mouse_button button{0}; @@ -69,7 +69,7 @@ struct mouse_button_released_event mouse* mouse{nullptr}; /// Mouse position, in pixels, relative to the window, when the button was released. - math::vector position{0, 0}; + math::vec2 position{0, 0}; /// Mouse button being released. mouse_button button{0}; @@ -84,10 +84,10 @@ struct mouse_scrolled_event mouse* mouse{nullptr}; /// Mouse position, in pixels, relative to the window, when the mouse was scrolled. - math::vector position{0, 0}; + math::vec2 position{0, 0}; /// Scroll velocity. - math::vector velocity{0.0f, 0.0f}; + math::fvec2 velocity{0.0f, 0.0f}; }; } // namespace input diff --git a/src/engine/input/mouse.cpp b/src/engine/input/mouse.cpp index 8c665fb..a573430 100644 --- a/src/engine/input/mouse.cpp +++ b/src/engine/input/mouse.cpp @@ -31,13 +31,13 @@ void mouse::release(mouse_button button) button_released_publisher.publish({this, position, button}); } -void mouse::move(const math::vector& position, const math::vector& difference) +void mouse::move(const math::vec2& position, const math::vec2& difference) { this->position = position; moved_publisher.publish({this, position, difference}); } -void mouse::scroll(const math::vector& velocity) +void mouse::scroll(const math::fvec2& velocity) { scrolled_publisher.publish({this, position, velocity}); } diff --git a/src/engine/input/mouse.hpp b/src/engine/input/mouse.hpp index cbeffdb..a3cad35 100644 --- a/src/engine/input/mouse.hpp +++ b/src/engine/input/mouse.hpp @@ -55,17 +55,17 @@ public: * @param position Mouse position, in pixels, relative to the window. * @param difference Relative movement of the mouse, in pixels. */ - void move(const math::vector& position, const math::vector& difference); + void move(const math::vec2& position, const math::vec2& difference); /** * Simulates mouse scrolling. * * @param velocity Scroll velocity. */ - void scroll(const math::vector& velocity); + void scroll(const math::fvec2& velocity); /// Returns the current mouse position, in pixels, relative to the window. - [[nodiscard]] inline const math::vector& get_position() const noexcept + [[nodiscard]] inline const math::vec2& get_position() const noexcept { return position; } @@ -101,7 +101,7 @@ public: } private: - math::vector position{0, 0}; + math::vec2 position{0, 0}; ::event::publisher button_pressed_publisher; ::event::publisher button_released_publisher; diff --git a/src/engine/math/glsl.hpp b/src/engine/math/glsl.hpp deleted file mode 100644 index 3ae76c9..0000000 --- a/src/engine/math/glsl.hpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_MATH_GLSL_HPP -#define ANTKEEPER_MATH_GLSL_HPP - -#include -#include -#include - -namespace math { -namespace glsl { - -/** - * Linear algebra data types with GLSL naming conventions. - */ -namespace types -{ - /// @name Vector types - /// @{ - - /** - * *n*-dimensional vector of booleans. - * - * @tparam N Number of elements - */ - /// @{ - template - using bvec = math::vector; - using bvec2 = bvec<2>; - using bvec3 = bvec<3>; - using bvec4 = bvec<4>; - /// @} - - /** - * *n*-dimensional vector of signed integers. - * - * @tparam N Number of elements - */ - /// @{ - template - using ivec = math::vector; - using ivec2 = ivec<2>; - using ivec3 = ivec<3>; - using ivec4 = ivec<4>; - /// @} - - /** - * *n*-dimensional vector of unsigned integers. - * - * @tparam N Number of elements - */ - /// @{ - template - using uvec = math::vector; - using uvec2 = uvec<2>; - using uvec3 = uvec<3>; - using uvec4 = uvec<4>; - /// @} - - /** - * *n*-dimensional vector of floating-point numbers. - * - * @tparam N Number of elements - */ - /// @{ - template - using fvec = math::vector; - using fvec2 = fvec<2>; - using fvec3 = fvec<3>; - using fvec4 = fvec<4>; - using vec2 = fvec2; - using vec3 = fvec3; - using vec4 = fvec4; - /// @} - - /** - * *n*-dimensional vector of double-precision floating-point numbers. - * - * @tparam N Number of elements - */ - /// @{ - template - using dvec = math::vector; - using dvec2 = dvec<2>; - using dvec3 = dvec<3>; - using dvec4 = dvec<4>; - /// @} - - /// @} - - /// @name Matrix types - /// @{ - - /** - * *n* by *m* matrix of floating-point numbers. - * - * @tparam N Number of columns. - * @tparam M Number of rows. - */ - /// @{ - template - using fmat = math::matrix; - using fmat2x2 = fmat<2, 2>; - using fmat2x3 = fmat<2, 3>; - using fmat2x4 = fmat<2, 4>; - using fmat3x2 = fmat<3, 2>; - using fmat3x3 = fmat<3, 3>; - using fmat3x4 = fmat<3, 4>; - using fmat4x2 = fmat<4, 2>; - using fmat4x3 = fmat<4, 3>; - using fmat4x4 = fmat<4, 4>; - using mat2x2 = fmat2x2; - using mat2x3 = fmat2x3; - using mat2x4 = fmat2x4; - using mat3x2 = fmat3x2; - using mat3x3 = fmat3x3; - using mat3x4 = fmat3x4; - using mat4x2 = fmat4x2; - using mat4x3 = fmat4x3; - using mat4x4 = fmat4x4; - /// @} - - /** - * *n* by *n* square matrix of floating-point numbers. - * - * @tparam N Number of columns and rows. - */ - /// @{ - using fmat2 = fmat2x2; - using fmat3 = fmat3x3; - using fmat4 = fmat4x4; - using mat2 = fmat2; - using mat3 = fmat3; - using mat4 = fmat4; - /// @} - - /** - * *n* by *m* matrix of double-precision floating-point numbers. - * - * @tparam N Number of columns. - * @tparam M Number of rows. - */ - /// @{ - template - using dmat = math::matrix; - using dmat2x2 = dmat<2, 2>; - using dmat2x3 = dmat<2, 3>; - using dmat2x4 = dmat<2, 4>; - using dmat3x2 = dmat<3, 2>; - using dmat3x3 = dmat<3, 3>; - using dmat3x4 = dmat<3, 4>; - using dmat4x2 = dmat<4, 2>; - using dmat4x3 = dmat<4, 3>; - using dmat4x4 = dmat<4, 4>; - /// @} - - /** - * *n* by *n* square matrix of double-precision floating-point numbers. - * - * @tparam N Number of columns and rows. - */ - /// @{ - using dmat2 = dmat2x2; - using dmat3 = dmat3x3; - using dmat4 = dmat4x4; - /// @} - - /// @} - - /// @name Quaternion types - /// @{ - - /** - * Quaternion with floating-point scalars. - * - * @tparam T Scalar type. - */ - /// @{ - using fquat = math::quaternion; - using quat = fquat; - /// @} - - /** - * Quaternion with double-precision floating-point scalars. - * - * @tparam T Scalar type. - */ - using dquat = math::quaternion; - - /// @} - -} // namespace types - -// Bring GLSL types into glsl namespace -using namespace types; - -} // namespace glsl -} // namespace math - -#endif // ANTKEEPER_MATH_GLSL_HPP diff --git a/src/engine/math/matrix.hpp b/src/engine/math/matrix.hpp index a7b52c5..6a637e0 100644 --- a/src/engine/math/matrix.hpp +++ b/src/engine/math/matrix.hpp @@ -28,6 +28,9 @@ namespace math { +/// Matrix types. +namespace matrix_types { + /** * *n* by *m* column-major matrix. * @@ -356,29 +359,107 @@ struct matrix /// @} }; -/// 2x2 matrix. +/** + * *n* by *m* matrix. + * + * @tparam T Element type. + */ +/// @{ template -using matrix2 = matrix; - -/// 2x2 matrix. +using mat2x2 = matrix; template -using matrix2x2 = matrix; - -/// 3x3 matrix. +using mat2x3 = matrix; template -using matrix3 = matrix; - -/// 3x3 matrix. +using mat2x4 = matrix; template -using matrix3x3 = matrix; - -/// 4x4 matrix. +using mat3x2 = matrix; +template +using mat3x3 = matrix; +template +using mat3x4 = matrix; template -using matrix4 = matrix; +using mat4x2 = matrix; +template +using mat4x3 = matrix; +template +using mat4x4 = matrix; +/// @} -/// 4x4 matrix. +/** + * *n* by *n* square matrix. + * + * @tparam T Element type. + */ +/// @{ +template +using mat2 = mat2x2; template -using matrix4x4 = matrix; +using mat3 = mat3x3; +template +using mat4 = mat4x4; +/// @} + +/** + * *n* by *m* matrix of single-precision floating-point numbers. + * + * @tparam N Number of columns. + * @tparam M Number of rows. + */ +/// @{ +template +using fmat = matrix; +using fmat2x2 = fmat<2, 2>; +using fmat2x3 = fmat<2, 3>; +using fmat2x4 = fmat<2, 4>; +using fmat3x2 = fmat<3, 2>; +using fmat3x3 = fmat<3, 3>; +using fmat3x4 = fmat<3, 4>; +using fmat4x2 = fmat<4, 2>; +using fmat4x3 = fmat<4, 3>; +using fmat4x4 = fmat<4, 4>; +/// @} + +/// *n* by *n* square matrix of single-precision floating-point numbers. +/// @{ +using fmat2 = fmat2x2; +using fmat3 = fmat3x3; +using fmat4 = fmat4x4; +/// @} + +/** + * *n* by *m* matrix of double-precision floating-point numbers. + * + * @tparam N Number of columns. + * @tparam M Number of rows. + */ +/// @{ +template +using dmat = matrix; +using dmat2x2 = dmat<2, 2>; +using dmat2x3 = dmat<2, 3>; +using dmat2x4 = dmat<2, 4>; +using dmat3x2 = dmat<3, 2>; +using dmat3x3 = dmat<3, 3>; +using dmat3x4 = dmat<3, 4>; +using dmat4x2 = dmat<4, 2>; +using dmat4x3 = dmat<4, 3>; +using dmat4x4 = dmat<4, 4>; +/// @} + +/// *n* by *n* square matrix of double-precision floating-point numbers. +/// @{ +using dmat2 = dmat2x2; +using dmat3 = dmat3x3; +using dmat4 = dmat4x4; +/// @} + +} // namespace matrix_types + +// Bring matrix types into math namespace +using namespace matrix_types; + +// Bring matrix types into math::types namespace +namespace types { using namespace matrix_types; } /** * Adds two matrices. @@ -472,13 +553,13 @@ template */ /// @{ template -[[nodiscard]] constexpr typename matrix::column_vector_type& get(math::matrix& m) noexcept; +[[nodiscard]] constexpr typename matrix::column_vector_type& get(matrix& m) noexcept; template -[[nodiscard]] constexpr typename matrix::column_vector_type&& get(math::matrix&& m) noexcept; +[[nodiscard]] constexpr typename matrix::column_vector_type&& get(matrix&& m) noexcept; template -[[nodiscard]] constexpr const typename matrix::column_vector_type& get(const math::matrix& m) noexcept; +[[nodiscard]] constexpr const typename matrix::column_vector_type& get(const matrix& m) noexcept; template -[[nodiscard]] constexpr const typename matrix::column_vector_type&& get(const math::matrix&& m) noexcept; +[[nodiscard]] constexpr const typename matrix::column_vector_type&& get(const matrix&& m) noexcept; /// @} /** @@ -563,7 +644,7 @@ template * @return Rotation matrix. */ template -[[nodiscard]] matrix rotate(T angle, const vector& axis); +[[nodiscard]] mat3 rotate(T angle, const vector& axis); /** * Produces a matrix which rotates Cartesian coordinates about the x-axis by a given angle. @@ -573,7 +654,7 @@ template * @return Rotation matrix. */ template -[[nodiscard]] matrix3 rotate_x(T angle); +[[nodiscard]] mat3 rotate_x(T angle); /** * Produces a matrix which rotates Cartesian coordinates about the y-axis by a given angle. @@ -583,7 +664,7 @@ template * @return Rotation matrix. */ template -[[nodiscard]] matrix3 rotate_y(T angle); +[[nodiscard]] mat3 rotate_y(T angle); /** * Produces a matrix which rotates Cartesian coordinates about the z-axis by a given angle. @@ -593,7 +674,7 @@ template * @return Rotation matrix. */ template -[[nodiscard]] matrix3 rotate_z(T angle); +[[nodiscard]] mat3 rotate_z(T angle); /** * Scales a matrix. @@ -707,7 +788,7 @@ constexpr T determinant(const matrix& m) noexcept /// @private template -constexpr T determinant(const matrix& m) noexcept +constexpr T determinant(const mat3& m) noexcept { return m[0][0] * m[1][1] * m[2][2] + @@ -790,28 +871,28 @@ constexpr matrix div(T a, const matrix& b) noexcept } template -inline constexpr typename matrix::column_vector_type& get(math::matrix& m) noexcept +inline constexpr typename matrix::column_vector_type& get(matrix& m) noexcept { static_assert(I < N); return m.columns[I]; } template -inline constexpr typename matrix::column_vector_type&& get(math::matrix&& m) noexcept +inline constexpr typename matrix::column_vector_type&& get(matrix&& m) noexcept { static_assert(I < N); return std::move(m.columns[I]); } template -inline constexpr const typename matrix::column_vector_type& get(const math::matrix& m) noexcept +inline constexpr const typename matrix::column_vector_type& get(const matrix& m) noexcept { static_assert(I < N); return m.columns[I]; } template -inline constexpr const typename matrix::column_vector_type&& get(const math::matrix&& m) noexcept +inline constexpr const typename matrix::column_vector_type&& get(const matrix&& m) noexcept { static_assert(I < N); return std::move(m.columns[I]); @@ -834,7 +915,7 @@ constexpr matrix inverse(const matrix& m) noexcept /// @private template -constexpr matrix inverse(const matrix& m) noexcept +constexpr mat3 inverse(const mat3& m) noexcept { const T inv_det = T{1} / determinant(m); @@ -961,13 +1042,13 @@ constexpr typename matrix::row_vector_type mul(const typename matrix -matrix rotate(T angle, const vector& axis) +mat3 rotate(T angle, const vector& axis) { const T c = std::cos(angle); const T s = std::sin(angle); const vector temp = mul(axis, T{1} - c); - matrix rotation; + mat3 rotation; rotation[0][0] = axis[0] * temp[0] + c; rotation[0][1] = axis[1] * temp[0] + axis[2] * s; rotation[0][2] = axis[2] * temp[0] - axis[1] * s; @@ -982,12 +1063,12 @@ matrix rotate(T angle, const vector& axis) } template -matrix3 rotate_x(T angle) +mat3 rotate_x(T angle) { const T c = std::cos(angle); const T s = std::sin(angle); - return matrix3 + return mat3 { T{1}, T{0}, T{0}, T{0}, c, s, @@ -996,12 +1077,12 @@ matrix3 rotate_x(T angle) } template -matrix3 rotate_y(T angle) +mat3 rotate_y(T angle) { const T c = std::cos(angle); const T s = std::sin(angle); - return matrix3 + return mat3 { c, T{0}, -s, T{0}, T{1}, T{0}, @@ -1010,12 +1091,12 @@ matrix3 rotate_y(T angle) } template -matrix3 rotate_z(T angle) +mat3 rotate_z(T angle) { const T c = std::cos(angle); const T s = std::sin(angle); - return matrix3 + return mat3 { c, s, T{0}, -s, c, T{0}, @@ -1311,13 +1392,14 @@ inline constexpr matrix& operator/=(matrix& a, T b) noexcept } // namespace math +// Bring matrix operators into global namespace using namespace math::operators; // Structured binding support namespace std { /** - * Provides access to the number of columns in a math::matrix as a compile-time constant expression. + * Provides access to the number of columns in a matrix as a compile-time constant expression. * * @tparam T Element type. * @tparam N Number of columns. @@ -1331,7 +1413,7 @@ namespace std }; /** - * Provides compile-time indexed access to the type of the columns in a math::matrix using a tuple-like interface. + * Provides compile-time indexed access to the type of the columns in a matrix using a tuple-like interface. * * @tparam I Index of a column. * @tparam T Element type. diff --git a/src/engine/math/quaternion.hpp b/src/engine/math/quaternion.hpp index 1a2a1a3..c494388 100644 --- a/src/engine/math/quaternion.hpp +++ b/src/engine/math/quaternion.hpp @@ -27,6 +27,9 @@ namespace math { +/// Quaternion types. +namespace quaternion_types { + /** * Quaternion composed of a real scalar part and imaginary vector part. * @@ -39,10 +42,10 @@ struct quaternion using scalar_type = T; /// Vector type. - using vector_type = vector; + using vector_type = vec3; /// Rotation matrix type. - using matrix_type = matrix; + using matrix_type = mat3; /// Quaternion real part. scalar_type r; @@ -143,7 +146,7 @@ struct quaternion template [[nodiscard]] inline constexpr explicit operator quaternion() const noexcept { - return {static_cast(r), vector(i)}; + return {static_cast(r), vec3(i)}; } /** @@ -183,7 +186,7 @@ struct quaternion * * @return Vector containing the real and imaginary parts of the quaternion. */ - [[nodiscard]] inline constexpr explicit operator vector() const noexcept + [[nodiscard]] inline constexpr explicit operator vec4() const noexcept { return {r, i.x(), i.y(), i.z()}; } @@ -201,6 +204,32 @@ struct quaternion } }; +/// @copydoc math::quaternion_types::quaternion +template +using quat = quaternion; + +/** + * Quaternion with single-precision floating-point scalars. + * + * @tparam T Scalar type. + */ +using fquat = quat; + +/** + * Quaternion with double-precision floating-point scalars. + * + * @tparam T Scalar type. + */ +using dquat = quat; + +} // namespace quaternion_types + +// Bring quaternion types into math namespace +using namespace quaternion_types; + +// Bring quaternion types into math::types namespace +namespace types { using namespace math::quaternion_types; } + /** * Adds two quaternions. * @@ -318,7 +347,7 @@ template * @return Unit rotation quaternion. */ template -[[nodiscard]] quaternion look_rotation(const vector& forward, vector up); +[[nodiscard]] quaternion look_rotation(const vec3& forward, vec3 up); /** * Multiplies two quaternions. @@ -355,7 +384,7 @@ template * @see https://fgiesen.wordpress.com/2019/02/09/rotating-a-single-vector-using-a-quaternion/ */ template -[[nodiscard]] constexpr vector mul(const quaternion& q, const vector& v) noexcept; +[[nodiscard]] constexpr vec3 mul(const quaternion& q, const vec3& v) noexcept; /** * Rotates a vector by the inverse of a unit quaternion. @@ -368,7 +397,7 @@ template * @warning @p q must be a unit quaternion. */ template -[[nodiscard]] constexpr vector mul(const vector& v, const quaternion& q) noexcept; +[[nodiscard]] constexpr vec3 mul(const vec3& v, const quaternion& q) noexcept; /** * Negates a quaternion. @@ -411,7 +440,7 @@ template * @return Quaternion representing the rotation. */ template -[[nodiscard]] quaternion angle_axis(T angle, const vector& axis); +[[nodiscard]] quaternion angle_axis(T angle, const vec3& axis); /** * Calculates a quaternion representing the minimum rotation from one direction to another directions. @@ -425,7 +454,7 @@ template * @warning @p from and @p to must be unit vectors. */ template -[[nodiscard]] quaternion rotation(const vector& from, const vector& to, T tolerance = T{1e-6}); +[[nodiscard]] quaternion rotation(const vec3& from, const vec3& to, T tolerance = T{1e-6}); /** * Performs spherical linear interpolation between two quaternions. @@ -491,7 +520,7 @@ template * @see https://www.euclideanspace.com/maths/geometry/rotations/for/decomposition/ */ template -void swing_twist(const quaternion& q, const vector& twist_axis, quaternion& swing, quaternion& twist, T tolerance = T{1e-6}); +void swing_twist(const quaternion& q, const vec3& twist_axis, quaternion& swing, quaternion& twist, T tolerance = T{1e-6}); /** * Converts a 3x3 rotation matrix to a quaternion. @@ -501,7 +530,7 @@ void swing_twist(const quaternion& q, const vector& twist_axis, quatern * @return Unit quaternion representing the rotation described by @p m. */ template -[[nodiscard]] quaternion quaternion_cast(const matrix& m); +[[nodiscard]] quaternion quaternion_cast(const mat3& m); template inline constexpr quaternion add(const quaternion& a, const quaternion& b) noexcept @@ -568,12 +597,12 @@ inline constexpr quaternion lerp(const quaternion& a, const quaternion& } template -quaternion look_rotation(const vector& forward, vector up) +quaternion look_rotation(const vec3& forward, vec3 up) { - const vector right = normalize(cross(forward, up)); + const vec3 right = normalize(cross(forward, up)); up = cross(right, forward); - const matrix m = + const mat3 m = { right, up, @@ -603,14 +632,14 @@ inline constexpr quaternion mul(const quaternion& a, T b) noexcept } template -constexpr vector mul(const quaternion& q, const vector& v) noexcept +constexpr vec3 mul(const quaternion& q, const vec3& v) noexcept { const auto t = cross(q.i, v) * T{2}; return v + q.r * t + cross(q.i, t); } template -inline constexpr vector mul(const vector& v, const quaternion& q) noexcept +inline constexpr vec3 mul(const vec3& v, const quaternion& q) noexcept { return mul(conjugate(q), v); } @@ -634,13 +663,13 @@ inline quaternion normalize(const quaternion& q) } template -quaternion angle_axis(T angle, const vector& axis) +quaternion angle_axis(T angle, const vec3& axis) { return {std::cos(angle * T{0.5}), axis * std::sin(angle * T{0.5})}; } template -quaternion rotation(const vector& from, const vector& to, T tolerance) +quaternion rotation(const vec3& from, const vec3& to, T tolerance) { const auto cos_theta = dot(from, to); @@ -709,7 +738,7 @@ inline constexpr quaternion sub(T a, const quaternion& b) noexcept } template -void swing_twist(const quaternion& q, const vector& twist_axis, quaternion& swing, quaternion& twist, T tolerance) +void swing_twist(const quaternion& q, const vec3& twist_axis, quaternion& swing, quaternion& twist, T tolerance) { if (sqr_length(q.i) <= tolerance) { @@ -740,7 +769,7 @@ void swing_twist(const quaternion& q, const vector& twist_axis, quatern } template -quaternion quaternion_cast(const matrix& m) +quaternion quaternion_cast(const mat3& m) { const T t = trace(m); @@ -859,16 +888,16 @@ inline constexpr quaternion operator*(T a, const quaternion& b) noexcept } /// @} -/// @copydoc mul(const quaternion&, const vector&) +/// @copydoc mul(const quaternion&, const vec3&) template -inline constexpr vector operator*(const quaternion& q, const vector& v) noexcept +inline constexpr vec3 operator*(const quaternion& q, const vec3& v) noexcept { return mul(q, v); } -/// @copydoc mul(const vector&, const quaternion&) +/// @copydoc mul(const vec3&, const quaternion&) template -inline constexpr vector operator*(const vector& v, const quaternion& q) noexcept +inline constexpr vec3 operator*(const vec3& v, const quaternion& q) noexcept { return mul(v, q); } @@ -989,6 +1018,7 @@ inline constexpr quaternion& operator/=(quaternion& a, T b) noexcept } // namespace math +// Bring quaternion operators into global namespace using namespace math::operators; #endif // ANTKEEPER_MATH_QUATERNION_HPP diff --git a/src/engine/math/se3.hpp b/src/engine/math/se3.hpp index bec4f3e..9d41ede 100644 --- a/src/engine/math/se3.hpp +++ b/src/engine/math/se3.hpp @@ -39,13 +39,13 @@ public: typedef T scalar_type; /// Vector type. - typedef math::vector3 vector_type; + typedef math::vec3 vector_type; /// Quaternion type. typedef math::quaternion quaternion_type; /// Transformation matrix type. - typedef math::matrix matrix_type; + typedef math::mat4 matrix_type; /// Vector representing the translation component of this SE(3) transformation. vector_type t; @@ -93,7 +93,7 @@ se3 se3::inverse() const template typename se3::matrix_type se3::matrix() const { - matrix_type m = math::matrix(math::matrix(r)); + matrix_type m = math::mat4(math::mat3(r)); m[3].x() = t.x(); m[3].y() = t.y(); diff --git a/src/engine/math/transform.hpp b/src/engine/math/transform.hpp index 337a94b..0fb38ac 100644 --- a/src/engine/math/transform.hpp +++ b/src/engine/math/transform.hpp @@ -197,16 +197,16 @@ template return mul(x, y); } -/// @copydoc math::mul(const math::transform&, const math::vector&) +/// @copydoc math::mul(const math::transform&, const math::vec3&) template -[[nodiscard]] inline constexpr math::vector operator*(const math::transform& t, const math::vector& v) noexcept +[[nodiscard]] inline constexpr math::vec3 operator*(const math::transform& t, const math::vec3& v) noexcept { return mul(t, v); } -/// @copydoc math::mul(const math::vector&, const math::transform&) +/// @copydoc math::mul(const math::vec3&, const math::transform&) template -[[nodiscard]] inline constexpr math::vector operator*(const math::vector& v, const math::transform& t) noexcept +[[nodiscard]] inline constexpr math::vec3 operator*(const math::vec3& v, const math::transform& t) noexcept { return mul(v, t); } diff --git a/src/engine/math/types.hpp b/src/engine/math/types.hpp new file mode 100644 index 0000000..a8aa3f8 --- /dev/null +++ b/src/engine/math/types.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_MATH_TYPES_HPP +#define ANTKEEPER_MATH_TYPES_HPP + +namespace math { + +/** + * Linear algebra data types. + */ +namespace types {} + +} // namespace math + +#include +#include +#include + +#endif // ANTKEEPER_MATH_TYPES_HPP diff --git a/src/engine/math/vector.hpp b/src/engine/math/vector.hpp index 233c432..b7dd0cd 100644 --- a/src/engine/math/vector.hpp +++ b/src/engine/math/vector.hpp @@ -25,11 +25,15 @@ #include #include #include +#include #include #include namespace math { +/// Vector types. +namespace vector_types { + /** * *n*-dimensional vector. * @@ -309,10 +313,10 @@ struct vector template [[nodiscard]] static constexpr vector one(std::index_sequence) noexcept { - //return {T{1}...}; + //return {element_type{1}...}; // MSVC bug workaround (I must be referenced for parameter pack expansion) - return {(I ? T{1} : T{1})...}; + return {(I ? element_type{1} : element_type{1})...}; } /** @@ -323,20 +327,123 @@ struct vector return one(std::make_index_sequence{}); } + /// @private + template + [[nodiscard]] static constexpr vector infinity(std::index_sequence) noexcept + { + //return {element_type{1}...}; + + // MSVC bug workaround (I must be referenced for parameter pack expansion) + return {(I ? std::numeric_limits::infinity() : std::numeric_limits::infinity())...}; + } + + /** + * Returns a vector of infinities, where every element is equal to infinity. + */ + [[nodiscard]] static constexpr vector infinity() noexcept + { + return infinity(std::make_index_sequence{}); + } + /// @} }; -/// Vector with two elements. +/** + * 2-dimensional vector. + * + * @tparam T Element type. + */ template -using vector2 = vector; +using vec2 = vector; -/// Vector with three elements. +/** + * 3-dimensional vector. + * + * @tparam T Element type. + */ template -using vector3 = vector; +using vec3 = vector; -/// Vector with four elements. +/** + * 4-dimensional vector. + * + * @tparam T Element type. + */ template -using vector4 = vector; +using vec4 = vector; + +/** + * *n*-dimensional vector of Boolean values. + * + * @tparam N Number of elements + */ +/// @{ +template +using bvec = vector; +using bvec2 = bvec<2>; +using bvec3 = bvec<3>; +using bvec4 = bvec<4>; +/// @} + +/** + * *n*-dimensional vector of signed integers. + * + * @tparam N Number of elements + */ +/// @{ +template +using ivec = vector; +using ivec2 = ivec<2>; +using ivec3 = ivec<3>; +using ivec4 = ivec<4>; +/// @} + +/** + * *n*-dimensional vector of unsigned integers. + * + * @tparam N Number of elements + */ +/// @{ +template +using uvec = vector; +using uvec2 = uvec<2>; +using uvec3 = uvec<3>; +using uvec4 = uvec<4>; +/// @} + +/** + * *n*-dimensional vector of single-precision floating-point numbers. + * + * @tparam N Number of elements + */ +/// @{ +template +using fvec = vector; +using fvec2 = fvec<2>; +using fvec3 = fvec<3>; +using fvec4 = fvec<4>; +/// @} + +/** + * *n*-dimensional vector of double-precision floating-point numbers. + * + * @tparam N Number of elements + */ +/// @{ +template +using dvec = vector; +using dvec2 = dvec<2>; +using dvec3 = dvec<3>; +using dvec4 = dvec<4>; +/// @} + +} // namespace vector_types + +// Bring vector types into math namespace +using namespace vector_types; + +// Bring vector types into math::types namespace +namespace types { using namespace math::vector_types; } /** * Returns the absolute values of each element. diff --git a/src/engine/physics/gas/atmosphere.hpp b/src/engine/physics/gas/atmosphere.hpp index 2d50b1d..6acc1ce 100644 --- a/src/engine/physics/gas/atmosphere.hpp +++ b/src/engine/physics/gas/atmosphere.hpp @@ -134,14 +134,14 @@ T extinction(T scattering, T albedo) * @return Optical depth between @p a and @p b. */ template -T optical_depth_exp(const math::vector3& a, const math::vector3& b, T r, T sh, std::size_t n) +T optical_depth_exp(const math::vec3& a, const math::vec3& b, T r, T sh, std::size_t n) { sh = T(-1) / sh; const T h = math::length(b - a) / T(n); - math::vector3 dy = (b - a) / T(n); - math::vector3 y = a + dy; + math::vec3 dy = (b - a) / T(n); + math::vec3 y = a + dy; T f_x = std::exp((math::length(a) - r) * sh); T f_y = std::exp((math::length(y) - r) * sh); @@ -171,15 +171,15 @@ T optical_depth_exp(const math::vector3& a, const math::vector3& b, T r, T * @return Optical depth between @p a and @p b. */ template -T optical_depth_tri(const math::vector3& p0, const math::vector3& p1, T r, T a, T b, T c, std::size_t n) +T optical_depth_tri(const math::vec3& p0, const math::vec3& p1, T r, T a, T b, T c, std::size_t n) { a = T(1) / (a - c); b = T(1) / (b - c); const T h = math::length(p1 - p0) / T(n); - math::vector3 dy = (p1 - p0) / T(n); - math::vector3 y = p0 + dy; + math::vec3 dy = (p1 - p0) / T(n); + math::vec3 y = p0 + dy; T z = math::length(p0) - r; T f_x = std::max(T(0), std::max(T(0), c - z) * a - std::max(T(0), z - c) * b + T(1)); diff --git a/src/engine/physics/kinematics/colliders/box-collider.hpp b/src/engine/physics/kinematics/colliders/box-collider.hpp index 8f75f81..8d4abee 100644 --- a/src/engine/physics/kinematics/colliders/box-collider.hpp +++ b/src/engine/physics/kinematics/colliders/box-collider.hpp @@ -55,7 +55,7 @@ public: * @param max Maximum extent of the box, in object space. */ /// @{ - inline box_collider(const math::vector& min, const math::vector& max) noexcept: + inline box_collider(const math::fvec3& min, const math::fvec3& max) noexcept: m_box{min, max} {} box_collider() noexcept = default; @@ -76,7 +76,7 @@ public: * * @param min Minimum extent of the box, in object space. */ - inline void set_min(const math::vector& min) noexcept + inline void set_min(const math::fvec3& min) noexcept { m_box.min = min; } @@ -86,7 +86,7 @@ public: * * @param max Maximum extent of the box, in object space. */ - inline void set_max(const math::vector& max) noexcept + inline void set_max(const math::fvec3& max) noexcept { m_box.max = max; } @@ -98,13 +98,13 @@ public: } /// Returns the minimum extent of the box, in object space. - [[nodiscard]] inline const math::vector& get_min() const noexcept + [[nodiscard]] inline const math::fvec3& get_min() const noexcept { return m_box.min; } /// Returns the maximum extent of the box, in object space. - [[nodiscard]] inline const math::vector& get_max() const noexcept + [[nodiscard]] inline const math::fvec3& get_max() const noexcept { return m_box.max; } diff --git a/src/engine/physics/kinematics/colliders/plane-collider.hpp b/src/engine/physics/kinematics/colliders/plane-collider.hpp index 282b4e1..9ac1a04 100644 --- a/src/engine/physics/kinematics/colliders/plane-collider.hpp +++ b/src/engine/physics/kinematics/colliders/plane-collider.hpp @@ -55,10 +55,10 @@ public: * @param constant Plane constant. */ /// @{ - inline plane_collider(const math::vector& normal, float constant) noexcept: + inline plane_collider(const math::fvec3& normal, float constant) noexcept: m_plane{normal, constant} {} - inline explicit plane_collider(const math::vector& normal) noexcept: + inline explicit plane_collider(const math::fvec3& normal) noexcept: m_plane{normal, 0.0f} {} plane_collider() noexcept = default; @@ -70,7 +70,7 @@ public: * @param normal Plane normal, in object space. * @param offset Offset from the origin, in object space. */ - inline plane_collider(const math::vector& normal, const math::vector& offset) noexcept: + inline plane_collider(const math::fvec3& normal, const math::fvec3& offset) noexcept: m_plane(normal, offset) {} @@ -89,7 +89,7 @@ public: * * @param normal Plane normal, in object space. */ - inline void set_normal(const math::vector& normal) noexcept + inline void set_normal(const math::fvec3& normal) noexcept { m_plane.normal = normal; } @@ -111,7 +111,7 @@ public: } /// Returns the plane normal, in object space. - [[nodiscard]] inline const math::vector& get_normal() const noexcept + [[nodiscard]] inline const math::fvec3& get_normal() const noexcept { return m_plane.normal; } diff --git a/src/engine/physics/kinematics/colliders/sphere-collider.hpp b/src/engine/physics/kinematics/colliders/sphere-collider.hpp index bb47294..973bd46 100644 --- a/src/engine/physics/kinematics/colliders/sphere-collider.hpp +++ b/src/engine/physics/kinematics/colliders/sphere-collider.hpp @@ -55,7 +55,7 @@ public: * @param radius Sphere radius. */ /// @{ - inline sphere_collider(const math::vector& center, float radius) noexcept: + inline sphere_collider(const math::fvec3& center, float radius) noexcept: m_sphere{center, radius} {} inline explicit sphere_collider(float radius) noexcept: @@ -79,7 +79,7 @@ public: * * @param center Sphere center, in object space. */ - inline void set_center(const math::vector& center) noexcept + inline void set_center(const math::fvec3& center) noexcept { m_sphere.center = center; } @@ -101,7 +101,7 @@ public: } /// Returns the center of the sphere, in object space. - [[nodiscard]] inline const math::vector& get_center() const noexcept + [[nodiscard]] inline const math::fvec3& get_center() const noexcept { return m_sphere.center; } diff --git a/src/engine/physics/kinematics/collision-contact.hpp b/src/engine/physics/kinematics/collision-contact.hpp index 0c11027..207cd2e 100644 --- a/src/engine/physics/kinematics/collision-contact.hpp +++ b/src/engine/physics/kinematics/collision-contact.hpp @@ -30,10 +30,10 @@ namespace physics { struct collision_contact { /// World-space contact point. - math::vector point{math::vector::zero()}; + math::fvec3 point{math::fvec3::zero()}; /// Contact normal, pointing from body a to body b. - math::vector normal{math::vector::zero()}; + math::fvec3 normal{math::fvec3::zero()}; /// Contact penetration depth. float depth{0.0f}; diff --git a/src/engine/physics/kinematics/constraints/spring-constraint.cpp b/src/engine/physics/kinematics/constraints/spring-constraint.cpp index e47be3e..ae4f471 100644 --- a/src/engine/physics/kinematics/constraints/spring-constraint.cpp +++ b/src/engine/physics/kinematics/constraints/spring-constraint.cpp @@ -29,21 +29,21 @@ void spring_constraint::solve(float dt) } // Get radius vectors from centers of mass to spring attachment points - const math::vector radius_a = m_body_a->get_orientation() * m_point_a; - const math::vector radius_b = m_body_b->get_orientation() * m_point_b; + const math::fvec3 radius_a = m_body_a->get_orientation() * m_point_a; + const math::fvec3 radius_b = m_body_b->get_orientation() * m_point_b; // Get world-space spring attachment points - const math::vector point_a = m_body_a->get_position() + radius_a; - const math::vector point_b = m_body_b->get_position() + radius_b; + const math::fvec3 point_a = m_body_a->get_position() + radius_a; + const math::fvec3 point_b = m_body_b->get_position() + radius_b; // Calculate relative velocity between the attachment points - const math::vector velocity = m_body_b->get_point_velocity(radius_b) - m_body_a->get_point_velocity(radius_a); + const math::fvec3 velocity = m_body_b->get_point_velocity(radius_b) - m_body_a->get_point_velocity(radius_a); // Calculate spring force // F = -k * (|x| - d) * (x / |x|) - bv - const math::vector difference = point_b - point_a; + const math::fvec3 difference = point_b - point_a; const float distance = std::sqrt(math::dot(difference, difference)); - const math::vector force = -m_stiffness * (distance - m_resting_length) * (difference / distance) - velocity * m_damping; + const math::fvec3 force = -m_stiffness * (distance - m_resting_length) * (difference / distance) - velocity * m_damping; // Apply spring force to bodies at attachment points m_body_a->apply_force(-force, radius_a); diff --git a/src/engine/physics/kinematics/constraints/spring-constraint.hpp b/src/engine/physics/kinematics/constraints/spring-constraint.hpp index 8b4c45f..032dd4e 100644 --- a/src/engine/physics/kinematics/constraints/spring-constraint.hpp +++ b/src/engine/physics/kinematics/constraints/spring-constraint.hpp @@ -40,7 +40,7 @@ public: * @param body_a Body to which the spring should be attached. * @param point_a Point on body a, in body-space, at which the spring should be attached. */ - inline void attach_a(rigid_body& body_a, const math::vector& point_a) noexcept + inline void attach_a(rigid_body& body_a, const math::fvec3& point_a) noexcept { m_body_a = &body_a; m_point_a = point_a; @@ -52,7 +52,7 @@ public: * @param body_b Body to which the spring should be attached. * @param point_b Point on body b, in body-space, at which the spring should be attached. */ - inline void attach_b(rigid_body& body_b, const math::vector& point_b) noexcept + inline void attach_b(rigid_body& body_b, const math::fvec3& point_b) noexcept { m_body_b = &body_b; m_point_b = point_b; @@ -126,13 +126,13 @@ public: } /// Returns the point at which the spring is attached to body a, in body-space. - [[nodiscard]] inline const math::vector& get_point_a() const noexcept + [[nodiscard]] inline const math::fvec3& get_point_a() const noexcept { return m_point_a; } /// Returns the point at which the spring is attached to body b, in body-space. - [[nodiscard]] inline const math::vector& get_point_b() const noexcept + [[nodiscard]] inline const math::fvec3& get_point_b() const noexcept { return m_point_b; } @@ -163,10 +163,10 @@ private: rigid_body* m_body_b{nullptr}; /// Point at which the spring is attached to body a, in body-space. - math::vector m_point_a{0.0f, 0.0f, 0.0f}; + math::fvec3 m_point_a{0.0f, 0.0f, 0.0f}; /// Point at which the spring is attached to body b, in body-space. - math::vector m_point_b{0.0f, 0.0f, 0.0f}; + math::fvec3 m_point_b{0.0f, 0.0f, 0.0f}; /// Resting length of the spring, in meters. float m_resting_length{0.0f}; diff --git a/src/engine/physics/kinematics/rigid-body.cpp b/src/engine/physics/kinematics/rigid-body.cpp index 57b9bf8..6f65c5c 100644 --- a/src/engine/physics/kinematics/rigid-body.cpp +++ b/src/engine/physics/kinematics/rigid-body.cpp @@ -38,8 +38,8 @@ void rigid_body::integrate_forces(float dt) noexcept m_angular_velocity = m_inverse_inertia * m_angular_momentum; // Clear forces - m_applied_force = math::vector::zero(); - m_applied_torque = math::vector::zero(); + m_applied_force = math::fvec3::zero(); + m_applied_torque = math::fvec3::zero(); } void rigid_body::integrate_velocities(float dt) noexcept @@ -51,7 +51,7 @@ void rigid_body::integrate_velocities(float dt) noexcept m_current_transform.translation += m_linear_velocity * dt; // Update orientation - const math::quaternion spin = math::quaternion{0.0f, m_angular_velocity * 0.5f} * m_current_transform.rotation; + const math::fquat spin = math::fquat{0.0f, m_angular_velocity * 0.5f} * m_current_transform.rotation; m_current_transform.rotation = math::normalize(m_current_transform.rotation + spin * dt); } diff --git a/src/engine/physics/kinematics/rigid-body.hpp b/src/engine/physics/kinematics/rigid-body.hpp index 661fbe2..63148e7 100644 --- a/src/engine/physics/kinematics/rigid-body.hpp +++ b/src/engine/physics/kinematics/rigid-body.hpp @@ -49,7 +49,7 @@ public: * * @param position Position of the rigid body. */ - inline void set_position(const math::vector& position) noexcept + inline void set_position(const math::fvec3& position) noexcept { m_current_transform.translation = position; } @@ -59,7 +59,7 @@ public: * * @param orientation Orientation of the rigid body. */ - inline void set_orientation(const math::quaternion& orientation) noexcept + inline void set_orientation(const math::fquat& orientation) noexcept { m_current_transform.rotation = orientation; } @@ -79,7 +79,7 @@ public: * * @param position Position of the rigid body. */ - inline void set_previous_position(const math::vector& position) noexcept + inline void set_previous_position(const math::fvec3& position) noexcept { m_previous_transform.translation = position; } @@ -89,7 +89,7 @@ public: * * @param orientation Orientation of the rigid body. */ - inline void set_previous_orientation(const math::quaternion& orientation) noexcept + inline void set_previous_orientation(const math::fquat& orientation) noexcept { m_previous_transform.rotation = orientation; } @@ -99,7 +99,7 @@ public: * * @param point World-space center of mass. */ - inline void set_center_of_mass(const math::vector& point) noexcept + inline void set_center_of_mass(const math::fvec3& point) noexcept { m_center_of_mass = point; } @@ -161,7 +161,7 @@ public: * * @param momentum Linear momentum, in kgâ‹…m/s. */ - inline void set_linear_momentum(const math::vector& momentum) noexcept + inline void set_linear_momentum(const math::fvec3& momentum) noexcept { m_linear_momentum = momentum; m_linear_velocity = m_inverse_mass * m_linear_momentum; @@ -172,7 +172,7 @@ public: * * @param momentum Angular momentum, in kgâ‹…m^2â‹…s^-1. */ - inline void set_angular_momentum(const math::vector& momentum) noexcept + inline void set_angular_momentum(const math::fvec3& momentum) noexcept { m_angular_momentum = momentum; m_angular_velocity = m_inverse_inertia * m_angular_momentum; @@ -183,7 +183,7 @@ public: * * @param velocity Linear velocity, in m/s. */ - inline void set_linear_velocity(const math::vector& velocity) noexcept + inline void set_linear_velocity(const math::fvec3& velocity) noexcept { m_linear_velocity = velocity; m_linear_momentum = m_mass * m_linear_velocity; @@ -194,7 +194,7 @@ public: * * @param velocity Angular velocity, rad/s. */ - inline void set_angular_velocity(const math::vector& velocity) noexcept + inline void set_angular_velocity(const math::fvec3& velocity) noexcept { m_angular_velocity = velocity; m_angular_momentum = m_inertia * m_angular_velocity; @@ -207,13 +207,13 @@ public: } /// Returns the current position of the rigid body. - [[nodiscard]] inline const math::vector& get_position() const noexcept + [[nodiscard]] inline const math::fvec3& get_position() const noexcept { return m_current_transform.translation; } /// Returns the current orientation of the rigid body. - [[nodiscard]] inline const math::quaternion& get_orientation() const noexcept + [[nodiscard]] inline const math::fquat& get_orientation() const noexcept { return m_current_transform.rotation; } @@ -225,19 +225,19 @@ public: } /// Returns the previous position of the rigid body. - [[nodiscard]] inline const math::vector& get_previous_position() const noexcept + [[nodiscard]] inline const math::fvec3& get_previous_position() const noexcept { return m_previous_transform.translation; } /// Returns the previous orientation of the rigid body. - [[nodiscard]] inline const math::quaternion& get_previous_orientation() const noexcept + [[nodiscard]] inline const math::fquat& get_previous_orientation() const noexcept { return m_previous_transform.rotation; } /// Returns the center of mass of the rigid body. - [[nodiscard]] inline const math::vector& get_center_of_mass() const noexcept + [[nodiscard]] inline const math::fvec3& get_center_of_mass() const noexcept { return m_center_of_mass; } @@ -285,37 +285,37 @@ public: } /// Returns the linear momentum of the rigid body, in kgâ‹…m/s. - [[nodiscard]] inline const math::vector& get_linear_momentum() const noexcept + [[nodiscard]] inline const math::fvec3& get_linear_momentum() const noexcept { return m_linear_momentum; } /// Returns the angular momentum of the rigid body, in kgâ‹…m^2â‹…s^-1. - [[nodiscard]] inline const math::vector& get_angular_momentum() const noexcept + [[nodiscard]] inline const math::fvec3& get_angular_momentum() const noexcept { return m_angular_momentum; } /// Returns the linear velocity of the rigid body, in m/s. - [[nodiscard]] inline const math::vector& get_linear_velocity() const noexcept + [[nodiscard]] inline const math::fvec3& get_linear_velocity() const noexcept { return m_linear_velocity; } /// Returns the angular velocity of the rigid body, in rad/s. - [[nodiscard]] inline const math::vector& get_angular_velocity() const noexcept + [[nodiscard]] inline const math::fvec3& get_angular_velocity() const noexcept { return m_angular_velocity; } /// Returns the total pre-integrated force, in N. - [[nodiscard]] inline const math::vector& get_applied_force() const noexcept + [[nodiscard]] inline const math::fvec3& get_applied_force() const noexcept { return m_applied_force; } /// Returns the total pre-integrated torque, in Nâ‹…m. - [[nodiscard]] inline const math::vector& get_applied_torque() const noexcept + [[nodiscard]] inline const math::fvec3& get_applied_torque() const noexcept { return m_applied_torque; } @@ -327,7 +327,7 @@ public: * * @return Point velocity. */ - [[nodiscard]] inline math::vector get_point_velocity(const math::vector& radius) const noexcept + [[nodiscard]] inline math::fvec3 get_point_velocity(const math::fvec3& radius) const noexcept { return m_linear_velocity + math::cross(m_angular_velocity, radius); } @@ -346,7 +346,7 @@ public: * @param force Force to apply, in N. * @param radius Radius vector from the center of mass to the point at which the force should be applied. */ - inline void apply_force(const math::vector& force, const math::vector& radius) noexcept + inline void apply_force(const math::fvec3& force, const math::fvec3& radius) noexcept { m_applied_force += force; m_applied_torque += math::cross(radius, force); @@ -357,7 +357,7 @@ public: * * @param force Force to apply, in N. */ - inline void apply_central_force(const math::vector& force) noexcept + inline void apply_central_force(const math::fvec3& force) noexcept { m_applied_force += force; } @@ -367,7 +367,7 @@ public: * * @param torque Torque to apply. */ - inline void apply_torque(const math::vector& torque) noexcept + inline void apply_torque(const math::fvec3& torque) noexcept { m_applied_torque += torque; } @@ -378,7 +378,7 @@ public: * @param impulse Impulse to apply, in Nâ‹…s. * @param radius Radius vector from the center of mass to the point at which the impulse should be applied. */ - inline void apply_impulse(const math::vector& impulse, const math::vector& radius) noexcept + inline void apply_impulse(const math::fvec3& impulse, const math::fvec3& radius) noexcept { m_linear_momentum += impulse; m_angular_momentum += math::cross(radius, impulse); @@ -393,7 +393,7 @@ public: * * @param impulse Impulse to apply, in Nâ‹…s. */ - inline void apply_central_impulse(const math::vector& impulse) noexcept + inline void apply_central_impulse(const math::fvec3& impulse) noexcept { m_linear_momentum += impulse; @@ -406,7 +406,7 @@ public: * * @param torque Torque impulse to apply. */ - inline void apply_torque_impulse(const math::vector& torque) noexcept + inline void apply_torque_impulse(const math::fvec3& torque) noexcept { m_angular_momentum += torque; @@ -417,8 +417,8 @@ public: /// Clears all pre-integrated forces. inline void clear_applied_forces() noexcept { - m_applied_force = math::vector::zero(); - m_applied_torque = math::vector::zero(); + m_applied_force = math::fvec3::zero(); + m_applied_torque = math::fvec3::zero(); } /** @@ -463,7 +463,7 @@ private: math::transform m_previous_transform{math::transform::identity()}; /// Center of mass. - math::vector m_center_of_mass{math::vector::zero()}; + math::fvec3 m_center_of_mass{math::fvec3::zero()}; /// Mass, in kg. float m_mass{1.0f}; @@ -487,22 +487,22 @@ private: std::shared_ptr m_collider; /// Linear momentum, in kgâ‹…m/s. - math::vector m_linear_momentum{math::vector::zero()}; + math::fvec3 m_linear_momentum{math::fvec3::zero()}; /// Angular momentum, in kgâ‹…m^2â‹…s^-1. - math::vector m_angular_momentum{math::vector::zero()}; + math::fvec3 m_angular_momentum{math::fvec3::zero()}; /// Linear velocity, in m/s. - math::vector m_linear_velocity{math::vector::zero()}; + math::fvec3 m_linear_velocity{math::fvec3::zero()}; /// Angular velocity, in rad/s. - math::vector m_angular_velocity{math::vector::zero()}; + math::fvec3 m_angular_velocity{math::fvec3::zero()}; /// Applied force, in N. - math::vector m_applied_force{math::vector::zero()}; + math::fvec3 m_applied_force{math::fvec3::zero()}; /// Applied torque, in Nâ‹…m. - math::vector m_applied_torque{math::vector::zero()}; + math::fvec3 m_applied_torque{math::fvec3::zero()}; }; } // namespace physics diff --git a/src/engine/physics/orbit/elements.hpp b/src/engine/physics/orbit/elements.hpp index 8ba0ef6..ac7bf3a 100644 --- a/src/engine/physics/orbit/elements.hpp +++ b/src/engine/physics/orbit/elements.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_PHYSICS_ORBIT_ELEMENTS_HPP #define ANTKEEPER_PHYSICS_ORBIT_ELEMENTS_HPP -#include +#include #include #include diff --git a/src/engine/physics/orbit/frame.hpp b/src/engine/physics/orbit/frame.hpp index cadf5b0..9ecc288 100644 --- a/src/engine/physics/orbit/frame.hpp +++ b/src/engine/physics/orbit/frame.hpp @@ -39,11 +39,11 @@ namespace pqw { * @return PQW spherical coordinates, in the ISO order of radial distance, inclination (radians), and true anomaly (radians). */ template - math::vector3 spherical(const math::vector3& v) + math::vec3 spherical(const math::vec3& v) { const T xx_yy = v.x() * v.x() + v.y() * v.y(); - return math::vector3 + return math::vec3 { std::sqrt(xx_yy + v.z() * v.z()), std::atan2(v.z(), std::sqrt(xx_yy)), @@ -61,14 +61,14 @@ namespace pqw { * @return PQW spherical coordinates, in the ISO order of radial distance, inclination (radians), and true anomaly (radians). */ template - math::vector3 spherical(T ec, T a, T ea, T b) + math::vec3 spherical(T ec, T a, T ea, T b) { const T x = a * (std::cos(ea) - ec); const T y = b * std::sin(ea); const T d = std::sqrt(x * x + y * y); const T ta = std::atan2(y, x); - return math::vector3{d, T(0), ta}; + return math::vec3{d, T(0), ta}; } /** @@ -80,7 +80,7 @@ namespace pqw { * @return PQW spherical coordinates, in the ISO order of radial distance, inclination (radians), and true anomaly (radians). */ template - math::vector3 spherical(T ec, T a, T ea) + math::vec3 spherical(T ec, T a, T ea) { const T b = a * std::sqrt(T(1) - ec * ec); return spherical(ec, a, ea, b); @@ -93,11 +93,11 @@ namespace pqw { * @return PQW Cartesian coordinates. */ template - math::vector3 cartesian(const math::vector3& v) + math::vec3 cartesian(const math::vec3& v) { const T x = v[0] * std::cos(v[1]); - return math::vector3 + return math::vec3 { x * std::cos(v[2]), x * std::sin(v[2]), @@ -115,7 +115,7 @@ namespace pqw { * @return PQW Cartesian coordinates. */ template - math::vector3 cartesian(T ec, T a, T ea, T b) + math::vec3 cartesian(T ec, T a, T ea, T b) { return cartesian(spherical(ec, a, ea, b)); } @@ -129,7 +129,7 @@ namespace pqw { * @return PQW Cartesian coordinates. */ template - math::vector3 cartesian(T ec, T a, T ea) + math::vec3 cartesian(T ec, T a, T ea) { return cartesian(spherical(ec, a, ea)); } @@ -167,11 +167,11 @@ namespace bci { * @return BCI Cartesian coordinates. */ template - math::vector3 cartesian(const math::vector3& v) + math::vec3 cartesian(const math::vec3& v) { const T x = v[0] * std::cos(v[1]); - return math::vector3 + return math::vec3 { x * std::cos(v[2]), x * std::sin(v[2]), @@ -186,11 +186,11 @@ namespace bci { * @return BCI spherical coordinates, in the ISO order of radial distance, declination (radians), and right ascension (radians). */ template - math::vector3 spherical(const math::vector3& v) + math::vec3 spherical(const math::vec3& v) { const T xx_yy = v.x() * v.x() + v.y() * v.y(); - return math::vector3 + return math::vec3 { std::sqrt(xx_yy + v.z() * v.z()), std::atan2(v.z(), std::sqrt(xx_yy)), @@ -255,11 +255,11 @@ namespace bcbf { * @return BCBF Cartesian coordinates. */ template - math::vector3 cartesian(const math::vector3& v) + math::vec3 cartesian(const math::vec3& v) { const T x = v[0] * std::cos(v[1]); - return math::vector3 + return math::vec3 { x * std::cos(v[2]), x * std::sin(v[2]), @@ -274,11 +274,11 @@ namespace bcbf { * @return BCBF spherical coordinates, in the ISO order of radial distance, latitude (radians), and longitude (radians). */ template - math::vector3 spherical(const math::vector3& v) + math::vec3 spherical(const math::vec3& v) { const T xx_yy = v.x() * v.x() + v.y() * v.y(); - return math::vector3 + return math::vec3 { std::sqrt(xx_yy + v.z() * v.z()), std::atan2(v.z(), std::sqrt(xx_yy)), @@ -322,7 +322,7 @@ namespace bcbf { template math::transformation::se3 to_enu(T distance, T latitude, T longitude) { - const math::vector3 t = {T(0), T(0), -distance}; + const math::vec3 t = {T(0), T(0), -distance}; const math::quaternion r = math::normalize ( math::quaternion::rotate_x(-math::half_pi + latitude) * @@ -344,12 +344,12 @@ namespace enu { * @return ENU Cartesian coordinates. */ template - math::vector3 cartesian(const math::vector3& v) + math::vec3 cartesian(const math::vec3& v) { const T x = v[0] * std::cos(v[1]); const T y = math::half_pi - v[2]; - return math::vector3 + return math::vec3 { x * std::cos(y), x * std::sin(y), @@ -364,11 +364,11 @@ namespace enu { * @return ENU spherical coordinates, in the ISO order of radial distance, elevation (radians), and azimuth (radians). */ template - math::vector3 spherical(const math::vector3& v) + math::vec3 spherical(const math::vec3& v) { const T xx_yy = v.x() * v.x() + v.y() * v.y(); - return math::vector3 + return math::vec3 { std::sqrt(xx_yy + v.z() * v.z()), std::atan2(v.z(), std::sqrt(xx_yy)), @@ -387,7 +387,7 @@ namespace enu { template math::transformation::se3 to_bcbf(T distance, T latitude, T longitude) { - const math::vector3 t = {T(0), T(0), distance}; + const math::vec3 t = {T(0), T(0), distance}; const math::quaternion r = math::normalize ( math::quaternion::rotate_z(longitude + math::half_pi) * diff --git a/src/engine/physics/orbit/state.hpp b/src/engine/physics/orbit/state.hpp index 109c97b..494485a 100644 --- a/src/engine/physics/orbit/state.hpp +++ b/src/engine/physics/orbit/state.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_PHYSICS_ORBIT_STATE_HPP #define ANTKEEPER_PHYSICS_ORBIT_STATE_HPP -#include +#include namespace physics { namespace orbit { @@ -37,7 +37,7 @@ struct state typedef T scalar_type; /// Vector type. - typedef math::vector3 vector_type; + typedef math::vec3 vector_type; /// Cartesian orbital position vector (r). vector_type r; diff --git a/src/engine/physics/orbit/trajectory.hpp b/src/engine/physics/orbit/trajectory.hpp index ebf8e4a..0f85d81 100644 --- a/src/engine/physics/orbit/trajectory.hpp +++ b/src/engine/physics/orbit/trajectory.hpp @@ -56,11 +56,11 @@ struct trajectory * @param t Time, on `[t0, t1)`. * @return Trajectory position at time @p t. */ - [[nodiscard]] math::vector position(T t) const; + [[nodiscard]] math::vec3 position(T t) const; }; template -math::vector trajectory::position(T t) const +math::vec3 trajectory::position(T t) const { t -= t0; std::size_t i = static_cast(t / dt); @@ -71,7 +71,7 @@ math::vector trajectory::position(T t) const t = (t / dt - i) * T(2) - T(1); - math::vector3 r; + math::vec3 r; r.x() = math::polynomial::chebyshev::evaluate(ax, ay, t); r.y() = math::polynomial::chebyshev::evaluate(ay, az, t); r.z() = math::polynomial::chebyshev::evaluate(az, az + n, t); diff --git a/src/engine/render/context.hpp b/src/engine/render/context.hpp index 91cc03e..6eb3c36 100644 --- a/src/engine/render/context.hpp +++ b/src/engine/render/context.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_RENDER_CONTEXT_HPP #define ANTKEEPER_RENDER_CONTEXT_HPP -#include +#include #include #include diff --git a/src/engine/render/material-variable-type.hpp b/src/engine/render/material-variable-type.hpp index a3f9756..a9f8e7f 100644 --- a/src/engine/render/material-variable-type.hpp +++ b/src/engine/render/material-variable-type.hpp @@ -29,25 +29,25 @@ namespace render { */ enum class material_variable_type: std::uint8_t { - bool1, - bool2, - bool3, - bool4, - int1, - int2, - int3, - int4, - uint1, - uint2, - uint3, - uint4, - float1, - float2, - float3, - float4, - float2x2, - float3x3, - float4x4, + bvec1, + bvec2, + bvec3, + bvec4, + ivec1, + ivec2, + ivec3, + ivec4, + uvec1, + uvec2, + uvec3, + uvec4, + fvec1, + fvec2, + fvec3, + fvec4, + fmat2, + fmat3, + fmat4, texture_1d, texture_2d, texture_3d, diff --git a/src/engine/render/material-variable.hpp b/src/engine/render/material-variable.hpp index d5866a6..6e10839 100644 --- a/src/engine/render/material-variable.hpp +++ b/src/engine/render/material-variable.hpp @@ -20,7 +20,8 @@ #ifndef ANTKEEPER_RENDER_MATERIAL_VARIABLE_HPP #define ANTKEEPER_RENDER_MATERIAL_VARIABLE_HPP -#include +#include +#include #include #include #include @@ -162,208 +163,208 @@ private: }; /// Boolean material variable. -using material_bool = material_variable; +using matvar_bool = material_variable; /// 2-dimensional boolean vector material variable. -using material_bool2 = material_variable; +using matvar_bvec2 = material_variable; /// 3-dimensional boolean vector material variable. -using material_bool3 = material_variable; +using matvar_bvec3 = material_variable; /// 4-dimensional boolean vector material variable. -using material_bool4 = material_variable; +using matvar_bvec4 = material_variable; /// Integer material variable. -using material_int = material_variable; +using matvar_int = material_variable; /// 2-dimensional integer vector material variable. -using material_int2 = material_variable; +using matvar_ivec2 = material_variable; /// 3-dimensional integer vector material variable. -using material_int3 = material_variable; +using matvar_ivec3 = material_variable; /// 4-dimensional integer vector material variable. -using material_int4 = material_variable; +using matvar_ivec4 = material_variable; /// Unsigned integer material variable. -using material_uint = material_variable; +using matvar_uint = material_variable; /// 2-dimensional unsigned integer vector material variable. -using material_uint2 = material_variable; +using matvar_uvec2 = material_variable; /// 3-dimensional unsigned integer vector material variable. -using material_uint3 = material_variable; +using matvar_uvec3 = material_variable; /// 4-dimensional unsigned integer vector material variable. -using material_uint4 = material_variable; +using matvar_uvec4 = material_variable; /// Floating-point material variable. -using material_float = material_variable; +using matvar_float = material_variable; /// 2-dimensional floating-point vector material variable. -using material_float2 = material_variable; +using matvar_fvec2 = material_variable; /// 3-dimensional floating-point vector material variable. -using material_float3 = material_variable; +using matvar_fvec3 = material_variable; /// 4-dimensional floating-point vector material variable. -using material_float4 = material_variable; +using matvar_fvec4 = material_variable; /// 2x2 floating-point matrix material variable. -using material_float2x2 = material_variable; +using matvar_fmat2 = material_variable; /// 3x3 floating-point matrix material variable. -using material_float3x3 = material_variable; +using matvar_fmat3 = material_variable; /// 4x4 floating-point matrix material variable. -using material_float4x4 = material_variable; +using matvar_fmat4 = material_variable; /// 1-dimensional texture material variable. -using material_texture_1d = material_variable>; +using matvar_texture_1d = material_variable>; /// 2-dimensional texture material variable. -using material_texture_2d = material_variable>; +using matvar_texture_2d = material_variable>; /// 3-dimensional texture material variable. -using material_texture_3d = material_variable>; +using matvar_texture_3d = material_variable>; /// Cube texture material variable. -using material_texture_cube = material_variable>; +using matvar_texture_cube = material_variable>; template <> -inline constexpr material_variable_type material_bool::type() const noexcept +inline constexpr material_variable_type matvar_bool::type() const noexcept { - return material_variable_type::bool1; + return material_variable_type::bvec1; } template <> -inline constexpr material_variable_type material_bool2::type() const noexcept +inline constexpr material_variable_type matvar_bvec2::type() const noexcept { - return material_variable_type::bool2; + return material_variable_type::bvec2; } template <> -inline constexpr material_variable_type material_bool3::type() const noexcept +inline constexpr material_variable_type matvar_bvec3::type() const noexcept { - return material_variable_type::bool3; + return material_variable_type::bvec3; } template <> -inline constexpr material_variable_type material_bool4::type() const noexcept +inline constexpr material_variable_type matvar_bvec4::type() const noexcept { - return material_variable_type::bool4; + return material_variable_type::bvec4; } template <> -inline constexpr material_variable_type material_int::type() const noexcept +inline constexpr material_variable_type matvar_int::type() const noexcept { - return material_variable_type::int1; + return material_variable_type::ivec1; } template <> -inline constexpr material_variable_type material_int2::type() const noexcept +inline constexpr material_variable_type matvar_ivec2::type() const noexcept { - return material_variable_type::int2; + return material_variable_type::ivec2; } template <> -inline constexpr material_variable_type material_int3::type() const noexcept +inline constexpr material_variable_type matvar_ivec3::type() const noexcept { - return material_variable_type::int3; + return material_variable_type::ivec3; } template <> -inline constexpr material_variable_type material_int4::type() const noexcept +inline constexpr material_variable_type matvar_ivec4::type() const noexcept { - return material_variable_type::int4; + return material_variable_type::ivec4; } template <> -inline constexpr material_variable_type material_uint::type() const noexcept +inline constexpr material_variable_type matvar_uint::type() const noexcept { - return material_variable_type::uint1; + return material_variable_type::uvec1; } template <> -inline constexpr material_variable_type material_uint2::type() const noexcept +inline constexpr material_variable_type matvar_uvec2::type() const noexcept { - return material_variable_type::uint2; + return material_variable_type::uvec2; } template <> -inline constexpr material_variable_type material_uint3::type() const noexcept +inline constexpr material_variable_type matvar_uvec3::type() const noexcept { - return material_variable_type::uint3; + return material_variable_type::uvec3; } template <> -inline constexpr material_variable_type material_uint4::type() const noexcept +inline constexpr material_variable_type matvar_uvec4::type() const noexcept { - return material_variable_type::uint4; + return material_variable_type::uvec4; } template <> -inline constexpr material_variable_type material_float::type() const noexcept +inline constexpr material_variable_type matvar_float::type() const noexcept { - return material_variable_type::float1; + return material_variable_type::fvec1; } template <> -inline constexpr material_variable_type material_float2::type() const noexcept +inline constexpr material_variable_type matvar_fvec2::type() const noexcept { - return material_variable_type::float2; + return material_variable_type::fvec2; } template <> -inline constexpr material_variable_type material_float3::type() const noexcept +inline constexpr material_variable_type matvar_fvec3::type() const noexcept { - return material_variable_type::float3; + return material_variable_type::fvec3; } template <> -inline constexpr material_variable_type material_float4::type() const noexcept +inline constexpr material_variable_type matvar_fvec4::type() const noexcept { - return material_variable_type::float4; + return material_variable_type::fvec4; } template <> -inline constexpr material_variable_type material_float2x2::type() const noexcept +inline constexpr material_variable_type matvar_fmat2::type() const noexcept { - return material_variable_type::float2x2; + return material_variable_type::fmat2; } template <> -inline constexpr material_variable_type material_float3x3::type() const noexcept +inline constexpr material_variable_type matvar_fmat3::type() const noexcept { - return material_variable_type::float3x3; + return material_variable_type::fmat3; } template <> -inline constexpr material_variable_type material_float4x4::type() const noexcept +inline constexpr material_variable_type matvar_fmat4::type() const noexcept { - return material_variable_type::float4x4; + return material_variable_type::fmat4; } template <> -inline constexpr material_variable_type material_texture_1d::type() const noexcept +inline constexpr material_variable_type matvar_texture_1d::type() const noexcept { return material_variable_type::texture_1d; } template <> -inline constexpr material_variable_type material_texture_2d::type() const noexcept +inline constexpr material_variable_type matvar_texture_2d::type() const noexcept { return material_variable_type::texture_2d; } template <> -inline constexpr material_variable_type material_texture_3d::type() const noexcept +inline constexpr material_variable_type matvar_texture_3d::type() const noexcept { return material_variable_type::texture_3d; } template <> -inline constexpr material_variable_type material_texture_cube::type() const noexcept +inline constexpr material_variable_type matvar_texture_cube::type() const noexcept { return material_variable_type::texture_cube; } diff --git a/src/engine/render/material.cpp b/src/engine/render/material.cpp index b555011..9760a8f 100644 --- a/src/engine/render/material.cpp +++ b/src/engine/render/material.cpp @@ -141,7 +141,7 @@ static bool load_texture_1d_property(resource_manager& resource_manager, render: if (json.is_array()) { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load textures std::size_t i = 0; @@ -156,7 +156,7 @@ static bool load_texture_1d_property(resource_manager& resource_manager, render: else { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load texture variable->set(resource_manager.load(json.get())); @@ -173,7 +173,7 @@ static bool load_texture_2d_property(resource_manager& resource_manager, render: if (json.is_array()) { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load textures std::size_t i = 0; @@ -188,7 +188,7 @@ static bool load_texture_2d_property(resource_manager& resource_manager, render: else { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load texture variable->set(resource_manager.load(json.get())); @@ -205,7 +205,7 @@ static bool load_texture_3d_property(resource_manager& resource_manager, render: if (json.is_array()) { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load textures std::size_t i = 0; @@ -220,7 +220,7 @@ static bool load_texture_3d_property(resource_manager& resource_manager, render: else { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load texture variable->set(resource_manager.load(json.get())); @@ -237,7 +237,7 @@ static bool load_texture_cube_property(resource_manager& resource_manager, rende if (json.is_array()) { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load textures std::size_t i = 0; @@ -252,7 +252,7 @@ static bool load_texture_cube_property(resource_manager& resource_manager, rende else { // Create variable - auto variable = std::make_shared(json.size()); + auto variable = std::make_shared(json.size()); // Load texture variable->set(resource_manager.load(json.get())); @@ -523,11 +523,11 @@ std::unique_ptr resource_loader::load(::reso if (type.find("float") != std::string::npos) { if (columns == 2 && rows == 2) - load_matrix_property(*material, key, columns, rows, value_element.value()); + load_matrix_property(*material, key, columns, rows, value_element.value()); else if (columns == 3 && rows == 3) - load_matrix_property(*material, key, columns, rows, value_element.value()); + load_matrix_property(*material, key, columns, rows, value_element.value()); else if (columns == 4 && rows == 4) - load_matrix_property(*material, key, columns, rows, value_element.value()); + load_matrix_property(*material, key, columns, rows, value_element.value()); } } // If variable type is a vector @@ -538,38 +538,38 @@ std::unique_ptr resource_loader::load(::reso if (type.find("float") != std::string::npos) { if (size == 2) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 3) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 4) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); } else if (type.find("uint") != std::string::npos) { if (size == 2) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 3) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 4) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); } else if (type.find("int") != std::string::npos) { if (size == 2) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 3) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 4) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); } else if (type.find("bool") != std::string::npos) { if (size == 2) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 3) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); else if (size == 4) - load_vector_property(*material, key, size, value_element.value()); + load_vector_property(*material, key, size, value_element.value()); } } // If variable type is a scalar diff --git a/src/engine/render/operation.hpp b/src/engine/render/operation.hpp index 99f7ee7..842ec78 100644 --- a/src/engine/render/operation.hpp +++ b/src/engine/render/operation.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_RENDER_OPERATION_HPP #define ANTKEEPER_RENDER_OPERATION_HPP -#include +#include #include #include #include @@ -41,11 +41,11 @@ struct operation std::size_t index_count{0}; std::shared_ptr material; - float4x4 transform{float4x4::identity()}; + math::fmat4 transform{math::fmat4::identity()}; float depth{0.0f}; std::size_t instance_count{0}; - std::span matrix_palette{}; + std::span matrix_palette{}; }; } // namespace render diff --git a/src/engine/render/passes/bloom-pass.cpp b/src/engine/render/passes/bloom-pass.cpp index b788599..3693ec1 100644 --- a/src/engine/render/passes/bloom-pass.cpp +++ b/src/engine/render/passes/bloom-pass.cpp @@ -65,7 +65,7 @@ bloom_pass::bloom_pass(gl::rasterizer* rasterizer, resource_manager* resource_ma // Build upsample shader program upsample_shader = upsample_shader_template->build(); - const float2 vertex_positions[] = + const math::fvec2 vertex_positions[] = { {-1.0f, 1.0f}, {-1.0f, -1.0f}, diff --git a/src/engine/render/passes/bloom-pass.hpp b/src/engine/render/passes/bloom-pass.hpp index 90e8d47..02c210b 100644 --- a/src/engine/render/passes/bloom-pass.hpp +++ b/src/engine/render/passes/bloom-pass.hpp @@ -106,7 +106,7 @@ private: std::vector> framebuffers; std::vector> textures; float filter_radius; - float2 corrected_filter_radius; + math::fvec2 corrected_filter_radius; std::vector> command_buffer; }; diff --git a/src/engine/render/passes/clear-pass.cpp b/src/engine/render/passes/clear-pass.cpp index 34d5116..62cf27b 100644 --- a/src/engine/render/passes/clear-pass.cpp +++ b/src/engine/render/passes/clear-pass.cpp @@ -51,7 +51,7 @@ void clear_pass::set_cleared_buffers(bool color, bool depth, bool stencil) rebuild_command_buffer(); } -void clear_pass::set_clear_color(const float4& color) +void clear_pass::set_clear_color(const math::fvec4& color) { clear_color = color; } diff --git a/src/engine/render/passes/clear-pass.hpp b/src/engine/render/passes/clear-pass.hpp index 89be077..fba0c04 100644 --- a/src/engine/render/passes/clear-pass.hpp +++ b/src/engine/render/passes/clear-pass.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_RENDER_CLEAR_PASS_HPP #include -#include +#include #include namespace render { @@ -50,7 +50,7 @@ public: * * @param color Clear color. */ - void set_clear_color(const float4& color); + void set_clear_color(const math::fvec4& color); /** * Sets the depth buffer clear value. @@ -72,7 +72,7 @@ private: bool clear_color_buffer; bool clear_depth_buffer; bool clear_stencil_buffer; - float4 clear_color; + math::fvec4 clear_color; float clear_depth; int clear_stencil; diff --git a/src/engine/render/passes/final-pass.cpp b/src/engine/render/passes/final-pass.cpp index c763dcc..17228fa 100644 --- a/src/engine/render/passes/final-pass.cpp +++ b/src/engine/render/passes/final-pass.cpp @@ -56,7 +56,7 @@ final_pass::final_pass(gl::rasterizer* rasterizer, const gl::framebuffer* frameb debug::log::warning("{}", shader_template->configure(gl::shader_stage::vertex)); } - const float2 vertex_positions[] = + const math::fvec2 vertex_positions[] = { {-1.0f, 1.0f}, {-1.0f, -1.0f}, diff --git a/src/engine/render/passes/final-pass.hpp b/src/engine/render/passes/final-pass.hpp index b3a6da1..bd28d60 100644 --- a/src/engine/render/passes/final-pass.hpp +++ b/src/engine/render/passes/final-pass.hpp @@ -60,7 +60,7 @@ private: float bloom_weight; std::shared_ptr blue_noise_texture; float blue_noise_scale; - float2 resolution; + math::fvec2 resolution; float time; int frame{}; diff --git a/src/engine/render/passes/fxaa-pass.cpp b/src/engine/render/passes/fxaa-pass.cpp index 4e22dc6..baf842d 100644 --- a/src/engine/render/passes/fxaa-pass.cpp +++ b/src/engine/render/passes/fxaa-pass.cpp @@ -44,7 +44,7 @@ fxaa_pass::fxaa_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuf // Build FXAA shader program shader = shader_template->build(); - const float2 vertex_positions[] = + const math::fvec2 vertex_positions[] = { {-1.0f, 1.0f}, {-1.0f, -1.0f}, @@ -125,7 +125,7 @@ void fxaa_pass::rebuild_command_buffer() ( [&, texel_size_var]() { - const float2 texel_size = 1.0f / float2{static_cast(source_texture->get_width()), static_cast(source_texture->get_height())}; + const math::fvec2 texel_size = 1.0f / math::fvec2{static_cast(source_texture->get_width()), static_cast(source_texture->get_height())}; texel_size_var->update(texel_size); } ); diff --git a/src/engine/render/passes/ground-pass.cpp b/src/engine/render/passes/ground-pass.cpp index 56fc81e..9793be5 100644 --- a/src/engine/render/passes/ground-pass.cpp +++ b/src/engine/render/passes/ground-pass.cpp @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -78,21 +78,21 @@ void ground_pass::render(render::context& ctx) auto viewport = framebuffer->get_dimensions(); rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport)); - float2 resolution = {static_cast(std::get<0>(viewport)), static_cast(std::get<1>(viewport))}; + math::fvec2 resolution = {static_cast(std::get<0>(viewport)), static_cast(std::get<1>(viewport))}; const scene::camera& camera = *ctx.camera; float clip_near = camera.get_clip_near_tween().interpolate(ctx.alpha); float clip_far = camera.get_clip_far_tween().interpolate(ctx.alpha); - float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (clip_near + clip_far) * 0.5f; - float4x4 model = math::scale(math::matrix4::identity(), model_scale); - float4x4 view = float4x4(float3x3(ctx.view)); - float4x4 model_view = view * model; - const float4x4& projection = ctx.projection; - const float4x4& view_projection = ctx.view_projection; - float4x4 model_view_projection = projection * model_view; + math::fvec3 model_scale = math::fvec3{1.0f, 1.0f, 1.0f} * (clip_near + clip_far) * 0.5f; + math::fmat4 model = math::scale(math::fmat4::identity(), model_scale); + math::fmat4 view = math::fmat4(math::fmat3(ctx.view)); + math::fmat4 model_view = view * model; + const math::fmat4& projection = ctx.projection; + const math::fmat4& view_projection = ctx.view_projection; + math::fmat4 model_view_projection = projection * model_view; - float3 directional_light_color = {0.0f, 0.0f, 0.0f}; - float3 directional_light_direction = {0.0f, 0.0f, 0.0f}; + math::fvec3 directional_light_color = {0.0f, 0.0f, 0.0f}; + math::fvec3 directional_light_direction = {0.0f, 0.0f, 0.0f}; // Collect lights const std::list* lights = ctx.collection->get_objects(scene::light::object_type_id); @@ -111,7 +111,7 @@ void ground_pass::render(render::context& ctx) const scene::directional_light* directional_light = static_cast(light); // Pre-expose light - float3 light_color = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure; + math::fvec3 light_color = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure; if (light_color.x() < directional_light_color.x()) break; diff --git a/src/engine/render/passes/ground-pass.hpp b/src/engine/render/passes/ground-pass.hpp index 0318382..af28831 100644 --- a/src/engine/render/passes/ground-pass.hpp +++ b/src/engine/render/passes/ground-pass.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_RENDER_GROUND_PASS_HPP #include -#include +#include #include #include #include diff --git a/src/engine/render/passes/material-pass.cpp b/src/engine/render/passes/material-pass.cpp index 7d33cc5..7aaaa16 100644 --- a/src/engine/render/passes/material-pass.cpp +++ b/src/engine/render/passes/material-pass.cpp @@ -622,8 +622,8 @@ void material_pass::build_shader_command_buffer(std::vectorupdate(std::span{rectangle_light_colors.data(), rectangle_light_count}); - rectangle_light_corners_var->update(std::span{rectangle_light_corners.data(), rectangle_light_count * 4}); + rectangle_light_colors_var->update(std::span{rectangle_light_colors.data(), rectangle_light_count}); + rectangle_light_corners_var->update(std::span{rectangle_light_corners.data(), rectangle_light_count * 4}); } ); } @@ -641,8 +641,8 @@ void material_pass::build_shader_command_buffer(std::vectorupdate(std::span{directional_light_colors.data(), directional_light_count}); - directional_light_directions_var->update(std::span{directional_light_directions.data(), directional_light_count}); + directional_light_colors_var->update(std::span{directional_light_colors.data(), directional_light_count}); + directional_light_directions_var->update(std::span{directional_light_directions.data(), directional_light_count}); } ); } @@ -693,8 +693,8 @@ void material_pass::build_shader_command_buffer(std::vectorupdate(std::span{point_light_colors.data(), point_light_count}); - point_light_positions_var->update(std::span{point_light_positions.data(), point_light_count}); + point_light_colors_var->update(std::span{point_light_colors.data(), point_light_count}); + point_light_positions_var->update(std::span{point_light_positions.data(), point_light_count}); } ); } @@ -716,10 +716,10 @@ void material_pass::build_shader_command_buffer(std::vectorupdate(std::span{spot_light_colors.data(), spot_light_count}); - spot_light_positions_var->update(std::span{spot_light_positions.data(), spot_light_count}); - spot_light_directions_var->update(std::span{spot_light_directions.data(), spot_light_count}); - spot_light_cutoffs_var->update(std::span{spot_light_cutoffs.data(), spot_light_count}); + spot_light_colors_var->update(std::span{spot_light_colors.data(), spot_light_count}); + spot_light_positions_var->update(std::span{spot_light_positions.data(), spot_light_count}); + spot_light_directions_var->update(std::span{spot_light_directions.data(), spot_light_count}); + spot_light_cutoffs_var->update(std::span{spot_light_cutoffs.data(), spot_light_count}); } ); } @@ -778,7 +778,7 @@ void material_pass::build_geometry_command_buffer(std::vectorupdate(math::transpose(math::inverse(math::matrix(*model)))); + normal_model_var->update(math::transpose(math::inverse(math::fmat3(*model)))); } ); } @@ -794,7 +794,7 @@ void material_pass::build_geometry_command_buffer(std::vectorupdate(model_view); - normal_model_view_var->update(math::transpose(math::inverse(math::matrix(model_view)))); + normal_model_view_var->update(math::transpose(math::inverse(math::fmat3(model_view)))); } ); } @@ -811,7 +811,7 @@ void material_pass::build_geometry_command_buffer(std::vectorupdate(math::transpose(math::inverse(math::matrix(model_view)))); + normal_model_view_var->update(math::transpose(math::inverse(math::fmat3(model_view)))); } ); } @@ -849,231 +849,231 @@ void material_pass::build_material_command_buffer(std::vectortype()) { - /// @TODO render::material_bool is broken due to the std::vector specialization. - // case gl::shader_variable_type::bool1: - // if (material_var->type() == material_variable_type::bool1) + /// @TODO render::matvar_bool is broken due to the std::vector specialization. + // case gl::shader_variable_type::bvec1: + // if (material_var->type() == material_variable_type::bvec1) // { // command_buffer.emplace_back // ( - // [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + // [size, shader_var, material_var = std::static_pointer_cast(material_var)]() // { // shader_var->update(std::span{material_var->data(), size}); // } // ); // } // break; - case gl::shader_variable_type::bool2: - if (material_var->type() == material_variable_type::bool2) + case gl::shader_variable_type::bvec2: + if (material_var->type() == material_variable_type::bvec2) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::bool3: - if (material_var->type() == material_variable_type::bool3) + case gl::shader_variable_type::bvec3: + if (material_var->type() == material_variable_type::bvec3) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::bool4: - if (material_var->type() == material_variable_type::bool4) + case gl::shader_variable_type::bvec4: + if (material_var->type() == material_variable_type::bvec4) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::int1: - if (material_var->type() == material_variable_type::int1) + case gl::shader_variable_type::ivec1: + if (material_var->type() == material_variable_type::ivec1) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::int2: - if (material_var->type() == material_variable_type::int2) + case gl::shader_variable_type::ivec2: + if (material_var->type() == material_variable_type::ivec2) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::int3: - if (material_var->type() == material_variable_type::int3) + case gl::shader_variable_type::ivec3: + if (material_var->type() == material_variable_type::ivec3) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::int4: - if (material_var->type() == material_variable_type::int4) + case gl::shader_variable_type::ivec4: + if (material_var->type() == material_variable_type::ivec4) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::uint1: - if (material_var->type() == material_variable_type::uint1) + case gl::shader_variable_type::uvec1: + if (material_var->type() == material_variable_type::uvec1) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::uint2: - if (material_var->type() == material_variable_type::uint2) + case gl::shader_variable_type::uvec2: + if (material_var->type() == material_variable_type::uvec2) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::uint3: - if (material_var->type() == material_variable_type::uint3) + case gl::shader_variable_type::uvec3: + if (material_var->type() == material_variable_type::uvec3) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::uint4: - if (material_var->type() == material_variable_type::uint4) + case gl::shader_variable_type::uvec4: + if (material_var->type() == material_variable_type::uvec4) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float1: - if (material_var->type() == material_variable_type::float1) + case gl::shader_variable_type::fvec1: + if (material_var->type() == material_variable_type::fvec1) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float2: - if (material_var->type() == material_variable_type::float2) + case gl::shader_variable_type::fvec2: + if (material_var->type() == material_variable_type::fvec2) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float3: - if (material_var->type() == material_variable_type::float3) + case gl::shader_variable_type::fvec3: + if (material_var->type() == material_variable_type::fvec3) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float4: - if (material_var->type() == material_variable_type::float4) + case gl::shader_variable_type::fvec4: + if (material_var->type() == material_variable_type::fvec4) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float2x2: - if (material_var->type() == material_variable_type::float2x2) + case gl::shader_variable_type::fmat2: + if (material_var->type() == material_variable_type::fmat2) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float3x3: - if (material_var->type() == material_variable_type::float3x3) + case gl::shader_variable_type::fmat3: + if (material_var->type() == material_variable_type::fmat3) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } break; - case gl::shader_variable_type::float4x4: - if (material_var->type() == material_variable_type::float4x4) + case gl::shader_variable_type::fmat4: + if (material_var->type() == material_variable_type::fmat4) { command_buffer.emplace_back ( - [size, shader_var, material_var = std::static_pointer_cast(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { - shader_var->update(std::span{material_var->data(), size}); + shader_var->update(std::span{material_var->data(), size}); } ); } @@ -1083,7 +1083,7 @@ void material_pass::build_material_command_buffer(std::vector(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span>{material_var->data(), size}); } @@ -1095,7 +1095,7 @@ void material_pass::build_material_command_buffer(std::vector(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span>{material_var->data(), size}); } @@ -1107,7 +1107,7 @@ void material_pass::build_material_command_buffer(std::vector(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span>{material_var->data(), size}); } @@ -1119,7 +1119,7 @@ void material_pass::build_material_command_buffer(std::vector(material_var)]() + [size, shader_var, material_var = std::static_pointer_cast(material_var)]() { shader_var->update(std::span>{material_var->data(), size}); } diff --git a/src/engine/render/passes/material-pass.hpp b/src/engine/render/passes/material-pass.hpp index f7c8790..67bc20b 100644 --- a/src/engine/render/passes/material-pass.hpp +++ b/src/engine/render/passes/material-pass.hpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -47,7 +47,7 @@ public: /// Sets the material to be used when a render operation is missing a material. If no fallback material is specified, render operations without materials will not be processed. void set_fallback_material(std::shared_ptr fallback); - inline void set_mouse_position(const float2& position) + inline void set_mouse_position(const math::fvec2& position) { mouse_position = position; } @@ -89,12 +89,12 @@ private: void build_material_command_buffer(std::vector>& command_buffer, const gl::shader_program& shader_program, const material& material) const; // Camera - const float4x4* view; - const float4x4* projection; - const float4x4* view_projection; - const float3* camera_position; + const math::fmat4* view; + const math::fmat4* projection; + const math::fmat4* view_projection; + const math::fvec3* camera_position; float camera_exposure; - float2 clip_depth; + math::fvec2 clip_depth; float log_depth_coef; // Light probes @@ -103,32 +103,32 @@ private: std::size_t light_probe_count; // Point lights - std::vector point_light_colors; - std::vector point_light_positions; + std::vector point_light_colors; + std::vector point_light_positions; std::size_t point_light_count; // Directional lights - std::vector directional_light_colors; - std::vector directional_light_directions; + std::vector directional_light_colors; + std::vector directional_light_directions; std::size_t directional_light_count; // Directional shadows std::vector directional_shadow_maps; std::vector directional_shadow_biases; std::vector*> directional_shadow_splits; - std::vector*> directional_shadow_matrices; + std::vector*> directional_shadow_matrices; std::size_t directional_shadow_count; // Spot lights - std::vector spot_light_colors; - std::vector spot_light_positions; - std::vector spot_light_directions; - std::vector spot_light_cutoffs; + std::vector spot_light_colors; + std::vector spot_light_positions; + std::vector spot_light_directions; + std::vector spot_light_cutoffs; std::size_t spot_light_count; // Rectangle lights - std::vector rectangle_light_colors; - std::vector rectangle_light_corners; + std::vector rectangle_light_colors; + std::vector rectangle_light_corners; std::size_t rectangle_light_count; // LTC @@ -143,12 +143,12 @@ private: float timestep; unsigned int frame{0}; float subframe; - float2 resolution; - float2 mouse_position; + math::fvec2 resolution; + math::fvec2 mouse_position; // Geometry - const float4x4* model; - std::span matrix_palette; + const math::fmat4* model; + std::span matrix_palette; /// Hash of the lighting state. std::size_t lighting_state_hash; diff --git a/src/engine/render/passes/outline-pass.cpp b/src/engine/render/passes/outline-pass.cpp index 6a3a23d..9ae9ed3 100644 --- a/src/engine/render/passes/outline-pass.cpp +++ b/src/engine/render/passes/outline-pass.cpp @@ -70,10 +70,10 @@ void outline_pass::render(render::context& ctx) rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport)); // Get camera matrices - float4x4 view = ctx.camera->get_view_tween().interpolate(ctx.alpha); - float4x4 view_projection = ctx.camera->get_view_projection_tween().interpolate(ctx.alpha); + math::fmat4 view = ctx.camera->get_view_tween().interpolate(ctx.alpha); + math::fmat4 view_projection = ctx.camera->get_view_projection_tween().interpolate(ctx.alpha); - float4x4 model_view_projection; + math::fmat4 model_view_projection; glEnable(GL_CULL_FACE); glCullFace(GL_BACK); @@ -153,7 +153,7 @@ void outline_pass::set_outline_width(float width) outline_width = width; } -void outline_pass::set_outline_color(const float4& color) +void outline_pass::set_outline_color(const math::fvec4& color) { outline_color = color; } diff --git a/src/engine/render/passes/outline-pass.hpp b/src/engine/render/passes/outline-pass.hpp index 9694157..cfa0094 100644 --- a/src/engine/render/passes/outline-pass.hpp +++ b/src/engine/render/passes/outline-pass.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_RENDER_OUTLINE_PASS_HPP #include -#include +#include #include #include #include @@ -41,7 +41,7 @@ public: void render(render::context& ctx) override; void set_outline_width(float width); - void set_outline_color(const float4& color); + void set_outline_color(const math::fvec4& color); private: std::unique_ptr fill_shader; @@ -53,7 +53,7 @@ private: const gl::shader_variable* stroke_color_var; float outline_width; - float4 outline_color; + math::fvec4 outline_color; }; } // namespace render diff --git a/src/engine/render/passes/resample-pass.cpp b/src/engine/render/passes/resample-pass.cpp index 2732eb6..6192739 100644 --- a/src/engine/render/passes/resample-pass.cpp +++ b/src/engine/render/passes/resample-pass.cpp @@ -44,7 +44,7 @@ resample_pass::resample_pass(gl::rasterizer* rasterizer, const gl::framebuffer* // Build resample shader program shader = shader_template->build(); - const float2 vertex_positions[] = + const math::fvec2 vertex_positions[] = { {-1.0f, 1.0f}, {-1.0f, -1.0f}, diff --git a/src/engine/render/passes/shadow-map-pass.cpp b/src/engine/render/passes/shadow-map-pass.cpp index 0caf9e7..869f7b8 100644 --- a/src/engine/render/passes/shadow-map-pass.cpp +++ b/src/engine/render/passes/shadow-map-pass.cpp @@ -62,13 +62,13 @@ shadow_map_pass::shadow_map_pass(gl::rasterizer* rasterizer, resource_manager* r skinned_model_view_projection_var = skinned_shader_program->variable("model_view_projection"); // Calculate bias-tile matrices - float4x4 bias_matrix = math::translate(math::matrix4::identity(), float3{0.5f, 0.5f, 0.5f}) * math::scale(math::matrix4::identity(), float3{0.5f, 0.5f, 0.5f}); - float4x4 tile_scale = math::scale(math::matrix4::identity(), float3{0.5f, 0.5f, 1.0f}); + math::fmat4 bias_matrix = math::translate(math::fmat4::identity(), math::fvec3{0.5f, 0.5f, 0.5f}) * math::scale(math::fmat4::identity(), math::fvec3{0.5f, 0.5f, 0.5f}); + math::fmat4 tile_scale = math::scale(math::fmat4::identity(), math::fvec3{0.5f, 0.5f, 1.0f}); for (int i = 0; i < 4; ++i) { float x = static_cast(i % 2) * 0.5f; float y = static_cast(i / 2) * 0.5f; - float4x4 tile_matrix = math::translate(math::matrix4::identity(), float3{x, y, 0.0f}) * tile_scale; + math::fmat4 tile_matrix = math::translate(math::fmat4::identity(), math::fvec3{x, y, 0.0f}) * tile_scale; bias_tile_matrices[i] = tile_matrix * bias_matrix; } } @@ -134,7 +134,7 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: /// @TODO: don't const_cast auto& cascade_distances = const_cast&>(light.get_shadow_cascade_distances()); - auto& cascade_matrices = const_cast&>(light.get_shadow_cascade_matrices()); + auto& cascade_matrices = const_cast&>(light.get_shadow_cascade_matrices()); // Calculate cascade far clipping plane distances cascade_distances[cascade_count - 1] = shadow_clip_far; @@ -153,13 +153,13 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: // Calculate viewports for each shadow map const int shadow_map_resolution = static_cast(light.get_shadow_framebuffer()->get_depth_attachment()->get_width()); const int cascade_resolution = shadow_map_resolution >> 1; - int4 shadow_map_viewports[4]; + math::ivec4 shadow_map_viewports[4]; for (int i = 0; i < 4; ++i) { int x = i % 2; int y = i / 2; - int4& viewport = shadow_map_viewports[i]; + math::ivec4& viewport = shadow_map_viewports[i]; viewport[0] = x * cascade_resolution; viewport[1] = y * cascade_resolution; viewport[2] = cascade_resolution; @@ -167,7 +167,7 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: } // Reverse half z clip-space coordinates of a cube - constexpr math::vector clip_space_cube[8] = + constexpr math::fvec4 clip_space_cube[8] = { {-1, -1, 1, 1}, // NBL { 1, -1, 1, 1}, // NBR @@ -180,11 +180,11 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: }; // Calculate world-space corners of camera view frustum - math::vector view_frustum_corners[8]; + math::fvec3 view_frustum_corners[8]; for (std::size_t i = 0; i < 8; ++i) { - math::vector corner = camera.get_inverse_view_projection() * clip_space_cube[i]; - view_frustum_corners[i] = math::vector(corner) / corner[3]; + math::fvec4 corner = camera.get_inverse_view_projection() * clip_space_cube[i]; + view_frustum_corners[i] = math::fvec3(corner) / corner[3]; } // Sort render operations @@ -195,14 +195,14 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: for (unsigned int i = 0; i < cascade_count; ++i) { // Set viewport for this shadow map - const int4& viewport = shadow_map_viewports[i]; + const math::ivec4& viewport = shadow_map_viewports[i]; rasterizer->set_viewport(viewport[0], viewport[1], viewport[2], viewport[3]); // Calculate world-space corners and center of camera subfrustum const float t_near = (i) ? cascade_distances[i - 1] / camera.get_clip_far() : 0.0f; const float t_far = cascade_distances[i] / camera.get_clip_far(); - math::vector subfrustum_center{0, 0, 0}; - math::vector subfrustum_corners[8]; + math::fvec3 subfrustum_center{0, 0, 0}; + math::fvec3 subfrustum_corners[8]; for (std::size_t i = 0; i < 4; ++i) { subfrustum_corners[i] = math::lerp(view_frustum_corners[i], view_frustum_corners[i + 4], t_near); @@ -214,22 +214,20 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: subfrustum_center *= (1.0f / 8.0f); // Calculate a view-projection matrix from the light's point-of-view - const float3 light_up = light.get_rotation() * config::global_up; - float4x4 light_view = math::look_at(subfrustum_center, subfrustum_center + light.get_direction(), light_up); - float4x4 light_projection = math::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); - float4x4 light_view_projection = light_projection * light_view; + const math::fvec3 light_up = light.get_rotation() * config::global_up; + math::fmat4 light_view = math::look_at(subfrustum_center, subfrustum_center + light.get_direction(), light_up); + math::fmat4 light_projection = math::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); + math::fmat4 light_view_projection = light_projection * light_view; // Calculate AABB of the subfrustum corners in light clip-space - geom::box cropping_bounds; - cropping_bounds.min = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; - cropping_bounds.max = {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; + geom::box cropping_bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < 8; ++i) { - math::vector corner4 = math::vector(subfrustum_corners[i]); + math::fvec4 corner4 = math::fvec4(subfrustum_corners[i]); corner4[3] = 1.0f; corner4 = light_view_projection * corner4; - const math::vector corner3 = math::vector(corner4) / corner4[3]; + const math::fvec3 corner3 = math::fvec3(corner4) / corner4[3]; cropping_bounds.min = math::min(cropping_bounds.min, corner3); cropping_bounds.max = math::max(cropping_bounds.max, corner3); @@ -296,7 +294,7 @@ void shadow_map_pass::render_csm(const scene::directional_light& light, render:: } // Calculate model-view-projection matrix - float4x4 model_view_projection = light_view_projection * operation->transform; + math::fmat4 model_view_projection = light_view_projection * operation->transform; // Upload operation-dependent parameters to shader program if (active_shader_program == unskinned_shader_program.get()) diff --git a/src/engine/render/passes/shadow-map-pass.hpp b/src/engine/render/passes/shadow-map-pass.hpp index 3c599a3..943b94b 100644 --- a/src/engine/render/passes/shadow-map-pass.hpp +++ b/src/engine/render/passes/shadow-map-pass.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_RENDER_SHADOW_MAP_PASS_HPP #include -#include +#include #include #include #include @@ -70,7 +70,7 @@ private: std::unique_ptr skinned_shader_program; const gl::shader_variable* skinned_model_view_projection_var; - float4x4 bias_tile_matrices[4]; + math::fmat4 bias_tile_matrices[4]; }; } // namespace render diff --git a/src/engine/render/passes/sky-pass.cpp b/src/engine/render/passes/sky-pass.cpp index db7c3d0..d8bfbf4 100644 --- a/src/engine/render/passes/sky-pass.cpp +++ b/src/engine/render/passes/sky-pass.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include #include @@ -63,24 +63,24 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe stars_model_vao(nullptr), star_material(nullptr), star_shader_program(nullptr), - observer_position_tween({0, 0, 0}, math::lerp), - sun_position_tween(float3{1.0f, 0.0f, 0.0f}, math::lerp), - sun_luminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp), - sun_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp), - icrf_to_eus_translation({0, 0, 0}, math::lerp), - icrf_to_eus_rotation(math::quaternion::identity(), math::nlerp), - moon_position_tween(float3{0, 0, 0}, math::lerp), - moon_rotation_tween(math::quaternion::identity(), math::nlerp), + observer_position_tween({0, 0, 0}, math::lerp), + sun_position_tween(math::fvec3{1.0f, 0.0f, 0.0f}, math::lerp), + sun_luminance_tween(math::fvec3{0.0f, 0.0f, 0.0f}, math::lerp), + sun_illuminance_tween(math::fvec3{0.0f, 0.0f, 0.0f}, math::lerp), + icrf_to_eus_translation({0, 0, 0}, math::lerp), + icrf_to_eus_rotation(math::fquat::identity(), math::nlerp), + moon_position_tween(math::fvec3{0, 0, 0}, math::lerp), + moon_rotation_tween(math::fquat::identity(), math::nlerp), moon_angular_radius_tween(0.0f, math::lerp), - moon_sunlight_direction_tween(float3{0, 0, 0}, math::lerp), - moon_sunlight_illuminance_tween(float3{0, 0, 0}, math::lerp), - moon_planetlight_direction_tween(float3{0, 0, 0}, math::lerp), - moon_planetlight_illuminance_tween(float3{0, 0, 0}, math::lerp), - moon_illuminance_tween(float3{0.0f, 0.0f, 0.0f}, math::lerp), + moon_sunlight_direction_tween(math::fvec3{0, 0, 0}, math::lerp), + moon_sunlight_illuminance_tween(math::fvec3{0, 0, 0}, math::lerp), + moon_planetlight_direction_tween(math::fvec3{0, 0, 0}, math::lerp), + moon_planetlight_illuminance_tween(math::fvec3{0, 0, 0}, math::lerp), + moon_illuminance_tween(math::fvec3{0.0f, 0.0f, 0.0f}, math::lerp), magnification(1.0f) { // Build quad VBO and VAO - const float2 vertex_positions[] = + const math::fvec2 vertex_positions[] = { {-1.0f, 1.0f}, {-1.0f, -1.0f}, @@ -220,13 +220,13 @@ void sky_pass::render(render::context& ctx) // Construct matrices const scene::camera& camera = *ctx.camera; - float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (camera.get_clip_near() + camera.get_clip_far()) * 0.5f; - float4x4 model = math::scale(math::matrix4::identity(), model_scale); - float4x4 view = float4x4(float3x3(camera.get_view())); - float4x4 model_view = view * model; - const float4x4& projection = camera.get_projection(); - float4x4 view_projection = projection * view; - float4x4 model_view_projection = projection * model_view; + math::fvec3 model_scale = math::fvec3{1.0f, 1.0f, 1.0f} * (camera.get_clip_near() + camera.get_clip_far()) * 0.5f; + math::fmat4 model = math::scale(math::fmat4::identity(), model_scale); + math::fmat4 view = math::fmat4(math::fmat3(camera.get_view())); + math::fmat4 model_view = view * model; + const math::fmat4& projection = camera.get_projection(); + math::fmat4 view_projection = projection * view; + math::fmat4 model_view_projection = projection * model_view; camera_exposure = camera.get_exposure_normalization(); // Interpolate observer position @@ -240,16 +240,16 @@ void sky_pass::render(render::context& ctx) }; // Get EUS direction to sun - float3 sun_position = sun_position_tween.interpolate(ctx.alpha); - float3 sun_direction = math::normalize(sun_position); + math::fvec3 sun_position = sun_position_tween.interpolate(ctx.alpha); + math::fvec3 sun_direction = math::normalize(sun_position); // Interpolate and expose sun luminance and illuminance - float3 sun_illuminance = sun_illuminance_tween.interpolate(ctx.alpha) * camera_exposure; - float3 sun_luminance = sun_luminance_tween.interpolate(ctx.alpha) * camera_exposure; + math::fvec3 sun_illuminance = sun_illuminance_tween.interpolate(ctx.alpha) * camera_exposure; + math::fvec3 sun_luminance = sun_luminance_tween.interpolate(ctx.alpha) * camera_exposure; - float3 moon_position = moon_position_tween.interpolate(ctx.alpha); - float3 moon_direction = math::normalize(moon_position); - float3 moon_illuminance = moon_illuminance_tween.interpolate(ctx.alpha) * camera_exposure; + math::fvec3 moon_position = moon_position_tween.interpolate(ctx.alpha); + math::fvec3 moon_direction = math::normalize(moon_position); + math::fvec3 moon_illuminance = moon_illuminance_tween.interpolate(ctx.alpha) * camera_exposure; float moon_angular_radius = moon_angular_radius_tween.interpolate(ctx.alpha) * magnification; float sun_y = color::aces::ap1.luminance(sun_transmitted_illuminance); @@ -285,7 +285,7 @@ void sky_pass::render(render::context& ctx) rasterizer->use_framebuffer(*framebuffer); auto viewport = framebuffer->get_dimensions(); rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport)); - float2 resolution = {static_cast(std::get<0>(viewport)), static_cast(std::get<1>(viewport))}; + math::fvec2 resolution = {static_cast(std::get<0>(viewport)), static_cast(std::get<1>(viewport))}; // Draw atmosphere if (sky_model && sky_shader_program) @@ -312,11 +312,11 @@ void sky_pass::render(render::context& ctx) if (sky_transmittance_lut_var) sky_transmittance_lut_var->update(*m_transmittance_lut_texture); if (sky_transmittance_lut_resolution_var) - sky_transmittance_lut_resolution_var->update(math::vector2(m_transmittance_lut_resolution)); + sky_transmittance_lut_resolution_var->update(math::fvec2(m_transmittance_lut_resolution)); if (sky_luminance_lut_var) sky_luminance_lut_var->update(*m_luminance_lut_texture); if (sky_luminance_lut_resolution_var) - sky_luminance_lut_resolution_var->update(math::vector2(m_luminance_lut_resolution)); + sky_luminance_lut_resolution_var->update(math::fvec2(m_luminance_lut_resolution)); //sky_material->update(ctx.alpha); @@ -346,7 +346,7 @@ void sky_pass::render(render::context& ctx) moon_transform.scale = {moon_radius, moon_radius, moon_radius}; model = moon_transform.matrix(); - float3x3 normal_model = math::transpose(math::inverse(float3x3(model))); + math::fmat3 normal_model = math::transpose(math::inverse(math::fmat3(model))); rasterizer->use_program(*moon_shader_program); if (moon_model_var) @@ -389,7 +389,7 @@ void sky_pass::render(render::context& ctx) { float star_distance = (camera.get_clip_near() + camera.get_clip_far()) * 0.5f; - model = float4x4(float3x3(icrf_to_eus.r)); + model = math::fmat4(math::fmat3(icrf_to_eus.r)); model = math::scale(model, {star_distance, star_distance, star_distance}); model_view_projection = view_projection * model; @@ -425,7 +425,7 @@ void sky_pass::set_transmittance_lut_sample_count(std::uint16_t count) } } -void sky_pass::set_transmittance_lut_resolution(const math::vector2& resolution) +void sky_pass::set_transmittance_lut_resolution(const math::vec2& resolution) { if (m_transmittance_lut_resolution.x() != resolution.x() || m_transmittance_lut_resolution.y() != resolution.y()) { @@ -468,7 +468,7 @@ void sky_pass::set_multiscattering_lut_scatter_sample_count(std::uint16_t count) } } -void sky_pass::set_multiscattering_lut_resolution(const math::vector2& resolution) +void sky_pass::set_multiscattering_lut_resolution(const math::vec2& resolution) { if (m_multiscattering_lut_resolution.x() != resolution.x() || m_multiscattering_lut_resolution.y() != resolution.y()) { @@ -496,7 +496,7 @@ void sky_pass::set_luminance_lut_sample_count(std::uint16_t count) } } -void sky_pass::set_luminance_lut_resolution(const math::vector2& resolution) +void sky_pass::set_luminance_lut_resolution(const math::vec2& resolution) { if (m_luminance_lut_resolution.x() != resolution.x() || m_luminance_lut_resolution.y() != resolution.y()) { @@ -678,18 +678,18 @@ void sky_pass::set_icrf_to_eus(const math::transformation::se3& transform icrf_to_eus_rotation[1] = transformation.r; } -void sky_pass::set_sun_position(const float3& position) +void sky_pass::set_sun_position(const math::fvec3& position) { sun_position_tween[1] = position; } -void sky_pass::set_sun_illuminance(const float3& illuminance, const float3& transmitted_illuminance) +void sky_pass::set_sun_illuminance(const math::fvec3& illuminance, const math::fvec3& transmitted_illuminance) { sun_illuminance_tween[1] = illuminance; sun_transmitted_illuminance = transmitted_illuminance; } -void sky_pass::set_sun_luminance(const float3& luminance) +void sky_pass::set_sun_luminance(const math::fvec3& luminance) { sun_luminance_tween[1] = luminance; } @@ -730,7 +730,7 @@ void sky_pass::set_observer_elevation(float elevation) observer_position_tween[1] = {0.0f, atmosphere_radii.x() + observer_elevation, 0.0f}; } -void sky_pass::set_rayleigh_parameters(float scale_height, const float3& scattering) +void sky_pass::set_rayleigh_parameters(float scale_height, const math::fvec3& scattering) { rayleigh_parameters = { @@ -760,7 +760,7 @@ void sky_pass::set_mie_parameters(float scale_height, float scattering, float ex m_render_multiscattering_lut = true; } -void sky_pass::set_ozone_parameters(float lower_limit, float upper_limit, float mode, const float3& absorption) +void sky_pass::set_ozone_parameters(float lower_limit, float upper_limit, float mode, const math::fvec3& absorption) { ozone_distribution = { @@ -775,12 +775,12 @@ void sky_pass::set_ozone_parameters(float lower_limit, float upper_limit, float m_render_multiscattering_lut = true; } -void sky_pass::set_airglow_luminance(const float3& luminance) +void sky_pass::set_airglow_luminance(const math::fvec3& luminance) { airglow_luminance = luminance; } -void sky_pass::set_ground_albedo(const float3& albedo) +void sky_pass::set_ground_albedo(const math::fvec3& albedo) { m_ground_albedo = albedo; @@ -788,12 +788,12 @@ void sky_pass::set_ground_albedo(const float3& albedo) m_render_multiscattering_lut = true; } -void sky_pass::set_moon_position(const float3& position) +void sky_pass::set_moon_position(const math::fvec3& position) { moon_position_tween[1] = position; } -void sky_pass::set_moon_rotation(const math::quaternion& rotation) +void sky_pass::set_moon_rotation(const math::fquat& rotation) { moon_rotation_tween[1] = rotation; } @@ -803,27 +803,27 @@ void sky_pass::set_moon_angular_radius(float angular_radius) moon_angular_radius_tween[1] = angular_radius; } -void sky_pass::set_moon_sunlight_direction(const float3& direction) +void sky_pass::set_moon_sunlight_direction(const math::fvec3& direction) { moon_sunlight_direction_tween[1] = direction; } -void sky_pass::set_moon_sunlight_illuminance(const float3& illuminance) +void sky_pass::set_moon_sunlight_illuminance(const math::fvec3& illuminance) { moon_sunlight_illuminance_tween[1] = illuminance; } -void sky_pass::set_moon_planetlight_direction(const float3& direction) +void sky_pass::set_moon_planetlight_direction(const math::fvec3& direction) { moon_planetlight_direction_tween[1] = direction; } -void sky_pass::set_moon_planetlight_illuminance(const float3& illuminance) +void sky_pass::set_moon_planetlight_illuminance(const math::fvec3& illuminance) { moon_planetlight_illuminance_tween[1] = illuminance; } -void sky_pass::set_moon_illuminance(const float3& illuminance, const float3& transmitted_illuminance) +void sky_pass::set_moon_illuminance(const math::fvec3& illuminance, const math::fvec3& transmitted_illuminance) { moon_illuminance_tween[1] = illuminance; moon_transmitted_illuminance = transmitted_illuminance; @@ -914,7 +914,7 @@ void sky_pass::rebuild_transmittance_lut_command_buffer() } if (auto resolution_var = m_transmittance_lut_shader_program->variable("resolution")) { - m_transmittance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::vector2(m_transmittance_lut_resolution));}); + m_transmittance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::fvec2(m_transmittance_lut_resolution));}); } // Draw quad @@ -990,7 +990,7 @@ void sky_pass::rebuild_multiscattering_lut_command_buffer() } if (auto resolution_var = m_multiscattering_lut_shader_program->variable("resolution")) { - m_multiscattering_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::vector2(m_multiscattering_lut_resolution));}); + m_multiscattering_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::fvec2(m_multiscattering_lut_resolution));}); } if (auto transmittance_lut_var = m_multiscattering_lut_shader_program->variable("transmittance_lut")) { @@ -1081,7 +1081,7 @@ void sky_pass::rebuild_luminance_lut_command_buffer() } if (auto resolution_var = m_luminance_lut_shader_program->variable("resolution")) { - m_luminance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::vector2(m_luminance_lut_resolution));}); + m_luminance_lut_command_buffer.emplace_back([&, resolution_var](){resolution_var->update(math::fvec2(m_luminance_lut_resolution));}); } if (auto transmittance_lut_var = m_luminance_lut_shader_program->variable("transmittance_lut")) { diff --git a/src/engine/render/passes/sky-pass.hpp b/src/engine/render/passes/sky-pass.hpp index 5f51eb8..77ab5b2 100644 --- a/src/engine/render/passes/sky-pass.hpp +++ b/src/engine/render/passes/sky-pass.hpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -74,7 +74,7 @@ public: * * @note Triggers rendering of transmittance LUT. */ - void set_transmittance_lut_resolution(const math::vector2& resolution); + void set_transmittance_lut_resolution(const math::vec2& resolution); /// Returns the number of transmittance integration samples. [[nodiscard]] inline std::uint16_t get_transmittance_lut_sample_count() const noexcept @@ -83,7 +83,7 @@ public: } /// Returns the resolution of the transmittance LUT texture, in pixels. - [[nodiscard]] inline const math::vector2& get_transmittance_lut_resolution() const noexcept + [[nodiscard]] inline const math::vec2& get_transmittance_lut_resolution() const noexcept { return m_transmittance_lut_resolution; } @@ -119,7 +119,7 @@ public: * * @note Triggers rendering of multiscattering LUT. */ - void set_multiscattering_lut_resolution(const math::vector2& resolution); + void set_multiscattering_lut_resolution(const math::vec2& resolution); /// Returns the number of multiscattering direction samples. [[nodiscard]] inline std::uint16_t get_multiscattering_lut_direction_sample_count() const noexcept @@ -134,7 +134,7 @@ public: } /// Returns the resolution of the multiscattering LUT texture, in pixels. - [[nodiscard]] inline const math::vector2& get_multiscattering_lut_resolution() const noexcept + [[nodiscard]] inline const math::vec2& get_multiscattering_lut_resolution() const noexcept { return m_multiscattering_lut_resolution; } @@ -160,7 +160,7 @@ public: * * @note Triggers rendering of luminance LUT. */ - void set_luminance_lut_resolution(const math::vector2& resolution); + void set_luminance_lut_resolution(const math::vec2& resolution); /// Returns the number of luminance integration samples. [[nodiscard]] inline std::uint16_t get_luminance_lut_sample_count() const noexcept @@ -169,7 +169,7 @@ public: } /// Returns the resolution of the luminance LUT texture, in pixels. - [[nodiscard]] inline const math::vector2& get_luminance_lut_resolution() const noexcept + [[nodiscard]] inline const math::vec2& get_luminance_lut_resolution() const noexcept { return m_luminance_lut_resolution; } @@ -186,27 +186,27 @@ public: void set_icrf_to_eus(const math::transformation::se3& transformation); - void set_sun_position(const float3& position); - void set_sun_luminance(const float3& luminance); - void set_sun_illuminance(const float3& illuminance, const float3& transmitted_illuminance); + void set_sun_position(const math::fvec3& position); + void set_sun_luminance(const math::fvec3& luminance); + void set_sun_illuminance(const math::fvec3& illuminance, const math::fvec3& transmitted_illuminance); void set_sun_angular_radius(float radius); void set_planet_radius(float radius); void set_atmosphere_upper_limit(float limit); void set_observer_elevation(float elevation); - void set_rayleigh_parameters(float scale_height, const float3& scattering); + void set_rayleigh_parameters(float scale_height, const math::fvec3& scattering); void set_mie_parameters(float scale_height, float scattering, float extinction, float anisotropy); - void set_ozone_parameters(float lower_limit, float upper_limit, float mode, const float3& absorption); - void set_airglow_luminance(const float3& luminance); - void set_ground_albedo(const float3& albedo); + void set_ozone_parameters(float lower_limit, float upper_limit, float mode, const math::fvec3& absorption); + void set_airglow_luminance(const math::fvec3& luminance); + void set_ground_albedo(const math::fvec3& albedo); - void set_moon_position(const float3& position); - void set_moon_rotation(const math::quaternion& rotation); + void set_moon_position(const math::fvec3& position); + void set_moon_rotation(const math::fquat& rotation); void set_moon_angular_radius(float angular_radius); - void set_moon_sunlight_direction(const float3& direction); - void set_moon_sunlight_illuminance(const float3& illuminance); - void set_moon_planetlight_direction(const float3& direction); - void set_moon_planetlight_illuminance(const float3& illuminance); - void set_moon_illuminance(const float3& illuminance, const float3& transmitted_illuminance); + void set_moon_sunlight_direction(const math::fvec3& direction); + void set_moon_sunlight_illuminance(const math::fvec3& illuminance); + void set_moon_planetlight_direction(const math::fvec3& direction); + void set_moon_planetlight_illuminance(const math::fvec3& illuminance); + void set_moon_illuminance(const math::fvec3& illuminance, const math::fvec3& transmitted_illuminance); @@ -228,7 +228,7 @@ private: // Transmittance std::uint16_t m_transmittance_lut_sample_count{40}; - math::vector2 m_transmittance_lut_resolution{256, 64}; + math::vec2 m_transmittance_lut_resolution{256, 64}; std::unique_ptr m_transmittance_lut_texture; std::unique_ptr m_transmittance_lut_framebuffer; std::shared_ptr m_transmittance_lut_shader_template; @@ -239,7 +239,7 @@ private: // Multiscattering std::uint16_t m_multiscattering_lut_direction_sample_count{64}; std::uint16_t m_multiscattering_lut_scatter_sample_count{20}; - math::vector2 m_multiscattering_lut_resolution{32, 32}; + math::vec2 m_multiscattering_lut_resolution{32, 32}; std::unique_ptr m_multiscattering_lut_texture; std::unique_ptr m_multiscattering_lut_framebuffer; std::shared_ptr m_multiscattering_lut_shader_template; @@ -249,7 +249,7 @@ private: // Luminance std::uint16_t m_luminance_lut_sample_count{30}; - math::vector2 m_luminance_lut_resolution{200, 100}; + math::vec2 m_luminance_lut_resolution{200, 100}; std::unique_ptr m_luminance_lut_texture; std::unique_ptr m_luminance_lut_framebuffer; std::shared_ptr m_luminance_lut_shader_template; @@ -264,9 +264,9 @@ private: std::unique_ptr m_sky_probe_shader_program; std::vector> m_sky_probe_command_buffer; - float3 dominant_light_direction; - float3 dominant_light_illuminance; - float3 observer_position; + math::fvec3 dominant_light_direction; + math::fvec3 dominant_light_illuminance; + math::fvec3 observer_position; float camera_exposure; std::shared_ptr sky_shader_program; @@ -326,36 +326,36 @@ private: const gl::shader_variable* star_exposure_var; const gl::shader_variable* star_inv_resolution_var; - float2 mouse_position; + math::fvec2 mouse_position; - tween sun_position_tween; - tween sun_luminance_tween; - tween sun_illuminance_tween; - float3 sun_transmitted_illuminance; - tween icrf_to_eus_translation; - tween> icrf_to_eus_rotation; + tween sun_position_tween; + tween sun_luminance_tween; + tween sun_illuminance_tween; + math::fvec3 sun_transmitted_illuminance; + tween icrf_to_eus_translation; + tween icrf_to_eus_rotation; - tween moon_position_tween; - tween> moon_rotation_tween; + tween moon_position_tween; + tween moon_rotation_tween; tween moon_angular_radius_tween; - tween moon_sunlight_direction_tween; - tween moon_sunlight_illuminance_tween; - tween moon_planetlight_direction_tween; - tween moon_planetlight_illuminance_tween; - tween moon_illuminance_tween; - float3 moon_transmitted_illuminance; + tween moon_sunlight_direction_tween; + tween moon_sunlight_illuminance_tween; + tween moon_planetlight_direction_tween; + tween moon_planetlight_illuminance_tween; + tween moon_illuminance_tween; + math::fvec3 moon_transmitted_illuminance; float sun_angular_radius; float atmosphere_upper_limit; - float4 atmosphere_radii; + math::fvec4 atmosphere_radii; float observer_elevation; - tween observer_position_tween; - float4 rayleigh_parameters; - float4 mie_parameters; - float3 ozone_distribution; - float3 ozone_absorption; - float3 airglow_luminance; - math::vector3 m_ground_albedo{}; + tween observer_position_tween; + math::fvec4 rayleigh_parameters; + math::fvec4 mie_parameters; + math::fvec3 ozone_distribution; + math::fvec3 ozone_absorption; + math::fvec3 airglow_luminance; + math::fvec3 m_ground_albedo{}; float magnification; }; diff --git a/src/engine/render/stages/light-probe-stage.cpp b/src/engine/render/stages/light-probe-stage.cpp index 71cfb88..b817914 100644 --- a/src/engine/render/stages/light-probe-stage.cpp +++ b/src/engine/render/stages/light-probe-stage.cpp @@ -33,7 +33,7 @@ light_probe_stage::light_probe_stage(gl::rasterizer& rasterizer, ::resource_mana { // Build quad VBO and VAO { - const math::vector2 vertex_positions[] = + const math::fvec2 vertex_positions[] = { {-1.0f, 1.0f}, {-1.0f, -1.0f}, @@ -331,7 +331,7 @@ void light_probe_stage::rebuild_cubemap_filter_lut_texture() m_rasterizer->use_framebuffer(*m_cubemap_filter_lut_framebuffer); m_rasterizer->set_viewport(0, 0, m_cubemap_filter_lut_texture->get_width(), m_cubemap_filter_lut_texture->get_height()); m_rasterizer->use_program(*m_cubemap_filter_lut_shader_program); - m_cubemap_filter_lut_resolution_var->update(math::vector2{static_cast(m_cubemap_filter_lut_texture->get_width()), static_cast(m_cubemap_filter_lut_texture->get_height())}); + m_cubemap_filter_lut_resolution_var->update(math::fvec2{static_cast(m_cubemap_filter_lut_texture->get_width()), static_cast(m_cubemap_filter_lut_texture->get_height())}); m_cubemap_filter_lut_face_size_var->update(128.0f); m_cubemap_filter_lut_mip_bias_var->update(m_cubemap_filter_mip_bias); m_rasterizer->draw_arrays(*m_quad_vao, gl::drawing_mode::triangle_strip, 0, 4); diff --git a/src/engine/scene/billboard.cpp b/src/engine/scene/billboard.cpp index 41ec679..482bda8 100644 --- a/src/engine/scene/billboard.cpp +++ b/src/engine/scene/billboard.cpp @@ -83,7 +83,7 @@ billboard::billboard() m_render_op.drawing_mode = gl::drawing_mode::triangles; m_render_op.start_index = 0; m_render_op.index_count = 6; - m_render_op.transform = float4x4::identity(); + m_render_op.transform = math::fmat4::identity(); } void billboard::render(render::context& ctx) const diff --git a/src/engine/scene/billboard.hpp b/src/engine/scene/billboard.hpp index f182db5..0b1251b 100644 --- a/src/engine/scene/billboard.hpp +++ b/src/engine/scene/billboard.hpp @@ -61,7 +61,7 @@ public: * * @param axis Cylindral billboard aligmment axis. */ - inline void set_alignment_axis(const math::vector& axis) noexcept + inline void set_alignment_axis(const math::fvec3& axis) noexcept { m_alignment_axis = axis; } @@ -81,7 +81,7 @@ public: return m_billboard_type; } - [[nodiscard]] inline const math::vector& get_alignment_axis() const noexcept + [[nodiscard]] inline const math::fvec3& get_alignment_axis() const noexcept { return m_alignment_axis; } @@ -94,7 +94,7 @@ private: mutable render::operation m_render_op; aabb_type m_bounds{{-1.0f, -1.0f, -1.0f}, {1.0f, 1.0f, 1.0f}}; billboard_type m_billboard_type{billboard_type::flat}; - math::vector m_alignment_axis{0.0f, 1.0f, 0.0f}; + math::fvec3 m_alignment_axis{0.0f, 1.0f, 0.0f}; }; } // namespace scene diff --git a/src/engine/scene/camera.cpp b/src/engine/scene/camera.cpp index 0ddad8d..ed825b2 100644 --- a/src/engine/scene/camera.cpp +++ b/src/engine/scene/camera.cpp @@ -24,20 +24,20 @@ namespace scene { -geom::ray camera::pick(const float2& ndc) const +geom::ray camera::pick(const math::fvec2& ndc) const { - const float4 near = m_inverse_view_projection * float4{ndc[0], ndc[1], 1.0f, 1.0f}; - const float4 far = m_inverse_view_projection * float4{ndc[0], ndc[1], 0.0f, 1.0f}; + 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 float3 origin = float3{near[0], near[1], near[2]} / near[3]; - const float3 direction = math::normalize(float3{far[0], far[1], far[2]} / far[3] - origin); + 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); return {origin, direction}; } -float3 camera::project(const float3& object, const float4& viewport) const +math::fvec3 camera::project(const math::fvec3& object, const math::fvec4& viewport) const { - float4 result = m_view_projection * float4{object[0], object[1], object[2], 1.0f}; + math::fvec4 result = m_view_projection * math::fvec4{object[0], object[1], object[2], 1.0f}; result[0] = (result[0] / result[3]) * 0.5f + 0.5f; result[1] = (result[1] / result[3]) * 0.5f + 0.5f; result[2] = (result[2] / result[3]) * 0.5f + 0.5f; @@ -45,12 +45,12 @@ float3 camera::project(const float3& object, const float4& viewport) const result[0] = result[0] * viewport[2] + viewport[0]; result[1] = result[1] * viewport[3] + viewport[1]; - return math::vector(result); + return math::fvec3(result); } -float3 camera::unproject(const float3& window, const float4& viewport) const +math::fvec3 camera::unproject(const math::fvec3& window, const math::fvec4& viewport) const { - float4 result; + math::fvec4 result; result[0] = ((window[0] - viewport[0]) / viewport[2]) * 2.0f - 1.0f; result[1] = ((window[1] - viewport[1]) / viewport[3]) * 2.0f - 1.0f; //result[2] = window[2] * 2.0f - 1.0f; z: [-1, 1] @@ -60,7 +60,7 @@ float3 camera::unproject(const float3& window, const float4& viewport) const result = m_inverse_view_projection * result; - return math::vector(result) * (1.0f / result[3]); + return math::fvec3(result) * (1.0f / result[3]); } void camera::set_perspective(float vertical_fov, float aspect_ratio, float clip_near, float clip_far) @@ -137,8 +137,8 @@ void camera::set_exposure_value(float ev100) void camera::transformed() { // Recalculate view and view-projection matrices - m_forward = get_rotation() * math::vector{0.0f, 0.0f, -1.0f}; - m_up = get_rotation() * math::vector{0.0f, 1.0f, 0.0f}; + 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); m_view_projection = m_projection * m_view; m_inverse_view_projection = math::inverse(m_view_projection); @@ -152,7 +152,7 @@ void camera::update_frustum() m_view_frustum.extract(m_view_projection); // Reverse half z clip-space coordinates of a cube - constexpr math::vector clip_space_cube[8] = + constexpr math::fvec4 clip_space_cube[8] = { {-1, -1, 1, 1}, // NBL { 1, -1, 1, 1}, // NBR @@ -165,12 +165,11 @@ void camera::update_frustum() }; // Update bounds - m_bounds.min = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; - m_bounds.max = {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; + m_bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < 8; ++i) { - const math::vector frustum_corner = m_inverse_view_projection * clip_space_cube[i]; - m_bounds.extend(math::vector(frustum_corner) / frustum_corner[3]); + const math::fvec4 frustum_corner = m_inverse_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 566c9de..1cfedec 100644 --- a/src/engine/scene/camera.hpp +++ b/src/engine/scene/camera.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -45,7 +45,7 @@ public: * * @return Picking ray. */ - [[nodiscard]] geom::ray pick(const float2& ndc) const; + [[nodiscard]] geom::ray pick(const math::fvec2& ndc) const; /** * Maps object coordinates to window coordinates. @@ -54,7 +54,7 @@ public: * @param viewport Vector containing the `x`, `y`, `w`, and `h` of the viewport. * @return Projected window coordinates. */ - [[nodiscard]] float3 project(const float3& object, const float4& viewport) const; + [[nodiscard]] math::fvec3 project(const math::fvec3& object, const math::fvec4& viewport) const; /** * Maps window coordinates to object coordinates. @@ -63,7 +63,7 @@ public: * @param viewport Vector containing the `x`, `y`, `w`, and `h` of the viewport. * @return Unprojected object coordinates. */ - [[nodiscard]] float3 unproject(const float3& window, const float4& viewport) const; + [[nodiscard]] math::fvec3 unproject(const math::fvec3& window, const math::fvec4& viewport) const; /** * Sets the camera's projection matrix using perspective projection. @@ -213,37 +213,37 @@ public: } /// Returns the camera's view matrix. - [[nodiscard]] inline const float4x4& get_view() const noexcept + [[nodiscard]] inline const math::fmat4& get_view() const noexcept { return m_view; } /// Returns the camera's projection matrix. - [[nodiscard]] inline const float4x4& get_projection() const noexcept + [[nodiscard]] inline const math::fmat4& get_projection() const noexcept { return m_projection; } /// Returns the camera's view-projection matrix. - [[nodiscard]] inline const float4x4& get_view_projection() const noexcept + [[nodiscard]] inline const math::fmat4& get_view_projection() const noexcept { return m_view_projection; } /// Returns the camera's inverse view-projection matrix. - [[nodiscard]] inline const float4x4& get_inverse_view_projection() const noexcept + [[nodiscard]] inline const math::fmat4& get_inverse_view_projection() const noexcept { return m_inverse_view_projection; } /// Returns the camera's forward vector. - [[nodiscard]] inline const math::vector& get_forward() const noexcept + [[nodiscard]] inline const math::fvec3& get_forward() const noexcept { return m_forward; } /// Returns the camera's up vector. - [[nodiscard]] inline const math::vector& get_up() const noexcept + [[nodiscard]] inline const math::fvec3& get_up() const noexcept { return m_up; } @@ -274,13 +274,13 @@ private: float m_exposure_value{0.0f}; float m_exposure_normalization{1.0f / 1.2f}; - float4x4 m_view{float4x4::identity()}; - float4x4 m_projection{float4x4::identity()}; - float4x4 m_view_projection{float4x4::identity()}; - float4x4 m_inverse_view_projection{float4x4::identity()}; + math::fmat4 m_view{math::fmat4::identity()}; + math::fmat4 m_projection{math::fmat4::identity()}; + math::fmat4 m_view_projection{math::fmat4::identity()}; + math::fmat4 m_inverse_view_projection{math::fmat4::identity()}; - math::vector m_forward{0.0f, 0.0f, -1.0f}; - math::vector m_up{0.0f, 1.0f, 0.0f}; + math::fvec3 m_forward{0.0f, 0.0f, -1.0f}; + math::fvec3 m_up{0.0f, 1.0f, 0.0f}; view_frustum_type m_view_frustum; diff --git a/src/engine/scene/directional-light.cpp b/src/engine/scene/directional-light.cpp index 388add7..caa0c77 100644 --- a/src/engine/scene/directional-light.cpp +++ b/src/engine/scene/directional-light.cpp @@ -26,9 +26,9 @@ directional_light::directional_light(): m_shadow_cascade_matrices(m_shadow_cascade_count) {} -void directional_light::set_direction(const math::vector3& direction) +void directional_light::set_direction(const math::fvec3& direction) { - set_rotation(math::rotation(math::vector3{0.0f, 0.0f, -1.0f}, direction)); + set_rotation(math::rotation(math::fvec3{0.0f, 0.0f, -1.0f}, direction)); } void directional_light::set_shadow_caster(bool caster) noexcept @@ -65,7 +65,7 @@ void directional_light::set_shadow_cascade_distribution(float weight) noexcept void directional_light::transformed() { - m_direction = get_rotation() * math::vector3{0.0f, 0.0f, -1.0f}; + m_direction = get_rotation() * math::fvec3{0.0f, 0.0f, -1.0f}; } void directional_light::color_updated() diff --git a/src/engine/scene/directional-light.hpp b/src/engine/scene/directional-light.hpp index 7ed9556..56611f0 100644 --- a/src/engine/scene/directional-light.hpp +++ b/src/engine/scene/directional-light.hpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -51,14 +51,14 @@ public: * * @param direction Unit-length light direction vector. */ - void set_direction(const math::vector3& direction); + void set_direction(const math::fvec3& direction); /** * Sets the color of the light. * * @param color Light color. */ - inline void set_color(const math::vector3& color) noexcept + inline void set_color(const math::fvec3& color) noexcept { m_color = color; color_updated(); @@ -76,13 +76,13 @@ public: } /// Returns a unit vector pointing in the light direction. - [[nodiscard]] inline const math::vector3& get_direction() const noexcept + [[nodiscard]] inline const math::fvec3& get_direction() const noexcept { return m_direction; } /// Returns the color of the light. - [[nodiscard]] inline const math::vector3& get_color() const noexcept + [[nodiscard]] inline const math::fvec3& get_color() const noexcept { return m_color; } @@ -94,7 +94,7 @@ public: } /// Returns the color-modulated illuminance of the light on a surface perpendicular to the light direction. - [[nodiscard]] inline const math::vector3& get_colored_illuminance() const noexcept + [[nodiscard]] inline const math::fvec3& get_colored_illuminance() const noexcept { return m_colored_illuminance; } @@ -196,11 +196,11 @@ public: /// Returns the array of world-space to cascade texture-space transformation matrices. /// @{ - [[nodiscard]] inline const std::vector& get_shadow_cascade_matrices() const noexcept + [[nodiscard]] inline const std::vector& get_shadow_cascade_matrices() const noexcept { return m_shadow_cascade_matrices; } - [[nodiscard]] inline std::vector& get_shadow_cascade_matrices() noexcept + [[nodiscard]] inline std::vector& get_shadow_cascade_matrices() noexcept { return m_shadow_cascade_matrices; } @@ -213,10 +213,10 @@ private: void color_updated(); void illuminance_updated(); - math::vector3 m_direction{0.0f, 0.0f, -1.0f}; - math::vector3 m_color{1.0f, 1.0f, 1.0f}; + math::fvec3 m_direction{0.0f, 0.0f, -1.0f}; + math::fvec3 m_color{1.0f, 1.0f, 1.0f}; float m_illuminance{}; - math::vector3 m_colored_illuminance{}; + math::fvec3 m_colored_illuminance{}; bool m_shadow_caster{false}; std::shared_ptr m_shadow_framebuffer{nullptr}; @@ -225,7 +225,7 @@ private: float m_shadow_cascade_coverage{1.0f}; float m_shadow_cascade_distribution{0.8f}; mutable std::vector m_shadow_cascade_distances; - mutable std::vector m_shadow_cascade_matrices; + mutable std::vector m_shadow_cascade_matrices; }; } // namespace scene diff --git a/src/engine/scene/light-probe.hpp b/src/engine/scene/light-probe.hpp index e9d96a4..8fb4edc 100644 --- a/src/engine/scene/light-probe.hpp +++ b/src/engine/scene/light-probe.hpp @@ -108,7 +108,7 @@ public: * * @see light_probe::update_illuminance_matrices() */ - [[nodiscard]] inline std::span, 3> get_illuminance_matrices() const noexcept + [[nodiscard]] inline std::span get_illuminance_matrices() const noexcept { return m_illuminance_matrices; } @@ -137,7 +137,7 @@ private: std::vector> m_luminance_framebuffers; std::shared_ptr m_illuminance_texture; std::shared_ptr m_illuminance_framebuffer; - math::matrix4 m_illuminance_matrices[3]; + math::fmat4 m_illuminance_matrices[3]; bool m_luminance_outdated{}; bool m_illuminance_outdated{}; }; diff --git a/src/engine/scene/object.hpp b/src/engine/scene/object.hpp index 850d67d..6a04027 100644 --- a/src/engine/scene/object.hpp +++ b/src/engine/scene/object.hpp @@ -36,8 +36,8 @@ namespace scene { class object_base { public: - using vector_type = math::vector; - using quaternion_type = math::quaternion; + using vector_type = math::fvec3; + using quaternion_type = math::fquat; using transform_type = math::transform; using aabb_type = geom::box; diff --git a/src/engine/scene/point-light.hpp b/src/engine/scene/point-light.hpp index e90738c..e357614 100644 --- a/src/engine/scene/point-light.hpp +++ b/src/engine/scene/point-light.hpp @@ -42,7 +42,7 @@ public: * * @param color Light color. */ - inline void set_color(const math::vector& color) noexcept + inline void set_color(const math::fvec3& color) noexcept { m_color = color; color_updated(); @@ -60,7 +60,7 @@ public: } /// Returns the color of the light. - [[nodiscard]] inline const math::vector3& get_color() const noexcept + [[nodiscard]] inline const math::fvec3& get_color() const noexcept { return m_color; } @@ -72,7 +72,7 @@ public: } /// Returns the color-modulated luminous flux of light. - [[nodiscard]] inline const math::vector3& get_colored_luminous_flux() const noexcept + [[nodiscard]] inline const math::fvec3& get_colored_luminous_flux() const noexcept { return m_colored_luminous_flux; } @@ -81,9 +81,9 @@ private: void color_updated(); void luminous_flux_updated(); - math::vector3 m_color{1.0f, 1.0f, 1.0f}; + math::fvec3 m_color{1.0f, 1.0f, 1.0f}; float m_luminous_flux{}; - math::vector3 m_colored_luminous_flux{}; + math::fvec3 m_colored_luminous_flux{}; }; } // namespace scene diff --git a/src/engine/scene/rectangle-light.cpp b/src/engine/scene/rectangle-light.cpp index 0f2acbe..c819d3c 100644 --- a/src/engine/scene/rectangle-light.cpp +++ b/src/engine/scene/rectangle-light.cpp @@ -32,14 +32,14 @@ void rectangle_light::transformed() const auto& transform = get_transform(); // Update corner positions - // m_corners[0] = transform * math::vector3{-0.5f, 0.0f, -0.5f}; - // m_corners[1] = transform * math::vector3{ 0.5f, 0.0f, -0.5f}; - // m_corners[2] = transform * math::vector3{ 0.5f, 0.0f, 0.5f}; - // m_corners[3] = transform * math::vector3{-0.5f, 0.0f, 0.5f}; - m_corners[0] = transform * math::vector3{-0.5f, -0.5f, 0.0f}; - m_corners[1] = transform * math::vector3{-0.5f, 0.5f, 0.0f}; - m_corners[2] = transform * math::vector3{ 0.5f, 0.5f, 0.0f}; - m_corners[3] = transform * math::vector3{ 0.5f, -0.5f, 0.0f}; + // m_corners[0] = transform * math::fvec3{-0.5f, 0.0f, -0.5f}; + // m_corners[1] = transform * math::fvec3{ 0.5f, 0.0f, -0.5f}; + // m_corners[2] = transform * math::fvec3{ 0.5f, 0.0f, 0.5f}; + // m_corners[3] = transform * math::fvec3{-0.5f, 0.0f, 0.5f}; + m_corners[0] = transform * math::fvec3{-0.5f, -0.5f, 0.0f}; + m_corners[1] = transform * math::fvec3{-0.5f, 0.5f, 0.0f}; + m_corners[2] = transform * math::fvec3{ 0.5f, 0.5f, 0.0f}; + m_corners[3] = transform * math::fvec3{ 0.5f, -0.5f, 0.0f}; // Update area m_area = get_scale().x() * get_scale().z(); diff --git a/src/engine/scene/rectangle-light.hpp b/src/engine/scene/rectangle-light.hpp index 5dcf292..b55cc56 100644 --- a/src/engine/scene/rectangle-light.hpp +++ b/src/engine/scene/rectangle-light.hpp @@ -44,7 +44,7 @@ public: * * @param color Light color. */ - inline void set_color(const math::vector& color) noexcept + inline void set_color(const math::fvec3& color) noexcept { m_color = color; color_updated(); @@ -73,7 +73,7 @@ public: } /// Returns the color of the light. - [[nodiscard]] inline const math::vector& get_color() const noexcept + [[nodiscard]] inline const math::fvec3& get_color() const noexcept { return m_color; } @@ -85,7 +85,7 @@ public: } /// Returns the color-modulated luminous flux of the light. - [[nodiscard]] inline const math::vector& get_colored_luminous_flux() const noexcept + [[nodiscard]] inline const math::fvec3& get_colored_luminous_flux() const noexcept { return m_colored_luminous_flux; } @@ -97,13 +97,13 @@ public: } /// Returns the color-modulated luminance of the light. - [[nodiscard]] inline const math::vector& get_colored_luminance() const noexcept + [[nodiscard]] inline const math::fvec3& get_colored_luminance() const noexcept { return m_colored_luminance; } /// Returns the positions of the light corners. - [[nodiscard]] inline std::span, 4> get_corners() const noexcept + [[nodiscard]] inline std::span get_corners() const noexcept { return m_corners; } @@ -116,12 +116,12 @@ private: void luminance_updated(); float m_area{1.0f}; - math::vector3 m_corners[4]; - math::vector3 m_color{1.0f, 1.0f, 1.0f}; + math::fvec3 m_corners[4]; + math::fvec3 m_color{1.0f, 1.0f, 1.0f}; float m_luminous_flux{}; - math::vector3 m_colored_luminous_flux{}; + math::fvec3 m_colored_luminous_flux{}; float m_luminance{}; - math::vector3 m_colored_luminance; + math::fvec3 m_colored_luminance; }; } // namespace scene diff --git a/src/engine/scene/skeletal-mesh.cpp b/src/engine/scene/skeletal-mesh.cpp index e9547dc..0afead2 100644 --- a/src/engine/scene/skeletal-mesh.cpp +++ b/src/engine/scene/skeletal-mesh.cpp @@ -86,8 +86,7 @@ void skeletal_mesh::update_bounds() const auto& model_bounds = m_model->get_bounds(); // Naive algorithm: transform each corner of the model AABB - m_bounds.min = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; - m_bounds.max = {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; + m_bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < 8; ++i) { m_bounds.extend(get_transform() * model_bounds.corner(i)); @@ -103,7 +102,7 @@ void skeletal_mesh::transformed() { update_bounds(); - const float4x4 transform_matrix = get_transform().matrix(); + const math::fmat4 transform_matrix = get_transform().matrix(); for (auto& operation: m_operations) { operation.transform = transform_matrix; diff --git a/src/engine/scene/spot-light.cpp b/src/engine/scene/spot-light.cpp index 3b6110b..4bdce64 100644 --- a/src/engine/scene/spot-light.cpp +++ b/src/engine/scene/spot-light.cpp @@ -22,7 +22,7 @@ namespace scene { -void spot_light::set_cutoff(const math::vector& cutoff) +void spot_light::set_cutoff(const math::fvec2& cutoff) { m_cutoff = cutoff; m_cosine_cutoff = {std::cos(m_cutoff.x()), std::cos(m_cutoff.y())}; @@ -30,7 +30,7 @@ void spot_light::set_cutoff(const math::vector& cutoff) void spot_light::transformed() { - m_direction = get_transform().rotation * math::vector{0.0f, 0.0f, -1.0f}; + m_direction = get_transform().rotation * math::fvec3{0.0f, 0.0f, -1.0f}; } } // namespace scene diff --git a/src/engine/scene/spot-light.hpp b/src/engine/scene/spot-light.hpp index c787d65..18e8d66 100644 --- a/src/engine/scene/spot-light.hpp +++ b/src/engine/scene/spot-light.hpp @@ -43,13 +43,13 @@ public: * * @param luminous_flux Luminous flux, in *lm*. */ - inline void set_luminous_flux(const math::vector& luminous_flux) noexcept + inline void set_luminous_flux(const math::fvec3& luminous_flux) noexcept { m_luminous_flux = luminous_flux; } /// Returns the luminous flux of the spot light, in *lm*. - [[nodiscard]] inline const math::vector& get_luminous_flux() const noexcept + [[nodiscard]] inline const math::fvec3& get_luminous_flux() const noexcept { return m_luminous_flux; } @@ -59,22 +59,22 @@ public: * * @param cutoff Vector containing the inner and outer cutoff angles, as x and y, respectively. */ - void set_cutoff(const math::vector& cutoff); + void set_cutoff(const math::fvec2& cutoff); /// Returns the direction vector. - [[nodiscard]] inline const math::vector& get_direction() const noexcept + [[nodiscard]] inline const math::fvec3& get_direction() const noexcept { return m_direction; } /// Returns the spot light cutoff angles. - [[nodiscard]] inline const math::vector& get_cutoff() const noexcept + [[nodiscard]] inline const math::fvec2& get_cutoff() const noexcept { return m_cutoff; } /// Returns the cosine of the spot light cutoff angles. - [[nodiscard]] inline const math::vector& get_cosine_cutoff() const noexcept + [[nodiscard]] inline const math::fvec2& get_cosine_cutoff() const noexcept { return m_cosine_cutoff; } @@ -82,10 +82,10 @@ public: private: void transformed() override; - math::vector m_luminous_flux{0.0f, 0.0f, 0.0f}; - math::vector m_direction{0.0f, 0.0f, -1.0f}; - math::vector m_cutoff{math::pi, math::pi}; - math::vector m_cosine_cutoff{-1.0f, -1.0f}; + math::fvec3 m_luminous_flux{0.0f, 0.0f, 0.0f}; + math::fvec3 m_direction{0.0f, 0.0f, -1.0f}; + math::fvec2 m_cutoff{math::pi, math::pi}; + math::fvec2 m_cosine_cutoff{-1.0f, -1.0f}; }; } // namespace scene diff --git a/src/engine/scene/static-mesh.cpp b/src/engine/scene/static-mesh.cpp index 1a176ec..a0860a8 100644 --- a/src/engine/scene/static-mesh.cpp +++ b/src/engine/scene/static-mesh.cpp @@ -84,8 +84,7 @@ void static_mesh::update_bounds() const auto& model_bounds = m_model->get_bounds(); // Naive algorithm: transform each corner of the model AABB - m_bounds.min = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; - m_bounds.max = {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; + m_bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < 8; ++i) { m_bounds.extend(get_transform() * model_bounds.corner(i)); @@ -101,7 +100,7 @@ void static_mesh::transformed() { update_bounds(); - const float4x4 transform_matrix = get_transform().matrix(); + const math::fmat4 transform_matrix = get_transform().matrix(); for (auto& operation: m_operations) { operation.transform = transform_matrix; diff --git a/src/engine/scene/text.cpp b/src/engine/scene/text.cpp index c899777..c47da97 100644 --- a/src/engine/scene/text.cpp +++ b/src/engine/scene/text.cpp @@ -121,7 +121,7 @@ void text::set_content(const std::string& content) } } -void text::set_color(const float4& color) +void text::set_color(const math::fvec4& color) { m_color = color; update_color(); @@ -130,8 +130,7 @@ void text::set_color(const float4& color) void text::transformed() { // Naive algorithm: transform each corner of the AABB - m_world_bounds.min = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}; - m_world_bounds.max = {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()}; + m_world_bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < 8; ++i) { m_world_bounds.extend(get_transform() * m_local_bounds.corner(i)); @@ -167,7 +166,7 @@ void text::update_content() const image& font_bitmap = m_font->get_bitmap(); // Init pen position - float2 pen_position = {0.0f, 0.0f}; + math::fvec2 pen_position = {0.0f, 0.0f}; // Reset local-space bounds m_local_bounds.min = {std::numeric_limits::infinity(), std::numeric_limits::infinity(), 0.0f}; @@ -190,7 +189,7 @@ void text::update_content() const type::bitmap_glyph& glyph = m_font->get_glyph(code); // Calculate vertex positions - float2 positions[6]; + math::fvec2 positions[6]; positions[0] = pen_position + glyph.metrics.horizontal_bearing; positions[1] = {positions[0].x(), positions[0].y() - glyph.metrics.height}; positions[2] = {positions[0].x() + glyph.metrics.width, positions[1].y()}; @@ -199,7 +198,7 @@ void text::update_content() positions[5] = positions[2]; // Calculate vertex UVs - float2 uvs[6]; + math::fvec2 uvs[6]; uvs[0] = {static_cast(glyph.position.x()), static_cast(glyph.position.y())}; uvs[1] = {uvs[0].x(), uvs[0].y() + glyph.metrics.height}; uvs[2] = {uvs[0].x() + glyph.metrics.width, uvs[1].y()}; @@ -238,7 +237,7 @@ void text::update_content() // Update local-space bounds for (int i = 0; i < 4; ++i) { - const float2& position = positions[i]; + const math::fvec2& position = positions[i]; for (int j = 0; j < 2; ++j) { m_local_bounds.min[j] = std::min(m_local_bounds.min[j], position[j]); diff --git a/src/engine/scene/text.hpp b/src/engine/scene/text.hpp index 899eaba..85da127 100644 --- a/src/engine/scene/text.hpp +++ b/src/engine/scene/text.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_SCENE_TEXT_HPP #include -#include +#include #include #include #include @@ -81,7 +81,7 @@ public: * * @param color RGBA color. */ - void set_color(const float4& color); + void set_color(const math::fvec4& color); /// Returns the text material. [[nodiscard]] inline std::shared_ptr get_material() const noexcept @@ -108,7 +108,7 @@ public: } /// Returns the text color. - [[nodiscard]] inline const float4& get_color() const noexcept + [[nodiscard]] inline const math::fvec4& get_color() const noexcept { return m_color; } @@ -131,7 +131,7 @@ private: type::text_direction m_direction{type::text_direction::ltr}; std::string m_content_u8; std::u32string m_content_u32; - float4 m_color{1.0f, 0.0f, 1.0f, 1.0f}; + math::fvec4 m_color{1.0f, 0.0f, 1.0f, 1.0f}; std::size_t m_vertex_stride{0}; std::size_t m_vertex_count{0}; std::vector m_vertex_data; diff --git a/src/engine/type/bitmap-glyph.hpp b/src/engine/type/bitmap-glyph.hpp index 6b2a5e5..1876627 100644 --- a/src/engine/type/bitmap-glyph.hpp +++ b/src/engine/type/bitmap-glyph.hpp @@ -22,7 +22,7 @@ #include #include -#include +#include namespace type { @@ -40,7 +40,7 @@ struct bitmap_glyph image bitmap; /// Position of the packed glyph bitmap within the font bitmap. - uint2 position; + math::uvec2 position; }; } // namespace type diff --git a/src/engine/type/font.cpp b/src/engine/type/font.cpp index e6dd88c..a2d3e19 100644 --- a/src/engine/type/font.cpp +++ b/src/engine/type/font.cpp @@ -31,7 +31,7 @@ font::font() font::~font() {} -void font::kern(char32_t first, char32_t second, const float2& offset) +void font::kern(char32_t first, char32_t second, const math::fvec2& offset) { kerning_table[first][second] = offset; } @@ -41,13 +41,13 @@ void font::set_font_metrics(const font_metrics& metrics) this->metrics = metrics; } -const float2& font::get_kerning(char32_t first, char32_t second) const +const math::fvec2& font::get_kerning(char32_t first, char32_t second) const { if (auto it_first = kerning_table.find(first); it_first != kerning_table.end()) if (auto it_second = it_first->second.find(second); it_second != it_first->second.end()) return it_second->second; - static const float2 no_kerning = {0.0f, 0.0f}; + static const math::fvec2 no_kerning = {0.0f, 0.0f}; return no_kerning; } diff --git a/src/engine/type/font.hpp b/src/engine/type/font.hpp index 9f92573..a856f22 100644 --- a/src/engine/type/font.hpp +++ b/src/engine/type/font.hpp @@ -64,7 +64,7 @@ public: * @param second UTF-32 character code of the second glyph. * @param offset Kerning offset. */ - void kern(char32_t first, char32_t second, const float2& offset); + void kern(char32_t first, char32_t second, const math::fvec2& offset); /** * Sets the font metrics @@ -88,7 +88,7 @@ public: * @param second UTF-32 character code of the second glyph. * @return Kerning offset. */ - const float2& get_kerning(char32_t first, char32_t second) const; + const math::fvec2& get_kerning(char32_t first, char32_t second) const; /// Returns the font's kerning table. const kerning_table& get_kerning_table() const; diff --git a/src/engine/type/freetype/ft-typeface.cpp b/src/engine/type/freetype/ft-typeface.cpp index c7ff015..9efdfad 100644 --- a/src/engine/type/freetype/ft-typeface.cpp +++ b/src/engine/type/freetype/ft-typeface.cpp @@ -121,7 +121,7 @@ bool ft_typeface::get_bitmap(float height, char32_t code, image& bitmap) const return true; } -bool ft_typeface::get_kerning(float height, char32_t first, char32_t second, float2& offset) const +bool ft_typeface::get_kerning(float height, char32_t first, char32_t second, math::fvec2& offset) const { // Check if typeface has kerning information if (!has_kerning()) @@ -143,7 +143,7 @@ bool ft_typeface::get_kerning(float height, char32_t first, char32_t second, flo throw std::runtime_error("FreeType failed to get kerning vector (error code " + std::to_string(error) + ")"); } - offset = float2{static_cast(kerning.x), static_cast(kerning.y)} / 64.0f; + offset = math::fvec2{static_cast(kerning.x), static_cast(kerning.y)} / 64.0f; return true; } diff --git a/src/engine/type/freetype/ft-typeface.hpp b/src/engine/type/freetype/ft-typeface.hpp index 37b5b98..1fc08f1 100644 --- a/src/engine/type/freetype/ft-typeface.hpp +++ b/src/engine/type/freetype/ft-typeface.hpp @@ -52,7 +52,7 @@ public: virtual bool get_metrics(float height, font_metrics& metrics) const; virtual bool get_metrics(float height, char32_t code, glyph_metrics& metrics) const; virtual bool get_bitmap(float height, char32_t code, image& bitmap) const; - virtual bool get_kerning(float height, char32_t first, char32_t second, float2& offset) const; + virtual bool get_kerning(float height, char32_t first, char32_t second, math::fvec2& offset) const; private: void set_face_pixel_size(float height) const; diff --git a/src/engine/type/glyph-metrics.hpp b/src/engine/type/glyph-metrics.hpp index 9d27243..776363f 100644 --- a/src/engine/type/glyph-metrics.hpp +++ b/src/engine/type/glyph-metrics.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_TYPE_GLYPH_METRICS_HPP #define ANTKEEPER_TYPE_GLYPH_METRICS_HPP -#include +#include namespace type { @@ -36,10 +36,10 @@ struct glyph_metrics float height; /// Offset from the pen position to the glyph's top-left edge, in horizontal layouts. - float2 horizontal_bearing; + math::fvec2 horizontal_bearing; /// Offset from the pen position to the glph's top-left edge, in vertical layouts. - float2 vertical_bearing; + math::fvec2 vertical_bearing; /// Distance to move the pen position after the glyph has been rendered, in horizontal layouts. float horizontal_advance; diff --git a/src/engine/type/kerning-table.hpp b/src/engine/type/kerning-table.hpp index e73dd65..79b0a1d 100644 --- a/src/engine/type/kerning-table.hpp +++ b/src/engine/type/kerning-table.hpp @@ -20,13 +20,13 @@ #ifndef ANTKEEPER_TYPE_KERNING_TABLE_HPP #define ANTKEEPER_TYPE_KERNING_TABLE_HPP -#include +#include #include namespace type { /// Table containing kerning offsets for pairs of glyphs. -typedef std::unordered_map> kerning_table; +typedef std::unordered_map> kerning_table; } // namespace type diff --git a/src/engine/type/typeface.hpp b/src/engine/type/typeface.hpp index f747cf9..fa0352d 100644 --- a/src/engine/type/typeface.hpp +++ b/src/engine/type/typeface.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include namespace type { @@ -130,7 +130,7 @@ public: * @param[out] offset Kerning offset. * @return `true` if a kerning offset was returned, `false` otherwise. */ - virtual bool get_kerning(float height, char32_t first, char32_t second, float2& offset) const = 0; + virtual bool get_kerning(float height, char32_t first, char32_t second, math::fvec2& offset) const = 0; /// Returns the set of characters supported by the typeface. [[nodiscard]] inline const std::unordered_set& get_charset() const noexcept diff --git a/src/engine/utility/fundamental-types.hpp b/src/engine/utility/fundamental-types.hpp deleted file mode 100644 index a509a36..0000000 --- a/src/engine/utility/fundamental-types.hpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_FUNDAMENTAL_TYPES_HPP -#define ANTKEEPER_FUNDAMENTAL_TYPES_HPP - -#include -#include - -/// 2D vector of bools -using bool2 = math::vector; - -/// 3D vector of bools -using bool3 = math::vector; - -/// 4D vector of bools -using bool4 = math::vector; - -/// 2D vector of chars -using char2 = math::vector; - -/// 3D vector of chars -using char3 = math::vector; - -/// 4D vector of chars -using char4 = math::vector; - -/// 2D vector of unsigned chars -using uchar2 = math::vector; - -/// 3D vector of unsigned chars -using uchar3 = math::vector; - -/// 4D vector of unsigned chars -using uchar4 = math::vector; - -/// 2D vector of shorts -using short2 = math::vector; - -/// 3D vector of shorts -using short3 = math::vector; - -/// 4D vector of shorts -using short4 = math::vector; - -/// 2D vector of unsigned shorts -using ushort2 = math::vector; - -/// 3D vector of unsigned shorts -using ushort3 = math::vector; - -/// 4D vector of unsigned shorts -using ushort4 = math::vector; - -/// 2D vector of ints -using int2 = math::vector; - -/// 3D vector of ints -using int3 = math::vector; - -/// 4D vector of ints -using int4 = math::vector; - -/// 2D vector of unsigned ints -using uint2 = math::vector; - -/// 3D vector of unsigned ints -using uint3 = math::vector; - -/// 4D vector of unsigned ints -using uint4 = math::vector; - -/// 2D vector of longs -using long2 = math::vector; - -/// 3D vector of longs -using long3 = math::vector; - -/// 4D vector of longs -using long4 = math::vector; - -/// 2D vector of unsigned longs -using ulong2 = math::vector; - -/// 3D vector of unsigned longs -using ulong3 = math::vector; - -/// 4D vector of unsigned longs -using ulong4 = math::vector; - -/// 2D vector of floats -using float2 = math::vector; - -/// 3D vector of floats -using float3 = math::vector; - -/// 4D vector of floats -using float4 = math::vector; - -/// 2D vector of doubles -using double2 = math::vector; - -/// 3D vector of doubles -using double3 = math::vector; - -/// 4D vector of doubles -using double4 = math::vector; - -/// 2x2 matrix of bools -using bool2x2 = math::matrix; - -/// 3x3 matrix of bools -using bool3x3 = math::matrix; - -/// 4x4 matrix of bools -using bool4x4 = math::matrix; - -/// 2x2 matrix of chars -using char2x2 = math::matrix; - -/// 3x3 matrix of chars -using char3x3 = math::matrix; - -/// 4x4 matrix of chars -using char4x4 = math::matrix; - -/// 2x2 matrix of unsigned chars -using uchar2x2 = math::matrix; - -/// 3x3 matrix of unsigned chars -using uchar3x3 = math::matrix; - -/// 4x4 matrix of unsigned chars -using uchar4x4 = math::matrix; - -/// 2x2 matrix of shorts -using short2x2 = math::matrix; - -/// 3x3 matrix of shorts -using short3x3 = math::matrix; - -/// 4x4 matrix of shorts -using short4x4 = math::matrix; - -/// 2x2 matrix of unsigned shorts -using ushort2x2 = math::matrix; - -/// 3x3 matrix of unsigned shorts -using ushort3x3 = math::matrix; - -/// 4x4 matrix of unsigned shorts -using ushort4x4 = math::matrix; - -/// 2x2 matrix of ints -using int2x2 = math::matrix; - -/// 3x3 matrix of ints -using int3x3 = math::matrix; - -/// 4x4 matrix of ints -using int4x4 = math::matrix; - -/// 2x2 matrix of unsigned ints -using uint2x2 = math::matrix; - -/// 3x3 matrix of unsigned ints -using uint3x3 = math::matrix; - -/// 4x4 matrix of unsigned ints -using uint4x4 = math::matrix; - -/// 2x2 matrix of longs -using long2x2 = math::matrix; - -/// 3x3 matrix of longs -using long3x3 = math::matrix; - -/// 4x4 matrix of longs -using long4x4 = math::matrix; - -/// 2x2 matrix of unsigned longs -using ulong2x2 = math::matrix; - -/// 3x3 matrix of unsigned longs -using ulong3x3 = math::matrix; - -/// 4x4 matrix of unsigned longs -using ulong4x4 = math::matrix; - -/// 2x2 matrix of floats -using float2x2 = math::matrix; - -/// 3x3 matrix of floats -using float3x3 = math::matrix; - -/// 4x4 matrix of floats -using float4x4 = math::matrix; - -/// 2x2 matrix of doubles -using double2x2 = math::matrix; - -/// 3x3 matrix of doubles -using double3x3 = math::matrix; - -/// 4x4 matrix of doubles -using double4x4 = math::matrix; - -#endif // ANTKEEPER_FUNDAMENTAL_TYPES_HPP diff --git a/src/game/ant/ant-morphogenesis.cpp b/src/game/ant/ant-morphogenesis.cpp index b42c7cd..881d6cd 100644 --- a/src/game/ant/ant-morphogenesis.cpp +++ b/src/game/ant/ant-morphogenesis.cpp @@ -87,9 +87,9 @@ void reskin_vertices float* tz = ty + 1; // Transform vertex attributes - const float3 position = (*transform) * float3{*px, *py, *pz}; - const float3 normal = math::normalize(transform->rotation * float3{*nx, *ny, *nz}); - const float3 tangent = math::normalize(transform->rotation * float3{*tx, *ty, *tz}); + const math::fvec3 position = (*transform) * math::fvec3{*px, *py, *pz}; + const math::fvec3 normal = math::normalize(transform->rotation * math::fvec3{*nx, *ny, *nz}); + const math::fvec3 tangent = math::normalize(transform->rotation * math::fvec3{*tx, *ty, *tz}); // Update vertex attributes *px = position.x(); @@ -154,12 +154,12 @@ float calculate_uv_area const float* uv_data_b = reinterpret_cast(uv_data + uv_attribute.stride * (i + 1)); const float* uv_data_c = reinterpret_cast(uv_data + uv_attribute.stride * (i + 2)); - const float3 uva = {uv_data_a[0], uv_data_a[1], 0.0f}; - const float3 uvb = {uv_data_b[0], uv_data_b[1], 0.0f}; - const float3 uvc = {uv_data_c[0], uv_data_c[1], 0.0f}; + const math::fvec3 uva = {uv_data_a[0], uv_data_a[1], 0.0f}; + const math::fvec3 uvb = {uv_data_b[0], uv_data_b[1], 0.0f}; + const math::fvec3 uvc = {uv_data_c[0], uv_data_c[1], 0.0f}; - const float3 uvab = uvb - uva; - const float3 uvac = uvc - uva; + const math::fvec3 uvab = uvb - uva; + const math::fvec3 uvac = uvc - uva; sum_area += math::length(math::cross(uvab, uvac)) * 0.5f; } @@ -185,19 +185,14 @@ float calculate_uv_area { const std::byte* position_data = vertex_data + position_attribute.offset; - geom::box bounds - { - {std::numeric_limits::infinity(), std::numeric_limits::infinity(), std::numeric_limits::infinity()}, - {-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), -std::numeric_limits::infinity()} - }; - + geom::box bounds = {math::fvec3::infinity(), -math::fvec3::infinity()}; for (std::size_t i = 0; i < vertex_count; ++i) { const float* px = reinterpret_cast(position_data + position_attribute.stride * i); const float* py = px + 1; const float* pz = py + 1; - bounds.extend(float3{*px, *py, *pz}); + bounds.extend(math::fvec3{*px, *py, *pz}); } return bounds; @@ -240,16 +235,16 @@ float calculate_uv_area std::unique_ptr exoskeleton_material = std::make_unique(*phenome.pigmentation->material); // Set roughness variable - exoskeleton_material->set_variable("exoskeleton_roughness", std::make_shared(1, phenome.sculpturing->roughness)); + exoskeleton_material->set_variable("exoskeleton_roughness", std::make_shared(1, phenome.sculpturing->roughness)); // Set normal map variable - exoskeleton_material->set_variable("exoskeleton_normal_map", std::make_shared(1, phenome.sculpturing->normal_map)); + exoskeleton_material->set_variable("exoskeleton_normal_map", std::make_shared(1, phenome.sculpturing->normal_map)); if (phenome.eyes->present) { // Set ommatidia scale variable const float ommatidia_scale = calculate_ommatidia_scale(eye_uv_area, static_cast(phenome.eyes->ommatidia_count)); - exoskeleton_material->set_variable("ommatidia_scale", std::make_shared(1, ommatidia_scale)); + exoskeleton_material->set_variable("ommatidia_scale", std::make_shared(1, ommatidia_scale)); } return exoskeleton_material; diff --git a/src/game/ant/ant-skeleton.cpp b/src/game/ant/ant-skeleton.cpp index 24934d0..3922489 100644 --- a/src/game/ant/ant-skeleton.cpp +++ b/src/game/ant/ant-skeleton.cpp @@ -139,27 +139,27 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) constexpr float procoxa_fold_angle_x = math::radians(15.0f); auto fold_procoxa_l = math::transform::identity(); auto fold_procoxa_r = math::transform::identity(); - fold_procoxa_l.rotation = math::angle_axis(procoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(procoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(procoxa_fold_angle_x, float3{1, 0, 0}); - fold_procoxa_r.rotation = math::angle_axis(-procoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-procoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(procoxa_fold_angle_x, float3{1, 0, 0}); + fold_procoxa_l.rotation = math::angle_axis(procoxa_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(procoxa_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(procoxa_fold_angle_x, math::fvec3{1, 0, 0}); + fold_procoxa_r.rotation = math::angle_axis(-procoxa_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-procoxa_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(procoxa_fold_angle_x, math::fvec3{1, 0, 0}); constexpr float profemur_fold_angle_z = math::radians(20.0f); constexpr float profemur_fold_angle_x = math::radians(80.0f); auto fold_profemur_l = math::transform::identity(); auto fold_profemur_r = math::transform::identity(); - fold_profemur_l.rotation = math::angle_axis(profemur_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(profemur_fold_angle_x, float3{1, 0, 0}); - fold_profemur_r.rotation = math::angle_axis(-profemur_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(profemur_fold_angle_x, float3{1, 0, 0}); + fold_profemur_l.rotation = math::angle_axis(profemur_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(profemur_fold_angle_x, math::fvec3{1, 0, 0}); + fold_profemur_r.rotation = math::angle_axis(-profemur_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(profemur_fold_angle_x, math::fvec3{1, 0, 0}); constexpr float protibia_fold_angle = math::radians(165.0f); auto fold_protibia_l = math::transform::identity(); auto fold_protibia_r = math::transform::identity(); - fold_protibia_l.rotation = math::angle_axis(-protibia_fold_angle, float3{1, 0, 0}); - fold_protibia_r.rotation = math::angle_axis(-protibia_fold_angle, float3{1, 0, 0}); + fold_protibia_l.rotation = math::angle_axis(-protibia_fold_angle, math::fvec3{1, 0, 0}); + fold_protibia_r.rotation = math::angle_axis(-protibia_fold_angle, math::fvec3{1, 0, 0}); constexpr float protarsomere1_fold_angle = math::radians(20.0f); auto fold_protarsomere1_l = math::transform::identity(); auto fold_protarsomere1_r = math::transform::identity(); - fold_protarsomere1_l.rotation = math::angle_axis(-protarsomere1_fold_angle, float3{1, 0, 0}); - fold_protarsomere1_r.rotation = math::angle_axis(-protarsomere1_fold_angle, float3{1, 0, 0}); + fold_protarsomere1_l.rotation = math::angle_axis(-protarsomere1_fold_angle, math::fvec3{1, 0, 0}); + fold_protarsomere1_r.rotation = math::angle_axis(-protarsomere1_fold_angle, math::fvec3{1, 0, 0}); pupa_pose.set_relative_transform(bones.procoxa_l, rest_pose.get_relative_transform(bones.procoxa_l) * fold_procoxa_l); pupa_pose.set_relative_transform(bones.procoxa_r, rest_pose.get_relative_transform(bones.procoxa_r) * fold_procoxa_r); @@ -178,26 +178,26 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) constexpr float mesocoxa_fold_angle_x = math::radians(10.0f); auto fold_mesocoxa_l = math::transform::identity(); auto fold_mesocoxa_r = math::transform::identity(); - fold_mesocoxa_l.rotation = math::angle_axis(-mesocoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(mesocoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-mesocoxa_fold_angle_x, float3{1, 0, 0}); - fold_mesocoxa_r.rotation = math::angle_axis(mesocoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(-mesocoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-mesocoxa_fold_angle_x, float3{1, 0, 0}); + fold_mesocoxa_l.rotation = math::angle_axis(-mesocoxa_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(mesocoxa_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-mesocoxa_fold_angle_x, math::fvec3{1, 0, 0}); + fold_mesocoxa_r.rotation = math::angle_axis(mesocoxa_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(-mesocoxa_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-mesocoxa_fold_angle_x, math::fvec3{1, 0, 0}); constexpr float mesofemur_fold_angle = math::radians(90.0f); auto fold_mesofemur_l = math::transform::identity(); auto fold_mesofemur_r = math::transform::identity(); - fold_mesofemur_l.rotation = math::angle_axis(mesofemur_fold_angle, float3{1, 0, 0}); - fold_mesofemur_r.rotation = math::angle_axis(mesofemur_fold_angle, float3{1, 0, 0}); + fold_mesofemur_l.rotation = math::angle_axis(mesofemur_fold_angle, math::fvec3{1, 0, 0}); + fold_mesofemur_r.rotation = math::angle_axis(mesofemur_fold_angle, math::fvec3{1, 0, 0}); constexpr float mesotibia_fold_angle = math::radians(162.0f); auto fold_mesotibia_l = math::transform::identity(); auto fold_mesotibia_r = math::transform::identity(); - fold_mesotibia_l.rotation = math::angle_axis(-mesotibia_fold_angle, float3{1, 0, 0}); - fold_mesotibia_r.rotation = math::angle_axis(-mesotibia_fold_angle, float3{1, 0, 0}); + fold_mesotibia_l.rotation = math::angle_axis(-mesotibia_fold_angle, math::fvec3{1, 0, 0}); + fold_mesotibia_r.rotation = math::angle_axis(-mesotibia_fold_angle, math::fvec3{1, 0, 0}); constexpr float mesotarsomere1_fold_angle = math::radians(20.0f); auto fold_mesotarsomere1_l = math::transform::identity(); auto fold_mesotarsomere1_r = math::transform::identity(); - fold_mesotarsomere1_l.rotation = math::angle_axis(-mesotarsomere1_fold_angle, float3{1, 0, 0}); - fold_mesotarsomere1_r.rotation = math::angle_axis(-mesotarsomere1_fold_angle, float3{1, 0, 0}); + fold_mesotarsomere1_l.rotation = math::angle_axis(-mesotarsomere1_fold_angle, math::fvec3{1, 0, 0}); + fold_mesotarsomere1_r.rotation = math::angle_axis(-mesotarsomere1_fold_angle, math::fvec3{1, 0, 0}); pupa_pose.set_relative_transform(bones.mesocoxa_l, rest_pose.get_relative_transform(bones.mesocoxa_l) * fold_mesocoxa_l); pupa_pose.set_relative_transform(bones.mesocoxa_r, rest_pose.get_relative_transform(bones.mesocoxa_r) * fold_mesocoxa_r); @@ -216,26 +216,26 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) constexpr float metacoxa_fold_angle_x = math::radians(25.0f); auto fold_metacoxa_l = math::transform::identity(); auto fold_metacoxa_r = math::transform::identity(); - fold_metacoxa_l.rotation = math::angle_axis(-metacoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(-metacoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(metacoxa_fold_angle_x, float3{1, 0, 0}); - fold_metacoxa_r.rotation = math::angle_axis(metacoxa_fold_angle_z, float3{0, 0, 1}) * math::angle_axis(metacoxa_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(metacoxa_fold_angle_x, float3{1, 0, 0}); + fold_metacoxa_l.rotation = math::angle_axis(-metacoxa_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(-metacoxa_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(metacoxa_fold_angle_x, math::fvec3{1, 0, 0}); + fold_metacoxa_r.rotation = math::angle_axis(metacoxa_fold_angle_z, math::fvec3{0, 0, 1}) * math::angle_axis(metacoxa_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(metacoxa_fold_angle_x, math::fvec3{1, 0, 0}); constexpr float metafemur_fold_angle = math::radians(105.0f); auto fold_metafemur_l = math::transform::identity(); auto fold_metafemur_r = math::transform::identity(); - fold_metafemur_l.rotation = math::angle_axis(metafemur_fold_angle, float3{1, 0, 0}); - fold_metafemur_r.rotation = math::angle_axis(metafemur_fold_angle, float3{1, 0, 0}); + fold_metafemur_l.rotation = math::angle_axis(metafemur_fold_angle, math::fvec3{1, 0, 0}); + fold_metafemur_r.rotation = math::angle_axis(metafemur_fold_angle, math::fvec3{1, 0, 0}); constexpr float metatibia_fold_angle = math::radians(165.0f); auto fold_metatibia_l = math::transform::identity(); auto fold_metatibia_r = math::transform::identity(); - fold_metatibia_l.rotation = math::angle_axis(-metatibia_fold_angle, float3{1, 0, 0}); - fold_metatibia_r.rotation = math::angle_axis(-metatibia_fold_angle, float3{1, 0, 0}); + fold_metatibia_l.rotation = math::angle_axis(-metatibia_fold_angle, math::fvec3{1, 0, 0}); + fold_metatibia_r.rotation = math::angle_axis(-metatibia_fold_angle, math::fvec3{1, 0, 0}); constexpr float metatarsomere1_fold_angle = math::radians(0.0f); auto fold_metatarsomere1_l = math::transform::identity(); auto fold_metatarsomere1_r = math::transform::identity(); - fold_metatarsomere1_l.rotation = math::angle_axis(-metatarsomere1_fold_angle, float3{1, 0, 0}); - fold_metatarsomere1_r.rotation = math::angle_axis(-metatarsomere1_fold_angle, float3{1, 0, 0}); + fold_metatarsomere1_l.rotation = math::angle_axis(-metatarsomere1_fold_angle, math::fvec3{1, 0, 0}); + fold_metatarsomere1_r.rotation = math::angle_axis(-metatarsomere1_fold_angle, math::fvec3{1, 0, 0}); pupa_pose.set_relative_transform(bones.metacoxa_l, rest_pose.get_relative_transform(bones.metacoxa_l) * fold_metacoxa_l); pupa_pose.set_relative_transform(bones.metacoxa_r, rest_pose.get_relative_transform(bones.metacoxa_r) * fold_metacoxa_r); @@ -251,7 +251,7 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) { constexpr float head_fold_angle = math::radians(80.0f); auto fold_head = math::transform::identity(); - fold_head.rotation = math::angle_axis(-head_fold_angle, float3{1, 0, 0}); + fold_head.rotation = math::angle_axis(-head_fold_angle, math::fvec3{1, 0, 0}); pupa_pose.set_relative_transform(bones.head, rest_pose.get_relative_transform(bones.head) * fold_head); } @@ -262,15 +262,15 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) constexpr float antennomere1_fold_angle_x = math::radians(45.0f); auto fold_antennomere1_l = math::transform::identity(); auto fold_antennomere1_r = math::transform::identity(); - fold_antennomere1_l.rotation = math::angle_axis(-antennomere1_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere1_fold_angle_x, float3{1, 0, 0}); - fold_antennomere1_r.rotation = math::angle_axis(antennomere1_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere1_fold_angle_x, float3{1, 0, 0}); + fold_antennomere1_l.rotation = math::angle_axis(-antennomere1_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-antennomere1_fold_angle_x, math::fvec3{1, 0, 0}); + fold_antennomere1_r.rotation = math::angle_axis(antennomere1_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-antennomere1_fold_angle_x, math::fvec3{1, 0, 0}); constexpr float antennomere2_fold_angle_y = math::radians(75.0f); constexpr float antennomere2_fold_angle_x = math::radians(25.0f); auto fold_antennomere2_l = math::transform::identity(); auto fold_antennomere2_r = math::transform::identity(); - fold_antennomere2_l.rotation = math::angle_axis(antennomere2_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere2_fold_angle_x, float3{1, 0, 0}); - fold_antennomere2_r.rotation = math::angle_axis(-antennomere2_fold_angle_y, float3{0, 1, 0}) * math::angle_axis(-antennomere2_fold_angle_x, float3{1, 0, 0}); + fold_antennomere2_l.rotation = math::angle_axis(antennomere2_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-antennomere2_fold_angle_x, math::fvec3{1, 0, 0}); + fold_antennomere2_r.rotation = math::angle_axis(-antennomere2_fold_angle_y, math::fvec3{0, 1, 0}) * math::angle_axis(-antennomere2_fold_angle_x, math::fvec3{1, 0, 0}); pupa_pose.set_relative_transform(bones.antennomere1_l, rest_pose.get_relative_transform(bones.antennomere1_l) * fold_antennomere1_l); pupa_pose.set_relative_transform(bones.antennomere1_r, rest_pose.get_relative_transform(bones.antennomere1_r) * fold_antennomere1_r); @@ -282,15 +282,15 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) { constexpr float petiole_fold_angle = math::radians(40.0f); auto fold_petiole = math::transform::identity(); - fold_petiole.rotation = math::angle_axis(petiole_fold_angle, float3{1, 0, 0}); + fold_petiole.rotation = math::angle_axis(petiole_fold_angle, math::fvec3{1, 0, 0}); constexpr float postpetiole_fold_angle = math::radians(35.0f); auto fold_postpetiole = math::transform::identity(); - fold_postpetiole.rotation = math::angle_axis(-postpetiole_fold_angle, float3{1, 0, 0}); + fold_postpetiole.rotation = math::angle_axis(-postpetiole_fold_angle, math::fvec3{1, 0, 0}); constexpr float gaster_fold_angle = math::radians(0.0f); auto fold_gaster = math::transform::identity(); - fold_gaster.rotation = math::angle_axis(-gaster_fold_angle, float3{1, 0, 0}); + fold_gaster.rotation = math::angle_axis(-gaster_fold_angle, math::fvec3{1, 0, 0}); if (bones.petiole) { @@ -309,7 +309,7 @@ void generate_ant_pupa_pose(skeleton& skeleton, const ant_bone_set& bones) // { // const float mesosoma_invert_angle = math::radians(90.0f); // auto invert_mesosoma = math::transform::identity(); - // invert_mesosoma.rotation = math::angle_axis(mesosoma_invert_angle, float3{0, 0, 1}); + // invert_mesosoma.rotation = math::angle_axis(mesosoma_invert_angle, math::fvec3{0, 0, 1}); // auto mesosoma = *skeleton.get_index("mesosoma"); // pupa_pose.set_relative_transform(bones.mesosoma, invert_mesosoma * rest_pose.get_relative_transform(bones.mesosoma)); diff --git a/src/game/ant/ant-swarm.cpp b/src/game/ant/ant-swarm.cpp index 28374b8..c28f378 100644 --- a/src/game/ant/ant-swarm.cpp +++ b/src/game/ant/ant-swarm.cpp @@ -39,11 +39,11 @@ * @see https://math.stackexchange.com/questions/87230/picking-random-points-in-the-volume-of-sphere-with-uniform-probability/87238#87238 */ template -static math::vector3 sphere_random(URBG& urbg) +static math::vec3 sphere_random(URBG& urbg) { std::uniform_real_distribution distribution(T{-1}, T{1}); - math::vector3 position; + math::vec3 position; for (std::size_t i = 0; i < 3; ++i) position[i] = distribution(urbg); @@ -53,14 +53,14 @@ static math::vector3 sphere_random(URBG& urbg) entity::id create_ant_swarm(::game& ctx) { // Determine swarm properties - const float3 swarm_center = {0, 100, 0}; + const math::fvec3 swarm_center = {0, 100, 0}; const float swarm_radius = 25.0f; const std::size_t male_count = 50; const std::size_t queen_count = 50; const std::size_t alate_count = male_count + queen_count; - const float3 male_scale = {0.5, 0.5, 0.5}; - const float3 queen_scale = {1, 1, 1}; + const math::fvec3 male_scale = {0.5, 0.5, 0.5}; + const math::fvec3 queen_scale = {1, 1, 1}; // Init transform component ::transform_component transform; @@ -69,7 +69,7 @@ entity::id create_ant_swarm(::game& ctx) // Init picking component ::picking_component picking; - picking.sphere = {float3{0, 0, 0}, 0.5f * 2.0f}; + picking.sphere = {math::fvec3{0, 0, 0}, 0.5f * 2.0f}; std::uint32_t male_picking_flags = 0b01; std::uint32_t queen_picking_flags = 0b10; @@ -93,7 +93,7 @@ entity::id create_ant_swarm(::game& ctx) steering.agent.max_force = 4.0f; steering.agent.max_speed = 5.0f; steering.agent.max_speed_squared = steering.agent.max_speed * steering.agent.max_speed; - steering.agent.orientation = math::quaternion::identity(); + steering.agent.orientation = math::fquat::identity(); steering.agent.forward = steering.agent.orientation * config::global_forward; steering.agent.up = steering.agent.orientation * config::global_up; steering.wander_weight = 1.0f; diff --git a/src/game/commands/commands.cpp b/src/game/commands/commands.cpp index dedc6d3..5df1af0 100644 --- a/src/game/commands/commands.cpp +++ b/src/game/commands/commands.cpp @@ -27,7 +27,7 @@ namespace command { -void translate(entity::registry& registry, entity::id eid, const float3& translation) +void translate(entity::registry& registry, entity::id eid, const math::fvec3& translation) { const ::transform_component* transform = registry.try_get<::transform_component>(eid); if (transform) @@ -43,7 +43,7 @@ void translate(entity::registry& registry, entity::id eid, const float3& transla } } -void rotate(entity::registry& registry, entity::id eid, float angle, const float3& axis) +void rotate(entity::registry& registry, entity::id eid, float angle, const math::fvec3& axis) { const ::transform_component* transform = registry.try_get<::transform_component>(eid); if (transform) @@ -59,7 +59,7 @@ void rotate(entity::registry& registry, entity::id eid, float angle, const float } } -void move_to(entity::registry& registry, entity::id eid, const float3& position) +void move_to(entity::registry& registry, entity::id eid, const math::fvec3& position) { const ::transform_component* transform = registry.try_get<::transform_component>(eid); if (transform) @@ -75,7 +75,7 @@ void move_to(entity::registry& registry, entity::id eid, const float3& position) } } -void warp_to(entity::registry& registry, entity::id eid, const float3& position) +void warp_to(entity::registry& registry, entity::id eid, const math::fvec3& position) { const ::transform_component* transform = registry.try_get<::transform_component>(eid); if (transform) @@ -91,7 +91,7 @@ void warp_to(entity::registry& registry, entity::id eid, const float3& position) } } -void set_scale(entity::registry& registry, entity::id eid, const float3& scale) +void set_scale(entity::registry& registry, entity::id eid, const math::fvec3& scale) { const ::transform_component* transform = registry.try_get<::transform_component>(eid); if (transform) diff --git a/src/game/commands/commands.hpp b/src/game/commands/commands.hpp index 0791ddc..37d6c68 100644 --- a/src/game/commands/commands.hpp +++ b/src/game/commands/commands.hpp @@ -22,18 +22,18 @@ #include #include -#include +#include #include /// Commands which operate on entity::id components namespace command { -void translate(entity::registry& registry, entity::id eid, const float3& translation); -void rotate(entity::registry& registry, entity::id eid, float angle, const float3& axis); -void move_to(entity::registry& registry, entity::id eid, const float3& position); -void warp_to(entity::registry& registry, entity::id eid, const float3& position); -void set_scale(entity::registry& registry, entity::id eid, const float3& scale); +void translate(entity::registry& registry, entity::id eid, const math::fvec3& translation); +void rotate(entity::registry& registry, entity::id eid, float angle, const math::fvec3& axis); +void move_to(entity::registry& registry, entity::id eid, const math::fvec3& position); +void warp_to(entity::registry& registry, entity::id eid, const math::fvec3& position); +void set_scale(entity::registry& registry, entity::id eid, const math::fvec3& scale); void set_transform(entity::registry& registry, entity::id eid, const math::transform& transform); void place(entity::registry& registry, entity::id eid, entity::id celestial_body_id, double altitude, double latitude, double longitude); void assign_render_layers(entity::registry& registry, entity::id eid, unsigned int layers); diff --git a/src/game/components/atmosphere-component.hpp b/src/game/components/atmosphere-component.hpp index e4e5fd7..3a0bf5c 100644 --- a/src/game/components/atmosphere-component.hpp +++ b/src/game/components/atmosphere-component.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ATMOSPHERE_COMPONENT_HPP #define ANTKEEPER_GAME_ATMOSPHERE_COMPONENT_HPP -#include +#include /// Atmosphere @@ -39,7 +39,7 @@ struct atmosphere_component double rayleigh_scale_height; /// (Dependent) Rayleigh scattering coefficients. - double3 rayleigh_scattering; + math::dvec3 rayleigh_scattering; /// Molar concentration of Mie particles at sea level, in mol/m-3. double mie_concentration; @@ -72,10 +72,10 @@ struct atmosphere_component double ozone_mode; /// (Dependent) Ozone absorption coefficients. - double3 ozone_absorption; + math::dvec3 ozone_absorption; /// Airglow luminance, in cd/m^2. - double3 airglow_luminance; + math::dvec3 airglow_luminance; }; diff --git a/src/game/components/blackbody-component.hpp b/src/game/components/blackbody-component.hpp index e4a83b0..81f3492 100644 --- a/src/game/components/blackbody-component.hpp +++ b/src/game/components/blackbody-component.hpp @@ -32,7 +32,7 @@ struct blackbody_component double luminance{}; /// Color of the blackbody. - math::vector color{}; + math::dvec3 color{}; }; #endif // ANTKEEPER_GAME_BLACKBODY_COMPONENT_HPP diff --git a/src/game/components/cavity-component.hpp b/src/game/components/cavity-component.hpp index d975697..d54670e 100644 --- a/src/game/components/cavity-component.hpp +++ b/src/game/components/cavity-component.hpp @@ -20,12 +20,12 @@ #ifndef ANTKEEPER_GAME_CAVITY_COMPONENT_HPP #define ANTKEEPER_GAME_CAVITY_COMPONENT_HPP -#include +#include struct cavity_component { - float3 position; + math::fvec3 position; float radius; }; diff --git a/src/game/components/legged-locomotion-component.hpp b/src/game/components/legged-locomotion-component.hpp index f3e4e2e..83416d1 100644 --- a/src/game/components/legged-locomotion-component.hpp +++ b/src/game/components/legged-locomotion-component.hpp @@ -28,7 +28,7 @@ struct legged_locomotion_component { /// Force vector. - math::vector force{0.0f, 0.0f, 0.0f}; + math::fvec3 force{0.0f, 0.0f, 0.0f}; }; #endif // ANTKEEPER_GAME_LEGGED_LOCOMOTION_COMPONENT_HPP diff --git a/src/game/components/orbit-component.hpp b/src/game/components/orbit-component.hpp index 93c0b1c..ab239fa 100644 --- a/src/game/components/orbit-component.hpp +++ b/src/game/components/orbit-component.hpp @@ -36,7 +36,7 @@ struct orbit_component double scale; /// Cartesian position of the orbit, w.r.t. the ICRF frame. - math::vector3 position; + math::dvec3 position; }; diff --git a/src/game/components/spring-component.hpp b/src/game/components/spring-component.hpp index 0bd09f7..9ea26b8 100644 --- a/src/game/components/spring-component.hpp +++ b/src/game/components/spring-component.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_SPRING_COMPONENT_HPP #include -#include +#include #include @@ -43,10 +43,10 @@ struct spring1_component struct spring2_component { /// Numeric spring with two components. - numeric_spring spring; + numeric_spring spring; /// Spring solved callback. - std::function callback; + std::function callback; }; /** @@ -55,10 +55,10 @@ struct spring2_component struct spring3_component { /// Numeric spring with three components. - numeric_spring spring; + numeric_spring spring; /// Spring solved callback. - std::function callback; + std::function callback; }; /** @@ -67,10 +67,10 @@ struct spring3_component struct spring4_component { /// Numeric spring with four components. - numeric_spring spring; + numeric_spring spring; /// Spring solved callback. - std::function callback; + std::function callback; }; diff --git a/src/game/components/steering-component.hpp b/src/game/components/steering-component.hpp index c408fe6..9d85048 100644 --- a/src/game/components/steering-component.hpp +++ b/src/game/components/steering-component.hpp @@ -38,7 +38,7 @@ struct steering_component // Seek behavior float seek_weight; - float3 seek_target; + math::fvec3 seek_target; // Flee behavior float flee_weight; diff --git a/src/game/components/trackable-component.hpp b/src/game/components/trackable-component.hpp index a0b8058..5d5def3 100644 --- a/src/game/components/trackable-component.hpp +++ b/src/game/components/trackable-component.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_TRACKABLE_COMPONENT_HPP #define ANTKEEPER_GAME_TRACKABLE_COMPONENT_HPP -#include +#include struct trackable_component diff --git a/src/game/components/winged-locomotion-component.hpp b/src/game/components/winged-locomotion-component.hpp index ee5730a..cdda3e0 100644 --- a/src/game/components/winged-locomotion-component.hpp +++ b/src/game/components/winged-locomotion-component.hpp @@ -28,7 +28,7 @@ struct winged_locomotion_component { /// Force vector. - math::vector force{0.0f, 0.0f, 0.0f}; + math::fvec3 force{0.0f, 0.0f, 0.0f}; }; #endif // ANTKEEPER_GAME_WINGED_LOCOMOTION_COMPONENT_HPP diff --git a/src/game/constraints/child-of-constraint.hpp b/src/game/constraints/child-of-constraint.hpp index fc48183..0d177cc 100644 --- a/src/game/constraints/child-of-constraint.hpp +++ b/src/game/constraints/child-of-constraint.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_CHILD_OF_CONSTRAINT_HPP #include -#include +#include /** diff --git a/src/game/constraints/ease-to-constraint.hpp b/src/game/constraints/ease-to-constraint.hpp index c4d48f2..0d9fe00 100644 --- a/src/game/constraints/ease-to-constraint.hpp +++ b/src/game/constraints/ease-to-constraint.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_EASE_TO_CONSTRAINT_HPP #include -#include +#include /** @@ -33,7 +33,7 @@ struct ease_to_constraint entity::id target; /// Start position. - float3 start; + math::fvec3 start; /// Total duration of the ease. float duration; @@ -42,7 +42,7 @@ struct ease_to_constraint float t; /// Pointer to the interpolation function. - float3 (*function)(const float3&, const float3&, float); + math::fvec3 (*function)(const math::fvec3&, const math::fvec3&, float); }; diff --git a/src/game/constraints/pivot-constraint.hpp b/src/game/constraints/pivot-constraint.hpp index 39d085c..19f7d61 100644 --- a/src/game/constraints/pivot-constraint.hpp +++ b/src/game/constraints/pivot-constraint.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_PIVOT_CONSTRAINT_HPP #include -#include +#include /** @@ -33,7 +33,7 @@ struct pivot_constraint entity::id target; /// Pivot point offset. - float3 offset; + math::fvec3 offset; }; diff --git a/src/game/constraints/spring-rotation-constraint.hpp b/src/game/constraints/spring-rotation-constraint.hpp index 4185241..1a27bc9 100644 --- a/src/game/constraints/spring-rotation-constraint.hpp +++ b/src/game/constraints/spring-rotation-constraint.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_SPRING_ROTATION_CONSTRAINT_HPP #include -#include +#include /** @@ -30,7 +30,7 @@ struct spring_rotation_constraint { /// Yaw, pitch, and roll angle spring. - numeric_spring spring; + numeric_spring spring; }; diff --git a/src/game/constraints/spring-to-constraint.hpp b/src/game/constraints/spring-to-constraint.hpp index e74c264..cb0c611 100644 --- a/src/game/constraints/spring-to-constraint.hpp +++ b/src/game/constraints/spring-to-constraint.hpp @@ -22,7 +22,7 @@ #include #include -#include +#include /** @@ -34,10 +34,10 @@ struct spring_to_constraint entity::id target; /// Translation spring. - numeric_spring translation; + numeric_spring translation; /// Rotation spring. - numeric_spring rotation; + numeric_spring rotation; /// Spring translation. bool spring_translation; diff --git a/src/game/constraints/spring-translation-constraint.hpp b/src/game/constraints/spring-translation-constraint.hpp index 827269c..c0f0293 100644 --- a/src/game/constraints/spring-translation-constraint.hpp +++ b/src/game/constraints/spring-translation-constraint.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_SPRING_TRANSLATION_CONSTRAINT_HPP #include -#include +#include /** @@ -30,7 +30,7 @@ struct spring_translation_constraint { /// Translation spring. - numeric_spring spring; + numeric_spring spring; }; diff --git a/src/game/constraints/track-to-constraint.hpp b/src/game/constraints/track-to-constraint.hpp index beedaf5..779e074 100644 --- a/src/game/constraints/track-to-constraint.hpp +++ b/src/game/constraints/track-to-constraint.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_TRACK_TO_CONSTRAINT_HPP #include -#include +#include /** @@ -33,7 +33,7 @@ struct track_to_constraint entity::id target; /// Up direction vector. - float3 up; + math::fvec3 up; }; diff --git a/src/game/controls.cpp b/src/game/controls.cpp index 7619f7e..08bc85f 100644 --- a/src/game/controls.cpp +++ b/src/game/controls.cpp @@ -475,7 +475,7 @@ void enable_menu_controls(::game& ctx) ctx.menu_action_map.enable(); // Function to select menu item at mouse position - auto select_menu_item = [&ctx](const math::vector& mouse_position) -> bool + auto select_menu_item = [&ctx](const math::fvec2& mouse_position) -> bool { const float padding = config::menu_mouseover_padding * ctx.menu_font.get_font_metrics().size; @@ -530,7 +530,7 @@ void enable_menu_controls(::game& ctx) [&ctx, select_menu_item](const auto& event) { // Select menu item at mouse position (if any) - select_menu_item(math::vector(event.position)); + select_menu_item(math::fvec2(event.position)); } ) ); @@ -541,7 +541,7 @@ void enable_menu_controls(::game& ctx) [&ctx, select_menu_item](const auto& event) { // Select menu item at mouse position (if any) - if (select_menu_item(math::vector(event.position))) + if (select_menu_item(math::fvec2(event.position))) { // Determine appropriate menu item callback auto callback = ctx.menu_select_callbacks[*ctx.menu_item_index]; diff --git a/src/game/ecoregion.hpp b/src/game/ecoregion.hpp index e3d7169..0d7623a 100644 --- a/src/game/ecoregion.hpp +++ b/src/game/ecoregion.hpp @@ -20,7 +20,7 @@ #ifndef ANTKEEPER_GAME_ECOREGION_HPP #define ANTKEEPER_GAME_ECOREGION_HPP -#include +#include #include #include "game/ant/ant-gene-pool.hpp" #include @@ -48,7 +48,7 @@ struct ecoregion std::shared_ptr terrain_material; /// Terrain albedo. - float3 terrain_albedo; + math::fvec3 terrain_albedo; /// Horizon material. std::shared_ptr horizon_material; diff --git a/src/game/fonts.cpp b/src/game/fonts.cpp index b40d95c..d80cfe6 100644 --- a/src/game/fonts.cpp +++ b/src/game/fonts.cpp @@ -63,7 +63,7 @@ static void build_bitmap_font(const type::typeface& typeface, float size, const if (auto var = material.get_variable("font_bitmap")) { // Update font texture - auto texture = std::static_pointer_cast(var)->get(); + auto texture = std::static_pointer_cast(var)->get(); texture->resize(font_bitmap.width(), font_bitmap.height(), font_bitmap.data()); } else @@ -74,7 +74,7 @@ static void build_bitmap_font(const type::typeface& typeface, float size, const font_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear); // Create font bitmap variable - material.set_variable("font_bitmap", std::make_shared(1, font_texture)); + material.set_variable("font_bitmap", std::make_shared(1, font_texture)); } material.set_shader_template(shader_template); } diff --git a/src/game/game.cpp b/src/game/game.cpp index e15098e..f87987d 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -751,7 +751,7 @@ void game::setup_rendering() surface_outline_pass = std::make_unique(window->get_rasterizer(), hdr_framebuffer.get(), resource_manager.get()); surface_outline_pass->set_outline_width(0.25f); - surface_outline_pass->set_outline_color(float4{1.0f, 1.0f, 1.0f, 1.0f}); + surface_outline_pass->set_outline_color(math::fvec4{1.0f, 1.0f, 1.0f, 1.0f}); surface_compositor = std::make_unique(); surface_compositor->add_pass(surface_shadow_map_clear_pass.get()); @@ -894,7 +894,7 @@ void game::setup_ui() // Menu BG material menu_bg_material = std::make_shared(); menu_bg_material->set_shader_template(resource_manager->load("ui-element-untextured.glsl")); - std::shared_ptr menu_bg_tint = std::make_shared(1, float4{0.0f, 0.0f, 0.0f, 0.5f}); + std::shared_ptr menu_bg_tint = std::make_shared(1, math::fvec4{0.0f, 0.0f, 0.0f, 0.5f}); menu_bg_material->set_variable("tint", menu_bg_tint); menu_bg_material->set_blend_mode(render::material_blend_mode::translucent); @@ -907,7 +907,7 @@ void game::setup_ui() // Create fade transition fade_transition = std::make_unique(); fade_transition->get_material()->set_shader_template(resource_manager->load("fade-transition.glsl")); - fade_transition_color = std::make_shared(1, float3{0, 0, 0}); + fade_transition_color = std::make_shared(1, math::fvec3{0, 0, 0}); fade_transition->get_material()->set_variable("color", fade_transition_color); fade_transition->get_billboard()->set_translation({0, 0, 98}); @@ -923,7 +923,7 @@ void game::setup_ui() { auto menu_bg_frame_callback = [menu_bg_tint](int channel, const float& opacity) { - menu_bg_tint->set(float4{0.0f, 0.0f, 0.0f, opacity}); + menu_bg_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, opacity}); }; // Menu BG fade in animation @@ -940,7 +940,7 @@ void game::setup_ui() { ui_scene->add_object(*menu_bg_billboard); - menu_bg_tint->set(float4{0.0f, 0.0f, 0.0f, 0.0f}); + menu_bg_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, 0.0f}); //menu_bg_billboard->set_active(true); } ); @@ -1033,13 +1033,10 @@ void game::setup_entities() void game::setup_systems() { const auto& viewport_size = window->get_viewport_size(); - float4 viewport = {0.0f, 0.0f, static_cast(viewport_size[0]), static_cast(viewport_size[1])}; + math::fvec4 viewport = {0.0f, 0.0f, static_cast(viewport_size[0]), static_cast(viewport_size[1])}; // Setup terrain system terrain_system = std::make_unique<::terrain_system>(*entity_registry); - terrain_system->set_patch_side_length(31.0f); - terrain_system->set_patch_subdivisions(31); - terrain_system->set_scene_collection(surface_scene.get()); // Setup camera system camera_system = std::make_unique<::camera_system>(*entity_registry); @@ -1047,7 +1044,6 @@ void game::setup_systems() // Setup subterrain system subterrain_system = std::make_unique<::subterrain_system>(*entity_registry, resource_manager.get()); - subterrain_system->set_scene(underground_scene.get()); // Setup collision system collision_system = std::make_unique<::collision_system>(*entity_registry); diff --git a/src/game/game.hpp b/src/game/game.hpp index 2259519..165637c 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -283,7 +283,7 @@ public: // Rendering //gl::rasterizer* rasterizer; - int2 render_resolution; + math::ivec2 render_resolution; float render_scale; int shadow_map_resolution; std::unique_ptr ui_clear_pass; @@ -346,7 +346,7 @@ public: std::unique_ptr> radial_transition_in; std::unique_ptr> radial_transition_out; std::unique_ptr fade_transition; - std::shared_ptr fade_transition_color; + std::shared_ptr fade_transition_color; std::unique_ptr radial_transition_inner; std::unique_ptr radial_transition_outer; std::unique_ptr> equip_tool_animation; @@ -395,7 +395,7 @@ public: ::frame_scheduler frame_scheduler; math::moving_average average_frame_duration; - double3 rgb_wavelengths; + math::dvec3 rgb_wavelengths; std::shared_ptr active_ecoregion; render::anti_aliasing_method anti_aliasing_method; diff --git a/src/game/graphics.cpp b/src/game/graphics.cpp index 359aba6..6147a6b 100644 --- a/src/game/graphics.cpp +++ b/src/game/graphics.cpp @@ -44,7 +44,7 @@ void create_framebuffers(::game& ctx) debug::log::trace("Creating framebuffers..."); // Calculate render resolution - const int2& viewport_size = ctx.window->get_viewport_size(); + const math::ivec2& viewport_size = ctx.window->get_viewport_size(); ctx.render_resolution = {static_cast(viewport_size.x() * ctx.render_scale + 0.5f), static_cast(viewport_size.y() * ctx.render_scale + 0.5f)}; // Create HDR framebuffer (32F color, 32F depth) @@ -118,7 +118,7 @@ void change_render_resolution(::game& ctx, float scale) ctx.render_scale = scale; // Recalculate render resolution - const int2& viewport_size = ctx.window->get_viewport_size(); + const math::ivec2& viewport_size = ctx.window->get_viewport_size(); ctx.render_resolution = {static_cast(viewport_size.x() * ctx.render_scale + 0.5f), static_cast(viewport_size.y() * ctx.render_scale + 0.5f)}; // Resize HDR framebuffer and attachments @@ -163,7 +163,7 @@ void save_screenshot(::game& ctx) debug::log::debug("Saving screenshot to \"{}\"...", screenshot_filepath_string); // Get viewport dimensions - const int2& viewport_size = ctx.window->get_viewport_size(); + const math::ivec2& viewport_size = ctx.window->get_viewport_size(); // Allocate screenshot image std::shared_ptr frame = std::make_shared(); diff --git a/src/game/menu.cpp b/src/game/menu.cpp index 6fcb7b5..55b5780 100644 --- a/src/game/menu.cpp +++ b/src/game/menu.cpp @@ -24,9 +24,7 @@ #include #include #include -#include - -using namespace math::glsl; +#include namespace menu { @@ -64,7 +62,7 @@ void update_text_color(::game& ctx) { auto [name, value] = ctx.menu_item_texts[i]; - const float4& color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; + const math::fvec4& color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; name->set_color(color); if (value) @@ -76,8 +74,8 @@ void align_text(::game& ctx, bool center, bool has_back, float anchor_y) { - const vec2 viewport_size = vec2(ctx.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(ctx.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; const float viewport_padding = viewport_size.y() * (1.0f / 9.0f); @@ -218,7 +216,7 @@ void setup_animations(::game& ctx) { auto [name, value] = ctx.menu_item_texts[i]; - float4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; + math::fvec4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; color[3] = color[3] * opacity; if (name) @@ -245,7 +243,7 @@ void fade_in(::game& ctx, const std::function& end_callback) { auto [name, value] = ctx.menu_item_texts[i]; - float4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; + math::fvec4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; color[3] = 0.0f; if (name) diff --git a/src/game/spawn.cpp b/src/game/spawn.cpp index be2b8e7..61004f0 100644 --- a/src/game/spawn.cpp +++ b/src/game/spawn.cpp @@ -22,7 +22,7 @@ #include "game/components/scene-component.hpp" #include -entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, const float3& position) +entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, const math::fvec3& position) { // Create entity entity::id egg_eid = ctx.entity_registry->create(); @@ -40,7 +40,7 @@ entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, return egg_eid; } -entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const float3& position) +entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const math::fvec3& position) { // Create entity entity::id larva_eid = ctx.entity_registry->create(); @@ -58,7 +58,7 @@ entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const float3& return larva_eid; } -entity::id spawn_worker_ant(::game& ctx, const ant_genome& genome, const float3& position) +entity::id spawn_worker_ant(::game& ctx, const ant_genome& genome, const math::fvec3& position) { return entt::null; } diff --git a/src/game/spawn.hpp b/src/game/spawn.hpp index 1950105..159a4d1 100644 --- a/src/game/spawn.hpp +++ b/src/game/spawn.hpp @@ -22,7 +22,7 @@ #include "game/game.hpp" #include "game/ant/ant-genome.hpp" -#include +#include /** @@ -35,7 +35,7 @@ * * @return Entity ID of the spawned ant egg. */ -entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, const float3& position); +entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, const math::fvec3& position); /** * Spawns an ant larva. @@ -46,7 +46,7 @@ entity::id spawn_ant_egg(::game& ctx, const ant_genome& genome, bool fertilized, * * @return Entity ID of the spawned ant larva. */ -entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const float3& position); +entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const math::fvec3& position); /** * Spawns a worker ant. @@ -57,7 +57,7 @@ entity::id spawn_ant_larva(::game& ctx, const ant_genome& genome, const float3& * * @return Entity ID of the spawned worker ant. */ -entity::id spawn_worker_ant(::game& ctx, const ant_genome& genome, const float3& position); +entity::id spawn_worker_ant(::game& ctx, const ant_genome& genome, const math::fvec3& position); #endif // ANTKEEPER_GAME_SPAWN_HPP diff --git a/src/game/states/collection-menu-state.cpp b/src/game/states/collection-menu-state.cpp index b21581c..bd3893c 100644 --- a/src/game/states/collection-menu-state.cpp +++ b/src/game/states/collection-menu-state.cpp @@ -44,7 +44,7 @@ collection_menu_state::collection_menu_state(::game& ctx): box_material = std::make_shared(); box_material->set_blend_mode(render::material_blend_mode::translucent); box_material->set_shader_template(ctx.resource_manager->load("ui-element-untextured.glsl")); - box_material->set_variable("tint", std::make_shared(1, float4{0.5f, 0.5f, 0.5f, 1})); + box_material->set_variable("tint", std::make_shared(1, math::fvec4{0.5f, 0.5f, 0.5f, 1})); // Construct box billboard box_billboard.set_material(box_material); @@ -53,7 +53,7 @@ collection_menu_state::collection_menu_state(::game& ctx): selection_material = std::make_shared(); selection_material->set_blend_mode(render::material_blend_mode::translucent); selection_material->set_shader_template(ctx.resource_manager->load("ui-element-untextured.glsl")); - box_material->set_variable("tint", std::make_shared(1, float4{1, 1, 1, 1})); + box_material->set_variable("tint", std::make_shared(1, math::fvec4{1, 1, 1, 1})); // Construct selection billboard selection_billboard.set_material(selection_material); @@ -81,7 +81,7 @@ collection_menu_state::collection_menu_state(::game& ctx): [&](const auto& event) { const auto& viewport_size = ctx.window->get_viewport_size(); - const float2 mouse_position = + const math::fvec2 mouse_position = { static_cast(event.position.x()), static_cast(viewport_size.y() - event.position.y() + 1) @@ -142,7 +142,7 @@ collection_menu_state::~collection_menu_state() void collection_menu_state::resize_box() { const float padding = 64.0f; - const auto viewport_size = float2(ctx.window->get_viewport_size()); + const auto viewport_size = math::fvec2(ctx.window->get_viewport_size()); box_bounds.min.x() = viewport_size.x() * 0.5f + padding; box_bounds.max.x() = viewport_size.x() - padding; @@ -152,8 +152,8 @@ void collection_menu_state::resize_box() box_bounds.max.y() = viewport_size.y() - padding; box_bounds.min.y() = std::max(padding, box_bounds.max.y() - selection_size * row_count); - const float2 box_size = box_bounds.size(); - const float2 box_center = box_bounds.center(); + const math::fvec2 box_size = box_bounds.size(); + const math::fvec2 box_center = box_bounds.center(); // Resize box box_billboard.set_scale({box_size.x() * 0.5f, box_size.y() * 0.5f, 1.0f}); diff --git a/src/game/states/credits-state.cpp b/src/game/states/credits-state.cpp index f3df44a..323e47f 100644 --- a/src/game/states/credits-state.cpp +++ b/src/game/states/credits-state.cpp @@ -27,17 +27,15 @@ #include #include "game/strings.hpp" #include -#include - -using namespace math::glsl; +#include credits_state::credits_state(::game& ctx): game_state(ctx) { debug::log::trace("Entering credits state..."); - const vec2 viewport_size = vec2(ctx.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(ctx.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; // Construct credits text credits_text.set_material(ctx.menu_font_material); @@ -78,8 +76,8 @@ credits_state::credits_state(::game& ctx): ( [&](const auto& event) { - const vec2 viewport_size = vec2(event.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(event.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; const auto& credits_aabb = credits_text.get_bounds(); float credits_w = credits_aabb.max.x() - credits_aabb.min.x(); float credits_h = credits_aabb.max.y() - credits_aabb.min.y(); @@ -154,4 +152,3 @@ credits_state::~credits_state() debug::log::trace("Exited credits state"); } - diff --git a/src/game/states/main-menu-state.cpp b/src/game/states/main-menu-state.cpp index 900d1e9..1b65362 100644 --- a/src/game/states/main-menu-state.cpp +++ b/src/game/states/main-menu-state.cpp @@ -36,7 +36,7 @@ #include "game/states/options-menu-state.hpp" #include "game/strings.hpp" #include "game/world.hpp" -#include +#include #include #include #include @@ -48,8 +48,6 @@ #include #include -using namespace math::glsl; - main_menu_state::main_menu_state(::game& ctx, bool fade_in): game_state(ctx) { @@ -57,8 +55,8 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ctx.ui_clear_pass->set_cleared_buffers(true, true, false); - const vec2 viewport_size = vec2(ctx.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(ctx.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; // Construct title text title_text = std::make_unique(); @@ -81,7 +79,7 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ( [this, &ctx](int channel, const float& opacity) { - float4 color = this->title_text->get_color(); + math::fvec4 color = this->title_text->get_color(); color[3] = opacity; this->title_text->set_color(color); } @@ -131,8 +129,8 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ctx.state_machine.pop(); // ctx.state_machine.emplace(std::make_unique(ctx)); // ctx.state_machine.emplace(std::make_unique(ctx)); - ctx.state_machine.emplace(std::make_unique(ctx)); - // ctx.state_machine.emplace(std::make_unique(ctx)); + // ctx.state_machine.emplace(std::make_unique(ctx)); + ctx.state_machine.emplace(std::make_unique(ctx)); } ); }; @@ -285,8 +283,8 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ( [&](const auto& event) { - const vec2 viewport_size = vec2(event.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(event.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; // Re-align title text const auto& title_aabb = title_text->get_bounds(); diff --git a/src/game/states/nest-selection-state.cpp b/src/game/states/nest-selection-state.cpp index 6f21249..ba78b10 100644 --- a/src/game/states/nest-selection-state.cpp +++ b/src/game/states/nest-selection-state.cpp @@ -117,12 +117,12 @@ nest_selection_state::nest_selection_state(::game& ctx): floor_eid, [](auto& component) { - component.local.rotation = math::angle_axis(math::radians(3.0f), float3{1.0f, 0.0f, 0.0f}); + component.local.rotation = math::angle_axis(math::radians(3.0f), math::fvec3{1.0f, 0.0f, 0.0f}); } ); auto floor_body = std::make_unique(); - auto floor_collider = std::make_shared(float3{0.0f, 1.0f, 0.0f}); + auto floor_collider = std::make_shared(math::fvec3{0.0f, 1.0f, 0.0f}); floor_collider->set_layer_mask(0b11); floor_collider->set_material(std::make_shared(1.0f, 0.5f, 1.0f)); floor_body->set_mass(0.0f); @@ -145,7 +145,7 @@ nest_selection_state::nest_selection_state(::game& ctx): - auto worker_collider = std::make_shared(float3{-1.0f, -1.0f, -1.0f}, float3{1.0f, 1.0f, 1.0f}); + auto worker_collider = std::make_shared(math::fvec3{-1.0f, -1.0f, -1.0f}, math::fvec3{1.0f, 1.0f, 1.0f}); //auto worker_collider = std::make_shared(1.0f); worker_collider->set_material(std::make_shared(0.4f, 0.1f, 0.2f)); @@ -189,14 +189,14 @@ nest_selection_state::nest_selection_state(::game& ctx): const auto& larva_head_relative_transform = larva_skeletal_mesh->get_pose().get_relative_transform(larva_ik_effector_bone_index); larva_ik_solver = std::make_shared(*larva_ik_rig, larva_ik_root_bone_index, larva_ik_effector_bone_index); - larva_ik_solver->set_effector_position(larva_head_relative_transform * float3{0.0f, 0.0f, -0.0f}); - larva_ik_solver->set_goal_position(larva_head_absolute_transform.translation + float3{0.2f, 0.2f, 0.5f}); + larva_ik_solver->set_effector_position(larva_head_relative_transform * math::fvec3{0.0f, 0.0f, -0.0f}); + larva_ik_solver->set_goal_position(larva_head_absolute_transform.translation + math::fvec3{0.2f, 0.2f, 0.5f}); larva_ik_rig->add_solver(larva_ik_solver); - //larva_skeletal_mesh->get_pose().set_relative_rotation(larva_ik_root_bone_index, math::angle_axis(math::radians(45.0f), float3{1.0f, 0.0f, 0.0f})); + //larva_skeletal_mesh->get_pose().set_relative_rotation(larva_ik_root_bone_index, math::angle_axis(math::radians(45.0f), math::fvec3{1.0f, 0.0f, 0.0f})); //larva_skeletal_mesh->get_pose().update(); ctx.entity_registry->emplace(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{1}); @@ -248,8 +248,8 @@ nest_selection_state::nest_selection_state(::game& ctx): // Setup controls setup_controls(); - // auto color_checker_archetype = ctx.resource_manager->load("color-checker.ent"); - // color_checker_archetype->create(*ctx.entity_registry); + auto color_checker_archetype = ctx.resource_manager->load("color-checker.ent"); + color_checker_archetype->create(*ctx.entity_registry); // auto ruler_archetype = ctx.resource_manager->load("ruler-10cm.ent"); // ruler_archetype->create(*ctx.entity_registry); @@ -415,15 +415,15 @@ void nest_selection_state::set_first_person_camera_rig_pedestal(float pedestal) // ); } -void nest_selection_state::move_first_person_camera_rig(const float2& direction, float factor) +void nest_selection_state::move_first_person_camera_rig(const math::fvec2& direction, float factor) { // const float speed = math::log_lerp(first_person_camera_near_speed, first_person_camera_far_speed, first_person_camera_rig_pedestal) * factor; // const spring_rotation_constraint& first_person_camera_rig_spring_rotation = ctx.entity_registry->get(first_person_camera_rig_spring_rotation_eid); - // const math::quaternion yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], float3{0.0f, 1.0f, 0.0f}); - // const float3 rotated_direction = math::normalize(yaw_rotation * float3{direction[0], 0.0f, direction[1]}); - // const float3 velocity = rotated_direction * speed; + // const math::fquat yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], math::fvec3{0.0f, 1.0f, 0.0f}); + // const math::fvec3 rotated_direction = math::normalize(yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]}); + // const math::fvec3 velocity = rotated_direction * speed; // ctx.entity_registry->patch // ( @@ -610,20 +610,20 @@ void nest_selection_state::setup_controls() constexpr float movement_speed = 200.0f; - auto move_first_person_camera_rig = [&](const float2& direction, float speed) + auto move_first_person_camera_rig = [&](const math::fvec2& direction, float speed) { const transform_component& first_person_camera_rig_transform = ctx.entity_registry->get(first_person_camera_rig_eid); //const spring_rotation_constraint& first_person_camera_rig_spring_rotation = ctx.entity_registry->get(first_person_camera_rig_spring_rotation_eid); - //const math::quaternion yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], float3{0.0f, 1.0f, 0.0f}); - //const float3 rotated_direction = yaw_rotation * float3{direction[0], 0.0f, direction[1]}; + //const math::fquat yaw_rotation = math::angle_axis(first_person_camera_rig_spring_rotation.spring.x0[0], math::fvec3{0.0f, 1.0f, 0.0f}); + //const math::fvec3 rotated_direction = yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]}; - const math::quaternion yaw_rotation = math::angle_axis(static_cast(first_person_camera_yaw), float3{0.0f, 1.0f, 0.0f}); + const math::fquat yaw_rotation = math::angle_axis(static_cast(first_person_camera_yaw), math::fvec3{0.0f, 1.0f, 0.0f}); - const float3 rotated_direction = yaw_rotation * float3{direction[0], 0.0f, direction[1]}; + const math::fvec3 rotated_direction = yaw_rotation * math::fvec3{direction[0], 0.0f, direction[1]}; - const float3 force = rotated_direction * speed; + const math::fvec3 force = rotated_direction * speed; moving = true; @@ -704,9 +704,9 @@ void nest_selection_state::setup_controls() first_person_camera_pitch += ctx.mouse_tilt_factor * static_cast(event.difference.y()); first_person_camera_pitch = std::min(math::half_pi, std::max(-math::half_pi, first_person_camera_pitch)); - const math::quaternion yaw_rotation = math::angle_axis(first_person_camera_yaw, {0.0f, 1.0, 0.0}); - const math::quaternion pitch_rotation = math::angle_axis(first_person_camera_pitch, {-1.0, 0.0, 0.0}); - const math::quaternion first_person_camera_orientation = math::quaternion(math::normalize(yaw_rotation * pitch_rotation)); + const math::dquat yaw_rotation = math::angle_axis(first_person_camera_yaw, {0.0f, 1.0, 0.0}); + const math::dquat pitch_rotation = math::angle_axis(first_person_camera_pitch, {-1.0, 0.0, 0.0}); + const math::fquat first_person_camera_orientation = math::fquat(math::normalize(yaw_rotation * pitch_rotation)); ctx.entity_registry->patch ( @@ -898,7 +898,7 @@ void nest_selection_state::setup_controls() if (ctx.mouse_look_action.is_active()) { auto projectile_collider = std::make_shared(1.0f); - //auto projectile_collider = std::make_shared(float3{-1.0f, -1.0f, -1.0f}, float3{1.0f, 1.0f, 1.0f}); + //auto projectile_collider = std::make_shared(math::fvec3{-1.0f, -1.0f, -1.0f}, math::fvec3{1.0f, 1.0f, 1.0f}); projectile_collider->set_material(std::make_shared(0.4f, 0.1f, 0.2f)); projectile_body->set_collider(std::move(projectile_collider)); @@ -919,7 +919,7 @@ void nest_selection_state::setup_controls() projectile_scene.object = projectile_mesh; } - projectile_body->apply_central_impulse(camera_transform.world.rotation * float3{0.0f, 0.0f, -10.0f}); + projectile_body->apply_central_impulse(camera_transform.world.rotation * math::fvec3{0.0f, 0.0f, -10.0f}); // auto spring_eid = ctx.entity_registry->create(); @@ -936,10 +936,10 @@ void nest_selection_state::setup_controls() ctx.entity_registry->emplace(projectile_eid, std::move(projectile_body)); - // body.linear_momentum = math::vector::zero(); - // body.angular_momentum = math::vector::zero(); - // body.linear_velocity = math::vector::zero(); - // body.angular_velocity = math::vector::zero(); + // body.linear_momentum = math::fvec3::zero(); + // body.angular_momentum = math::fvec3::zero(); + // body.linear_velocity = math::fvec3::zero(); + // body.angular_velocity = math::fvec3::zero(); //body.apply_central_impulse({0.0f, 100.5f, 0.0f}); diff --git a/src/game/states/nest-selection-state.hpp b/src/game/states/nest-selection-state.hpp index 392ab3e..d57697d 100644 --- a/src/game/states/nest-selection-state.hpp +++ b/src/game/states/nest-selection-state.hpp @@ -22,7 +22,7 @@ #include "game/states/game-state.hpp" #include -#include +#include #include #include #include @@ -37,7 +37,7 @@ private: void create_first_person_camera_rig(); void destroy_first_person_camera_rig(); void set_first_person_camera_rig_pedestal(float pedestal); - void move_first_person_camera_rig(const float2& direction, float factor); + void move_first_person_camera_rig(const math::fvec2& direction, float factor); void satisfy_first_person_camera_rig_constraints(); void setup_controls(); @@ -55,7 +55,7 @@ private: bool adjust_zoom{false}; bool moving{false}; - float2 movement_direction{0.0f, 0.0f}; + math::fvec2 movement_direction{0.0f, 0.0f}; float movement_speed{0.0f}; entity::id worker_ant_eid; diff --git a/src/game/states/nest-view-state.cpp b/src/game/states/nest-view-state.cpp index e98b12d..8409845 100644 --- a/src/game/states/nest-view-state.cpp +++ b/src/game/states/nest-view-state.cpp @@ -81,6 +81,7 @@ #include #include #include +#include nest_view_state::nest_view_state(::game& ctx): game_state(ctx) @@ -105,7 +106,7 @@ nest_view_state::nest_view_state(::game& ctx): debug::log::trace("Generated genome"); debug::log::trace("Building worker phenome..."); - ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::queen); + ant_phenome worker_phenome = ant_phenome(*genome, ant_caste_type::worker); debug::log::trace("Built worker phenome..."); debug::log::trace("Generating worker model..."); @@ -116,7 +117,7 @@ nest_view_state::nest_view_state(::game& ctx): // ctx.underground_directional_light = std::make_unique(); // ctx.underground_directional_light->set_color({1.0f, 1.0f, 1.0f}); // ctx.underground_directional_light->set_illuminance(2.0f); - // ctx.underground_directional_light->set_direction(math::normalize(math::vector{0, -1, 0})); + // ctx.underground_directional_light->set_direction(math::normalize(math::fvec3{0, -1, 0})); // ctx.underground_directional_light->set_shadow_caster(true); // ctx.underground_directional_light->set_shadow_framebuffer(ctx.shadow_map_framebuffer); // ctx.underground_directional_light->set_shadow_bias(0.005f); @@ -126,27 +127,28 @@ nest_view_state::nest_view_state(::game& ctx): // ctx.underground_scene->add_object(*ctx.underground_directional_light); ctx.underground_clear_pass->set_clear_color({0.214f, 0.214f, 0.214f, 1.0f}); + // ctx.underground_clear_pass->set_clear_color({}); light_probe = std::make_shared(); light_probe->set_luminance_texture(ctx.resource_manager->load("grey-furnace.tex")); ctx.underground_scene->add_object(*light_probe); //const float color_temperature = 5000.0f; - //const math::vector3 light_color = color::aces::ap1.from_xyz * color::cat::matrix(color::illuminant::deg2::d50, color::aces::white_point) * color::cct::to_xyz(color_temperature); - const math::vector3 light_color{1.0f, 1.0f, 1.0f}; + //const math::fvec3 light_color = color::aces::ap1.from_xyz * color::cat::matrix(color::illuminant::deg2::d50, color::aces::white_point) * color::cct::to_xyz(color_temperature); + const math::fvec3 light_color{1.0f, 1.0f, 1.0f}; // Create rectangle light ctx.underground_rectangle_light = std::make_unique(); ctx.underground_rectangle_light->set_color(light_color); - ctx.underground_rectangle_light->set_luminous_flux(1000.0f); - ctx.underground_rectangle_light->set_translation({-13.0f, 5.0f, -5.0f}); - ctx.underground_rectangle_light->set_rotation(math::quaternion::rotate_x(math::radians(90.0f))); + ctx.underground_rectangle_light->set_luminous_flux(1500.0f); + ctx.underground_rectangle_light->set_translation({0.0f, 10.0f, 0.0f}); + ctx.underground_rectangle_light->set_rotation(math::fquat::rotate_x(math::radians(90.0f))); ctx.underground_rectangle_light->set_scale(7.0f); ctx.underground_scene->add_object(*ctx.underground_rectangle_light); // Create light rectangle auto light_rectangle_model = ctx.resource_manager->load("light-rectangle.mdl"); auto light_rectangle_material = std::make_shared(*light_rectangle_model->get_groups().front().material); - light_rectangle_emissive = std::static_pointer_cast(light_rectangle_material->get_variable("emissive")); + light_rectangle_emissive = std::static_pointer_cast(light_rectangle_material->get_variable("emissive")); light_rectangle_emissive->set(ctx.underground_rectangle_light->get_colored_luminance()); auto light_rectangle_static_mesh = std::make_shared(light_rectangle_model); light_rectangle_static_mesh->set_material(0, light_rectangle_material); @@ -162,73 +164,79 @@ nest_view_state::nest_view_state(::game& ctx): } ); - // Create chamber - auto chamber_eid = ctx.entity_registry->create(); - scene_component chamber_scene_component; - chamber_scene_component.object = std::make_shared(ctx.resource_manager->load("soil-nest.mdl")); - chamber_scene_component.layer_mask = 2; - ctx.entity_registry->emplace(chamber_eid, std::move(chamber_scene_component)); + // Create petri dish + auto petri_dish_eid = ctx.entity_registry->create(); + scene_component petri_dish_scene_component; + petri_dish_scene_component.object = std::make_shared(ctx.resource_manager->load("square-petri-dish.mdl")); + petri_dish_scene_component.layer_mask = 2; + ctx.entity_registry->emplace(petri_dish_eid, std::move(petri_dish_scene_component)); + + // Create petri dish cement + auto petri_dish_cement_eid = ctx.entity_registry->create(); + scene_component petri_dish_cement_scene_component; + petri_dish_cement_scene_component.object = std::make_shared(ctx.resource_manager->load("square-petri-dish-cement.mdl")); + petri_dish_cement_scene_component.layer_mask = 2; + ctx.entity_registry->emplace(petri_dish_cement_eid, std::move(petri_dish_cement_scene_component)); // Create worker auto worker_skeletal_mesh = std::make_unique(worker_model); - auto worker_ant_eid = ctx.entity_registry->create(); + worker_eid = ctx.entity_registry->create(); transform_component worker_transform_component; worker_transform_component.local = math::transform::identity(); - worker_transform_component.local.translation = {0, 0.5f, -4}; + worker_transform_component.local.translation = {0, 0.1f, 0}; + worker_transform_component.local.scale = math::fvec3::one() * worker_phenome.body_size->mean_mesosoma_length; worker_transform_component.world = worker_transform_component.local; - ctx.entity_registry->emplace(worker_ant_eid, worker_transform_component); - ctx.entity_registry->emplace(worker_ant_eid, std::move(worker_skeletal_mesh), std::uint8_t{1}); + ctx.entity_registry->emplace(worker_eid, worker_transform_component); + ctx.entity_registry->emplace(worker_eid, std::move(worker_skeletal_mesh), std::uint8_t{2}); // Create cocoon auto cocoon_eid = ctx.entity_registry->create(); - ctx.entity_registry->emplace(cocoon_eid, std::make_shared(worker_phenome.cocoon->model), std::uint8_t{2}); + auto cocoon_static_mesh = std::make_shared(worker_phenome.cocoon->model); + cocoon_static_mesh->set_scale(worker_phenome.body_size->mean_mesosoma_length); + ctx.entity_registry->emplace(cocoon_eid, std::move(cocoon_static_mesh), std::uint8_t{2}); ctx.entity_registry->patch ( cocoon_eid, [&](auto& component) { - component.object->set_translation({-5.0f, 0.0f, 5.0f}); + component.object->set_translation({-4.0f, 0.0f, 4.0f}); } ); + // Create color checker + auto color_checker_eid = ctx.entity_registry->create(); + scene_component color_checker_scene_component; + color_checker_scene_component.object = std::make_shared(ctx.resource_manager->load("color-checker.mdl")); + color_checker_scene_component.object->set_translation({0, 0, 4}); + color_checker_scene_component.layer_mask = 2; + ctx.entity_registry->emplace(color_checker_eid, std::move(color_checker_scene_component)); + // Create larva - auto larva_eid = ctx.entity_registry->create(); + larva_eid = ctx.entity_registry->create(); auto larva_skeletal_mesh = std::make_shared(worker_phenome.larva->model); + larva_skeletal_mesh->set_scale(worker_phenome.body_size->mean_mesosoma_length); ctx.entity_registry->emplace(larva_eid, std::move(larva_skeletal_mesh), std::uint8_t{2}); ctx.entity_registry->patch ( larva_eid, [&](auto& component) { - component.object->set_translation({5.0f, 0.0f, 5.0f}); - } - ); - - // Create suzanne - auto suzanne_eid = ctx.entity_registry->create(); - auto suzanne_static_mesh = std::make_shared(ctx.resource_manager->load("suzanne.mdl")); - ctx.entity_registry->emplace(suzanne_eid, std::move(suzanne_static_mesh), std::uint8_t{2}); - ctx.entity_registry->patch - ( - suzanne_eid, - [&](auto& component) - { - component.object->set_translation({-13.0f, 0.0f, -5.0f}); + component.object->set_translation({4.0f, 0.0f, 4.0f}); } ); // Create sphere - auto sphere_eid = ctx.entity_registry->create(); - auto sphere_static_mesh = std::make_shared(ctx.resource_manager->load("sphere.mdl")); - ctx.entity_registry->emplace(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{2}); - ctx.entity_registry->patch - ( - sphere_eid, - [&](auto& component) - { - component.object->set_translation({0.0f, 0.0f, 0.0f}); - } - ); + // auto sphere_eid = ctx.entity_registry->create(); + // auto sphere_static_mesh = std::make_shared(ctx.resource_manager->load("sphere.mdl")); + // ctx.entity_registry->emplace(sphere_eid, std::move(sphere_static_mesh), std::uint8_t{2}); + // ctx.entity_registry->patch + // ( + // sphere_eid, + // [&](auto& component) + // { + // component.object->set_translation({0.0f, 0.0f, 0.0f}); + // } + // ); // Disable UI color clear ctx.ui_clear_pass->set_cleared_buffers(false, true, false); @@ -244,7 +252,7 @@ nest_view_state::nest_view_state(::game& ctx): // Setup camera ctx.underground_camera->set_exposure_value(0.0f); - + const auto& viewport_size = ctx.window->get_viewport_size(); const float aspect_ratio = static_cast(viewport_size[0]) / static_cast(viewport_size[1]); @@ -271,6 +279,17 @@ nest_view_state::nest_view_state(::game& ctx): // Refresh frame scheduler ctx.frame_scheduler.refresh(); + // Load navmesh + navmesh = ctx.resource_manager->load("square-petri-dish-navmesh.msh"); + + // Generate navmesh attributes + geom::generate_face_normals(*navmesh); + + // Build navmesh BVH + debug::log::info("building bvh"); + navmesh_bvh = std::make_unique(*navmesh); + debug::log::info("building bvh done"); + debug::log::trace("Entered nest view state"); } @@ -342,13 +361,13 @@ void nest_view_state::zoom_third_person_camera(double zoom) set_third_person_camera_zoom(third_person_camera_zoom + zoom); } -void nest_view_state::translate_third_person_camera(const math::vector& direction, double magnitude) +void nest_view_state::translate_third_person_camera(const math::dvec3& direction, double magnitude) { // Scale translation magnitude by factor of focal plane height magnitude *= third_person_camera_focal_plane_height * third_person_camera_speed; // Rotate translation direction according to camera yaw - const math::vector rotated_direction = third_person_camera_yaw_rotation * direction; + const math::dvec3 rotated_direction = third_person_camera_yaw_rotation * direction; third_person_camera_focal_point += rotated_direction * magnitude; @@ -365,7 +384,7 @@ void nest_view_state::rotate_third_person_camera(const input::mouse_moved_event& void nest_view_state::handle_mouse_motion(const input::mouse_moved_event& event) { - ctx.underground_material_pass->set_mouse_position(float2(event.position)); + ctx.underground_material_pass->set_mouse_position(math::fvec2(event.position)); if (!mouse_look && !mouse_grip && !mouse_zoom) { @@ -374,9 +393,9 @@ void nest_view_state::handle_mouse_motion(const input::mouse_moved_event& event) if (mouse_grip) { - const math::vector viewport_size = math::vector(ctx.window->get_viewport_size()); + const math::dvec2 viewport_size = math::dvec2(ctx.window->get_viewport_size()); - math::vector translation + math::dvec3 translation { third_person_camera_focal_plane_width * (static_cast(-event.difference.x()) / (viewport_size.x() - 1.0)), 0.0, @@ -407,7 +426,7 @@ void nest_view_state::handle_mouse_motion(const input::mouse_moved_event& event) void nest_view_state::update_third_person_camera() { - const math::vector camera_position = third_person_camera_focal_point + third_person_camera_orientation * math::vector{0.0f, 0.0f, third_person_camera_focal_distance}; + const math::dvec3 camera_position = third_person_camera_focal_point + third_person_camera_orientation * math::dvec3{0.0f, 0.0f, third_person_camera_focal_distance}; ctx.entity_registry->patch ( @@ -416,8 +435,8 @@ void nest_view_state::update_third_person_camera() { auto& camera = static_cast(*component.object); - camera.set_translation(math::vector(camera_position)); - camera.set_rotation(math::quaternion(third_person_camera_orientation)); + camera.set_translation(math::fvec3(camera_position)); + camera.set_rotation(math::fquat(third_person_camera_orientation)); camera.set_perspective(static_cast(third_person_camera_vfov), camera.get_aspect_ratio(), camera.get_clip_near(), camera.get_clip_far()); } ); @@ -467,13 +486,13 @@ void nest_view_state::load_or_save_camera_preset(std::uint8_t index) } } -geom::ray nest_view_state::get_mouse_ray(const math::vector& mouse_position) const +geom::ray nest_view_state::get_mouse_ray(const math::vec2& mouse_position) const { // Get window viewport size const auto& viewport_size = ctx.window->get_viewport_size(); // Transform mouse coordinates from window space to NDC space - const math::vector mouse_ndc = + const math::fvec2 mouse_ndc = { static_cast(mouse_position.x()) / static_cast(viewport_size.x() - 1) * 2.0f - 1.0f, (1.0f - static_cast(mouse_position.y()) / static_cast(viewport_size.y() - 1)) * 2.0f - 1.0f @@ -542,6 +561,76 @@ void nest_view_state::setup_controls() } ctx.input_manager->set_relative_mouse_mode(mouse_look || mouse_grip || mouse_zoom); + + // BVH picking test + const auto& mouse_position = (*ctx.input_manager->get_mice().begin())->get_position(); + const auto mouse_ray = get_mouse_ray(mouse_position); + + debug::log::info("pick:"); + float nearest_hit = std::numeric_limits::infinity(); + bool hit = false; + std::uint32_t hit_index; + const auto& vertex_positions = navmesh->vertices().attributes().at("position"); + std::size_t test_count = 0; + + + int box_test_passed = 0; + navmesh_bvh->visit + ( + mouse_ray, + [&](std::uint32_t index) + { + ++box_test_passed; + + geom::brep_face* face = navmesh->faces()[index]; + auto loop = face->loops().begin(); + const auto& a = vertex_positions[loop->vertex()->index()]; + const auto& b = vertex_positions[(++loop)->vertex()->index()]; + const auto& c = vertex_positions[(++loop)->vertex()->index()]; + + if (auto intersection = geom::intersection(mouse_ray, a, b, c)) + { + ++test_count; + float t = std::get<0>(*intersection); + if (t < nearest_hit) + { + hit = true; + nearest_hit = t; + hit_index = index; + } + } + + + } + ); + + debug::log::info("box tests passed: {}", box_test_passed); + + if (hit) + { + const auto& navmesh_face_normals = navmesh->faces().attributes().at("normal"); + + const auto& hit_normal = navmesh_face_normals[hit_index]; + + const math::fvec3 translation = mouse_ray.origin + mouse_ray.direction * nearest_hit; + const math::fquat rotation = math::rotation(math::fvec3{0, 1, 0}, hit_normal); + + ctx.entity_registry->patch + ( + larva_eid, + [&](auto& component) + { + component.object->set_translation(translation); + component.object->set_rotation(rotation); + } + ); + + debug::log::info("hit! test count: {}", test_count); + } + else + { + debug::log::info("no hit"); + } } ) ); diff --git a/src/game/states/nest-view-state.hpp b/src/game/states/nest-view-state.hpp index 39cf077..02b91f4 100644 --- a/src/game/states/nest-view-state.hpp +++ b/src/game/states/nest-view-state.hpp @@ -22,7 +22,7 @@ #include "game/states/game-state.hpp" #include -#include +#include #include #include #include @@ -30,6 +30,8 @@ #include #include #include +#include +#include class nest_view_state: public game_state { @@ -45,7 +47,7 @@ private: void set_third_person_camera_rotation(double yaw, double pitch); void zoom_third_person_camera(double zoom); - void translate_third_person_camera(const math::vector& direction, double magnitude); + void translate_third_person_camera(const math::dvec3& direction, double magnitude); void rotate_third_person_camera(const input::mouse_moved_event& event); void handle_mouse_motion(const input::mouse_moved_event& event); @@ -55,7 +57,7 @@ private: void save_camera_preset(std::uint8_t index); void load_or_save_camera_preset(std::uint8_t index); - [[nodiscard]] geom::ray get_mouse_ray(const math::vector& mouse_position) const; + [[nodiscard]] geom::ray get_mouse_ray(const math::vec2& mouse_position) const; void setup_controls(); @@ -66,14 +68,14 @@ private: bool mouse_grip{false}; bool mouse_zoom{false}; geom::plane mouse_grip_plane{{0.0, 1.0, 0.0}, 0.0}; - math::vector mouse_grip_point{}; + math::fvec3 mouse_grip_point{}; bool moving{false}; entity::id third_person_camera_rig_eid{entt::null}; double third_person_camera_yaw{0.0}; double third_person_camera_pitch{math::radians(45.0)}; - math::vector third_person_camera_focal_point{0.0, 0.0, 0.0}; + math::dvec3 third_person_camera_focal_point{0.0, 0.0, 0.0}; double third_person_camera_zoom{0.25}; std::uint32_t third_person_camera_zoom_step_count{6}; @@ -91,22 +93,27 @@ private: double third_person_camera_focal_plane_width{}; double third_person_camera_focal_plane_height{}; double third_person_camera_focal_distance{}; - math::quaternion third_person_camera_yaw_rotation{math::quaternion::identity()}; - math::quaternion third_person_camera_pitch_rotation{math::quaternion::identity()}; - math::quaternion third_person_camera_orientation{math::quaternion::identity()}; + math::dquat third_person_camera_yaw_rotation{math::dquat::identity()}; + math::dquat third_person_camera_pitch_rotation{math::dquat::identity()}; + math::dquat third_person_camera_orientation{math::dquat::identity()}; struct camera_preset { double yaw{}; double pitch{}; - math::vector focal_point{}; + math::dvec3 focal_point{}; double zoom{0.25}; }; std::vector> camera_presets{10}; - std::shared_ptr light_rectangle_emissive; + std::shared_ptr light_rectangle_emissive; std::shared_ptr light_probe; + + std::shared_ptr navmesh; + std::unique_ptr navmesh_bvh; + entity::id larva_eid; + entity::id worker_eid; }; #endif // ANTKEEPER_NEST_VIEW_STATE_HPP diff --git a/src/game/states/nuptial-flight-state.cpp b/src/game/states/nuptial-flight-state.cpp index 74c5505..7f08bd8 100644 --- a/src/game/states/nuptial-flight-state.cpp +++ b/src/game/states/nuptial-flight-state.cpp @@ -220,7 +220,7 @@ void nuptial_flight_state::create_camera_rig() camera_rig_focus_ease_to.start = {0, 0, 0}; camera_rig_focus_ease_to.duration = camera_rig_focus_ease_to_duration; camera_rig_focus_ease_to.t = camera_rig_focus_ease_to.duration; - camera_rig_focus_ease_to.function = &ease::out_expo; + camera_rig_focus_ease_to.function = &ease::out_expo; constraint_stack_node_component camera_rig_focus_ease_to_node; camera_rig_focus_ease_to_node.active = true; camera_rig_focus_ease_to_node.weight = 1.0f; @@ -539,7 +539,7 @@ void nuptial_flight_state::setup_controls() const auto& viewport_size = ctx.window->get_viewport_size(); // Transform mouse coordinates from window space to NDC space - const float2 mouse_ndc = + const math::fvec2 mouse_ndc = { static_cast(mouse_position.x()) / static_cast(viewport_size.x() - 1) * 2.0f - 1.0f, (1.0f - static_cast(mouse_position.y()) / static_cast(viewport_size.y() - 1)) * 2.0f - 1.0f @@ -796,7 +796,7 @@ void nuptial_flight_state::enable_controls() const auto viewport_size = ctx.window->get_viewport_size(); // Transform mouse coordinates from window space to NDC space - const float2 mouse_ndc = + const math::fvec2 mouse_ndc = { static_cast(mouse_x) / static_cast(viewport_size[0] - 1) * 2.0f - 1.0f, (1.0f - static_cast(mouse_y) / static_cast(viewport_size[1] - 1)) * 2.0f - 1.0f @@ -1091,7 +1091,7 @@ void nuptial_flight_state::select_entity(entity::id entity_id) } } -void nuptial_flight_state::select_nearest_entity(const float3& direction) +void nuptial_flight_state::select_nearest_entity(const math::fvec3& direction) { if (!ctx.entity_registry->valid(selected_eid)) return; @@ -1101,8 +1101,8 @@ void nuptial_flight_state::select_nearest_entity(const float3& direction) return; // Construct picking plane - const float3 picking_normal = math::normalize(ctx.surface_camera->get_rotation() * direction); - const float3 picking_origin = selected_eid_transform->world.translation; + const math::fvec3 picking_normal = math::normalize(ctx.surface_camera->get_rotation() * direction); + const math::fvec3 picking_origin = selected_eid_transform->world.translation; // Pick entity entity::id picked_eid = ctx.collision_system->pick_nearest(picking_origin, picking_normal, ~selected_picking_flag); diff --git a/src/game/states/nuptial-flight-state.hpp b/src/game/states/nuptial-flight-state.hpp index 3bced3e..a0d7cff 100644 --- a/src/game/states/nuptial-flight-state.hpp +++ b/src/game/states/nuptial-flight-state.hpp @@ -22,7 +22,7 @@ #include "game/states/game-state.hpp" #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ private: void disable_controls(); void select_entity(entity::id entity_id); - void select_nearest_entity(const float3& direction); + void select_nearest_entity(const math::fvec3& direction); // Camera entity::id camera_rig_focus_eid; diff --git a/src/game/states/splash-state.cpp b/src/game/states/splash-state.cpp index 0f4855d..6bd63ca 100644 --- a/src/game/states/splash-state.cpp +++ b/src/game/states/splash-state.cpp @@ -25,21 +25,19 @@ #include #include #include -#include +#include #include #include #include #include -using namespace math::glsl; - splash_state::splash_state(::game& ctx): game_state(ctx) { debug::log::trace("Entering splash state..."); - const vec2 viewport_size = vec2(ctx.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(ctx.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; // Enable color buffer clearing in UI pass ctx.ui_clear_pass->set_cleared_buffers(true, true, false); @@ -54,9 +52,9 @@ splash_state::splash_state(::game& ctx): splash_billboard_material = std::make_shared(); splash_billboard_material->set_blend_mode(render::material_blend_mode::translucent); splash_billboard_material->set_shader_template(ctx.resource_manager->load("ui-element-textured.glsl")); - splash_billboard_material->set_variable("background", std::make_shared(1, splash_texture)); + splash_billboard_material->set_variable("background", std::make_shared(1, splash_texture)); - auto splash_tint = std::make_shared(1, float4{1, 1, 1, 0}); + auto splash_tint = std::make_shared(1, math::fvec4{1, 1, 1, 0}); splash_billboard_material->set_variable("tint", splash_tint); // Construct splash billboard @@ -88,7 +86,7 @@ splash_state::splash_state(::game& ctx): // Setup animation frame callbacks auto set_splash_opacity = [splash_tint](int channel, const float& opacity) { - splash_tint->set(float4{1, 1, 1, opacity}); + splash_tint->set(math::fvec4{1, 1, 1, opacity}); }; splash_fade_in_animation.set_frame_callback(set_splash_opacity); splash_fade_out_animation.set_frame_callback(set_splash_opacity); @@ -131,8 +129,8 @@ splash_state::splash_state(::game& ctx): ( [&](const auto& event) { - const vec2 viewport_size = vec2(event.window->get_viewport_size()); - const vec2 viewport_center = viewport_size * 0.5f; + const math::fvec2 viewport_size = math::fvec2(event.window->get_viewport_size()); + const math::fvec2 viewport_center = viewport_size * 0.5f; splash_billboard.set_translation({std::round(viewport_center.x()), std::round(viewport_center.y()), 0.0f}); } ); diff --git a/src/game/systems/astronomy-system.cpp b/src/game/systems/astronomy-system.cpp index dfd3c8e..d8d2f0e 100644 --- a/src/game/systems/astronomy-system.cpp +++ b/src/game/systems/astronomy-system.cpp @@ -55,7 +55,7 @@ astronomy_system::astronomy_system(entity::registry& registry): enu_to_eus = math::transformation::se3 { {0, 0, 0}, - math::quaternion::rotate_x(-math::half_pi) + math::dquat::rotate_x(-math::half_pi) }; registry.on_construct<::observer_component>().connect<&astronomy_system::on_observer_modified>(this); @@ -118,7 +118,7 @@ void astronomy_system::update(float t, float dt) // if (sky_pass) // { - // sky_pass->set_ground_albedo(math::vector3{1.0f, 1.0f, 1.0f} * static_cast(reference_body->albedo)); + // sky_pass->set_ground_albedo(math::fvec3{1.0f, 1.0f, 1.0f} * static_cast(reference_body->albedo)); // } // Update ICRF to EUS transformation @@ -134,7 +134,7 @@ void astronomy_system::update(float t, float dt) return; // Transform orbital Cartesian position (r) from the ICRF frame to the EUS frame - const double3 r_eus = icrf_to_eus * orbit.position; + const math::dvec3 r_eus = icrf_to_eus * orbit.position; // Evaluate body orientation polynomials const double body_pole_ra = math::polynomial::horner(body.pole_ra.begin(), body.pole_ra.end(), time_centuries); @@ -142,7 +142,7 @@ void astronomy_system::update(float t, float dt) const double body_prime_meridian = math::polynomial::horner(body.prime_meridian.begin(), body.prime_meridian.end(), time_days); // Determine body orientation in the ICRF frame - math::quaternion rotation_icrf = physics::orbit::frame::bcbf::to_bci + math::dquat rotation_icrf = physics::orbit::frame::bcbf::to_bci ( body_pole_ra, body_pole_dec, @@ -150,11 +150,11 @@ void astronomy_system::update(float t, float dt) ).r; // Transform body orientation from the ICRF frame to the EUS frame. - math::quaternion rotation_eus = math::normalize(icrf_to_eus.r * rotation_icrf); + math::dquat rotation_eus = math::normalize(icrf_to_eus.r * rotation_icrf); // Update local transform - transform.local.translation = math::normalize(float3(r_eus)); - transform.local.rotation = math::quaternion(rotation_eus); + transform.local.translation = math::normalize(math::fvec3(r_eus)); + transform.local.rotation = math::fquat(rotation_eus); transform.local.scale = {1.0f, 1.0f, 1.0f}; } ); @@ -164,28 +164,28 @@ void astronomy_system::update(float t, float dt) [&](entity::id entity_id, const auto& blackbody_body, const auto& blackbody_orbit, const auto& blackbody) { // Transform blackbody position from ICRF frame to EUS frame - const double3 blackbody_position_eus = icrf_to_eus * blackbody_orbit.position; + const math::dvec3 blackbody_position_eus = icrf_to_eus * blackbody_orbit.position; // Measure distance and direction, in EUS frame, from observer to blackbody const double observer_blackbody_distance = math::length(blackbody_position_eus); - const double3 observer_blackbody_direction_eus = blackbody_position_eus / observer_blackbody_distance; + const math::dvec3 observer_blackbody_direction_eus = blackbody_position_eus / observer_blackbody_distance; // Measure blackbody solid angle as seen by observer const double observer_blackbody_angular_radius = astro::angular_radius(blackbody_body.radius, observer_blackbody_distance); const double observer_blackbody_solid_angle = geom::solid_angle::cone(observer_blackbody_angular_radius); // Calculate illuminance from blackbody reaching observer - const double3 observer_blackbody_illuminance = blackbody.color * blackbody.luminance * observer_blackbody_solid_angle; + const math::dvec3 observer_blackbody_illuminance = blackbody.color * blackbody.luminance * observer_blackbody_solid_angle; // Calculate illuminance from blackbody reaching observer after atmospheric extinction - double3 observer_blackbody_transmitted_illuminance = observer_blackbody_illuminance; + math::dvec3 observer_blackbody_transmitted_illuminance = observer_blackbody_illuminance; if (reference_atmosphere) { // Construct ray at observer pointing towards the blackbody const geom::ray ray = {{0, 0, 0}, observer_blackbody_direction_eus}; // Integrate atmospheric spectral transmittance factor between observer and blackbody - double3 transmittance = integrate_transmittance(*observer, *reference_body, *reference_atmosphere, ray); + math::dvec3 transmittance = integrate_transmittance(*observer, *reference_body, *reference_atmosphere, ray); // Attenuate illuminance from blackbody reaching observer by spectral transmittance factor observer_blackbody_transmitted_illuminance *= transmittance; @@ -194,13 +194,13 @@ void astronomy_system::update(float t, float dt) // Update sun light if (sun_light != nullptr) { - const double3 blackbody_up_eus = icrf_to_eus.r * double3{0, 0, 1}; + const math::dvec3 blackbody_up_eus = icrf_to_eus.r * math::dvec3{0, 0, 1}; sun_light->set_rotation ( math::look_rotation ( - float3(-observer_blackbody_direction_eus), - float3(blackbody_up_eus) + math::fvec3(-observer_blackbody_direction_eus), + math::fvec3(blackbody_up_eus) ) ); @@ -209,7 +209,7 @@ void astronomy_system::update(float t, float dt) const auto max_component = math::max(observer_blackbody_transmitted_illuminance); if (max_component > 0.0) { - sun_light->set_color(math::vector3(observer_blackbody_transmitted_illuminance / max_component)); + sun_light->set_color(math::fvec3(observer_blackbody_transmitted_illuminance / max_component)); } else { @@ -220,9 +220,9 @@ void astronomy_system::update(float t, float dt) // Upload blackbody params to sky pass if (this->sky_pass) { - this->sky_pass->set_sun_position(float3(blackbody_position_eus)); - this->sky_pass->set_sun_luminance(float3(blackbody.color * blackbody.luminance)); - this->sky_pass->set_sun_illuminance(float3(observer_blackbody_illuminance), float3(observer_blackbody_transmitted_illuminance)); + this->sky_pass->set_sun_position(math::fvec3(blackbody_position_eus)); + this->sky_pass->set_sun_luminance(math::fvec3(blackbody.color * blackbody.luminance)); + this->sky_pass->set_sun_illuminance(math::fvec3(observer_blackbody_illuminance), math::fvec3(observer_blackbody_transmitted_illuminance)); this->sky_pass->set_sun_angular_radius(static_cast(observer_blackbody_angular_radius)); } @@ -231,14 +231,14 @@ void astronomy_system::update(float t, float dt) [&](entity::id entity_id, const auto& reflector_body, const auto& reflector_orbit, const auto& reflector, const auto& transform) { // Transform reflector position from ICRF frame to EUS frame - const double3 reflector_position_eus = icrf_to_eus * reflector_orbit.position; + const math::dvec3 reflector_position_eus = icrf_to_eus * reflector_orbit.position; // Measure distance and direction, in EUS frame, from observer to reflector const double observer_reflector_distance = math::length(reflector_position_eus); - const double3 observer_reflector_direction_eus = reflector_position_eus / observer_reflector_distance; + const math::dvec3 observer_reflector_direction_eus = reflector_position_eus / observer_reflector_distance; // Measure distance and direction, in EUS frame, from reflector to blackbody - double3 reflector_blackbody_direction_eus = blackbody_position_eus - reflector_position_eus; + math::dvec3 reflector_blackbody_direction_eus = blackbody_position_eus - reflector_position_eus; const double reflector_blackbody_distance = math::length(reflector_blackbody_direction_eus); reflector_blackbody_direction_eus /= reflector_blackbody_distance; @@ -247,24 +247,24 @@ void astronomy_system::update(float t, float dt) const double reflector_blackbody_solid_angle = geom::solid_angle::cone(reflector_blackbody_angular_radius); // Calculate blackbody illuminance reaching reflector - const double3 reflector_blackbody_illuminance = blackbody.color * blackbody.luminance * reflector_blackbody_solid_angle; + const math::dvec3 reflector_blackbody_illuminance = blackbody.color * blackbody.luminance * reflector_blackbody_solid_angle; // Measure reflector solid angle as seen by observer const double observer_reflector_angular_radius = astro::angular_radius(reflector_body.radius, observer_reflector_distance); const double observer_reflector_solid_angle = geom::solid_angle::cone(observer_reflector_angular_radius); // Determine phase factor of reflector as seen by observer - const double observer_reflector_phase_factor = dot(observer_reflector_direction_eus, -reflector_blackbody_direction_eus) * 0.5 + 0.5; + const double observer_reflector_phase_factor = math::dot(observer_reflector_direction_eus, -reflector_blackbody_direction_eus) * 0.5 + 0.5; // Measure observer reference body solid angle as seen by reflector const double reflector_observer_angular_radius = astro::angular_radius(reference_body->radius, observer_reflector_distance); const double reflector_observer_solid_angle = geom::solid_angle::cone(reflector_observer_angular_radius); // Determine phase factor of observer reference body as by reflector - const double reflector_observer_phase_factor = dot(-observer_reflector_direction_eus, -observer_blackbody_direction_eus) * 0.5 + 0.5; + const double reflector_observer_phase_factor = math::dot(-observer_reflector_direction_eus, -observer_blackbody_direction_eus) * 0.5 + 0.5; // Calculate spectral transmittance between observer and reflector factor due to atmospheric extinction - double3 observer_reflector_transmittance = {1, 1, 1}; + math::dvec3 observer_reflector_transmittance = {1, 1, 1}; if (reference_atmosphere) { // const geom::ray ray = {{0, 0, 0}, observer_reflector_direction_eus}; @@ -272,39 +272,39 @@ void astronomy_system::update(float t, float dt) } // Measure luminance of observer reference body as seen by reflector - const double3 reflector_observer_luminance = observer_blackbody_illuminance * reference_body->albedo * observer_reflector_transmittance * reflector_observer_phase_factor * math::inv_pi; + const math::dvec3 reflector_observer_luminance = observer_blackbody_illuminance * reference_body->albedo * observer_reflector_transmittance * reflector_observer_phase_factor * math::inv_pi; // Measure illuminance from observer reference body reaching reflector - const double3 reflector_observer_illuminance = reflector_observer_luminance * reflector_observer_solid_angle; + const math::dvec3 reflector_observer_illuminance = reflector_observer_luminance * reflector_observer_solid_angle; // Measure luminance of reflector as seen by observer - const double3 observer_reflector_luminance = (reflector_blackbody_illuminance * observer_reflector_phase_factor + reflector_observer_illuminance) * reflector.albedo * observer_reflector_transmittance * math::inv_pi; + const math::dvec3 observer_reflector_luminance = (reflector_blackbody_illuminance * observer_reflector_phase_factor + reflector_observer_illuminance) * reflector.albedo * observer_reflector_transmittance * math::inv_pi; // Measure illuminance from reflector reaching observer - const double3 observer_reflector_illuminance = observer_reflector_luminance * observer_reflector_solid_angle; + const math::dvec3 observer_reflector_illuminance = observer_reflector_luminance * observer_reflector_solid_angle; if (this->sky_pass) { this->sky_pass->set_moon_position(transform.local.translation); this->sky_pass->set_moon_rotation(transform.local.rotation); this->sky_pass->set_moon_angular_radius(static_cast(observer_reflector_angular_radius)); - this->sky_pass->set_moon_sunlight_direction(float3(-reflector_blackbody_direction_eus)); - this->sky_pass->set_moon_sunlight_illuminance(float3(reflector_blackbody_illuminance * observer_reflector_transmittance)); - this->sky_pass->set_moon_planetlight_direction(float3(observer_reflector_direction_eus)); - this->sky_pass->set_moon_planetlight_illuminance(float3(reflector_observer_illuminance * observer_reflector_transmittance)); - this->sky_pass->set_moon_illuminance(float3(observer_reflector_illuminance / observer_reflector_transmittance), float3(observer_reflector_illuminance)); + this->sky_pass->set_moon_sunlight_direction(math::fvec3(-reflector_blackbody_direction_eus)); + this->sky_pass->set_moon_sunlight_illuminance(math::fvec3(reflector_blackbody_illuminance * observer_reflector_transmittance)); + this->sky_pass->set_moon_planetlight_direction(math::fvec3(observer_reflector_direction_eus)); + this->sky_pass->set_moon_planetlight_illuminance(math::fvec3(reflector_observer_illuminance * observer_reflector_transmittance)); + this->sky_pass->set_moon_illuminance(math::fvec3(observer_reflector_illuminance / observer_reflector_transmittance), math::fvec3(observer_reflector_illuminance)); } if (moon_light) { - const float3 reflector_up_eus = float3(icrf_to_eus.r * double3{0, 0, 1}); + const math::fvec3 reflector_up_eus = math::fvec3(icrf_to_eus.r * math::dvec3{0, 0, 1}); moon_light->set_illuminance(static_cast(math::max(observer_reflector_illuminance))); const auto max_component = math::max(observer_reflector_illuminance); if (max_component > 0.0) { - moon_light->set_color(math::vector3(observer_reflector_illuminance / max_component)); + moon_light->set_color(math::fvec3(observer_reflector_illuminance / max_component)); } else { @@ -315,7 +315,7 @@ void astronomy_system::update(float t, float dt) ( math::look_rotation ( - float3(-observer_reflector_direction_eus), + math::fvec3(-observer_reflector_direction_eus), reflector_up_eus ) ); @@ -363,7 +363,7 @@ void astronomy_system::set_moon_light(scene::directional_light* light) moon_light = light; } -void astronomy_system::set_starlight_illuminance(const double3& illuminance) +void astronomy_system::set_starlight_illuminance(const math::dvec3& illuminance) { starlight_illuminance = illuminance; } @@ -390,7 +390,7 @@ void astronomy_system::set_sky_pass(::render::sky_pass* pass) if (reference_body) { sky_pass->set_planet_radius(static_cast(reference_body->radius)); - // sky_pass->set_ground_albedo(math::vector3{1.0f, 1.0f, 1.0f} * static_cast(reference_body->albedo)); + // sky_pass->set_ground_albedo(math::fvec3{1.0f, 1.0f, 1.0f} * static_cast(reference_body->albedo)); } else { @@ -554,16 +554,16 @@ void astronomy_system::update_icrf_to_eus(const ::celestial_body_component& body ( math::transformation::se3 { - float3(icrf_to_eus.t), - math::quaternion(icrf_to_eus.r) + math::fvec3(icrf_to_eus.t), + math::fquat(icrf_to_eus.r) } ); } } -double3 astronomy_system::integrate_transmittance(const ::observer_component& observer, const ::celestial_body_component& body, const ::atmosphere_component& atmosphere, geom::ray ray) const +math::dvec3 astronomy_system::integrate_transmittance(const ::observer_component& observer, const ::celestial_body_component& body, const ::atmosphere_component& atmosphere, geom::ray ray) const { - math::vector3 transmittance = {1, 1, 1}; + math::dvec3 transmittance = {1, 1, 1}; // Make ray height relative to center of reference body ray.origin.y() += body.radius + observer.elevation; @@ -590,7 +590,7 @@ double3 astronomy_system::integrate_transmittance(const ::observer_component& ob const double sample_end_distance = std::get<1>(*intersection); // Integrate atmospheric particle densities - math::vector3 densities{}; + math::dvec3 densities{}; double previous_sample_distance = 0.0; for (std::size_t i = 0; i < transmittance_samples; ++i) { @@ -610,7 +610,7 @@ double3 astronomy_system::integrate_transmittance(const ::observer_component& ob } // Calculate extinction coefficients from integrated atmospheric particle densities - const math::vector3 extinction = densities.x() * atmosphere.rayleigh_scattering + + const math::dvec3 extinction = densities.x() * atmosphere.rayleigh_scattering + densities.y() * atmosphere.mie_extinction + densities.z() * atmosphere.ozone_absorption; diff --git a/src/game/systems/astronomy-system.hpp b/src/game/systems/astronomy-system.hpp index d8a39a8..0a11419 100644 --- a/src/game/systems/astronomy-system.hpp +++ b/src/game/systems/astronomy-system.hpp @@ -23,7 +23,7 @@ #include "game/systems/updatable-system.hpp" #include #include -#include +#include #include #include #include "game/components/observer-component.hpp" @@ -81,7 +81,7 @@ public: void set_sun_light(scene::directional_light* light); void set_moon_light(scene::directional_light* light); - void set_starlight_illuminance(const double3& illuminance); + void set_starlight_illuminance(const math::dvec3& illuminance); void set_sky_pass(::render::sky_pass* pass); [[nodiscard]] inline double get_time() const noexcept @@ -125,7 +125,7 @@ private: * * @return Spectral transmittance factor. */ - double3 integrate_transmittance(const ::observer_component& observer, const ::celestial_body_component& body, const ::atmosphere_component& atmosphere, geom::ray ray) const; + math::dvec3 integrate_transmittance(const ::observer_component& observer, const ::celestial_body_component& body, const ::atmosphere_component& atmosphere, geom::ray ray) const; /// Time since epoch, in days. double time_days; @@ -157,7 +157,7 @@ private: scene::directional_light* sun_light; scene::directional_light* moon_light; ::render::sky_pass* sky_pass; - double3 starlight_illuminance; + math::dvec3 starlight_illuminance; }; diff --git a/src/game/systems/atmosphere-system.cpp b/src/game/systems/atmosphere-system.cpp index e774340..ddb0caf 100644 --- a/src/game/systems/atmosphere-system.cpp +++ b/src/game/systems/atmosphere-system.cpp @@ -45,7 +45,7 @@ atmosphere_system::~atmosphere_system() void atmosphere_system::update(float t, float dt) {} -void atmosphere_system::set_rgb_wavelengths(const double3& wavelengths) +void atmosphere_system::set_rgb_wavelengths(const math::dvec3& wavelengths) { rgb_wavelengths = wavelengths; @@ -141,10 +141,10 @@ void atmosphere_system::update_sky_pass() return; sky_pass->set_atmosphere_upper_limit(static_cast(component->upper_limit)); - sky_pass->set_rayleigh_parameters(static_cast(component->rayleigh_scale_height), math::vector(component->rayleigh_scattering)); + sky_pass->set_rayleigh_parameters(static_cast(component->rayleigh_scale_height), math::fvec3(component->rayleigh_scattering)); sky_pass->set_mie_parameters(static_cast(component->mie_scale_height), static_cast(component->mie_scattering), static_cast(component->mie_extinction), static_cast(component->mie_anisotropy)); - sky_pass->set_ozone_parameters(static_cast(component->ozone_lower_limit), static_cast(component->ozone_upper_limit), static_cast(component->ozone_mode), math::vector(component->ozone_absorption)); - sky_pass->set_airglow_luminance(math::vector(component->airglow_luminance)); + sky_pass->set_ozone_parameters(static_cast(component->ozone_lower_limit), static_cast(component->ozone_upper_limit), static_cast(component->ozone_mode), math::fvec3(component->ozone_absorption)); + sky_pass->set_airglow_luminance(math::fvec3(component->airglow_luminance)); } void atmosphere_system::on_atmosphere_construct(entity::registry& registry, entity::id entity_id) diff --git a/src/game/systems/atmosphere-system.hpp b/src/game/systems/atmosphere-system.hpp index 233dcde..67b4a23 100644 --- a/src/game/systems/atmosphere-system.hpp +++ b/src/game/systems/atmosphere-system.hpp @@ -22,7 +22,7 @@ #include "game/systems/updatable-system.hpp" #include -#include +#include #include "game/components/atmosphere-component.hpp" #include @@ -44,7 +44,7 @@ public: * * @param wavelengths Vector containing the wavelengths of red (x), green (y), and blue (z) light, in meters. */ - void set_rgb_wavelengths(const double3& wavelengths); + void set_rgb_wavelengths(const math::dvec3& wavelengths); void set_sky_pass(::render::sky_pass* pass); @@ -64,8 +64,8 @@ private: void on_atmosphere_destroy(entity::registry& registry, entity::id entity_id); entity::id active_atmosphere_eid; - double3 rgb_wavelengths; - double3 rgb_ozone_cross_sections; + math::dvec3 rgb_wavelengths; + math::dvec3 rgb_ozone_cross_sections; ::atmosphere_component* atmosphere_component; ::render::sky_pass* sky_pass; }; diff --git a/src/game/systems/blackbody-system.cpp b/src/game/systems/blackbody-system.cpp index 67c4383..2402817 100644 --- a/src/game/systems/blackbody-system.cpp +++ b/src/game/systems/blackbody-system.cpp @@ -47,7 +47,7 @@ blackbody_system::~blackbody_system() void blackbody_system::update(float t, float dt) {} -void blackbody_system::set_illuminant(const math::vector2& illuminant) +void blackbody_system::set_illuminant(const math::vec2& illuminant) { m_illuminant = illuminant; m_xyz_to_rgb = color::aces::ap1.from_xyz * color::cat::matrix(m_illuminant, color::aces::white_point); @@ -59,7 +59,7 @@ void blackbody_system::update_blackbody(entity::id entity_id) auto& blackbody = registry.get(entity_id); // Construct a lambda function which calculates the blackbody's RGB luminance of a given wavelength - auto rgb_spectral_luminance = [&](double wavelength_nm) -> math::vector3 + auto rgb_spectral_luminance = [&](double wavelength_nm) -> math::dvec3 { // Convert wavelength from nanometers to meters const double wavelength_m = wavelength_nm * 1e-9; @@ -71,14 +71,14 @@ void blackbody_system::update_blackbody(entity::id entity_id) const double spectral_luminance = spectral_radiance * 1e-9 * physics::light::max_luminous_efficacy; // Calculate the XYZ color of the wavelength using CIE color matching functions then transform to RGB - const math::vector3 rgb_color = m_xyz_to_rgb * color::xyz::match(wavelength_nm); + const math::dvec3 rgb_color = m_xyz_to_rgb * color::xyz::match(wavelength_nm); // Scale RGB color by spectral luminance return rgb_color * spectral_luminance; }; // Integrate the blackbody RGB spectral luminance over wavelengths in the visible spectrum - const math::vector3 rgb_luminance = math::quadrature::simpson(rgb_spectral_luminance, m_visible_wavelengths_nm.begin(), m_visible_wavelengths_nm.end()); + const math::dvec3 rgb_luminance = math::quadrature::simpson(rgb_spectral_luminance, m_visible_wavelengths_nm.begin(), m_visible_wavelengths_nm.end()); // Extract luminance and color from RGB luminance blackbody.luminance = math::max(rgb_luminance); diff --git a/src/game/systems/blackbody-system.hpp b/src/game/systems/blackbody-system.hpp index 391a242..2f0f254 100644 --- a/src/game/systems/blackbody-system.hpp +++ b/src/game/systems/blackbody-system.hpp @@ -44,7 +44,7 @@ public: * * @param illuminant CIE chromaticity coordinates of an illuminant. */ - void set_illuminant(const math::vector2& illuminant); + void set_illuminant(const math::vec2& illuminant); private: void update_blackbody(entity::id entity_id); @@ -53,8 +53,8 @@ private: void on_blackbody_update(entity::registry& registry, entity::id entity_id); std::vector m_visible_wavelengths_nm; - math::vector2 m_illuminant; - math::matrix3x3 m_xyz_to_rgb; + math::vec2 m_illuminant; + math::mat3 m_xyz_to_rgb; }; diff --git a/src/game/systems/camera-system.cpp b/src/game/systems/camera-system.cpp index c393910..8f509db 100644 --- a/src/game/systems/camera-system.cpp +++ b/src/game/systems/camera-system.cpp @@ -30,7 +30,7 @@ void camera_system::update(float t, float dt) } -void camera_system::set_viewport(const float4& viewport) +void camera_system::set_viewport(const math::fvec4& viewport) { this->viewport = viewport; } diff --git a/src/game/systems/camera-system.hpp b/src/game/systems/camera-system.hpp index 908dc61..942872b 100644 --- a/src/game/systems/camera-system.hpp +++ b/src/game/systems/camera-system.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_CAMERA_SYSTEM_HPP #include "game/systems/updatable-system.hpp" -#include +#include class camera_system: public updatable_system @@ -30,10 +30,10 @@ public: explicit camera_system(entity::registry& registry); virtual void update(float t, float dt); - void set_viewport(const float4& viewport); + void set_viewport(const math::fvec4& viewport); private: - float4 viewport; + math::fvec4 viewport; }; diff --git a/src/game/systems/collision-system.cpp b/src/game/systems/collision-system.cpp index 6ec2dda..a0ebd15 100644 --- a/src/game/systems/collision-system.cpp +++ b/src/game/systems/collision-system.cpp @@ -80,7 +80,7 @@ entity::id collision_system::pick_nearest(const geom::ray& ray, std::u return nearest_eid; } -entity::id collision_system::pick_nearest(const math::vector& origin, const math::vector& normal, std::uint32_t flags) const +entity::id collision_system::pick_nearest(const math::fvec3& origin, const math::fvec3& normal, std::uint32_t flags) const { entity::id nearest_eid = entt::null; float nearest_sqr_distance = std::numeric_limits::infinity(); @@ -98,7 +98,7 @@ entity::id collision_system::pick_nearest(const math::vector& origin, return; // Transform picking sphere center - math::vector picking_sphere_center = transform.world * picking.sphere.center; + math::fvec3 picking_sphere_center = transform.world * picking.sphere.center; // Skip entity if picking sphere center has negative distance from picking plane if (picking_plane.distance(picking_sphere_center) < 0.0f) diff --git a/src/game/systems/collision-system.hpp b/src/game/systems/collision-system.hpp index f216120..5d000dd 100644 --- a/src/game/systems/collision-system.hpp +++ b/src/game/systems/collision-system.hpp @@ -55,7 +55,7 @@ public: * * @return ID of the picked entity, or `entt::null` if no entity was picked. */ - entity::id pick_nearest(const math::vector& origin, const math::vector& normal, std::uint32_t flags) const; + entity::id pick_nearest(const math::fvec3& origin, const math::fvec3& normal, std::uint32_t flags) const; }; diff --git a/src/game/systems/constraint-system.cpp b/src/game/systems/constraint-system.cpp index 8a1ce05..8bdce0a 100644 --- a/src/game/systems/constraint-system.cpp +++ b/src/game/systems/constraint-system.cpp @@ -260,7 +260,7 @@ void constraint_system::handle_pivot_constraint(transform_component& transform, if (target_transform) { // Get pivot center point - const float3 pivot_center = target_transform->world.translation + constraint.offset; + const math::fvec3 pivot_center = target_transform->world.translation + constraint.offset; // Pivot translation transform.world.translation = pivot_center + transform.world.rotation * (transform.world.translation - pivot_center); @@ -271,12 +271,12 @@ void constraint_system::handle_pivot_constraint(transform_component& transform, void constraint_system::handle_spring_rotation_constraint(transform_component& transform, spring_rotation_constraint& constraint, float dt) { // Solve yaw, pitch, and roll angle spring - solve_numeric_spring(constraint.spring, dt); + solve_numeric_spring(constraint.spring, dt); // Build yaw, pitch, and roll quaternions - const math::quaternion yaw = math::angle_axis(constraint.spring.x0[0], {0.0f, 1.0f, 0.0f}); - const math::quaternion pitch = math::angle_axis(constraint.spring.x0[1], {-1.0f, 0.0f, 0.0f}); - const math::quaternion roll = math::angle_axis(constraint.spring.x0[2], {0.0f, 0.0f, -1.0f}); + const math::fquat yaw = math::angle_axis(constraint.spring.x0[0], {0.0f, 1.0f, 0.0f}); + const math::fquat pitch = math::angle_axis(constraint.spring.x0[1], {-1.0f, 0.0f, 0.0f}); + const math::fquat roll = math::angle_axis(constraint.spring.x0[2], {0.0f, 0.0f, -1.0f}); // Update transform rotation transform.world.rotation = math::normalize(yaw * pitch * roll); @@ -296,7 +296,7 @@ void constraint_system::handle_spring_to_constraint(transform_component& transfo constraint.translation.x1 = target_transform->world.translation; // Solve translation spring - solve_numeric_spring(constraint.translation, dt); + solve_numeric_spring(constraint.translation, dt); // Update transform translation transform.world.translation = constraint.translation.x0; @@ -306,13 +306,13 @@ void constraint_system::handle_spring_to_constraint(transform_component& transfo if (constraint.spring_rotation) { // Update rotation spring target - constraint.rotation.x1 = float4(target_transform->world.rotation); + constraint.rotation.x1 = math::fvec4(target_transform->world.rotation); // Solve rotation spring - solve_numeric_spring(constraint.rotation, dt); + solve_numeric_spring(constraint.rotation, dt); // Update transform rotation - transform.world.rotation = math::normalize(math::quaternion{constraint.rotation.x0[0], constraint.rotation.x0[1], constraint.rotation.x0[2], constraint.rotation.x0[3]}); + transform.world.rotation = math::normalize(math::fquat{constraint.rotation.x0[0], constraint.rotation.x0[1], constraint.rotation.x0[2], constraint.rotation.x0[3]}); } } } @@ -321,7 +321,7 @@ void constraint_system::handle_spring_to_constraint(transform_component& transfo void constraint_system::handle_spring_translation_constraint(transform_component& transform, spring_translation_constraint& constraint, float dt) { // Solve translation spring - solve_numeric_spring(constraint.spring, dt); + solve_numeric_spring(constraint.spring, dt); // Update transform translation transform.world.translation = constraint.spring.x0; @@ -329,9 +329,9 @@ void constraint_system::handle_spring_translation_constraint(transform_component void constraint_system::handle_three_dof_constraint(transform_component& transform, const three_dof_constraint& constraint) { - const math::quaternion yaw = math::angle_axis(constraint.yaw, {0.0f, 1.0f, 0.0f}); - const math::quaternion pitch = math::angle_axis(constraint.pitch, {-1.0f, 0.0f, 0.0f}); - const math::quaternion roll = math::angle_axis(constraint.roll, {0.0f, 0.0f, -1.0f}); + const math::fquat yaw = math::angle_axis(constraint.yaw, {0.0f, 1.0f, 0.0f}); + const math::fquat pitch = math::angle_axis(constraint.pitch, {-1.0f, 0.0f, 0.0f}); + const math::fquat roll = math::angle_axis(constraint.roll, {0.0f, 0.0f, -1.0f}); transform.world.rotation = math::normalize(yaw * pitch * roll); } diff --git a/src/game/systems/locomotion-system.cpp b/src/game/systems/locomotion-system.cpp index 2a033ee..8b174b9 100644 --- a/src/game/systems/locomotion-system.cpp +++ b/src/game/systems/locomotion-system.cpp @@ -60,8 +60,8 @@ void locomotion_system::update(float t, float dt) const auto& locomotion = winged_group.get(entity_id); auto& body = *(winged_group.get(entity_id).body); - const math::vector gravity{0.0f, 9.80665f * 10.0f, 0.0f}; - //const math::vector gravity{0.0f, 0.0f, 0.0f}; + const math::fvec3 gravity{0.0f, 9.80665f * 10.0f, 0.0f}; + //const math::fvec3 gravity{0.0f, 0.0f, 0.0f}; // Apply locomotive force body.apply_central_force(locomotion.force + gravity * body.get_mass()); diff --git a/src/game/systems/orbit-system.hpp b/src/game/systems/orbit-system.hpp index 647ce40..980cd8b 100644 --- a/src/game/systems/orbit-system.hpp +++ b/src/game/systems/orbit-system.hpp @@ -21,7 +21,7 @@ #define ANTKEEPER_GAME_ORBIT_SYSTEM_HPP #include "game/systems/updatable-system.hpp" -#include +#include #include #include "game/components/orbit-component.hpp" #include @@ -73,7 +73,7 @@ private: std::shared_ptr> ephemeris; double time; double time_scale; - std::vector positions; + std::vector positions; std::unordered_set ephemeris_indices; }; diff --git a/src/game/systems/physics-system.cpp b/src/game/systems/physics-system.cpp index 52bffa8..34d55a7 100644 --- a/src/game/systems/physics-system.cpp +++ b/src/game/systems/physics-system.cpp @@ -144,7 +144,7 @@ void physics_system::integrate(float dt) if (sqr_speed) { const float drag_magnitude = -0.5f * air_density * sqr_speed * sphere_drag_coef * sphere_cross_section_area; - const math::vector drag_force = math::normalize(body.linear_velocity) * drag_magnitude; + const math::fvec3 drag_force = math::normalize(body.linear_velocity) * drag_magnitude; body.apply_central_force(drag_force); } */ @@ -305,10 +305,10 @@ void physics_system::resolve_collisions() { const physics::collision_contact& contact = manifold.contacts[i]; - const math::vector radius_a = contact.point - body_a.get_position(); - const math::vector radius_b = contact.point - body_b.get_position(); + const math::fvec3 radius_a = contact.point - body_a.get_position(); + const math::fvec3 radius_b = contact.point - body_b.get_position(); - math::vector relative_velocity = body_b.get_point_velocity(radius_b) - body_a.get_point_velocity(radius_a); + math::fvec3 relative_velocity = body_b.get_point_velocity(radius_b) - body_a.get_point_velocity(radius_a); const float contact_velocity = math::dot(relative_velocity, contact.normal); if (contact_velocity > 0.0f) @@ -317,8 +317,8 @@ void physics_system::resolve_collisions() } const float reaction_impulse_num = -(1.0f + restitution_coef) * contact_velocity; - const math::vector ra_cross_n = math::cross(radius_a, contact.normal); - const math::vector rb_cross_n = math::cross(radius_b, contact.normal); + const math::fvec3 ra_cross_n = math::cross(radius_a, contact.normal); + const math::fvec3 rb_cross_n = math::cross(radius_b, contact.normal); const float reaction_impulse_den = sum_inverse_mass + math::dot ( @@ -327,7 +327,7 @@ void physics_system::resolve_collisions() contact.normal ); const float reaction_impulse_mag = (reaction_impulse_num / reaction_impulse_den) * impulse_scale; - const math::vector reaction_impulse = contact.normal * reaction_impulse_mag; + const math::fvec3 reaction_impulse = contact.normal * reaction_impulse_mag; // Apply reaction impulses body_a.apply_impulse(-reaction_impulse, radius_a); @@ -335,7 +335,7 @@ void physics_system::resolve_collisions() //relative_velocity = body_b.get_point_velocity(radius_b) - body_a.get_point_velocity(radius_a); - math::vector contact_tangent = relative_velocity - contact.normal * contact_velocity; + math::fvec3 contact_tangent = relative_velocity - contact.normal * contact_velocity; const float sqr_tangent_length = math::sqr_length(contact_tangent); if (sqr_tangent_length > 0.0f) { @@ -343,8 +343,8 @@ void physics_system::resolve_collisions() } const float friction_impulse_num = math::dot(relative_velocity, -contact_tangent); - const math::vector ra_cross_t = math::cross(radius_a, contact_tangent); - const math::vector rb_cross_t = math::cross(radius_b, contact_tangent); + const math::fvec3 ra_cross_t = math::cross(radius_a, contact_tangent); + const math::fvec3 rb_cross_t = math::cross(radius_b, contact_tangent); const float friction_impulse_den = sum_inverse_mass + math::dot ( @@ -359,7 +359,7 @@ void physics_system::resolve_collisions() friction_impulse_mag = -reaction_impulse_mag * dynamic_friction_coef; } - const math::vector friction_impulse = contact_tangent * friction_impulse_mag; + const math::fvec3 friction_impulse = contact_tangent * friction_impulse_mag; body_a.apply_impulse(-friction_impulse, radius_a); body_b.apply_impulse(friction_impulse, radius_b); @@ -382,7 +382,7 @@ void physics_system::correct_positions() { const physics::collision_contact& contact = manifold.contacts[i]; - math::vector correction = contact.normal * (std::max(0.0f, contact.depth - depth_threshold) / sum_inverse_mass) * correction_factor; + math::fvec3 correction = contact.normal * (std::max(0.0f, contact.depth - depth_threshold) / sum_inverse_mass) * correction_factor; body_a.set_position(body_a.get_position() - correction * body_a.get_inverse_mass()); body_b.set_position(body_b.get_position() + correction * body_b.get_inverse_mass()); @@ -401,7 +401,7 @@ void physics_system::narrow_phase_plane_sphere(physics::rigid_body& body_a, phys const auto& sphere_b = static_cast(*body_b.get_collider()); // Transform plane into world-space - const math::vector plane_normal = body_a.get_orientation() * plane_a.get_normal(); + const math::fvec3 plane_normal = body_a.get_orientation() * plane_a.get_normal(); const float plane_constant = plane_a.get_constant() - math::dot(plane_normal, body_a.get_position()); const float signed_distance = math::dot(plane_normal, body_b.get_position()) + plane_constant; @@ -431,12 +431,12 @@ void physics_system::narrow_phase_plane_box(physics::rigid_body& body_a, physics const auto& box_b = static_cast(*body_b.get_collider()); // Transform plane into world-space - const math::vector plane_normal = body_a.get_orientation() * plane_a.get_normal(); + const math::fvec3 plane_normal = body_a.get_orientation() * plane_a.get_normal(); const float plane_constant = plane_a.get_constant() - math::dot(plane_normal, body_a.get_position()); const auto& box_min = box_b.get_min(); const auto& box_max = box_b.get_max(); - const math::vector corners[8] = + const math::fvec3 corners[8] = { {box_min.x(), box_min.y(), box_min.z()}, {box_min.x(), box_min.y(), box_max.z()}, @@ -456,7 +456,7 @@ void physics_system::narrow_phase_plane_box(physics::rigid_body& body_a, physics for (std::size_t i = 0; i < 8; ++i) { // Transform corner into world-space - const math::vector point = body_b.get_transform() * corners[i]; + const math::fvec3 point = body_b.get_transform() * corners[i]; const float signed_distance = math::dot(plane_normal, point) + plane_constant; @@ -552,8 +552,8 @@ void physics_system::narrow_phase_sphere_sphere(physics::rigid_body& body_a, phy const auto& collider_b = static_cast(*body_b.get_collider()); // Transform spheres into world-space - const math::vector center_a = body_a.get_transform() * collider_a.get_center(); - const math::vector center_b = body_b.get_transform() * collider_b.get_center(); + const math::fvec3 center_a = body_a.get_transform() * collider_a.get_center(); + const math::fvec3 center_b = body_b.get_transform() * collider_b.get_center(); const float radius_a = collider_a.get_radius(); const float radius_b = collider_b.get_radius(); @@ -561,7 +561,7 @@ void physics_system::narrow_phase_sphere_sphere(physics::rigid_body& body_a, phy const float sum_radii = radius_a + radius_b; // Get vector from center a to center b - const math::vector difference = center_b - center_a; + const math::fvec3 difference = center_b - center_a; const float sqr_distance = math::sqr_length(difference); if (sqr_distance > sum_radii * sum_radii) @@ -604,7 +604,7 @@ void physics_system::narrow_phase_sphere_capsule(physics::rigid_body& body_a, ph const auto& collider_b = static_cast(*body_b.get_collider()); // Transform sphere into world-space - const math::vector center_a = body_a.get_transform() * collider_a.get_center(); + const math::fvec3 center_a = body_a.get_transform() * collider_a.get_center(); const float radius_a = collider_a.get_radius(); // Transform capsule into world-space @@ -622,7 +622,7 @@ void physics_system::narrow_phase_sphere_capsule(physics::rigid_body& body_a, ph const auto closest_point = geom::closest_point(segment_b, center_a); // Get vector from sphere center to point to on capsule segment - const math::vector difference = closest_point - center_a; + const math::fvec3 difference = closest_point - center_a; const float sqr_distance = math::sqr_length(difference); if (sqr_distance > sum_radii * sum_radii) @@ -717,7 +717,7 @@ void physics_system::narrow_phase_capsule_capsule(physics::rigid_body& body_a, p const float sum_radii = capsule_a.radius + capsule_b.radius; // Get vector from closest point on segment a to closest point on segment b - const math::vector difference = closest_b - closest_a; + const math::fvec3 difference = closest_b - closest_a; const float sqr_distance = math::sqr_length(difference); if (sqr_distance > sum_radii * sum_radii) diff --git a/src/game/systems/physics-system.hpp b/src/game/systems/physics-system.hpp index c6de5a3..fdd3372 100644 --- a/src/game/systems/physics-system.hpp +++ b/src/game/systems/physics-system.hpp @@ -45,7 +45,7 @@ public: * * @param gravity Gravity vector. */ - inline void set_gravity(const math::vector& gravity) noexcept + inline void set_gravity(const math::fvec3& gravity) noexcept { this->gravity = gravity; } @@ -84,7 +84,7 @@ private: std::array, 4>, 4> narrow_phase_table; - math::vector gravity{0.0f, -9.80665f, 0.0f}; + math::fvec3 gravity{0.0f, -9.80665f, 0.0f}; std::vector> broad_phase_pairs; std::vector narrow_phase_manifolds; diff --git a/src/game/systems/spring-system.cpp b/src/game/systems/spring-system.cpp index 827f718..ea5d5ff 100644 --- a/src/game/systems/spring-system.cpp +++ b/src/game/systems/spring-system.cpp @@ -45,7 +45,7 @@ void spring_system::update(float t, float dt) ( [&](entity::id spring_eid, auto& component) { - solve_numeric_spring(component.spring, dt); + solve_numeric_spring(component.spring, dt); if (component.callback) component.callback(component.spring.x0); } @@ -55,7 +55,7 @@ void spring_system::update(float t, float dt) ( [&](entity::id spring_eid, auto& component) { - solve_numeric_spring(component.spring, dt); + solve_numeric_spring(component.spring, dt); if (component.callback) component.callback(component.spring.x0); } @@ -65,7 +65,7 @@ void spring_system::update(float t, float dt) ( [&](entity::id spring_eid, auto& component) { - solve_numeric_spring(component.spring, dt); + solve_numeric_spring(component.spring, dt); if (component.callback) component.callback(component.spring.x0); } diff --git a/src/game/systems/steering-system.cpp b/src/game/systems/steering-system.cpp index c2212d4..e50f639 100644 --- a/src/game/systems/steering-system.cpp +++ b/src/game/systems/steering-system.cpp @@ -47,7 +47,7 @@ void steering_system::update(float t, float dt) agent.velocity = body.get_linear_velocity(); // Accumulate steering forces - float3 force = {0, 0, 0}; + math::fvec3 force = {0, 0, 0}; if (steering.wander_weight) { //force += ai::steering::behavior::wander_2d(agent, steering.wander_noise * dt, steering.wander_distance, steering.wander_radius, steering.wander_angle) * steering.wander_weight; diff --git a/src/game/systems/subterrain-system.cpp b/src/game/systems/subterrain-system.cpp index f3c6f65..7ce3023 100644 --- a/src/game/systems/subterrain-system.cpp +++ b/src/game/systems/subterrain-system.cpp @@ -18,353 +18,13 @@ */ #include "game/systems/subterrain-system.hpp" -#include "game/components/cavity-component.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include subterrain_system::subterrain_system(entity::registry& registry, ::resource_manager* resource_manager): - updatable_system(registry), - resource_manager(resource_manager) -{ - -/* - // Load subterrain materials - subterrain_inside_material = nullptr;//resource_manager->load<::render::material>("subterrain-inside.mtl"); - subterrain_outside_material = nullptr;//resource_manager->load<::render::material>("subterrain-outside.mtl"); - - // Allocate subterrain model - subterrain_model = new ::render::model(); - - // Create inside model group - subterrain_inside_group = subterrain_model->add_group("inside"); - subterrain_inside_group->set_material(subterrain_inside_material); - subterrain_inside_group->set_drawing_mode(gl::drawing_mode::triangles); - subterrain_inside_group->set_start_index(0); - subterrain_inside_group->set_index_count(0); - - // Create outside model group - subterrain_outside_group = subterrain_model->add_group("outside"); - subterrain_outside_group->set_material(subterrain_outside_material); - subterrain_outside_group->set_drawing_mode(gl::drawing_mode::triangles); - subterrain_outside_group->set_start_index(0); - subterrain_outside_group->set_index_count(0); - - // Determine vertex size (position, normal, barycentric) - subterrain_model_vertex_size = 3 + 3 + 3; - subterrain_model_vertex_stride = subterrain_model_vertex_size * sizeof(float); - - // Get model VBO and VAO - gl::vertex_buffer* vbo = subterrain_model->get_vertex_buffer(); - gl::vertex_array* vao = subterrain_model->get_vertex_array(); - - std::size_t attribute_offset = 0; - - // Define position vertex attribute - gl::vertex_attribute position_attribute; - position_attribute.buffer = vbo; - position_attribute.offset = attribute_offset; - position_attribute.stride = subterrain_model_vertex_stride; - position_attribute.type = gl::vertex_attribute_type::float_32; - position_attribute.components = 3; - attribute_offset += position_attribute.components * sizeof(float); - - // Define normal vertex attribute - gl::vertex_attribute normal_attribute; - normal_attribute.buffer = vbo; - normal_attribute.offset = attribute_offset; - normal_attribute.stride = subterrain_model_vertex_stride; - normal_attribute.type = gl::vertex_attribute_type::float_32; - normal_attribute.components = 3; - attribute_offset += normal_attribute.components * sizeof(float); - - // Define barycentric vertex attribute - gl::vertex_attribute barycentric_attribute; - barycentric_attribute.buffer = vbo; - barycentric_attribute.offset = attribute_offset; - barycentric_attribute.stride = subterrain_model_vertex_stride; - barycentric_attribute.type = gl::vertex_attribute_type::float_32; - barycentric_attribute.components = 3; - attribute_offset += barycentric_attribute.components * sizeof(float); - - // Bind vertex attributes to VAO - vao->bind(::render::vertex_attribute::position, position_attribute); - vao->bind(::render::vertex_attribute::normal, normal_attribute); - vao->bind(::render::vertex_attribute::barycentric, barycentric_attribute); - - // Calculate adjusted bounds to fit isosurface resolution - //isosurface_resolution = 0.325f; - isosurface_resolution = 0.5f; - float ideal_volume_size = 200.0f; - int octree_depth = std::floor(std::log(ideal_volume_size / isosurface_resolution) / std::log(2)) + 1; - float adjusted_volume_size = std::pow(2.0f, octree_depth) * isosurface_resolution; - - // Set subterrain bounds - subterrain_bounds.min = float3{-0.5f, -1.0f, -0.5f} * adjusted_volume_size; - subterrain_bounds.max = float3{ 0.5f, 0.0f, 0.5f} * adjusted_volume_size; - - // Set subterrain model bounds - subterrain_model->set_bounds(subterrain_bounds); - - // Allocate cube tree - cube_tree = new ::cube_tree(subterrain_bounds, octree_depth); - - // Allocate mesh - subterrain_mesh = new geom::mesh(); - - first_run = true; - */ -} + updatable_system(registry) +{} subterrain_system::~subterrain_system() -{ - /* - delete subterrain_model; - delete subterrain_mesh; - */ -} +{} void subterrain_system::update(float t, float dt) -{ - /* - if (first_run) - { - first_run = false; - //auto subterrain_entity = registry.create(); - //registry.assign(subterrain_entity, subterrain_model); - - subterrain_static_mesh = new scene::static_mesh(subterrain_model); - collection->add_object(subterrain_static_mesh); - } - - bool digging = false; - - registry.view().each( - [this, &digging](entity::id entity_id, auto& cavity) - { - this->dig(cavity.position, cavity.radius); - this->registry.destroy(entity_id); - - digging = true; - }); - - if (digging) - { - - //std::cout << "regenerating subterrain mesh...\n"; - regenerate_subterrain_mesh(); - //std::cout << "regenerating subterrain mesh... done\n"; - - //std::cout << "regenerating subterrain model...\n"; - regenerate_subterrain_model(); - //std::cout << "regenerating subterrain model... done\n"; - } - */ -} - -void subterrain_system::set_scene(scene::collection* collection) -{ - //this->collection = collection; -} - -void subterrain_system::regenerate_subterrain_mesh() -{ - /* - delete subterrain_mesh; - subterrain_mesh = new geom::mesh(); - subterrain_vertices.clear(); - subterrain_triangles.clear(); - subterrain_vertex_map.clear(); - - //std::cout << "marching...\n"; - merged = 0; - march(cube_tree); - //std::cout << "merged " << merged << " vertices\n"; - //std::cout << "marching...done\n"; - - //std::cout << "vertex count: " << subterrain_vertices.size() << std::endl; - //std::cout << "triangle count: " << subterrain_triangles.size() << std::endl; - - //std::cout << "creating mesh...\n"; - create_triangle_mesh(*subterrain_mesh, subterrain_vertices, subterrain_triangles); - //std::cout << "creating mesh... done\n"; - */ -} - -void subterrain_system::march(::cube_tree* node) -{ - /* - if (!node->is_leaf()) - { - for (::cube_tree* child: node->children) - march(child); - return; - } - else if (node->depth != node->max_depth) - { - return; - } - - // Get node bounds - const geom::box& bounds = node->get_bounds(); - - // Polygonize cube - float vertex_buffer[12 * 3]; - std::uint_fast8_t vertex_count; - std::int_fast8_t triangle_buffer[5 * 3]; - std::uint_fast8_t triangle_count; - const float* corners = &node->corners[0][0]; - const float* distances = &node->distances[0]; - geom::mc::polygonize(vertex_buffer, &vertex_count, triangle_buffer, &triangle_count, corners, distances); - - // Remap local vertex buffer indices (0-11) to mesh vertex indices - std::uint_fast32_t vertex_remap[12]; - for (int i = 0; i < vertex_count; ++i) - { - const float3& vertex = reinterpret_cast(vertex_buffer[i * 3]); - - if (auto it = subterrain_vertex_map.find(vertex); it != subterrain_vertex_map.end()) - { - vertex_remap[i] = it->second; - ++merged; - } - else - { - vertex_remap[i] = subterrain_vertices.size(); - subterrain_vertex_map[vertex] = subterrain_vertices.size(); - subterrain_vertices.push_back(vertex); - } - } - - // Add triangles - for (std::uint_fast32_t i = 0; i < triangle_count; ++i) - { - subterrain_triangles.push_back( - { - vertex_remap[triangle_buffer[i * 3]], - vertex_remap[triangle_buffer[i * 3 + 1]], - vertex_remap[triangle_buffer[i * 3 + 2]] - }); - } - */ -} - -void subterrain_system::regenerate_subterrain_model() -{ - /* - float3* face_normals = new float3[subterrain_mesh->get_faces().size()]; - calculate_face_normals(face_normals, *subterrain_mesh); - - static const float3 barycentric_coords[3] = - { - float3{1, 0, 0}, - float3{0, 1, 0}, - float3{0, 0, 1} - }; - - float* vertex_data = new float[subterrain_model_vertex_size * subterrain_mesh->get_faces().size() * 3]; - float* v = vertex_data; - for (std::size_t i = 0; i < subterrain_mesh->get_faces().size(); ++i) - { - geom::mesh::face* face = subterrain_mesh->get_faces()[i]; - geom::mesh::edge* ab = face->edge; - geom::mesh::edge* bc = face->edge->next; - geom::mesh::edge* ca = face->edge->previous; - geom::mesh::vertex* a = ab->vertex; - geom::mesh::vertex* b = bc->vertex; - geom::mesh::vertex* c = ca->vertex; - geom::mesh::vertex* vertices[3] = {a, b, c}; - - for (std::size_t j = 0; j < 3; ++j) - { - geom::mesh::vertex* vertex = vertices[j]; - - float3 n = {0, 0, 0}; - geom::mesh::edge* start = vertex->edge; - geom::mesh::edge* edge = start; - do - { - if (edge->face) - { - n += face_normals[edge->face->index]; - } - - edge = edge->previous->symmetric; - } - while (edge != start); - n = math::normalize(n); - - //float3 n = reinterpret_cast(face_normals[i * 3]); - - *(v++) = vertex->position[0]; - *(v++) = vertex->position[1]; - *(v++) = vertex->position[2]; - - *(v++) = n[0]; - *(v++) = n[1]; - *(v++) = n[2]; - - *(v++) = barycentric_coords[j][0]; - *(v++) = barycentric_coords[j][1]; - *(v++) = barycentric_coords[j][2]; - } - } - - // Resized VBO and upload vertex data - gl::vertex_buffer* vbo = subterrain_model->get_vertex_buffer(); - vbo->resize(subterrain_mesh->get_faces().size() * 3 * subterrain_model_vertex_stride, vertex_data); - - // Deallocate vertex data - delete[] face_normals; - delete[] vertex_data; - - // Update model groups - subterrain_inside_group->set_index_count(subterrain_mesh->get_faces().size() * 3); - subterrain_outside_group->set_index_count(subterrain_mesh->get_faces().size() * 3); - */ -} - -void subterrain_system::dig(const float3& position, float radius) -{ - /* - // Construct region containing the cavity sphere - geom::box region = {position, position}; - for (int i = 0; i < 3; ++i) - { - region.min[i] -= radius + isosurface_resolution; - region.max[i] += radius + isosurface_resolution; - } - - // Subdivide the octree to the maximum depth within the region - cube_tree->subdivide_max(region); - - // Query all octree leaf nodes within the region - std::list<::cube_tree*> nodes; - cube_tree->visit_leaves(region, - [&position, radius](::cube_tree& node) - { - for (int i = 0; i < 8; ++i) - { - // For outside normals (also set node initial distance to +infinity) - //float distance = math::length(node->corners[i] - position) - radius; - // if (distance < node->distances[i]) - - float distance = radius - math::length(node.corners[i] - position); - if (distance > node.distances[i]) - node.distances[i] = distance; - } - }); - */ -} - +{} diff --git a/src/game/systems/subterrain-system.hpp b/src/game/systems/subterrain-system.hpp index 404a37f..1bae197 100644 --- a/src/game/systems/subterrain-system.hpp +++ b/src/game/systems/subterrain-system.hpp @@ -21,65 +21,7 @@ #define ANTKEEPER_GAME_SUBTERRAIN_SYSTEM_HPP #include "game/systems/updatable-system.hpp" -#include -#include -#include -#include -#include -#include - -class resource_manager; - - -struct cube_tree; - -template -struct epsilon -{ - static const double value; -}; - -template -const double epsilon::value = static_cast(Mantissa) * std::pow(10.0, Exponent); - -typedef epsilon<1, -5> epsilon_1en5; - -template -struct vector_hasher -{ - typedef math::vector vector_type; - - std::size_t operator()(const vector_type& v) const noexcept - { - static const T inverse_epsilon = T(1) / Epsilon::value; - - std::size_t hash = 0; - for (std::size_t i = 0; i < N; ++i) - { - std::int64_t j = static_cast(v[i] * inverse_epsilon); - hash ^= std::hash()(j) + 0x9e3779b9 + (hash << 6) + (hash >> 2); - } - - return hash; - } -}; - -template -struct vector_equals -{ - typedef math::vector vector_type; - - bool operator()(const vector_type& a, const vector_type& b) const noexcept - { - for (std::size_t i = 0; i < N; ++i) - { - if (std::fabs(b[i] - a[i]) >= Epsilon::value) - return false; - } - - return true; - } -}; +#include class subterrain_system: public updatable_system { @@ -87,42 +29,8 @@ public: subterrain_system(entity::registry& registry, ::resource_manager* resource_manager); ~subterrain_system(); virtual void update(float t, float dt); - - void set_scene(scene::collection* collection); private: - void regenerate_subterrain_mesh(); - void march(cube_tree* node); - void regenerate_subterrain_model(); - void dig(const float3&position, float radius); - float distance(const cube_tree& node, const float3& sample) const; - - resource_manager* resource_manager; - geom::mesh* subterrain_mesh; - ::render::model* subterrain_model; - ::render::material* subterrain_inside_material; - ::render::material* subterrain_outside_material; - ::render::model_group* subterrain_inside_group; - ::render::model_group* subterrain_outside_group; - int subterrain_model_vertex_size; - int subterrain_model_vertex_stride; - geom::box subterrain_bounds; - cube_tree* cube_tree; - std::vector subterrain_vertices; - std::vector> subterrain_triangles; - float isosurface_resolution; - bool first_run; - int merged; - - std::unordered_map< - float3, - std::uint_fast32_t, - vector_hasher, - vector_equals> subterrain_vertex_map; - - scene::collection* collection; - scene::static_mesh* subterrain_static_mesh; }; - #endif // ANTKEEPER_GAME_SUBTERRAIN_SYSTEM_HPP diff --git a/src/game/systems/terrain-system.cpp b/src/game/systems/terrain-system.cpp index 48529e8..51d5245 100644 --- a/src/game/systems/terrain-system.cpp +++ b/src/game/systems/terrain-system.cpp @@ -1,652 +1,31 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#include "game/systems/terrain-system.hpp" -#include "game/components/terrain-component.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -terrain_system::terrain_system(entity::registry& registry): - updatable_system(registry), - patch_side_length(0.0f), - patch_subdivisions(0), - patch_material(nullptr), - elevation_function(nullptr), - scene_collection(nullptr), - patch_base_mesh(nullptr), - patch_vertex_size(0), - patch_vertex_stride(0) -{ - // Specify vertex size and stride - // (position + uv + normal + tangent + barycentric + target) - patch_vertex_size = 3 + 2 + 3 + 4 + 3 + 3; - patch_vertex_stride = patch_vertex_size * sizeof(float); - - // Init quadtee node sizes at each depth - for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i) - { - quadtree_node_size[i] = 0.0f; - quadtree_node_resolution[i] = static_cast(std::exp2(i)); - } - - // registry.on_construct().connect<&terrain_system::on_terrain_construct>(this); - // registry.on_update().connect<&terrain_system::on_terrain_update>(this); - // registry.on_destroy().connect<&terrain_system::on_terrain_destroy>(this); -} - -terrain_system::~terrain_system() -{ - // registry.on_construct().disconnect<&terrain_system::on_terrain_construct>(this); - // registry.on_update().disconnect<&terrain_system::on_terrain_update>(this); - // registry.on_destroy().disconnect<&terrain_system::on_terrain_destroy>(this); -} - -void terrain_system::update(float t, float dt) -{ - /* - // Clear quadtree - quadtree.clear(); - - // For each camera - this->registry.view().each - ( - [&](entity::id camera_eid, const auto& camera) - { - if (!camera.object) - return; - - const scene::camera& cam = *camera.object; - - // Determine camera node location - const auto [x, y, z] = cam.get_translation(); - - quadtree_node_type node_depth = quadtree.max_depth; - const float node_size = quadtree_node_size[node_depth]; - quadtree_node_type node_resolution = quadtree_node_resolution[node_depth]; - - quadtree_node_type node_x = static_cast(x / node_size + node_resolution / 2); - quadtree_node_type node_y = static_cast(z / node_size + node_resolution / 2); - quadtree_node_type node_location = geom::morton::encode(node_x, node_y); - //quadtree.insert(quadtree.node(node_depth, node_location)); - - node_stack.push(quadtree.node(node_depth, node_location)); - balance_quadtree(); - - for (const quadtree_node_type& node: quadtree) - { - if (!quadtree.is_leaf(node)) - continue; - - if (patches.find(node) == patches.end()) - { - patch* node_patch = generate_patch(node); - patches[node] = node_patch; - scene_collection->add_object(node_patch->static_mesh); - } - } - } - ); - - - - /// Toggle visibility of terrain scene objects - for (auto it = patches.begin(); it != patches.end(); ++it) - { - bool active = (quadtree.contains(it->first) && quadtree.is_leaf(it->first)); - it->second->static_mesh->set_active(active); - } - */ -} - -void terrain_system::set_patch_side_length(float length) -{ - patch_side_length = length; - - // Recalculate node sizes at each quadtree depth - for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i) - { - quadtree_node_size[i] = std::exp2(static_cast(quadtree_type::max_depth - i)) * patch_side_length; - } -} - -void terrain_system::set_patch_subdivisions(std::size_t n) -{ - patch_subdivisions = n; - - // Recalculate patch properties - patch_cell_count = (patch_subdivisions + 1) * (patch_subdivisions + 1); - patch_triangle_count = patch_cell_count * 2; - - // Resize patch vertex data buffer - patch_vertex_data.resize(patch_triangle_count * 3 * patch_vertex_size); - - // Resize patch buffers - - std::size_t vertex_buffer_row_size = patch_subdivisions + 4; - std::size_t vertex_buffer_column_size = vertex_buffer_row_size; - - patch_vertex_buffer.resize(vertex_buffer_row_size); - for (std::size_t i = 0; i < patch_vertex_buffer.size(); ++i) - patch_vertex_buffer[i].resize(vertex_buffer_column_size); - - rebuild_patch_base_mesh(); -} - -void terrain_system::set_patch_material(std::shared_ptr<::render::material> material) -{ - patch_material = material; -} - -void terrain_system::set_elevation_function(const std::function& f) -{ - elevation_function = f; -} - -void terrain_system::set_scene_collection(scene::collection* collection) -{ - scene_collection = collection; -} - -void terrain_system::on_terrain_construct(entity::registry& registry, entity::id entity_id) -{ -} - -void terrain_system::on_terrain_update(entity::registry& registry, entity::id entity_id) -{ -} - -void terrain_system::on_terrain_destroy(entity::registry& registry, entity::id entity_id) -{ -} - -float terrain_system::get_patch_size(quadtree_node_type node) const -{ - return quadtree_node_size[quadtree_type::depth(node)]; -} - -float3 terrain_system::get_patch_center(quadtree_node_type node) const -{ - const float node_size = get_patch_size(node); - const float node_offset = quadtree_node_size[0] * -0.5f + node_size * 0.5f; - - // Extract node location from Morton location code - quadtree_type::node_type node_location = quadtree_type::location(node); - quadtree_type::node_type node_location_x; - quadtree_type::node_type node_location_y; - geom::morton::decode(node_location, node_location_x, node_location_y); - - return float3 - { - node_offset + static_cast(node_location_x) * node_size, - 0.0f, - node_offset + static_cast(node_location_y) * node_size - }; -} - -void terrain_system::rebuild_patch_base_mesh() -{ - // Rebuild grid - patch_base_mesh = geom::meshes::grid_xy(1.0f, patch_subdivisions, patch_subdivisions); - - // Convert quads to triangle fans - for (std::size_t i = 0; i < patch_base_mesh->get_faces().size(); ++i) - { - geom::mesh::face* face = patch_base_mesh->get_faces()[i]; - - std::size_t edge_count = 1; - for (geom::mesh::edge* edge = face->edge->next; edge != face->edge; edge = edge->next) - ++edge_count; - - if (edge_count > 3) - { - geom::poke_face(*patch_base_mesh, face->index); - --i; - } - } - - // Transform patch base mesh coordinates from XY plane to XZ plane - const math::quaternion xy_to_xz = math::quaternion::rotate_x(math::half_pi); - for (geom::mesh::vertex* vertex: patch_base_mesh->get_vertices()) - { - vertex->position = xy_to_xz * vertex->position; - } -} - -void terrain_system::balance_quadtree() -{ - while (!node_stack.empty()) - { - quadtree_node_type node = node_stack.top(); - node_stack.pop(); - - if (quadtree.contains(node)) - continue; - - quadtree.insert(node); - - const auto depth = quadtree.depth(node); - if (depth < 2) - continue; - - const quadtree_node_type parent = quadtree.parent(node); - const quadtree_node_type parent_depth = depth - 1; - const quadtree_node_type parent_resolution = quadtree_node_resolution[parent_depth]; - - for (quadtree_node_type i = 0; i < quadtree.children_per_node; ++i) - { - const auto location = quadtree.location(quadtree.sibling(parent, i)); - quadtree_node_type x, y; - geom::morton::decode(location, x, y); - - if (x < parent_resolution - 1) - { - if (y < parent_resolution - 1) - node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x + 1, y + 1))); - if (y > 0) - node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x + 1, y - 1))); - } - - if (x > 0) - { - if (y < parent_resolution - 1) - node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x - 1, y + 1))); - if (y > 0) - node_stack.push(quadtree.node(parent_depth, geom::morton::encode(x - 1, y - 1))); - } - } - } -} - -std::unique_ptr terrain_system::generate_patch_mesh(quadtree_node_type node) const -{ - // Extract node depth - const quadtree_type::node_type node_depth = quadtree_type::depth(node); - - // Get size of node at depth - const float node_size = quadtree_node_size[node_depth]; - - // Extract node Morton location code and decode location - const quadtree_type::node_type node_location = quadtree_type::location(node); - quadtree_type::node_type node_location_x; - quadtree_type::node_type node_location_y; - geom::morton::decode(node_location, node_location_x, node_location_y); - - // Determine center of node - const float node_offset = quadtree_node_size[0] * -0.5f + node_size * 0.5f; - const float3 node_center = - { - node_offset + static_cast(node_location_x) * node_size, - 0.0f, - node_offset + static_cast(node_location_y) * node_size - }; - - // Copy patch base mesh - std::unique_ptr patch_mesh = std::make_unique(*patch_base_mesh); - - // Modify patch mesh vertex positions - for (geom::mesh::vertex* v: patch_mesh->get_vertices()) - { - v->position.x() = node_center.x() + v->position.x() * node_size; - v->position.z() = node_center.z() + v->position.z() * node_size; - v->position.y() = elevation_function(v->position.x(), v->position.z()); - } - - return patch_mesh; -} - -::render::model* terrain_system::generate_patch_model(quadtree_node_type node) const -{ - // Get size and position of patch - const float patch_size = get_patch_size(node); - const float3 patch_center = get_patch_center(node); - - // Calculate size of a patch cell - const float cell_size = patch_size / static_cast(patch_subdivisions + 1); - - // Init patch bounds - geom::box patch_bounds; - patch_bounds.min.x() = patch_center.x() - patch_size * 0.5f; - patch_bounds.min.y() = std::numeric_limits::infinity(); - patch_bounds.min.z() = patch_center.z() - patch_size * 0.5f; - patch_bounds.max.x() = patch_center.x() + patch_size * 0.5f; - patch_bounds.max.y() = -std::numeric_limits::infinity(); - patch_bounds.max.z() = patch_center.z() + patch_size * 0.5f; - - // Calculate positions and UVs of patch vertices and immediately neighboring vertices - float3 first_vertex_position = - { - patch_bounds.min.x() - cell_size, - patch_center.y(), - patch_bounds.min.z() - cell_size - }; - float3 vertex_position = first_vertex_position; - for (std::size_t i = 0; i < patch_vertex_buffer.size(); ++i) - { - // For each column - for (std::size_t j = 0; j < patch_vertex_buffer[i].size(); ++j) - { - // Calculate vertex elevation - vertex_position.y() = elevation_function(vertex_position.x(), vertex_position.z()); - - // Update patch bounds - patch_bounds.min.y() = std::min(patch_bounds.min.y(), vertex_position.y()); - patch_bounds.max.y() = std::max(patch_bounds.max.y(), vertex_position.y()); - - // Update patch vertex position - patch_vertex_buffer[i][j].position = vertex_position; - - // Calculate patch vertex UV - patch_vertex_buffer[i][j].uv.x() = (vertex_position.x() - patch_bounds.min.x()) / patch_size; - patch_vertex_buffer[i][j].uv.y() = (vertex_position.z() - patch_bounds.min.z()) / patch_size; - - // Init patch vertex normal, tangent, and bitangent - patch_vertex_buffer[i][j].normal = {0, 0, 0}; - patch_vertex_buffer[i][j].tangent = {0, 0, 0}; - patch_vertex_buffer[i][j].bitangent = {0, 0, 0}; - - vertex_position.x() += cell_size; - } - - vertex_position.z() += cell_size; - vertex_position.x() = first_vertex_position.x(); - } - - // Accumulate normals, tangents, and bitangents - for (std::size_t i = 0; i < patch_vertex_buffer.size() - 1; ++i) - { - for (std::size_t j = 0; j < patch_vertex_buffer[i].size() - 1; ++j) - { - patch_vertex& a = patch_vertex_buffer[i ][j]; - patch_vertex& b = patch_vertex_buffer[i+1][j]; - patch_vertex& c = patch_vertex_buffer[i ][j+1]; - patch_vertex& d = patch_vertex_buffer[i+1][j+1]; - - auto add_ntb = [](auto& a, auto& b, auto& c) - { - const float3 ba = b.position - a.position; - const float3 ca = c.position - a.position; - const float2 uvba = b.uv - a.uv; - const float2 uvca = c.uv - a.uv; - - const float3 normal = math::normalize(math::cross(ba, ca)); - const float f = 1.0f / (uvba.x() * uvca.y() - uvca.x() * uvba.y()); - const float3 tangent = (ba * uvca.y() - ca * uvba.y()) * f; - const float3 bitangent = (ba * -uvca.x() + ca * uvba.x()) * f; - - a.normal += normal; - a.tangent += tangent; - a.bitangent += bitangent; - - b.normal += normal; - b.tangent += tangent; - b.bitangent += bitangent; - - c.normal += normal; - c.tangent += tangent; - c.bitangent += bitangent; - }; - - if ((j + i) % 2) - { - add_ntb(a, b, c); - add_ntb(c, b, d); - } - else - { - add_ntb(a, b, d); - add_ntb(a, d, c); - } - } - } - - // Finalize normals, tangents, and bitangent signs of patch vertices - for (std::size_t i = 1; i < patch_vertex_buffer.size() - 1; ++i) - { - for (std::size_t j = 1; j < patch_vertex_buffer[i].size() - 1; ++j) - { - auto& vertex = patch_vertex_buffer[i][j]; - - // Normalize normal - vertex.normal = math::normalize(vertex.normal); - - // Gram-Schmidt orthogonalize tangent - vertex.tangent = math::normalize(vertex.tangent - vertex.normal * math::dot(vertex.normal, vertex.tangent)); - - // Calculate bitangent sign - vertex.bitangent_sign = std::copysign(1.0f, math::dot(math::cross(vertex.normal, vertex.tangent), vertex.bitangent)); - } - } - - /* - - 0 subdivisions: - +---+---+---+ - | | - + +---+ + - | | | | - + +---+ + - | | - +---+---+---+ - - 1 subdivision: - +---+---+---+---+ - | | - + +---+---+ + - | | | | | - + +---+---+ + - | | | | | - + +---+---+ + - | | - +---+---+---+---+ - - 2 subdivisions: - +---+---+---+---+---+ - | | - + +---+---+---+ + - | | | | | | - + +---+---+---+ + - | | | | | | - + +---+---+---+ + - | | | | | | - + +---+---+---+ + - | | - +---+---+---+---+---+ - */ - - // For each row - float* v = patch_vertex_data.data(); - for (std::size_t i = 1; i < patch_vertex_buffer.size() - 2; ++i) - { - // For each column - for (std::size_t j = 1; j < patch_vertex_buffer[i].size() - 2; ++j) - { - // a---c - // | | - // b---d - const patch_vertex& a = patch_vertex_buffer[i ][j]; - const patch_vertex& b = patch_vertex_buffer[i+1][j]; - const patch_vertex& c = patch_vertex_buffer[i ][j+1]; - const patch_vertex& d = patch_vertex_buffer[i+1][j+1]; - - auto add_triangle = [&v](const patch_vertex& a, const patch_vertex& b, const patch_vertex& c) - { - auto add_vertex = [&v](const patch_vertex& vertex, const float3& barycentric) - { - // Position - *(v++) = vertex.position[0]; - *(v++) = vertex.position[1]; - *(v++) = vertex.position[2]; - - // UV - *(v++) = vertex.uv[0]; - *(v++) = vertex.uv[1]; - - // Normal - *(v++) = vertex.normal[0]; - *(v++) = vertex.normal[1]; - *(v++) = vertex.normal[2]; - - /// Tangent - *(v++) = vertex.tangent[0]; - *(v++) = vertex.tangent[1]; - *(v++) = vertex.tangent[2]; - *(v++) = vertex.bitangent_sign; - - // Barycentric - *(v++) = barycentric[0]; - *(v++) = barycentric[1]; - *(v++) = barycentric[2]; - - // Morph target (LOD transition) - *(v++) = 0.0f; - *(v++) = 0.0f; - *(v++) = 0.0f; - }; - - add_vertex(a, float3{1, 0, 0}); - add_vertex(b, float3{0, 1, 0}); - add_vertex(c, float3{0, 0, 1}); - }; - - if ((j + i) % 2) - { - add_triangle(a, b, c); - add_triangle(c, b, d); - } - else - { - add_triangle(a, b, d); - add_triangle(a, d, c); - } - } - } - - /* - - // Allocate patch model - ::render::model* patch_model = new ::render::model(); - - // Get model VBO and VAO - gl::vertex_buffer* vbo = patch_model->get_vertex_buffer(); - gl::vertex_array* vao = patch_model->get_vertex_array(); - - // Resize model VBO and upload vertex data - vbo->resize(patch_triangle_count * 3 * patch_vertex_stride, patch_vertex_data); - - std::size_t attribute_offset = 0; - - // Define position vertex attribute - gl::vertex_attribute position_attribute; - position_attribute.buffer = vbo; - position_attribute.offset = attribute_offset; - position_attribute.stride = patch_vertex_stride; - position_attribute.type = gl::vertex_attribute_type::float_32; - position_attribute.components = 3; - attribute_offset += position_attribute.components * sizeof(float); - - // Define UV vertex attribute - gl::vertex_attribute uv_attribute; - uv_attribute.buffer = vbo; - uv_attribute.offset = attribute_offset; - uv_attribute.stride = patch_vertex_stride; - uv_attribute.type = gl::vertex_attribute_type::float_32; - uv_attribute.components = 2; - attribute_offset += uv_attribute.components * sizeof(float); - - // Define normal vertex attribute - gl::vertex_attribute normal_attribute; - normal_attribute.buffer = vbo; - normal_attribute.offset = attribute_offset; - normal_attribute.stride = patch_vertex_stride; - normal_attribute.type = gl::vertex_attribute_type::float_32; - normal_attribute.components = 3; - attribute_offset += normal_attribute.components * sizeof(float); - - // Define tangent vertex attribute - gl::vertex_attribute tangent_attribute; - tangent_attribute.buffer = vbo; - tangent_attribute.offset = attribute_offset; - tangent_attribute.stride = patch_vertex_stride; - tangent_attribute.type = gl::vertex_attribute_type::float_32; - tangent_attribute.components = 4; - attribute_offset += tangent_attribute.components * sizeof(float); - - // Define barycentric vertex attribute - gl::vertex_attribute barycentric_attribute; - barycentric_attribute.buffer = vbo; - barycentric_attribute.offset = attribute_offset; - barycentric_attribute.stride = patch_vertex_stride; - barycentric_attribute.type = gl::vertex_attribute_type::float_32; - barycentric_attribute.components = 3; - attribute_offset += barycentric_attribute.components * sizeof(float); - - // Define target vertex attribute - gl::vertex_attribute target_attribute; - target_attribute.buffer = vbo; - target_attribute.offset = attribute_offset; - target_attribute.stride = patch_vertex_stride; - target_attribute.type = gl::vertex_attribute_type::float_32; - target_attribute.components = 3; - attribute_offset += target_attribute.components * sizeof(float); - - // Bind vertex attributes to VAO - vao->bind(::render::vertex_attribute::position, position_attribute); - vao->bind(::render::vertex_attribute::uv, uv_attribute); - vao->bind(::render::vertex_attribute::normal, normal_attribute); - vao->bind(::render::vertex_attribute::tangent, tangent_attribute); - vao->bind(::render::vertex_attribute::barycentric, barycentric_attribute); - vao->bind(::render::vertex_attribute::target, target_attribute); - - // Create model group - ::render::model_group* patch_model_group = patch_model->add_group("terrain"); - patch_model_group->set_material(patch_material); - patch_model_group->set_drawing_mode(gl::drawing_mode::triangles); - patch_model_group->set_start_index(0); - patch_model_group->set_index_count(patch_triangle_count * 3); - - // Set patch model bounds - patch_model->set_bounds(patch_bounds); - - return patch_model; - */ - - return nullptr; -} - -terrain_system::patch* terrain_system::generate_patch(quadtree_node_type node) -{ - /* - patch* node_patch = new patch(); - node_patch->mesh = nullptr;//generate_patch_mesh(node); - node_patch->model = generate_patch_model(node); - node_patch->static_mesh = new scene::static_mesh(node_patch->model); - return node_patch; - */ - return nullptr; -} - +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#include "game/systems/terrain-system.hpp" + +terrain_system::terrain_system(entity::registry& registry): + updatable_system(registry) +{} + +terrain_system::~terrain_system() +{} + +void terrain_system::update(float t, float dt) +{ +} diff --git a/src/game/systems/terrain-system.hpp b/src/game/systems/terrain-system.hpp index 62fa178..ecc39d3 100644 --- a/src/game/systems/terrain-system.hpp +++ b/src/game/systems/terrain-system.hpp @@ -1,155 +1,42 @@ -/* - * Copyright (C) 2023 Christopher J. Howard - * - * This file is part of Antkeeper source code. - * - * Antkeeper source code is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Antkeeper source code is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Antkeeper source code. If not, see . - */ - -#ifndef ANTKEEPER_GAME_TERRAIN_SYSTEM_HPP -#define ANTKEEPER_GAME_TERRAIN_SYSTEM_HPP - -#include "game/systems/updatable-system.hpp" -#include "game/components/terrain-component.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/** - * Generates terrain patches and performs terrain patch LOD selection. - */ -class terrain_system: public updatable_system -{ -public: - explicit terrain_system(entity::registry& registry); - ~terrain_system(); - - virtual void update(float t, float dt); - - /** - * Sets the size of a patch. - * - * @param length Side length of a patch. - */ - void set_patch_side_length(float length); - - /** - * Sets the number of subdivisions of a patch. Zero subdivisions results in a single quad, one subdivison results in four quads, etc. - * - * @param n Number of subdivisions. - */ - void set_patch_subdivisions(std::size_t n); - - /** - * Sets the material of each patch. - * - * @param material Patch material. - */ - void set_patch_material(std::shared_ptr<::render::material> material); - - /** - * Sets the terrain elevation function. - * - * @param f Function which returns the terrain height (Y-coordinate) given X- and Z-coordinates. - */ - void set_elevation_function(const std::function& f); - - /** - * Sets the scene collection into which terrain patch model instances will be inserted. - */ - void set_scene_collection(scene::collection* collection); - -private: - typedef geom::unordered_quadtree16 quadtree_type; - typedef typename quadtree_type::node_type quadtree_node_type; - - void balance_quadtree(); - - struct patch - { - geom::mesh* mesh; - ::render::model* model; - scene::static_mesh* static_mesh; - }; - - void on_terrain_construct(entity::registry& registry, entity::id entity_id); - void on_terrain_update(entity::registry& registry, entity::id entity_id); - void on_terrain_destroy(entity::registry& registry, entity::id entity_id); - - float get_patch_size(quadtree_node_type node) const; - float3 get_patch_center(quadtree_node_type node) const; - - void rebuild_patch_base_mesh(); - - /** - * Generates a mesh for a terrain patch given the patch's quadtree node - */ - std::unique_ptr generate_patch_mesh(quadtree_node_type node) const; - - /** - * Generates a model for a terrain patch given the patch's mesh. - */ - ::render::model* generate_patch_model(quadtree_node_type node) const; - - patch* generate_patch(quadtree_node_type node); - - float patch_side_length; - std::size_t patch_subdivisions; - std::size_t patch_cell_count; - std::size_t patch_triangle_count; - std::size_t patch_vertex_size; - std::size_t patch_vertex_stride; - mutable std::vector patch_vertex_data; - - struct patch_vertex - { - float3 position; - float2 uv; - float3 normal; - float3 tangent; - float3 bitangent; - float bitangent_sign; - }; - - mutable std::vector> patch_vertex_buffer; - - - std::shared_ptr<::render::material> patch_material; - std::function elevation_function; - scene::collection* scene_collection; - - std::unique_ptr patch_base_mesh; - - /// Quadtree describing level of detail - quadtree_type quadtree; - float quadtree_node_size[quadtree_type::max_depth + 1]; - quadtree_node_type quadtree_node_resolution[quadtree_type::max_depth + 1]; - - /// Map linking quadtree nodes to terrain patches - std::unordered_map patches; - - std::stack node_stack; -}; - - -#endif // ANTKEEPER_GAME_TERRAIN_SYSTEM_HPP +/* + * Copyright (C) 2023 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_GAME_TERRAIN_SYSTEM_HPP +#define ANTKEEPER_GAME_TERRAIN_SYSTEM_HPP + +#include "game/systems/updatable-system.hpp" +#include "game/components/terrain-component.hpp" +#include + +/** + * Generates terrain patches and performs terrain patch LOD selection. + */ +class terrain_system: public updatable_system +{ +public: + explicit terrain_system(entity::registry& registry); + ~terrain_system(); + + virtual void update(float t, float dt); + +private: + +}; + +#endif // ANTKEEPER_GAME_TERRAIN_SYSTEM_HPP diff --git a/src/game/world.cpp b/src/game/world.cpp index f754804..2e1c9d6 100644 --- a/src/game/world.cpp +++ b/src/game/world.cpp @@ -232,7 +232,7 @@ void create_stars(::game& ctx) float* star_vertex = star_vertex_data.data(); // Init starlight illuminance - double3 starlight_illuminance = {0, 0, 0}; + math::dvec3 starlight_illuminance = {0, 0, 0}; // Build star catalog vertex data for (std::size_t i = 1; i < star_catalog->rows.size(); ++i) @@ -262,16 +262,16 @@ void create_stars(::game& ctx) dec = math::wrap_radians(math::radians(dec)); // Convert ICRF coordinates from spherical to Cartesian - float3 position = physics::orbit::frame::bci::cartesian(float3{1.0f, dec, ra}); + math::fvec3 position = physics::orbit::frame::bci::cartesian(math::fvec3{1.0f, dec, ra}); // Convert color index to color temperature float cct = color::index::bv_to_cct(bv); // Calculate XYZ color from color temperature - float3 color_xyz = color::cct::to_xyz(cct); + math::fvec3 color_xyz = color::cct::to_xyz(cct); // Transform XYZ color to ACEScg colorspace - float3 color_acescg = color::aces::ap1.from_xyz * color_xyz; + math::fvec3 color_acescg = color::aces::ap1.from_xyz * color_xyz; // Convert apparent magnitude to brightness factor relative to a 0th magnitude star float brightness = physics::light::vmag::to_brightness(vmag); @@ -286,7 +286,7 @@ void create_stars(::game& ctx) *(star_vertex++) = brightness; // Calculate spectral illuminance - double3 illuminance = double3(color_acescg * physics::light::vmag::to_illuminance(vmag)); + math::dvec3 illuminance = math::dvec3(color_acescg * physics::light::vmag::to_illuminance(vmag)); // Add spectral illuminance to total starlight illuminance starlight_illuminance += illuminance; @@ -461,15 +461,15 @@ void enter_ecoregion(::game& ctx, const ecoregion& ecoregion) std::for_each ( std::execution::par_unseq, - img.begin>(), - img.end>(), + img.begin>(), + img.end>(), [pixels, width, height, scale_x, scale_y, frequency](auto& pixel) { - const std::size_t i = &pixel - (math::vector*)pixels; + const std::size_t i = &pixel - (math::vec4*)pixels; const std::size_t y = i / width; const std::size_t x = i % width; - const float2 position = + const math::fvec2 position = { static_cast(x) * scale_x, static_cast(y) * scale_y @@ -484,7 +484,7 @@ void enter_ecoregion(::game& ctx, const ecoregion& ecoregion) const float f1_distance = std::sqrt(f1_sqr_distance); - const float2 uv = (position + f1_displacement) / frequency; + const math::fvec2 uv = (position + f1_displacement) / frequency; pixel = { @@ -517,30 +517,30 @@ void enter_ecoregion(::game& ctx, const ecoregion& ecoregion) ctx.ground_pass->set_ground_model(terrestrial_hemisphere_model); // Setup terrain - ctx.terrain_system->set_patch_material(ecoregion.terrain_material); - ctx.terrain_system->set_elevation_function - ( - [](float x, float z) -> float - { - const float2 position = float2{x, z}; + // ctx.terrain_system->set_patch_material(ecoregion.terrain_material); + // ctx.terrain_system->set_elevation_function + // ( + // [](float x, float z) -> float + // { + // const math::fvec2 position = math::fvec2{x, z}; - const std::size_t octaves = 3; - const float lacunarity = 1.5f; - const float gain = 0.5f; + // const std::size_t octaves = 3; + // const float lacunarity = 1.5f; + // const float gain = 0.5f; - const float fbm = math::noise::fbm - ( - position * 0.005f, - octaves, - lacunarity, - gain - ); + // const float fbm = math::noise::fbm + // ( + // position * 0.005f, + // octaves, + // lacunarity, + // gain + // ); - float y = fbm * 4.0f; + // float y = fbm * 4.0f; - return y; - } - ); + // return y; + // } + // ); } debug::log::trace("Entered ecoregion {}", ecoregion.name);