2018-10-06 20:39:40 -07:00
|
|
|
#pragma once
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2016-03-04 15:03:26 -08:00
|
|
|
#include <cassert>
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2019-09-01 00:38:45 -07:00
|
|
|
#include "zeus/Global.hpp"
|
|
|
|
#include "zeus/Math.hpp"
|
|
|
|
|
2018-12-07 17:16:50 -08:00
|
|
|
namespace zeus {
|
|
|
|
class CVector2f {
|
2016-01-16 15:16:30 -08:00
|
|
|
public:
|
2018-12-07 17:16:50 -08:00
|
|
|
simd<float> mSimd;
|
2020-05-01 16:20:31 -07:00
|
|
|
constexpr CVector2f() : mSimd() {}
|
2018-12-07 17:16:50 -08:00
|
|
|
|
|
|
|
template <typename T>
|
2019-02-23 23:15:32 -08:00
|
|
|
constexpr CVector2f(const simd<T>& s) : mSimd(s) {}
|
2018-12-07 21:23:50 -08:00
|
|
|
|
2019-02-23 23:15:32 -08:00
|
|
|
explicit constexpr CVector2f(float xy) : mSimd(xy) {}
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
constexpr void assign(float x, float y) {
|
|
|
|
mSimd.set(x, y);
|
2018-12-07 17:16:50 -08:00
|
|
|
}
|
|
|
|
|
2019-02-23 23:15:32 -08:00
|
|
|
constexpr CVector2f(float x, float y) : mSimd(x, y, 0.f, 0.f) {}
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool operator==(const CVector2f& rhs) const {
|
|
|
|
return mSimd[0] == rhs.mSimd[0] && mSimd[1] == rhs.mSimd[1];
|
|
|
|
}
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool operator!=(const CVector2f& rhs) const {
|
|
|
|
return mSimd[0] != rhs.mSimd[0] || mSimd[1] != rhs.mSimd[1];
|
|
|
|
}
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool operator<(const CVector2f& rhs) const {
|
|
|
|
return mSimd[0] < rhs.mSimd[0] && mSimd[1] < rhs.mSimd[1];
|
|
|
|
}
|
2016-04-26 03:36:44 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool operator<=(const CVector2f& rhs) const {
|
|
|
|
return mSimd[0] <= rhs.mSimd[0] && mSimd[1] <= rhs.mSimd[1];
|
|
|
|
}
|
2015-10-25 12:31:41 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool operator>(const CVector2f& rhs) const {
|
|
|
|
return mSimd[0] > rhs.mSimd[0] && mSimd[1] > rhs.mSimd[1];
|
|
|
|
}
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool operator>=(const CVector2f& rhs) const {
|
|
|
|
return mSimd[0] >= rhs.mSimd[0] && mSimd[1] >= rhs.mSimd[1];
|
|
|
|
}
|
2016-04-26 03:36:44 -07:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator+(const CVector2f& rhs) const { return mSimd + rhs.mSimd; }
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator-(const CVector2f& rhs) const { return mSimd - rhs.mSimd; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator-() const { return -mSimd; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator*(const CVector2f& rhs) const { return mSimd * rhs.mSimd; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator/(const CVector2f& rhs) const { return mSimd / rhs.mSimd; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator+(float val) const { return mSimd + simd<float>(val); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator-(float val) const { return mSimd - simd<float>(val); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator*(float val) const { return mSimd * simd<float>(val); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2022-05-31 17:17:23 -07:00
|
|
|
[[nodiscard]] CVector2f operator/(float val) const {
|
2018-12-07 17:16:50 -08:00
|
|
|
float ooval = 1.f / val;
|
|
|
|
return mSimd * simd<float>(ooval);
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator+=(const CVector2f& rhs) {
|
|
|
|
mSimd += rhs.mSimd;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator-=(const CVector2f& rhs) {
|
|
|
|
mSimd -= rhs.mSimd;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator*=(const CVector2f& rhs) {
|
|
|
|
mSimd *= rhs.mSimd;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator/=(const CVector2f& rhs) {
|
|
|
|
mSimd /= rhs.mSimd;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator+=(float rhs) {
|
|
|
|
mSimd += simd<float>(rhs);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator-=(float rhs) {
|
|
|
|
mSimd -= simd<float>(rhs);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator*=(float rhs) {
|
|
|
|
mSimd *= simd<float>(rhs);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CVector2f& operator/=(float rhs) {
|
|
|
|
float oorhs = 1.f / rhs;
|
2021-05-23 11:52:00 -07:00
|
|
|
mSimd *= simd<float>(oorhs);
|
2018-12-07 17:16:50 -08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void normalize() {
|
|
|
|
float mag = magnitude();
|
|
|
|
mag = 1.f / mag;
|
|
|
|
*this *= CVector2f(mag);
|
|
|
|
}
|
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] CVector2f normalized() const {
|
2018-12-07 17:16:50 -08:00
|
|
|
float mag = magnitude();
|
|
|
|
mag = 1.f / mag;
|
|
|
|
return *this * mag;
|
|
|
|
}
|
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
[[nodiscard]] constexpr CVector2f perpendicularVector() const { return {-y(), x()}; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
[[nodiscard]] constexpr float cross(const CVector2f& rhs) const { return (x() * rhs.y()) - (y() * rhs.x()); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
[[nodiscard]] constexpr float dot(const CVector2f& rhs) const { return mSimd.dot2(rhs.mSimd); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
[[nodiscard]] constexpr float magSquared() const { return mSimd.dot2(mSimd); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2021-01-06 17:33:36 -08:00
|
|
|
[[nodiscard]] float magnitude() const { return std::sqrt(magSquared()); }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
constexpr void zeroOut() { mSimd = 0.f; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
constexpr void splat(float xy) { mSimd = xy; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] static float getAngleDiff(const CVector2f& a, const CVector2f& b);
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] static CVector2f lerp(const CVector2f& a, const CVector2f& b, float t) {
|
2018-12-07 17:16:50 -08:00
|
|
|
return zeus::simd<float>(1.f - t) * a.mSimd + b.mSimd * zeus::simd<float>(t);
|
|
|
|
}
|
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] static CVector2f nlerp(const CVector2f& a, const CVector2f& b, float t) {
|
|
|
|
return lerp(a, b, t).normalized();
|
|
|
|
}
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] static CVector2f slerp(const CVector2f& a, const CVector2f& b, float t);
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2021-01-06 17:33:36 -08:00
|
|
|
[[nodiscard]] bool isNormalized() const { return std::fabs(1.f - magSquared()) < 0.01f; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2021-01-06 17:33:36 -08:00
|
|
|
[[nodiscard]] bool canBeNormalized() const {
|
2018-12-07 17:16:50 -08:00
|
|
|
if (std::isinf(x()) || std::isinf(y()))
|
|
|
|
return false;
|
|
|
|
return std::fabs(x()) >= FLT_EPSILON || std::fabs(y()) >= FLT_EPSILON;
|
|
|
|
}
|
|
|
|
|
2020-09-15 21:41:47 -07:00
|
|
|
[[nodiscard]] bool isZero() const { return mSimd[0] == 0.f && mSimd[1] == 0.f; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] bool isEqu(const CVector2f& other, float epsilon = FLT_EPSILON) const {
|
2018-12-07 17:16:50 -08:00
|
|
|
const CVector2f diffVec = other - *this;
|
|
|
|
return (diffVec.x() <= epsilon && diffVec.y() <= epsilon);
|
|
|
|
}
|
|
|
|
|
2021-02-15 18:03:44 -08:00
|
|
|
[[nodiscard]] simd<float>::reference operator[](size_t idx) {
|
2018-12-07 17:16:50 -08:00
|
|
|
assert(idx < 2);
|
|
|
|
return mSimd[idx];
|
|
|
|
}
|
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
[[nodiscard]] constexpr float operator[](size_t idx) const {
|
2018-12-07 17:16:50 -08:00
|
|
|
assert(idx < 2);
|
|
|
|
return mSimd[idx];
|
|
|
|
}
|
|
|
|
|
2020-05-01 16:20:31 -07:00
|
|
|
[[nodiscard]] constexpr float x() const { return mSimd[0]; }
|
|
|
|
[[nodiscard]] constexpr float y() const { return mSimd[1]; }
|
2018-12-07 17:16:50 -08:00
|
|
|
|
2021-02-15 18:03:44 -08:00
|
|
|
[[nodiscard]] simd<float>::reference x() { return mSimd[0]; }
|
|
|
|
[[nodiscard]] simd<float>::reference y() { return mSimd[1]; }
|
2015-05-03 22:41:38 -07:00
|
|
|
};
|
2020-04-19 00:16:34 -07:00
|
|
|
constexpr inline CVector2f skOne2f(1.f);
|
|
|
|
constexpr inline CVector2f skNegOne2f(-1.f);
|
|
|
|
constexpr inline CVector2f skZero2f(0.f);
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] inline CVector2f operator+(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) + rhs.mSimd; }
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] inline CVector2f operator-(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) - rhs.mSimd; }
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] inline CVector2f operator*(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) * rhs.mSimd; }
|
2015-05-03 22:41:38 -07:00
|
|
|
|
2020-02-29 01:33:29 -08:00
|
|
|
[[nodiscard]] inline CVector2f operator/(float lhs, const CVector2f& rhs) { return zeus::simd<float>(lhs) / rhs.mSimd; }
|
2018-12-07 21:23:50 -08:00
|
|
|
} // namespace zeus
|