// // Vector4.h // #pragma once #include #include namespace omath { template requires std::is_arithmetic_v class Vector4 : public Vector3 { public: Type w; constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w): Vector3(x, y, z), w(w) { } constexpr Vector4() noexcept : Vector3(), w(0) {}; [[nodiscard]] constexpr bool operator==(const Vector4& other) const noexcept { return Vector3::operator==(other) && w == other.w; } [[nodiscard]] constexpr bool operator!=(const Vector4& other) const noexcept { return !(*this == other); } constexpr Vector4& operator+=(const Vector4& other) noexcept { Vector3::operator+=(other); w += other.w; return *this; } constexpr Vector4& operator-=(const Vector4& other) noexcept { Vector3::operator-=(other); w -= other.w; return *this; } constexpr Vector4& operator*=(const Type& value) noexcept { Vector3::operator*=(value); w *= value; return *this; } constexpr Vector4& operator*=(const Vector4& other) noexcept { Vector3::operator*=(other); w *= other.w; return *this; } constexpr Vector4& operator/=(const Type& value) noexcept { Vector3::operator/=(value); w /= value; return *this; } constexpr Vector4& operator/=(const Vector4& other) noexcept { Vector3::operator/=(other); w /= other.w; return *this; } [[nodiscard]] constexpr Type length_sqr() const noexcept { return Vector3::length_sqr() + w * w; } [[nodiscard]] constexpr Type dot(const Vector4& other) const noexcept { return Vector3::dot(other) + w * other.w; } [[nodiscard]] Vector3 length() const noexcept { return std::sqrt(length_sqr()); } constexpr Vector4& abs() noexcept { Vector3::abs(); w = w < 0.f ? -w : w; return *this; } constexpr Vector4& clamp(const Type& min, const Type& max) noexcept { this->x = std::clamp(this->x, min, max); this->y = std::clamp(this->y, min, max); this->z = std::clamp(this->z, min, max); return *this; } [[nodiscard]] constexpr Vector4 operator-() const noexcept { return {-this->x, -this->y, -this->z, -w}; } [[nodiscard]] constexpr Vector4 operator+(const Vector4& other) const noexcept { return {this->x + other.x, this->y + other.y, this->z + other.z, w + other.w}; } [[nodiscard]] constexpr Vector4 operator-(const Vector4& other) const noexcept { return {this->x - other.x, this->y - other.y, this->z - other.z, w - other.w}; } [[nodiscard]] constexpr Vector4 operator*(const Type& value) const noexcept { return {this->x * value, this->y * value, this->z * value, w * value}; } [[nodiscard]] constexpr Vector4 operator*(const Vector4& other) const noexcept { return {this->x * other.x, this->y * other.y, this->z * other.z, w * other.w}; } [[nodiscard]] constexpr Vector4 operator/(const Type& value) const noexcept { return {this->x / value, this->y / value, this->z / value, w / value}; } [[nodiscard]] constexpr Vector4 operator/(const Vector4& other) const noexcept { return {this->x / other.x, this->y / other.y, this->z / other.z, w / other.w}; } [[nodiscard]] constexpr Type sum() const noexcept { return Vector3::sum() + w; } #ifdef OMATH_IMGUI_INTEGRATION [[nodiscard]] ImVec4 to_im_vec4() const noexcept { return { static_cast(this->x), static_cast(this->y), static_cast(this->z), static_cast(w), }; } #endif }; } // namespace omath