From b372b95ede2765934a00392e90b4c5ad6eb4dba8 Mon Sep 17 00:00:00 2001 From: light7734 Date: Tue, 20 Jan 2026 11:07:35 +0330 Subject: [PATCH] refactor(math): minor qol changes --- modules/math/algebra.cppm | 4 ++- modules/math/vec2.cppm | 47 +++++++++++++++++++++++++------- modules/math/vec3.cppm | 49 ++++++++++++++++++++++++++++++--- modules/math/vec4.cppm | 57 ++++++++++++++++++++++++++++++++++++--- 4 files changed, 139 insertions(+), 18 deletions(-) diff --git a/modules/math/algebra.cppm b/modules/math/algebra.cppm index 5513e8e..ffe8bd8 100644 --- a/modules/math/algebra.cppm +++ b/modules/math/algebra.cppm @@ -1,6 +1,7 @@ export module math.algebra; + +import preliminary; import math.mat4; -import std; export namespace lt::math { @@ -35,6 +36,7 @@ export namespace lt::math { * https://www.youtube.com/watch?v=EqNcqBdrNyI */ template + requires(std::is_arithmetic_v) constexpr auto perspective(T field_of_view, T aspect_ratio, T z_near, T z_far) { const T half_fov_tan = std::tan(field_of_view / static_cast(2)); diff --git a/modules/math/vec2.cppm b/modules/math/vec2.cppm index 125874d..8bc57a1 100644 --- a/modules/math/vec2.cppm +++ b/modules/math/vec2.cppm @@ -5,8 +5,11 @@ import preliminary; namespace lt::math { export template + requires(std::is_arithmetic_v) struct vec2_impl { + static constexpr auto num_elements = 2u; + constexpr vec2_impl(): x(), y() { } @@ -29,15 +32,15 @@ struct vec2_impl return !(*this == other); } - [[nodiscard]] auto operator*(const vec2_impl &other) const -> vec2_impl + [[nodiscard]] constexpr auto operator+(const vec2_impl &other) const -> vec2_impl { return { - x * other.x, - y * other.y, + x + other.x, + y + other.y, }; } - [[nodiscard]] auto operator-(const vec2_impl &other) const -> vec2_impl + [[nodiscard]] constexpr auto operator-(const vec2_impl &other) const -> vec2_impl { return { x - other.x, @@ -45,17 +48,43 @@ struct vec2_impl }; } - [[nodiscard]] auto operator*(f32 scalar) const -> vec2_impl + [[nodiscard]] constexpr auto operator*(const vec2_impl &other) const -> vec2_impl { return { - x * scalar, - y * scalar, + x * other.x, + y * other.y, }; } - T x; // NOLINT + [[nodiscard]] constexpr auto operator/(const vec2_impl &other) const -> vec2_impl + { + return { + x / other.x, + y / other.y, + }; + } - T y; // NOLINT + [[nodiscard]] constexpr auto operator[](u8 idx) -> T & + { + debug_check(idx <= num_elements, "vec2 out of bound: {}", idx); + return ((T *)this)[idx]; + } + + [[nodiscard]] constexpr auto operator[](u8 idx) const -> const T & + { + debug_check(idx < num_elements, "vec2 out of bound: {}", idx); + return ((T *)this)[idx]; + } + + friend auto operator<<(std::ostream &stream, vec2_impl value) -> std::ostream & + { + stream << value.x << ", " << value.y; + return stream; + } + + T x; + + T y; }; diff --git a/modules/math/vec3.cppm b/modules/math/vec3.cppm index 0b13a90..88c4fec 100644 --- a/modules/math/vec3.cppm +++ b/modules/math/vec3.cppm @@ -6,8 +6,11 @@ import math.vec2; namespace lt::math { export template + requires(std::is_arithmetic_v) struct vec3_impl { + static constexpr auto num_elements = 3u; + constexpr vec3_impl(): x(), y(), z() { } @@ -20,6 +23,14 @@ struct vec3_impl { } + constexpr vec3_impl(vec2_impl xy, T z): x(xy.x), y(xy.y), z(z) + { + } + + constexpr vec3_impl(T x, vec2_impl yz): x(x), y(yz.y), z(yz.z) + { + } + [[nodiscard]] auto operator==(const vec3_impl &other) const -> bool { return x == other.x && y == other.y && z == other.z; @@ -30,6 +41,15 @@ struct vec3_impl return !(*this == other); } + [[nodiscard]] constexpr auto operator+(const vec3_impl &other) const -> vec3_impl + { + return { + x + other.x, + y + other.y, + z + other.z, + }; + } + [[nodiscard]] constexpr auto operator-(const vec3_impl &other) const -> vec3_impl { return { @@ -48,17 +68,38 @@ struct vec3_impl }; } + [[nodiscard]] constexpr auto operator/(const vec3_impl &other) const -> vec3_impl + { + return { + x / other.x, + y / other.y, + z / other.z, + }; + } + + [[nodiscard]] constexpr auto operator[](u8 idx) -> T & + { + debug_check(idx <= num_elements, "vec3 out of bound: {}", idx); + return ((T *)this)[idx]; + } + + [[nodiscard]] constexpr auto operator[](u8 idx) const -> const T & + { + debug_check(idx < num_elements, "vec3 out of bound: {}", idx); + return ((T *)this)[idx]; + } + friend auto operator<<(std::ostream &stream, vec3_impl value) -> std::ostream & { stream << value.x << ", " << value.y << ", " << value.z; return stream; } - T x; // NOLINT + T x; - T y; // NOLINT + T y; - T z; // NOLINT + T z; }; export using vec3 = vec3_impl; @@ -69,7 +110,7 @@ export using uvec3 = vec3_impl; } // namespace lt::math -template +export template struct std::formatter> { constexpr auto parse(std::format_parse_context &context) diff --git a/modules/math/vec4.cppm b/modules/math/vec4.cppm index ee59164..83e2d02 100644 --- a/modules/math/vec4.cppm +++ b/modules/math/vec4.cppm @@ -7,6 +7,7 @@ import math.vec3; namespace lt::math { export template + requires(std::is_arithmetic_v) struct vec4_impl { static constexpr auto num_elements = 4u; @@ -23,6 +24,26 @@ struct vec4_impl { } + constexpr vec4_impl(vec2_impl xy, T z, T w): x(xy.x), y(xy.y), z(z), w(w) + { + } + + constexpr vec4_impl(T x, T y, vec2_impl zw): x(x), y(y), z(zw.z), w(zw.w) + { + } + + constexpr vec4_impl(vec2_impl xy, vec2_impl zw): x(xy.x), y(xy.y), z(zw.z), w(zw.w) + { + } + + constexpr vec4_impl(vec3_impl xyz, T w): x(xyz.x), y(xyz.y), z(xyz.z), w(w) + { + } + + constexpr vec4_impl(T x, vec3_impl yzw): x(x), y(yzw.y), z(yzw.z), w(yzw.w) + { + } + [[nodiscard]] auto operator==(const vec4_impl &other) const -> bool { return x == other.x && y == other.y && z == other.z && w == other.w; @@ -33,6 +54,16 @@ struct vec4_impl return !(*this == other); } + [[nodiscard]] constexpr auto operator+(const vec4_impl &other) const -> vec4_impl + { + return { + x + other.x, + y + other.y, + z + other.z, + w + other.w, + }; + } + [[nodiscard]] constexpr auto operator-(const vec4_impl &other) const -> vec4_impl { return { @@ -43,17 +74,35 @@ struct vec4_impl }; } + [[nodiscard]] constexpr auto operator*(const vec4_impl &other) const -> vec4_impl + { + return { + x * other.x, + y * other.y, + z * other.z, + w * other.w, + }; + } + + [[nodiscard]] constexpr auto operator/(const vec4_impl &other) const -> vec4_impl + { + return { + x / other.x, + y / other.y, + z / other.z, + w / other.w, + }; + } + [[nodiscard]] constexpr auto operator[](u8 idx) -> T & { - // TODO(Light): Use contract - ensure(idx <= num_elements, "vec4 out of bound: {}", idx); + debug_check(idx <= num_elements, "vec4 out of bound: {}", idx); return ((T *)this)[idx]; } [[nodiscard]] constexpr auto operator[](u8 idx) const -> const T & { - // TODO(Light): Use contract - ensure(idx < num_elements, "vec4 out of bound: {}", idx); + debug_check(idx < num_elements, "vec4 out of bound: {}", idx); return ((T *)this)[idx]; }