From dcb0c910af7bdc06bfc2253fb8d2b15afbc4fe45 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 21 Oct 2020 17:41:38 -0400 Subject: [PATCH] Common/Matrix: Allow TVec classes to be used in constexpr contexts Much of these classes are operating on integral types and are pretty standard behavior as far as vectors go. Some member functions can be made constexpr to make them more flexible and allow them to be used in constexpr contexts. --- Source/Core/Common/Matrix.h | 89 +++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/Source/Core/Common/Matrix.h b/Source/Core/Common/Matrix.h index bf1e80b567..56840acab1 100644 --- a/Source/Core/Common/Matrix.h +++ b/Source/Core/Common/Matrix.h @@ -17,24 +17,24 @@ namespace Common template union TVec3 { - TVec3() = default; - TVec3(T _x, T _y, T _z) : data{_x, _y, _z} {} + constexpr TVec3() = default; + constexpr TVec3(T _x, T _y, T _z) : data{_x, _y, _z} {} template - explicit TVec3(const TVec3& other) : TVec3(other.x, other.y, other.z) + constexpr explicit TVec3(const TVec3& other) : TVec3(other.x, other.y, other.z) { } - TVec3 Cross(const TVec3& rhs) const + constexpr TVec3 Cross(const TVec3& rhs) const { return {(y * rhs.z) - (rhs.y * z), (z * rhs.x) - (rhs.z * x), (x * rhs.y) - (rhs.x * y)}; } - T Dot(const TVec3& other) const { return x * other.x + y * other.y + z * other.z; } - T LengthSquared() const { return Dot(*this); } + constexpr T Dot(const TVec3& other) const { return x * other.x + y * other.y + z * other.z; } + constexpr T LengthSquared() const { return Dot(*this); } T Length() const { return std::sqrt(LengthSquared()); } TVec3 Normalized() const { return *this / Length(); } - TVec3& operator+=(const TVec3& rhs) + constexpr TVec3& operator+=(const TVec3& rhs) { x += rhs.x; y += rhs.y; @@ -42,7 +42,7 @@ union TVec3 return *this; } - TVec3& operator-=(const TVec3& rhs) + constexpr TVec3& operator-=(const TVec3& rhs) { x -= rhs.x; y -= rhs.y; @@ -50,7 +50,7 @@ union TVec3 return *this; } - TVec3& operator*=(const TVec3& rhs) + constexpr TVec3& operator*=(const TVec3& rhs) { x *= rhs.x; y *= rhs.y; @@ -58,7 +58,7 @@ union TVec3 return *this; } - TVec3& operator/=(const TVec3& rhs) + constexpr TVec3& operator/=(const TVec3& rhs) { x /= rhs.x; y /= rhs.y; @@ -66,7 +66,7 @@ union TVec3 return *this; } - TVec3 operator-() const { return {-x, -y, -z}; } + constexpr TVec3 operator-() const { return {-x, -y, -z}; } // Apply function to each element and return the result. template @@ -103,7 +103,7 @@ TVec3 operator<(const TVec3& lhs, const TVec3& rhs) return lhs.Map(std::less{}, rhs); } -inline TVec3 operator!(const TVec3& vec) +constexpr TVec3 operator!(const TVec3& vec) { return {!vec.x, !vec.y, !vec.z}; } @@ -150,13 +150,16 @@ using DVec3 = TVec3; template union TVec4 { - TVec4() = default; - TVec4(TVec3 _vec, T _w) : TVec4{_vec.x, _vec.y, _vec.z, _w} {} - TVec4(T _x, T _y, T _z, T _w) : data{_x, _y, _z, _w} {} + constexpr TVec4() = default; + constexpr TVec4(TVec3 _vec, T _w) : TVec4{_vec.x, _vec.y, _vec.z, _w} {} + constexpr TVec4(T _x, T _y, T _z, T _w) : data{_x, _y, _z, _w} {} - T Dot(const TVec4& other) const { return x * other.x + y * other.y + z * other.z + w * other.w; } + constexpr T Dot(const TVec4& other) const + { + return x * other.x + y * other.y + z * other.z + w * other.w; + } - TVec4& operator*=(const TVec4& rhs) + constexpr TVec4& operator*=(const TVec4& rhs) { x *= rhs.x; y *= rhs.y; @@ -165,7 +168,7 @@ union TVec4 return *this; } - TVec4& operator/=(const TVec4& rhs) + constexpr TVec4& operator/=(const TVec4& rhs) { x /= rhs.x; y /= rhs.y; @@ -174,8 +177,8 @@ union TVec4 return *this; } - TVec4& operator*=(T scalar) { return *this *= TVec4{scalar, scalar, scalar, scalar}; } - TVec4& operator/=(T scalar) { return *this /= TVec4{scalar, scalar, scalar, scalar}; } + constexpr TVec4& operator*=(T scalar) { return *this *= TVec4{scalar, scalar, scalar, scalar}; } + constexpr TVec4& operator/=(T scalar) { return *this /= TVec4{scalar, scalar, scalar, scalar}; } std::array data = {}; @@ -189,13 +192,13 @@ union TVec4 }; template -TVec4 operator*(TVec4 lhs, std::common_type_t scalar) +constexpr TVec4 operator*(TVec4 lhs, std::common_type_t scalar) { return lhs *= scalar; } template -TVec4 operator/(TVec4 lhs, std::common_type_t scalar) +constexpr TVec4 operator/(TVec4 lhs, std::common_type_t scalar) { return lhs /= scalar; } @@ -206,63 +209,63 @@ using DVec4 = TVec4; template union TVec2 { - TVec2() = default; - TVec2(T _x, T _y) : data{_x, _y} {} + constexpr TVec2() = default; + constexpr TVec2(T _x, T _y) : data{_x, _y} {} template - explicit TVec2(const TVec2& other) : TVec2(other.x, other.y) + constexpr explicit TVec2(const TVec2& other) : TVec2(other.x, other.y) { } - T Cross(const TVec2& rhs) const { return (x * rhs.y) - (y * rhs.x); } - T Dot(const TVec2& rhs) const { return (x * rhs.x) + (y * rhs.y); } - T LengthSquared() const { return Dot(*this); } + constexpr T Cross(const TVec2& rhs) const { return (x * rhs.y) - (y * rhs.x); } + constexpr T Dot(const TVec2& rhs) const { return (x * rhs.x) + (y * rhs.y); } + constexpr T LengthSquared() const { return Dot(*this); } T Length() const { return std::sqrt(LengthSquared()); } TVec2 Normalized() const { return *this / Length(); } - TVec2& operator+=(const TVec2& rhs) + constexpr TVec2& operator+=(const TVec2& rhs) { x += rhs.x; y += rhs.y; return *this; } - TVec2& operator-=(const TVec2& rhs) + constexpr TVec2& operator-=(const TVec2& rhs) { x -= rhs.x; y -= rhs.y; return *this; } - TVec2& operator*=(const TVec2& rhs) + constexpr TVec2& operator*=(const TVec2& rhs) { x *= rhs.x; y *= rhs.y; return *this; } - TVec2& operator/=(const TVec2& rhs) + constexpr TVec2& operator/=(const TVec2& rhs) { x /= rhs.x; y /= rhs.y; return *this; } - TVec2& operator*=(T scalar) + constexpr TVec2& operator*=(T scalar) { x *= scalar; y *= scalar; return *this; } - TVec2& operator/=(T scalar) + constexpr TVec2& operator/=(T scalar) { x /= scalar; y /= scalar; return *this; } - TVec2 operator-() const { return {-x, -y}; } + constexpr TVec2 operator-() const { return {-x, -y}; } std::array data = {}; @@ -274,48 +277,48 @@ union TVec2 }; template -TVec2 operator<(const TVec2& lhs, const TVec2& rhs) +constexpr TVec2 operator<(const TVec2& lhs, const TVec2& rhs) { return {lhs.x < rhs.x, lhs.y < rhs.y}; } -inline TVec2 operator!(const TVec2& vec) +constexpr TVec2 operator!(const TVec2& vec) { return {!vec.x, !vec.y}; } template -TVec2 operator+(TVec2 lhs, const TVec2& rhs) +constexpr TVec2 operator+(TVec2 lhs, const TVec2& rhs) { return lhs += rhs; } template -TVec2 operator-(TVec2 lhs, const TVec2& rhs) +constexpr TVec2 operator-(TVec2 lhs, const TVec2& rhs) { return lhs -= rhs; } template -TVec2 operator*(TVec2 lhs, const TVec2& rhs) +constexpr TVec2 operator*(TVec2 lhs, const TVec2& rhs) { return lhs *= rhs; } template -TVec2 operator/(TVec2 lhs, const TVec2& rhs) +constexpr TVec2 operator/(TVec2 lhs, const TVec2& rhs) { return lhs /= rhs; } template -auto operator*(TVec2 lhs, T2 scalar) +constexpr auto operator*(TVec2 lhs, T2 scalar) { return TVec2(lhs) *= scalar; } template -auto operator/(TVec2 lhs, T2 scalar) +constexpr auto operator/(TVec2 lhs, T2 scalar) { return TVec2(lhs) /= scalar; }