277 lines
8.5 KiB
C++
277 lines
8.5 KiB
C++
namespace math
|
|
{
|
|
|
|
template<typename T> constexpr vec4<T>::vec4(T x, T y, T z, T w) noexcept : x(x), y(y), z(z), w(w) {}
|
|
template<typename T> constexpr vec4<T>::vec4(T v) noexcept : x(v), y(v), z(v), w(v) {}
|
|
template<typename T> constexpr vec4<T>::vec4(std::array<T, 4> const& v) noexcept : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator-() const noexcept
|
|
{
|
|
return vec4<T>(-x, -y, -z, -w);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr T& vec4<T>::operator[](size_t i) noexcept
|
|
{
|
|
TL_PLAIN_ASSERT(i < sizeof(*this) / sizeof(T));
|
|
|
|
//if you hit this TL_PLAIN_ASSERT, your compiler introduces padding. Check for #pragma packs without pop
|
|
TL_PLAIN_ASSERT(&((T*)this)[0] == &x && &((T*)this)[1] == &y);
|
|
|
|
return ((T*)this)[i];
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr T const& vec4<T>::operator[](size_t i) const noexcept
|
|
{
|
|
TL_PLAIN_ASSERT(i < sizeof(*this) / sizeof(T));
|
|
|
|
//if you hit this TL_PLAIN_ASSERT, your compiler introduces padding. Check for #pragma packs without pop
|
|
TL_PLAIN_ASSERT(&((T*)this)[0] == &x && &((T*)this)[1] == &y);
|
|
|
|
return ((T*)this)[i];
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator+(T s) const noexcept
|
|
{
|
|
return vec4<T>(x + s, y + s, z + s, w + s);
|
|
}
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator+(vec4<T> const& v) const noexcept
|
|
{
|
|
return vec4<T>(x + v.x, y + v.y, z + v.z, w + v.w);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator-(T s) const noexcept
|
|
{
|
|
return vec4<T>(x - s, y - s, z - s, w - s);
|
|
}
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator-(vec4<T> const& v) const noexcept
|
|
{
|
|
return vec4<T>(x - v.x, y - v.y, z - v.z, w - v.w);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator*(T s) const noexcept
|
|
{
|
|
return vec4<T>(x * s, y * s, z * s, w * s);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> vec4<T>::operator/(T s) const noexcept
|
|
{
|
|
TL_PLAIN_ASSERT(!is_zero(s));
|
|
if constexpr (std::is_floating_point_v<T>)
|
|
{
|
|
T is = T(1) / s;
|
|
return vec4<T>(x * is, y * is, z * is, w * is);
|
|
}
|
|
else
|
|
return vec4<T>(x / s, y / s, z / s, w / s);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator+=(T s) noexcept
|
|
{
|
|
x += s;
|
|
y += s;
|
|
z += s;
|
|
w += s;
|
|
return *this;
|
|
}
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator+=(vec4<T> const& v) noexcept
|
|
{
|
|
x += v.x;
|
|
y += v.y;
|
|
z += v.z;
|
|
w += v.w;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator-=(T s) noexcept
|
|
{
|
|
x -= s;
|
|
y -= s;
|
|
z -= s;
|
|
w -= s;
|
|
return *this;
|
|
}
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator-=(vec4<T> const& v) noexcept
|
|
{
|
|
x -= v.x;
|
|
y -= v.y;
|
|
z -= v.z;
|
|
w -= v.w;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator*=(T s) noexcept
|
|
{
|
|
x *= s;
|
|
y *= s;
|
|
z *= s;
|
|
w *= s;
|
|
return *this;
|
|
}
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator*=(vec4<T> const& v) noexcept
|
|
{
|
|
x *= v.x;
|
|
y *= v.y;
|
|
z *= v.z;
|
|
w *= v.w;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator/=(T s) noexcept
|
|
{
|
|
TL_PLAIN_ASSERT(!is_zero(s));
|
|
if constexpr (std::is_floating_point_v<T>)
|
|
{
|
|
T is = T(1) / s;
|
|
x *= is;
|
|
y *= is;
|
|
z *= is;
|
|
w *= is;
|
|
}
|
|
else
|
|
{
|
|
x /= s;
|
|
y /= s;
|
|
z /= s;
|
|
w /= s;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T>& vec4<T>::operator/=(vec4<T> const& v) noexcept
|
|
{
|
|
TL_PLAIN_ASSERT(!cwise::any(cwise::is_zero(v)));
|
|
x /= v.x;
|
|
y /= v.y;
|
|
z /= v.z;
|
|
w /= v.w;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> operator*(T s, vec4<T> const& v) noexcept
|
|
{
|
|
return v*s;
|
|
}
|
|
template<typename T>
|
|
constexpr vec4<T> operator/(T s, vec4<T> const& v) noexcept
|
|
{
|
|
return vec4<T>(s) / v;
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> operator*(vec4<T> const& v0, vec4<T> const& v1) noexcept
|
|
{
|
|
return vec4<T>(v0.x * v1.x, v0.y * v1.y, v0.z * v1.z, v0.w * v1.w);
|
|
}
|
|
|
|
template<typename T>
|
|
constexpr vec4<T> operator/(vec4<T> const& u, vec4<T> const& v) noexcept
|
|
{
|
|
TL_PLAIN_ASSERT(!cwise::any(cwise::is_zero(v)));
|
|
return vec4<T>(u.x / v.x, u.y / v.y, u.z / v.z, u.w / v.w);
|
|
}
|
|
|
|
template<typename T>
|
|
template<class Policy>
|
|
constexpr vec4<T>& vec4<T>::normalize() noexcept
|
|
{
|
|
const T len_sq = x * x + y * y + z * z + w * w;
|
|
const T len_inv = inv_sqrt<T, Policy>(len_sq);
|
|
x *= len_inv;
|
|
y *= len_inv;
|
|
z *= len_inv;
|
|
w *= len_inv;
|
|
return *this;
|
|
}
|
|
template<typename T>
|
|
template<class Policy>
|
|
constexpr T vec4<T>::length() const noexcept
|
|
{
|
|
return sqrt<T, Policy>(x * x + y * y + z * z + w * w);
|
|
}
|
|
template<typename T>
|
|
constexpr T vec4<T>::length_sq() const noexcept
|
|
{
|
|
return x * x + y * y + z * z + w * w;
|
|
}
|
|
|
|
} //math
|
|
|
|
|
|
#include "tl/hash_and_combine.h"
|
|
|
|
namespace eastl
|
|
{
|
|
template<typename T>
|
|
struct hash<math::vec4<T>>
|
|
{
|
|
std::size_t operator()(const math::vec4<T>& p) const
|
|
{
|
|
size_t seed = 0;
|
|
tl::hash_and_combine(seed, p.x);
|
|
tl::hash_and_combine(seed, p.y);
|
|
tl::hash_and_combine(seed, p.z);
|
|
tl::hash_and_combine(seed, p.w);
|
|
return seed;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
class numeric_limits<math::vec4<T>>
|
|
{
|
|
public:
|
|
typedef math::vec4<T> value_type;
|
|
|
|
static EA_CONSTEXPR_OR_CONST bool is_specialized = true;
|
|
static EA_CONSTEXPR_OR_CONST int digits = tl::numeric_limits<T>::digits;
|
|
static EA_CONSTEXPR_OR_CONST int digits10 = tl::numeric_limits<T>::digits10;
|
|
static EA_CONSTEXPR_OR_CONST int max_digits10 = tl::numeric_limits<T>::max_digits10;
|
|
static EA_CONSTEXPR_OR_CONST bool is_signed = tl::numeric_limits<T>::is_signed;
|
|
static EA_CONSTEXPR_OR_CONST bool is_integer = tl::numeric_limits<T>::is_integer;
|
|
static EA_CONSTEXPR_OR_CONST bool is_exact = tl::numeric_limits<T>::is_exact;
|
|
static EA_CONSTEXPR_OR_CONST int radix = tl::numeric_limits<T>::radix;
|
|
static EA_CONSTEXPR_OR_CONST int min_exponent = tl::numeric_limits<T>::min_exponent;
|
|
static EA_CONSTEXPR_OR_CONST int min_exponent10 = tl::numeric_limits<T>::min_exponent10;
|
|
static EA_CONSTEXPR_OR_CONST int max_exponent = tl::numeric_limits<T>::max_exponent;
|
|
static EA_CONSTEXPR_OR_CONST int max_exponent10 = tl::numeric_limits<T>::max_exponent10;
|
|
static EA_CONSTEXPR_OR_CONST bool is_bounded = tl::numeric_limits<T>::is_bounded;
|
|
static EA_CONSTEXPR_OR_CONST bool is_modulo = tl::numeric_limits<T>::is_modulo;
|
|
static EA_CONSTEXPR_OR_CONST bool traps = tl::numeric_limits<T>::traps;
|
|
static EA_CONSTEXPR_OR_CONST bool tinyness_before = tl::numeric_limits<T>::tinyness_before;
|
|
static EA_CONSTEXPR_OR_CONST float_round_style round_style = tl::numeric_limits<T>::round_style;
|
|
static EA_CONSTEXPR_OR_CONST bool has_infinity = tl::numeric_limits<T>::has_infinity;
|
|
static EA_CONSTEXPR_OR_CONST bool has_quiet_NaN = tl::numeric_limits<T>::has_quiet_NaN;
|
|
static EA_CONSTEXPR_OR_CONST bool has_signaling_NaN = tl::numeric_limits<T>::has_signaling_NaN;
|
|
static EA_CONSTEXPR_OR_CONST float_denorm_style has_denorm = tl::numeric_limits<T>::has_denorm;
|
|
static EA_CONSTEXPR_OR_CONST bool has_denorm_loss = tl::numeric_limits<T>::has_denorm_loss;
|
|
static EA_CONSTEXPR_OR_CONST bool is_iec559 = tl::numeric_limits<T>::is_iec559;
|
|
|
|
static value_type min() noexcept { return value_type(tl::numeric_limits<T>::min()); }
|
|
static value_type max() noexcept { return value_type(tl::numeric_limits<T>::max()); }
|
|
static value_type lowest() noexcept { return value_type(tl::numeric_limits<T>::lowest()); }
|
|
static value_type epsilon() noexcept { return value_type(tl::numeric_limits<T>::epsilon()); }
|
|
static value_type round_error() noexcept { return value_type(tl::numeric_limits<T>::round_error()); }
|
|
static value_type infinity() noexcept { return value_type(tl::numeric_limits<T>::infinity()); }
|
|
static value_type quiet_NaN() noexcept { return value_type(tl::numeric_limits<T>::quiet_NaN()); }
|
|
static value_type signaling_NaN() noexcept { return value_type(tl::numeric_limits<T>::signaling_NaN()); }
|
|
static value_type denorm_min() noexcept { return value_type(tl::numeric_limits<T>::denorm_min()); }
|
|
};
|
|
}
|