mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-25 05:54:57 +00:00
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.
This commit is contained in:
parent
de96fe0860
commit
dcb0c910af
1 changed files with 46 additions and 43 deletions
|
@ -17,24 +17,24 @@ namespace Common
|
||||||
template <typename T>
|
template <typename T>
|
||||||
union TVec3
|
union TVec3
|
||||||
{
|
{
|
||||||
TVec3() = default;
|
constexpr TVec3() = default;
|
||||||
TVec3(T _x, T _y, T _z) : data{_x, _y, _z} {}
|
constexpr TVec3(T _x, T _y, T _z) : data{_x, _y, _z} {}
|
||||||
|
|
||||||
template <typename OtherT>
|
template <typename OtherT>
|
||||||
explicit TVec3(const TVec3<OtherT>& other) : TVec3(other.x, other.y, other.z)
|
constexpr explicit TVec3(const TVec3<OtherT>& 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)};
|
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; }
|
constexpr T Dot(const TVec3& other) const { return x * other.x + y * other.y + z * other.z; }
|
||||||
T LengthSquared() const { return Dot(*this); }
|
constexpr T LengthSquared() const { return Dot(*this); }
|
||||||
T Length() const { return std::sqrt(LengthSquared()); }
|
T Length() const { return std::sqrt(LengthSquared()); }
|
||||||
TVec3 Normalized() const { return *this / Length(); }
|
TVec3 Normalized() const { return *this / Length(); }
|
||||||
|
|
||||||
TVec3& operator+=(const TVec3& rhs)
|
constexpr TVec3& operator+=(const TVec3& rhs)
|
||||||
{
|
{
|
||||||
x += rhs.x;
|
x += rhs.x;
|
||||||
y += rhs.y;
|
y += rhs.y;
|
||||||
|
@ -42,7 +42,7 @@ union TVec3
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec3& operator-=(const TVec3& rhs)
|
constexpr TVec3& operator-=(const TVec3& rhs)
|
||||||
{
|
{
|
||||||
x -= rhs.x;
|
x -= rhs.x;
|
||||||
y -= rhs.y;
|
y -= rhs.y;
|
||||||
|
@ -50,7 +50,7 @@ union TVec3
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec3& operator*=(const TVec3& rhs)
|
constexpr TVec3& operator*=(const TVec3& rhs)
|
||||||
{
|
{
|
||||||
x *= rhs.x;
|
x *= rhs.x;
|
||||||
y *= rhs.y;
|
y *= rhs.y;
|
||||||
|
@ -58,7 +58,7 @@ union TVec3
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec3& operator/=(const TVec3& rhs)
|
constexpr TVec3& operator/=(const TVec3& rhs)
|
||||||
{
|
{
|
||||||
x /= rhs.x;
|
x /= rhs.x;
|
||||||
y /= rhs.y;
|
y /= rhs.y;
|
||||||
|
@ -66,7 +66,7 @@ union TVec3
|
||||||
return *this;
|
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.
|
// Apply function to each element and return the result.
|
||||||
template <typename F>
|
template <typename F>
|
||||||
|
@ -103,7 +103,7 @@ TVec3<bool> operator<(const TVec3<T>& lhs, const TVec3<T>& rhs)
|
||||||
return lhs.Map(std::less<T>{}, rhs);
|
return lhs.Map(std::less<T>{}, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TVec3<bool> operator!(const TVec3<bool>& vec)
|
constexpr TVec3<bool> operator!(const TVec3<bool>& vec)
|
||||||
{
|
{
|
||||||
return {!vec.x, !vec.y, !vec.z};
|
return {!vec.x, !vec.y, !vec.z};
|
||||||
}
|
}
|
||||||
|
@ -150,13 +150,16 @@ using DVec3 = TVec3<double>;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
union TVec4
|
union TVec4
|
||||||
{
|
{
|
||||||
TVec4() = default;
|
constexpr TVec4() = default;
|
||||||
TVec4(TVec3<T> _vec, T _w) : TVec4{_vec.x, _vec.y, _vec.z, _w} {}
|
constexpr TVec4(TVec3<T> _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(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;
|
x *= rhs.x;
|
||||||
y *= rhs.y;
|
y *= rhs.y;
|
||||||
|
@ -165,7 +168,7 @@ union TVec4
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec4& operator/=(const TVec4& rhs)
|
constexpr TVec4& operator/=(const TVec4& rhs)
|
||||||
{
|
{
|
||||||
x /= rhs.x;
|
x /= rhs.x;
|
||||||
y /= rhs.y;
|
y /= rhs.y;
|
||||||
|
@ -174,8 +177,8 @@ union TVec4
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec4& operator*=(T scalar) { return *this *= TVec4{scalar, scalar, scalar, scalar}; }
|
constexpr 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}; }
|
||||||
|
|
||||||
std::array<T, 4> data = {};
|
std::array<T, 4> data = {};
|
||||||
|
|
||||||
|
@ -189,13 +192,13 @@ union TVec4
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec4<T> operator*(TVec4<T> lhs, std::common_type_t<T> scalar)
|
constexpr TVec4<T> operator*(TVec4<T> lhs, std::common_type_t<T> scalar)
|
||||||
{
|
{
|
||||||
return lhs *= scalar;
|
return lhs *= scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec4<T> operator/(TVec4<T> lhs, std::common_type_t<T> scalar)
|
constexpr TVec4<T> operator/(TVec4<T> lhs, std::common_type_t<T> scalar)
|
||||||
{
|
{
|
||||||
return lhs /= scalar;
|
return lhs /= scalar;
|
||||||
}
|
}
|
||||||
|
@ -206,63 +209,63 @@ using DVec4 = TVec4<double>;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
union TVec2
|
union TVec2
|
||||||
{
|
{
|
||||||
TVec2() = default;
|
constexpr TVec2() = default;
|
||||||
TVec2(T _x, T _y) : data{_x, _y} {}
|
constexpr TVec2(T _x, T _y) : data{_x, _y} {}
|
||||||
|
|
||||||
template <typename OtherT>
|
template <typename OtherT>
|
||||||
explicit TVec2(const TVec2<OtherT>& other) : TVec2(other.x, other.y)
|
constexpr explicit TVec2(const TVec2<OtherT>& other) : TVec2(other.x, other.y)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
T Cross(const TVec2& rhs) const { return (x * rhs.y) - (y * rhs.x); }
|
constexpr 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); }
|
constexpr T Dot(const TVec2& rhs) const { return (x * rhs.x) + (y * rhs.y); }
|
||||||
T LengthSquared() const { return Dot(*this); }
|
constexpr T LengthSquared() const { return Dot(*this); }
|
||||||
T Length() const { return std::sqrt(LengthSquared()); }
|
T Length() const { return std::sqrt(LengthSquared()); }
|
||||||
TVec2 Normalized() const { return *this / Length(); }
|
TVec2 Normalized() const { return *this / Length(); }
|
||||||
|
|
||||||
TVec2& operator+=(const TVec2& rhs)
|
constexpr TVec2& operator+=(const TVec2& rhs)
|
||||||
{
|
{
|
||||||
x += rhs.x;
|
x += rhs.x;
|
||||||
y += rhs.y;
|
y += rhs.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec2& operator-=(const TVec2& rhs)
|
constexpr TVec2& operator-=(const TVec2& rhs)
|
||||||
{
|
{
|
||||||
x -= rhs.x;
|
x -= rhs.x;
|
||||||
y -= rhs.y;
|
y -= rhs.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec2& operator*=(const TVec2& rhs)
|
constexpr TVec2& operator*=(const TVec2& rhs)
|
||||||
{
|
{
|
||||||
x *= rhs.x;
|
x *= rhs.x;
|
||||||
y *= rhs.y;
|
y *= rhs.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec2& operator/=(const TVec2& rhs)
|
constexpr TVec2& operator/=(const TVec2& rhs)
|
||||||
{
|
{
|
||||||
x /= rhs.x;
|
x /= rhs.x;
|
||||||
y /= rhs.y;
|
y /= rhs.y;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec2& operator*=(T scalar)
|
constexpr TVec2& operator*=(T scalar)
|
||||||
{
|
{
|
||||||
x *= scalar;
|
x *= scalar;
|
||||||
y *= scalar;
|
y *= scalar;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec2& operator/=(T scalar)
|
constexpr TVec2& operator/=(T scalar)
|
||||||
{
|
{
|
||||||
x /= scalar;
|
x /= scalar;
|
||||||
y /= scalar;
|
y /= scalar;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TVec2 operator-() const { return {-x, -y}; }
|
constexpr TVec2 operator-() const { return {-x, -y}; }
|
||||||
|
|
||||||
std::array<T, 2> data = {};
|
std::array<T, 2> data = {};
|
||||||
|
|
||||||
|
@ -274,48 +277,48 @@ union TVec2
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec2<bool> operator<(const TVec2<T>& lhs, const TVec2<T>& rhs)
|
constexpr TVec2<bool> operator<(const TVec2<T>& lhs, const TVec2<T>& rhs)
|
||||||
{
|
{
|
||||||
return {lhs.x < rhs.x, lhs.y < rhs.y};
|
return {lhs.x < rhs.x, lhs.y < rhs.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TVec2<bool> operator!(const TVec2<bool>& vec)
|
constexpr TVec2<bool> operator!(const TVec2<bool>& vec)
|
||||||
{
|
{
|
||||||
return {!vec.x, !vec.y};
|
return {!vec.x, !vec.y};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec2<T> operator+(TVec2<T> lhs, const TVec2<T>& rhs)
|
constexpr TVec2<T> operator+(TVec2<T> lhs, const TVec2<T>& rhs)
|
||||||
{
|
{
|
||||||
return lhs += rhs;
|
return lhs += rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec2<T> operator-(TVec2<T> lhs, const TVec2<T>& rhs)
|
constexpr TVec2<T> operator-(TVec2<T> lhs, const TVec2<T>& rhs)
|
||||||
{
|
{
|
||||||
return lhs -= rhs;
|
return lhs -= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec2<T> operator*(TVec2<T> lhs, const TVec2<T>& rhs)
|
constexpr TVec2<T> operator*(TVec2<T> lhs, const TVec2<T>& rhs)
|
||||||
{
|
{
|
||||||
return lhs *= rhs;
|
return lhs *= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TVec2<T> operator/(TVec2<T> lhs, const TVec2<T>& rhs)
|
constexpr TVec2<T> operator/(TVec2<T> lhs, const TVec2<T>& rhs)
|
||||||
{
|
{
|
||||||
return lhs /= rhs;
|
return lhs /= rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename T2>
|
template <typename T, typename T2>
|
||||||
auto operator*(TVec2<T> lhs, T2 scalar)
|
constexpr auto operator*(TVec2<T> lhs, T2 scalar)
|
||||||
{
|
{
|
||||||
return TVec2<decltype(lhs.x * scalar)>(lhs) *= scalar;
|
return TVec2<decltype(lhs.x * scalar)>(lhs) *= scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename T2>
|
template <typename T, typename T2>
|
||||||
auto operator/(TVec2<T> lhs, T2 scalar)
|
constexpr auto operator/(TVec2<T> lhs, T2 scalar)
|
||||||
{
|
{
|
||||||
return TVec2<decltype(lhs.x / scalar)>(lhs) /= scalar;
|
return TVec2<decltype(lhs.x / scalar)>(lhs) /= scalar;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue