#ifndef MATH_QUAT_H #define MATH_QUAT_H #include namespace engine::math { struct Quaternion { static constexpr Quaternion zero() { return {0.f, 0.f, 0.f, 0.f}; } static constexpr Quaternion one() { return {1.f, 0.f, 0.f, 0.f}; } static constexpr Quaternion euler_zxy(float rx, float ry, float rz) { float ca = std::cos(rx / 2.f), sa = std::sin(rx / 2.f), cb = std::cos(ry / 2.f), sb = std::sin(ry / 2.f), cc = std::cos(rz / 2.f), sc = std::sin(rz / 2.f); return { ca * cb * cc + sa * sb * sc, sa * cb * cc + ca * sb * sc, ca * sb * cc - sa * cb * sc, ca * cb * sc - sa * sb * cc, }; } static constexpr Quaternion rot_y(float a) { return {std::cos(a / 2.f), 0.f, std::sin(a / 2.f), 0.f}; } float w, x, y, z; constexpr Quaternion() {} constexpr Quaternion(float w, float x, float y, float z) : w{w}, x{x}, y{y}, z{z} {} constexpr bool operator==(const Quaternion& other) const & { return w == other.w && x == other.x && y == other.y && z == other.z; } constexpr bool operator!=(const Quaternion& other) const & { return !(*this == other); } constexpr Quaternion operator+() const & { return *this; } constexpr Quaternion operator-() const & { return { -w, -x, -y, -z }; } constexpr Quaternion operator+(const Quaternion& other) const & { return { w + other.w, x + other.x, y + other.y, z + other.z }; } constexpr Quaternion operator-(const Quaternion& other) const & { return *this + (-other); } constexpr Quaternion operator*(const Quaternion& other) const & { return { w * other.w - x * other.x - y * other.y - z * other.z, w * other.x + x * other.w + y * other.z - z * other.y, w * other.y + y * other.w + z * other.x - x * other.z, w * other.z + z * other.w + x * other.y - y * other.x, }; } constexpr Quaternion conjugate() const & { return {w, -x, -y, -z}; } }; } #endif // MATH_QUAT_H