refactor(math): minor qol changes

This commit is contained in:
light7734 2026-01-20 11:07:35 +03:30
parent 985a4414d7
commit b372b95ede
4 changed files with 139 additions and 18 deletions

View file

@ -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<typename T>
requires(std::is_arithmetic_v<T>)
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<T>(2));

View file

@ -5,8 +5,11 @@ import preliminary;
namespace lt::math {
export template<typename T = f32>
requires(std::is_arithmetic_v<T>)
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<T> &other) const -> vec2_impl
[[nodiscard]] constexpr auto operator+(const vec2_impl<T> &other) const -> vec2_impl
{
return {
x * other.x,
y * other.y,
x + other.x,
y + other.y,
};
}
[[nodiscard]] auto operator-(const vec2_impl<T> &other) const -> vec2_impl
[[nodiscard]] constexpr auto operator-(const vec2_impl<T> &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<T> &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<T> &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<T> value) -> std::ostream &
{
stream << value.x << ", " << value.y;
return stream;
}
T x;
T y;
};

View file

@ -6,8 +6,11 @@ import math.vec2;
namespace lt::math {
export template<typename T = f32>
requires(std::is_arithmetic_v<T>)
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<T> xy, T z): x(xy.x), y(xy.y), z(z)
{
}
constexpr vec3_impl(T x, vec2_impl<T> yz): x(x), y(yz.y), z(yz.z)
{
}
[[nodiscard]] auto operator==(const vec3_impl<T> &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<T> &other) const -> vec3_impl
{
return {
x + other.x,
y + other.y,
z + other.z,
};
}
[[nodiscard]] constexpr auto operator-(const vec3_impl<T> &other) const -> vec3_impl
{
return {
@ -48,17 +68,38 @@ struct vec3_impl
};
}
[[nodiscard]] constexpr auto operator/(const vec3_impl<T> &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<T> 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<f32>;
@ -69,7 +110,7 @@ export using uvec3 = vec3_impl<u32>;
} // namespace lt::math
template<typename T>
export template<typename T>
struct std::formatter<lt::math::vec3_impl<T>>
{
constexpr auto parse(std::format_parse_context &context)

View file

@ -7,6 +7,7 @@ import math.vec3;
namespace lt::math {
export template<typename T = f32>
requires(std::is_arithmetic_v<T>)
struct vec4_impl
{
static constexpr auto num_elements = 4u;
@ -23,6 +24,26 @@ struct vec4_impl
{
}
constexpr vec4_impl(vec2_impl<T> xy, T z, T w): x(xy.x), y(xy.y), z(z), w(w)
{
}
constexpr vec4_impl(T x, T y, vec2_impl<T> zw): x(x), y(y), z(zw.z), w(zw.w)
{
}
constexpr vec4_impl(vec2_impl<T> xy, vec2_impl<T> zw): x(xy.x), y(xy.y), z(zw.z), w(zw.w)
{
}
constexpr vec4_impl(vec3_impl<T> xyz, T w): x(xyz.x), y(xyz.y), z(xyz.z), w(w)
{
}
constexpr vec4_impl(T x, vec3_impl<T> yzw): x(x), y(yzw.y), z(yzw.z), w(yzw.w)
{
}
[[nodiscard]] auto operator==(const vec4_impl<T> &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<T> &other) const -> vec4_impl
{
return {
x + other.x,
y + other.y,
z + other.z,
w + other.w,
};
}
[[nodiscard]] constexpr auto operator-(const vec4_impl<T> &other) const -> vec4_impl
{
return {
@ -43,17 +74,35 @@ struct vec4_impl
};
}
[[nodiscard]] constexpr auto operator*(const vec4_impl<T> &other) const -> vec4_impl
{
return {
x * other.x,
y * other.y,
z * other.z,
w * other.w,
};
}
[[nodiscard]] constexpr auto operator/(const vec4_impl<T> &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];
}