From 72c9ab61529788ae55366d8a32161b61840abdd0 Mon Sep 17 00:00:00 2001 From: Rinzii Date: Wed, 1 Nov 2023 11:26:16 -0400 Subject: [PATCH] implement all free and member functions for our vectors --- include/mim/detail/func/func_vector1.inl | 54 ++++++ include/mim/detail/func/func_vector2.inl | 124 ++++++++++++- include/mim/detail/func/func_vector3.inl | 188 ++++++++++++++++++-- include/mim/detail/func/func_vector4.inl | 88 +++++++++ include/mim/detail/type/type_quaternion.hpp | 1 - include/mim/detail/type/type_vector1.hpp | 53 ++++-- include/mim/detail/type/type_vector2.hpp | 77 ++++++-- include/mim/detail/type/type_vector2.inl | 2 - include/mim/detail/type/type_vector3.hpp | 81 +++++++-- include/mim/detail/type/type_vector3.inl | 1 - include/mim/detail/type/type_vector4.hpp | 54 ++++-- include/mim/detail/type/type_vector4.inl | 1 - 12 files changed, 637 insertions(+), 87 deletions(-) diff --git a/include/mim/detail/func/func_vector1.inl b/include/mim/detail/func/func_vector1.inl index 85de9bb..99dbfad 100644 --- a/include/mim/detail/func/func_vector1.inl +++ b/include/mim/detail/func/func_vector1.inl @@ -7,6 +7,7 @@ namespace mim { + /// Member Functions template constexpr T vec<1, T>::length() const @@ -68,9 +69,62 @@ namespace mim return (x - v.x) * (x - v.x); } + template + constexpr vec<1, T> vec<1, T>::hadamard(const vec<1, T> & v) const + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return this->x * v.x; + } + + /// Free functions + + template + constexpr T length(vec<1, T> const& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length() on a non-arithmetic vector."); + return v.length(); + } + + template + constexpr T length_squared(vec<1, T> const& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length_squared() on a non-arithmetic vector."); + return v.length_squared(); + } + + template + constexpr vec<1, T> normalized(vec<1, T> const& v) + { + static_assert(std::is_floating_point::value, "Cannot normalize a non-floating-point vector."); + return v.normalized(); + } + template + constexpr bool is_normalized(vec<1, T> const& v) + { + static_assert(std::is_floating_point::value, "Cannot normalize a non-floating-point vector."); + return v.is_normalized(); + } + template + constexpr T distance(vec<1, T> const& v1, vec<1, T> const& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance() on a non-arithmetic vector."); + return v1.distance(v2); + } + template + constexpr T distance_squared(vec<1, T> const& v1, vec<1, T> const& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance_squared() on a non-arithmetic vector."); + return v1.distance_squared(v2); + } + template + constexpr vec<1, T> hadamard(vec<1, T> const& v1, vec<1, T> const& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return v1.hadamard(v2); + } } diff --git a/include/mim/detail/func/func_vector2.inl b/include/mim/detail/func/func_vector2.inl index c24bcc4..708ea40 100644 --- a/include/mim/detail/func/func_vector2.inl +++ b/include/mim/detail/func/func_vector2.inl @@ -7,6 +7,7 @@ namespace mim { + /// Member Functions template constexpr T vec<2, T>::length() const @@ -69,9 +70,6 @@ namespace mim return (x - v.x) * (x - v.x) + (y - v.y) * (y - v.y); } - - /// Functions - template constexpr T vec<2, T>::dot(const vec<2, T>& v) const { @@ -79,6 +77,24 @@ namespace mim return x * v.x + y * v.y; } + template + constexpr vec<2, T> vec<2, T>::cross(const vec<2, T>& v) const + { + static_assert(std::is_arithmetic::value, "Cannot use the cross product on a non-arithmetic vector."); + + // Mathematically a cross product is normally only valid for 3D vectors. + // However, we can still compute a cross product for 2D vectors using the wedge product. + // This is particularly useful for game development thus we allow it. + return vec<2, T>(this->x * v.y - this->y * v.x); + } + + template + constexpr vec<2, T> vec<2, T>::hadamard(const vec<2, T>& v) const + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return vec<2, T>(x * v.x, y * v.y); + } + // TODO: Implement rotate()? // TODO: Make this constexpr once sine and cosine are constexpr. @@ -132,4 +148,106 @@ namespace mim } + /// Free functions + + template + constexpr T length(const vec<2, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length() on a non-arithmetic vector."); + return v.length(); + } + + template + constexpr T length_squared(const vec<2, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length_squared() on a non-arithmetic vector."); + return v.length_squared(); + } + + template + constexpr vec<2, T> normalized(const vec<2, T>& v) + { + static_assert(std::is_floating_point::value, "Cannot normalize a non-floating-point vector."); + return v.normalized(); + } + + template + constexpr bool is_normalized(const vec<2, T>& v) + { + static_assert(std::is_floating_point::value, "Cannot normalize a non-floating-point vector."); + return v.is_normalized(); + } + + template + constexpr T distance(const vec<2, T>& v1, const vec<2, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance() on a non-arithmetic vector."); + return v1.distance(v2); + } + + template + constexpr T distance_squared(const vec<2, T>& v1, const vec<2, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance_squared() on a non-arithmetic vector."); + return v1.distance_squared(v2); + } + + template + constexpr T dot(const vec<2, T>& v1, const vec<2, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use the dot product on a non-arithmetic vector."); + return v1.dot(v2); + } + + template + constexpr vec<2, T> cross(const vec<2, T>& v1, const vec<2, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use the cross product on a non-arithmetic vector."); + return v1.cross(v2); + } + + template + constexpr vec<2, T> hadamard(const vec<2, T>& v1, const vec<2, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return v1.hadamard(v2); + } + + template + constexpr vec<2, T> rotated(const vec<2, T>& v, T angle) + { + static_assert(std::is_arithmetic::value, "Cannot rotate a non-arithmetic vector."); + return v.rotated(angle); + } + + template + constexpr vec<2, T> clamp(const vec<2, T>& v, const vec<2, T>& min, const vec<2, T>& max) + { + static_assert(std::is_arithmetic::value, "Cannot use clamp() on a non-arithmetic vector."); + return v.clamp(min, max); + } + + template + constexpr vec<2, T> reflect(const vec<2, T>& v, const vec<2, T>& normal) + { + static_assert(std::is_arithmetic::value, "Cannot use reflect() on a non-arithmetic vector."); + return v.reflect(normal); + } + + template + constexpr vec<2, T> refract(const vec<2, T>& v, const vec<2, T>& normal, T eta) + { + static_assert(std::is_arithmetic::value, "Cannot use refract() on a non-arithmetic vector."); + return v.refract(normal, eta); + } + + template + constexpr vec<2, T> project(const vec<2, T>& v, const vec<2, T>& to) + { + static_assert(std::is_arithmetic::value, "Cannot use project() on a non-arithmetic vector."); + return v.project(to); + } + + + } diff --git a/include/mim/detail/func/func_vector3.inl b/include/mim/detail/func/func_vector3.inl index 784c9ed..04b96ff 100644 --- a/include/mim/detail/func/func_vector3.inl +++ b/include/mim/detail/func/func_vector3.inl @@ -11,6 +11,13 @@ namespace mim /// Member functions + template + constexpr vec<3, T> vec<3, T>::inverse() const + { + static_assert(std::is_floating_point::value, "Cannot use inverse() on a non-floating-point vector."); + return vec<3, T>(T{ 1 } / x, T{ 1 } / y, T{ 1 } / z); + } + template constexpr T vec<3, T>::length() const { @@ -76,29 +83,82 @@ namespace mim template constexpr T vec<3, T>::dot(const vec<3, T>& v) const { + static_assert(std::is_arithmetic::value, "Cannot use the dot product on a non-arithmetic vector."); return x * v.x + y * v.y + z * v.z; } template - constexpr T vec<3, T>::cross(const vec<3, T>& v) const + constexpr vec<3, T> vec<3, T>::cross(const vec<3, T>& v) const { - static_assert(std::is_arithmetic::value, "Cannot use the dot product on a non-arithmetic vector."); - return x * v.y - y * v.x - z * v.z; + static_assert(std::is_floating_point::value, "Cannot use the cross product on a non-floating-point vector."); + return vec<3, T>( + x.y * y.z - y.y * x.z, + x.z * y.x - y.z * x.x, + x.x * y.y - y.x * x.y + ); } template - constexpr void vec<3, T>::rotate(T angle) + constexpr vec<3, T> vec<3, T>::hadamard(const vec<3, T>& v) const { - // This may require floats only instead of all arithmetic types. - static_assert(std::is_arithmetic::value, "Cannot rotate a non-arithmetic vector."); - // TODO: Implement rotation of a vec3 using Euler angles. + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return vec<3, T>(x * v.x, y * v.y, z * v.z); + } + template + constexpr void vec<3, T>::rotate(const vec<3, T>& axis, T angle) + { + static_assert(std::is_floating_point::value, "Cannot rotate a non-floating-point vector."); + + // Rotation matrix from https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle + + // The provided axis must be normalized. + // TODO: Maybe add in a means to tell the function the axis is already normalized? + axis.normalize(); + + // the unit matrix will become the rotational matrix + vec<3, T> unitMatrix[3] = { + vec<3, T>(1, 0, 0), + vec<3, T>(0, 1, 0), + vec<3, T>(0, 0, 1) + }; + + vec<3, T> axisSqr(axis.x * axis.x, axis.y * axis.y, axis.z * axis.z); + T cosAngle = std::cos(angle); + + unitMatrix[0][0] = axisSqr.x + (1 - axisSqr.x) * cosAngle; + unitMatrix[1][1] = axisSqr.y + (1 - axisSqr.y) * cosAngle; + unitMatrix[2][2] = axisSqr.z + (1 - axisSqr.z) * cosAngle; + + T sinAngle = std::sin(angle); + T t = 1 - cosAngle; + + T xyzt = axis.x * axis.y * t; + T zyxs = axis.z * sinAngle; + unitMatrix[0][1] = xyzt - zyxs; + unitMatrix[1][0] = xyzt + zyxs; + + xyzt = axis.x * axis.z * t; + zyxs = axis.y * sinAngle; + unitMatrix[0][2] = xyzt + zyxs; + unitMatrix[2][0] = xyzt - zyxs; + + xyzt = axis.y * axis.z * t; + zyxs = axis.x * sinAngle; + unitMatrix[1][2] = xyzt - zyxs; + unitMatrix[2][1] = xyzt + zyxs; + + *this = vec<3, T>( + unitMatrix[0].dot(*this), + unitMatrix[1].dot(*this), + unitMatrix[2].dot(*this) + ); } template constexpr vec<3, T> vec<3, T>::rotated(T angle) const { - static_assert(std::is_arithmetic::value, "Cannot rotate a non-arithmetic vector."); + static_assert(std::is_floating_point::value, "Cannot rotate a non-floating-point vector."); vec<3, T> v = *this; v.rotate(angle); return v; @@ -149,17 +209,66 @@ namespace mim } template - constexpr vec<3, T> vec<3, T>::project(const vec<3, T>& to) const + constexpr vec<3, T> vec<3, T>::project(const vec<3, T>& normal) const { static_assert(std::is_arithmetic::value, "Cannot use project() on a non-arithmetic vector."); // TODO: Validate this function. - return to * (this->dot(to) / to.length_squared()); + return normal * (this->dot(normal) / normal.length_squared()); } /// Free functions + template + constexpr vec<3, T> inverse(const vec<3, T>& v) + { + static_assert(std::is_floating_point::value, "Cannot use inverse() on a non-floating-point vector."); + return vec<3, T>(T{ 1 } / v.x, T{ 1 } / v.y, T{ 1 } / v.z); + } + + template + constexpr T length(const vec<3, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length() on a non-arithmetic vector."); + return v.length(); + } + + template + constexpr T length_squared(const vec<3, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length_squared() on a non-arithmetic vector."); + return v.length_squared(); + } + + template + constexpr vec<3, T> normalized(const vec<3, T>& v) + { + static_assert(std::is_floating_point::value, "Cannot normalize a non-floating-point vector."); + return v.normalized(); + } + + template + constexpr bool is_normalized(const vec<3, T>& v) + { + static_assert(std::is_floating_point::value, "Cannot normalize a non-floating-point vector."); + return v.is_normalized(); + } + + template + constexpr vec<3, T> distance(const vec<3, T>& v1, const vec<3, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance() on a non-arithmetic vector."); + return v1.distance(v2); + } + + template + constexpr vec<3, T> distance_squared(const vec<3, T>& v1, const vec<3, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance_squared() on a non-arithmetic vector."); + return v1.distance_squared(v2); + } + template constexpr vec<3, T> dot(const vec<3, T>& v1, const vec<3, T>& v2) { @@ -171,17 +280,58 @@ namespace mim constexpr vec<3, T> cross(const vec<3, T>& v1, const vec<3, T>& v2) { static_assert(std::is_arithmetic::value, "Cannot use the cross product on a non-arithmetic vector."); - return vec<3, T>( - (v1.y * v2.z) - (v1.z * v2.y), - -((v1.x * v2.z) - (v1.z * v2.x)), - (v1.x * v2.y) - (v1.y * v2.x) + return vec<3, T>( + v1.y * v2.z - v2.y * v1.z, + v1.z * v2.x - v2.z * v1.x, + v1.x * v2.y - v2.x * v1.y ); + } template - constexpr vec<3, T> inverse(const vec<3, T>& v) - { - static_assert(std::is_floating_point::value, "Cannot use inverse() on a non-floating-point vector."); - return vec<3, T>(T{ 1 } / v.x, T{ 1 } / v.y, T{ 1 } / v.z); - } + constexpr vec<3, T> hadamard(const vec<3, T>& v1, const vec<3, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return vec<3, T>(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); + } + + template + constexpr vec<3, T> rotated(const vec<3, T>& v, T angle) + { + static_assert(std::is_floating_point::value, "Cannot rotate a non-floating-point vector."); + return v.rotated(angle); + } + + template + constexpr vec<3, T> clamp(const vec<3, T>& v, const vec<3, T>& min, const vec<3, T>& max) + { + static_assert(std::is_arithmetic::value, "Cannot use clamp() on a non-arithmetic vector."); + return vec<3, T>( + ::mim::math::clamp(v.x, min.x, max.x), + ::mim::math::clamp(v.y, min.y, max.y), + ::mim::math::clamp(v.z, min.z, max.z) + ); + } + + template + constexpr vec<3, T> reflect(const vec<3, T>& v, const vec<3, T>& normal) + { + static_assert(std::is_arithmetic::value, "Cannot use reflect() on a non-arithmetic vector."); + return v.reflect(normal); + } + + template + constexpr vec<3, T> refract(const vec<3, T>& v, const vec<3, T>& normal, T eta) + { + static_assert(std::is_arithmetic::value, "Cannot use refract() on a non-arithmetic vector."); + return v.refract(normal, eta); + } + + template + constexpr vec<3, T> project(const vec<3, T>& v, const vec<3, T>& normal) + { + static_assert(std::is_arithmetic::value, "Cannot use project() on a non-arithmetic vector."); + return v.project(normal); + } + } diff --git a/include/mim/detail/func/func_vector4.inl b/include/mim/detail/func/func_vector4.inl index 27df7e0..ba2e8fb 100644 --- a/include/mim/detail/func/func_vector4.inl +++ b/include/mim/detail/func/func_vector4.inl @@ -5,6 +5,8 @@ namespace mim { + /// Member Functions + template constexpr T vec<4, T>::length() const { @@ -68,4 +70,90 @@ namespace mim return (x - v.x) * (x - v.x) + (y - v.y) * (y - v.y) + (z - v.z) * (z - v.z) + (w - v.w) * (w - v.w); } + template + constexpr T vec<4, T>::dot(const vec<4, T>& v) const + { + static_assert(std::is_arithmetic::value, "Cannot use dot() on a non-arithmetic vector."); + return x * v.x + y * v.y + z * v.z + w * v.w; + } + + template + constexpr vec<4, T> vec<4, T>::hadamard(const vec<4, T>& v) const + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return vec<4, T>(x * v.x, y * v.y, z * v.z, w * v.w); + } + + template + constexpr vec<4, T> vec<4, T>::clamp(const vec<4, T> & min, const vec<4, T> & max) const + { + static_assert(std::is_arithmetic::value, "Cannot use clamp() on a non-arithmetic vector."); + return vec<4, T>( + ::mim::math::clamp(x, min.x, max.x), + ::mim::math::clamp(y, min.y, max.y), + ::mim::math::clamp(z, min.z, max.z), + ::mim::math::clamp(w, min.w, max.w) + ); + } + + + /// Free functions + + template + constexpr T length(const vec<4, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length() on a non-arithmetic vector."); + return v.length(); + } + + template + constexpr T length_squared(const vec<4, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use length_squared() on a non-arithmetic vector."); + return v.length_squared(); + } + + template + constexpr vec<4, T> normalized(const vec<4, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use normalized() on a non-arithmetic vector."); + return v.normalized(); + } + + template + MIM_NODISCARD constexpr bool is_normalized(const vec<4, T>& v) + { + static_assert(std::is_arithmetic::value, "Cannot use is_normalized() on a non-arithmetic vector."); + return v.is_normalized(); + } + + template + constexpr T distance(const vec<4, T>& v1, const vec<4, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance() on a non-arithmetic vector."); + return v1.distance(v2); + } + + template + constexpr T distance_squared(const vec<4, T>& v1, const vec<4, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use distance_squared() on a non-arithmetic vector."); + return v1.distance_squared(v2); + } + + template + constexpr T dot(const vec<4, T>& v1, const vec<4, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use dot() on a non-arithmetic vector."); + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w; + } + + template + constexpr vec<4, T> hadamard(const vec<4, T>& v1, const vec<4, T>& v2) + { + static_assert(std::is_arithmetic::value, "Cannot use hadamard() on a non-arithmetic vector."); + return vec<4, T>(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w); + } + + } diff --git a/include/mim/detail/type/type_quaternion.hpp b/include/mim/detail/type/type_quaternion.hpp index 334043f..ad8b71c 100644 --- a/include/mim/detail/type/type_quaternion.hpp +++ b/include/mim/detail/type/type_quaternion.hpp @@ -2,7 +2,6 @@ #pragma once -#include "mim/detail/compute/compute_quaternion.hpp" #include "mim/detail/defines.hpp" namespace mim diff --git a/include/mim/detail/type/type_vector1.hpp b/include/mim/detail/type/type_vector1.hpp index 410a71a..61cb226 100644 --- a/include/mim/detail/type/type_vector1.hpp +++ b/include/mim/detail/type/type_vector1.hpp @@ -14,17 +14,17 @@ namespace mim { template struct vec<1, T> { - /// Aliases + // Aliases using value_type = T; using type = vec<1, T>; using size_type = size_t; static constexpr auto size_v = 1; - /// Data + // Data T x; - /// Element Accessors + // Element Accessors static constexpr std::size_t size() { return size_v; } @@ -37,7 +37,7 @@ namespace mim const T& at(std::size_t i) const; - /// Constructors + // Constructors constexpr vec(); @@ -45,7 +45,7 @@ namespace mim constexpr explicit vec(T scalar); - /// Template Constructors + // Template Constructors template constexpr explicit vec(U scalar); @@ -62,7 +62,7 @@ namespace mim template constexpr explicit vec(vec<4, U> const& v); - /// Assignment Operators + // Assignment Operators constexpr vec<1, T>& operator=(T scalar); @@ -146,7 +146,7 @@ namespace mim template constexpr vec<1, T>& operator%=(vec<1, U> const& v); - /// Increment and Decrement Operators + // Increment and Decrement Operators constexpr vec<1, T>& operator++(); @@ -156,7 +156,7 @@ namespace mim constexpr const vec<1, T> operator--(int); - /// Bitwise Assignment Operators + // Bitwise Assignment Operators template constexpr vec<1, T>& operator&=(U scalar); @@ -189,7 +189,7 @@ namespace mim constexpr vec<1, T>& operator>>=(vec<1, U> const& v); - /// Function Declarations + // Function Declarations constexpr T length() const; @@ -205,11 +205,15 @@ namespace mim constexpr T distance_squared(const vec<1, T>& v) const; + constexpr vec<1, T> hadamard(const vec<1, T>& v) const; + }; - /// Unary Operators + /// Free operators + + // Unary Operators template constexpr vec<1, T> operator+(vec<1, T> const& v); @@ -217,7 +221,7 @@ namespace mim template constexpr vec<1, T> operator-(vec<1, T> const& v); - /// Binary Operators + // Binary Operators template constexpr vec<1, T> operator+(vec<1, T> const& v, T scalar); @@ -264,7 +268,7 @@ namespace mim template constexpr vec<1, T> operator%(vec<1, T> const& v1, vec<1, T> const& v2); - /// Bitwise Binary Operators + // Bitwise Binary Operators template constexpr vec<1, T> operator&(vec<1, T> const& v, T scalar); @@ -314,7 +318,7 @@ namespace mim template constexpr vec<1, T> operator~(vec<1, T> const& v); - /// Comparison Operators + // Comparison Operators template constexpr bool operator==(vec<1, T> const& v1, vec<1, T> const& v2); @@ -327,6 +331,29 @@ namespace mim constexpr vec<1, bool> operator||(vec<1, bool> const& v1, vec<1, bool> const& v2); + /// Free functions + + template + constexpr T length(vec<1, T> const& v); + + template + constexpr T length_squared(vec<1, T> const& v); + + template + constexpr vec<1, T> normalized(vec<1, T> const& v); + + template + MIM_NODISCARD constexpr bool is_normalized(vec<1, T> const& v); + + template + constexpr T distance(vec<1, T> const& v1, vec<1, T> const& v2); + + template + constexpr T distance_squared(vec<1, T> const& v1, vec<1, T> const& v2); + + template + constexpr vec<1, T> hadamard(vec<1, T> const& v1, vec<1, T> const& v2); + } // namespace mim #include "mim/detail/type/type_vector1.inl" diff --git a/include/mim/detail/type/type_vector2.hpp b/include/mim/detail/type/type_vector2.hpp index bfaa9c2..bd69136 100644 --- a/include/mim/detail/type/type_vector2.hpp +++ b/include/mim/detail/type/type_vector2.hpp @@ -30,9 +30,7 @@ namespace mim const T& at(std::size_t i) const; - // Many of these constructors use as reference section 5.4.1 of the GLSL 1.30.08 specification - - /// Constructors + // Constructors constexpr vec(); @@ -42,7 +40,7 @@ namespace mim constexpr explicit vec(T scalar); - /// U Template Constructors + // U Template Constructors template constexpr explicit vec(vec<1, U> const& scalar); @@ -56,7 +54,7 @@ namespace mim template constexpr explicit vec(vec<4, U> const& v); - /// AB Template Constructors + // AB Template Constructors template constexpr explicit vec(A _x, B _y); @@ -70,7 +68,7 @@ namespace mim template constexpr vec(vec<1, A> const& _x, vec<1, B> const& _y); - /// Assignment Operators + // Assignment Operators constexpr vec<2, T>& operator=(T scalar); @@ -127,7 +125,7 @@ namespace mim template constexpr vec<2, T>& operator%=(vec<2, U> const& v); - /// Increment and Decrement Operators + // Increment and Decrement Operators constexpr vec<2, T>& operator++(); @@ -137,7 +135,7 @@ namespace mim constexpr const vec<2, T> operator--(int); - /// Bitwise Assignment Operators + // Bitwise Assignment Operators template constexpr vec<2, T>& operator&=(U scalar); @@ -185,7 +183,7 @@ namespace mim constexpr vec<2, T>& operator>>=(vec<2, U> const& v); - /// Generic Function Declarations + // Function Declarations constexpr T length() const; @@ -201,10 +199,11 @@ namespace mim constexpr T distance_squared(const vec<2, T>& v) const; + constexpr T dot(const vec<2, T>& v) const; - /// Function Declarations + constexpr vec<2, T> cross(const vec<2, T>& v) const; - constexpr T dot(const vec<2, T>& v) const; + constexpr vec<2, T> hadamard(const vec<2, T>& v) const; vec<2, T> rotated(T angle) const; @@ -217,7 +216,9 @@ namespace mim constexpr vec<2, T> project(const vec<2, T>& to) const; }; - /// Unary Operators + /// Free operators + + // Unary Operators template constexpr vec<2, T> operator+(vec<2, T> const& v); @@ -225,7 +226,7 @@ namespace mim template constexpr vec<2, T> operator-(vec<2, T> const& v); - /// Binary Operators + // Binary Operators // TODO: Decide if we should allow scalar operations on vec2 using vec3-4 template @@ -303,7 +304,7 @@ namespace mim template constexpr vec<2, T> operator%(vec<2, T> const& v1, vec<1, T> const& v); - /// Bitwise Binary Operators + // Bitwise Binary Operators // TODO: Decide if we should allow bitwise operations on vec2 using vec3-4 template @@ -384,7 +385,7 @@ namespace mim template constexpr vec<2, T> operator~(vec<2, T> const& v); - /// Conditional operators + // Conditional operators template constexpr bool operator==(vec<2, T> const& v1, vec<2, T> const& v2); @@ -396,6 +397,52 @@ namespace mim constexpr vec<2, bool> operator||(vec<2, bool> const& v1, vec<2, bool> const& v2); + /// Free functions + + template + constexpr T length(const vec<2, T>& v); + + template + constexpr T length_squared(const vec<2, T>& v); + + template + constexpr vec<2, T> normalized(const vec<2, T>& v); + + template + MIM_NODISCARD constexpr bool is_normalized(const vec<2, T>& v); + + template + constexpr T distance(const vec<2, T>& v1, const vec<2, T>& v2); + + template + constexpr T distance_squared(const vec<2, T>& v1, const vec<2, T>& v2); + + template + constexpr T dot(const vec<2, T>& v1, const vec<2, T>& v2); + + template + constexpr vec<2, T> cross(const vec<2, T>& v1, const vec<2, T>& v2); + + template + constexpr vec<2, T> hadamard(const vec<2, T>& v1, const vec<2, T>& v2); + + template + constexpr vec<2, T> rotated(const vec<2, T>& v, T angle); + + template + constexpr vec<2, T> clamp(const vec<2, T>& v, const vec<2, T>& min, const vec<2, T>& max); + + template + constexpr vec<2, T> reflect(const vec<2, T>& v, const vec<2, T>& normal); + + template + constexpr vec<2, T> refract(const vec<2, T>& v, const vec<2, T>& normal, T eta); + + template + constexpr vec<2, T> project(const vec<2, T>& v, const vec<2, T>& to); + + + } // namespace mim diff --git a/include/mim/detail/type/type_vector2.inl b/include/mim/detail/type/type_vector2.inl index c035a71..9f7bdcd 100644 --- a/include/mim/detail/type/type_vector2.inl +++ b/include/mim/detail/type/type_vector2.inl @@ -1,7 +1,5 @@ // Copyright (c) 2023-Present Mim contributors (see LICENSE) -#include "mim/detail/compute/compute_vector.hpp" - namespace mim { diff --git a/include/mim/detail/type/type_vector3.hpp b/include/mim/detail/type/type_vector3.hpp index a00fbd5..3696232 100644 --- a/include/mim/detail/type/type_vector3.hpp +++ b/include/mim/detail/type/type_vector3.hpp @@ -22,9 +22,7 @@ namespace mim constexpr T& operator[](size_type i); constexpr T const& operator[](size_type i) const; - // Many of these constructors use as reference section 5.4.1 of the GLSL 1.30.08 specification - - /// Constructors + // Constructors constexpr vec(); @@ -34,7 +32,7 @@ namespace mim constexpr explicit vec(T scalar); - /// U Template Constructors + // U Template Constructors template constexpr explicit vec(vec<1, U> const& scalar); @@ -42,7 +40,7 @@ namespace mim template constexpr explicit vec(vec<3, U> const& v); - /// XYZ Template Constructors + // XYZ Template Constructors template constexpr vec(X _x, Y _y, Z _z); @@ -82,7 +80,7 @@ namespace mim template constexpr vec(vec<1, A> const& _x, vec<2, B> const& _yz); - /// Assignment Operators + // Assignment Operators constexpr vec<3, T>& operator=(T scalar); @@ -139,7 +137,7 @@ namespace mim template constexpr vec<3, T>& operator%=(vec<3, U> const& v); - /// Increment and Decrement Operators + // Increment and Decrement Operators constexpr vec<3, T>& operator++(); @@ -149,7 +147,7 @@ namespace mim constexpr const vec<3, T> operator--(int); - /// Bitwise Assignment Operators + // Bitwise Assignment Operators template constexpr vec<3, T>& operator&=(U scalar); @@ -197,7 +195,9 @@ namespace mim constexpr vec<3, T>& operator>>=(vec<3, U> const& v); - /// Generic Function Declarations + // Function Declarations + + constexpr vec<3, T> inverse() const; constexpr T length() const; @@ -213,21 +213,29 @@ namespace mim constexpr T distance_squared(const vec<3, T>& v) const; + constexpr T dot(const vec<3, T>& v) const; - /// Function Declarations + constexpr vec<3, T> cross(const vec<3, T>& v) const; + + constexpr vec<3, T> hadamard(const vec<3, T>& v) const; + + constexpr void rotate(const vec<3, T>& axis, T angle); - constexpr T dot(const vec<3, T>& v) const; - constexpr T cross(const vec<3, T>& v) const; - constexpr void rotate(T angle); constexpr vec<3, T> rotated(T angle) const; + constexpr vec<3, T> clamp(const vec<3, T>& min, const vec<3, T>& max) const; + constexpr vec<3, T> reflect(const vec<3, T>& normal) const; + constexpr vec<3, T> refract(const vec<3, T>& normal, T eta) const; + constexpr vec<3, T> project(const vec<3, T>& normal) const; }; - /// Unary Operators + /// Free operators + + // Unary Operators template constexpr vec<3, T> operator+(vec<3, T> const& v); @@ -235,7 +243,7 @@ namespace mim template constexpr vec<3, T> operator-(vec<3, T> const& v); - /// Binary Operators + // Binary Operators template constexpr vec<3, T> operator+(vec<3, T> const& v, T scalar); @@ -312,7 +320,7 @@ namespace mim template constexpr vec<3, T> operator%(vec<3, T> const& v1, vec<3, T> const& v2); - /// Bitwise Binary Operators + // Bitwise Binary Operators template constexpr vec<3, T> operator&(vec<3, T> const& v, T scalar); @@ -392,7 +400,7 @@ namespace mim template constexpr vec<3, T> operator~(vec<3, T> const& v); - /// Conditional Operators + // Conditional Operators template constexpr bool operator==(vec<3, T> const& v1, vec<3, T> const& v2); @@ -407,7 +415,28 @@ namespace mim constexpr vec<3, bool> operator||(vec<3, T> const& v1, vec<3, T> const& v2); - // Free functions + /// Free functions + + template + constexpr vec<3, T> inverse(vec<3, T> const& v); + + template + constexpr T length(vec<3, T> const& v); + + template + constexpr T length_squared(vec<3, T> const& v); + + template + constexpr vec<3, T> normalized(vec<3, T> const& v); + + template + MIM_NODISCARD constexpr bool is_normalized(vec<3, T> const& v); + + template + constexpr T distance(vec<3, T> const& v1, vec<3, T> const& v2); + + template + constexpr T distance_squared(vec<3, T> const& v1, vec<3, T> const& v2); template constexpr vec<3, T> dot(vec<3, T> const& v1, vec<3, T> const& v2); @@ -416,8 +445,22 @@ namespace mim constexpr vec<3, T> cross(vec<3, T> const& v1, vec<3, T> const& v2); template - constexpr vec<3, T> inverse(vec<3, T> const& v, T epsilon = 0.001f); + constexpr vec<3, T> hadamard(vec<3, T> const& v1, vec<3, T> const& v2); + template + constexpr vec<3, T> rotated(vec<3, T> const& v, T angle); + + template + constexpr vec<3, T> clamp(vec<3, T> const& v, vec<3, T> const& min, vec<3, T> const& max); + + template + constexpr vec<3, T> reflect(vec<3, T> const& v, vec<3, T> const& normal); + + template + constexpr vec<3, T> refract(vec<3, T> const& v, vec<3, T> const& normal, T eta); + + template + constexpr vec<3, T> project(vec<3, T> const& v, vec<3, T> const& normal); } // namespace mim diff --git a/include/mim/detail/type/type_vector3.inl b/include/mim/detail/type/type_vector3.inl index 1303de7..ec63560 100644 --- a/include/mim/detail/type/type_vector3.inl +++ b/include/mim/detail/type/type_vector3.inl @@ -1,6 +1,5 @@ // Copyright (c) 2023-Present Mim contributors (see LICENSE) -#include "mim/detail/compute/compute_vector.hpp" namespace mim { diff --git a/include/mim/detail/type/type_vector4.hpp b/include/mim/detail/type/type_vector4.hpp index e877db5..7928c92 100644 --- a/include/mim/detail/type/type_vector4.hpp +++ b/include/mim/detail/type/type_vector4.hpp @@ -195,7 +195,7 @@ namespace mim template constexpr vec<4, T>& operator%=(vec<4, U> const& v); - /// Increment and Decrement Operators + // Increment and Decrement Operators constexpr vec<4, T>& operator++(); @@ -205,7 +205,7 @@ namespace mim constexpr const vec<4, T> operator--(int); - /// Bitwise Assignment Operators + // Bitwise Assignment Operators template constexpr vec<4, T>& operator&=(U scalar); @@ -253,7 +253,7 @@ namespace mim constexpr vec<4, T>& operator>>=(vec<4, U> const& v); - /// Generic Function Declarations + // Functions constexpr T length() const; @@ -269,18 +269,19 @@ namespace mim constexpr T distance_squared(const vec<4, T>& v) const; - - /// Function Declarations + // TODO: Maybe add the wedge product as an option? constexpr T dot(const vec<4, T>& v) const; - constexpr vec<4, T> rotated(T angle) const; + + constexpr vec<4, T> hadamard(const vec<4, T>& v) const; + constexpr vec<4, T> clamp(const vec<4, T>& min, const vec<4, T>& max) const; - constexpr vec<4, T> reflect(const vec<4, T>& normal) const; - constexpr vec<4, T> refract(const vec<4, T>& normal, T eta) const; - constexpr vec<4, T> project(const vec<4, T>& normal) const; + }; - /// Unary Operators + /// Free functions + + // Unary Operators template constexpr vec<4, T> operator+(vec<4, T> const& v); @@ -288,7 +289,7 @@ namespace mim template constexpr vec<4, T> operator-(vec<4, T> const& v); - /// Binary Operators + // Binary Operators template constexpr vec<4, T> operator+(vec<4, T> const& v, T const& scalar); @@ -365,7 +366,7 @@ namespace mim template constexpr vec<4, T> operator%(vec<4, T> const& v1, vec<4, T> const& v2); - /// Bitwise Binary Operators + // Bitwise Binary Operators template constexpr vec<4, T> operator&(vec<4, T> const& v, T scalar); @@ -445,7 +446,7 @@ namespace mim template constexpr vec<4, T> operator~(vec<4, T> const& v); - /// Conditional Binary Operators + // Conditional Binary Operators template constexpr bool operator==(vec<4, T> const& v1, vec<4, T> const& v2); @@ -458,6 +459,33 @@ namespace mim constexpr vec<4, bool> operator||(vec<4, bool> const& v1, vec<4, bool> const& v2); + /// These functions are defined in func_vector4.inl + + template + constexpr T length(vec<4, T> const& v); + + template + constexpr T length_squared(vec<4, T> const& v); + + template + constexpr vec<4, T> normalized(vec<4, T> const& v); + + template + MIM_NODISCARD constexpr bool is_normalized(vec<4, T> const& v); + + template + constexpr T distance(vec<4, T> const& v1, vec<4, T> const& v2); + + template + constexpr T distance_squared(vec<4, T> const& v1, vec<4, T> const& v2); + + template + constexpr T dot(vec<4, T> const& v1, vec<4, T> const& v2); + + template + constexpr vec<4, T> hadamard(vec<4, T> const& v1, vec<4, T> const& v2); + + } // namespace mim #include "mim/detail/type/type_vector4.inl" diff --git a/include/mim/detail/type/type_vector4.inl b/include/mim/detail/type/type_vector4.inl index 9712208..6f67d3b 100644 --- a/include/mim/detail/type/type_vector4.inl +++ b/include/mim/detail/type/type_vector4.inl @@ -1,6 +1,5 @@ // Copyright (c) 2023-Present Mim contributors (see LICENSE) -#include "mim/detail/compute/compute_vector.hpp" namespace mim {