Refactors Vector operations for type safety

Ensures type safety in Vector2, Vector3, and Vector4 operations by using static_cast(0) instead of relying on implicit conversions.
This prevents potential issues with different numeric types.

Adds from_im_vec2 and from_im_vec4 methods for creating vectors from ImVec2/ImVec4 types.
This commit is contained in:
2025-08-06 06:06:42 +03:00
parent 21ec23d77b
commit 08d2ccc03a
3 changed files with 19 additions and 8 deletions

View File

@@ -142,7 +142,7 @@ namespace omath
[[nodiscard]] Vector2 normalized() const noexcept [[nodiscard]] Vector2 normalized() const noexcept
{ {
const Type len = length(); const Type len = length();
return len > 0.f ? *this / len : *this; return len > static_cast<Type>(0) ? *this / len : *this;
} }
#endif #endif
[[nodiscard]] constexpr Type length_sqr() const noexcept [[nodiscard]] constexpr Type length_sqr() const noexcept
@@ -153,8 +153,8 @@ namespace omath
constexpr Vector2& abs() noexcept constexpr Vector2& abs() noexcept
{ {
// FIXME: Replace with std::abs, if it will become constexprable // FIXME: Replace with std::abs, if it will become constexprable
x = x < 0 ? -x : x; x = x < static_cast<Type>(0) ? -x : x;
y = y < 0 ? -y : y; y = y < static_cast<Type>(0) ? -y : y;
return *this; return *this;
} }
@@ -202,6 +202,11 @@ namespace omath
{ {
return {static_cast<float>(this->x), static_cast<float>(this->y)}; return {static_cast<float>(this->x), static_cast<float>(this->y)};
} }
[[nodiscard]]
static Vector3<float> from_im_vec2(const ImVec2& other) noexcept
{
return {static_cast<Type>(other.x), static_cast<Type>(other.y)};
}
#endif #endif
}; };
} // namespace omath } // namespace omath

View File

@@ -151,7 +151,7 @@ namespace omath
{ {
const Type len = this->length(); const Type len = this->length();
return len != 0 ? *this / len : *this; return len != static_cast<Type>(0) ? *this / len : *this;
} }
[[nodiscard]] Type length_2d() const noexcept [[nodiscard]] Type length_2d() const noexcept
@@ -221,7 +221,7 @@ namespace omath
{ {
const auto bottom = length() * other.length(); const auto bottom = length() * other.length();
if (bottom == 0.f) if (bottom == static_cast<Type>(0))
return std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE); return std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE);
return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom)); return Angle<float, 0.f, 180.f, AngleFlags::Clamped>::from_radians(std::acos(dot(other) / bottom));
@@ -230,7 +230,7 @@ namespace omath
[[nodiscard]] bool is_perpendicular(const Vector3& other) const noexcept [[nodiscard]] bool is_perpendicular(const Vector3& other) const noexcept
{ {
if (const auto angle = angle_between(other)) if (const auto angle = angle_between(other))
return angle->as_degrees() == 90.f; return angle->as_degrees() == static_cast<Type>(90);
return false; return false;
} }

View File

@@ -18,7 +18,7 @@ namespace omath
constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w): Vector3<Type>(x, y, z), w(w) constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w): Vector3<Type>(x, y, z), w(w)
{ {
} }
constexpr Vector4() noexcept : Vector3<Type>(), w(0) {}; constexpr Vector4() noexcept: Vector3<Type>(), w(static_cast<Type>(0)) {};
[[nodiscard]] [[nodiscard]]
constexpr bool operator==(const Vector4& other) const noexcept constexpr bool operator==(const Vector4& other) const noexcept
@@ -169,6 +169,12 @@ namespace omath
static_cast<float>(w), static_cast<float>(w),
}; };
} }
[[nodiscard]]
static Vector4<float> from_im_vec4(const ImVec4& other) noexcept
{
return {static_cast<Type>(other.x), static_cast<Type>(other.y), static_cast<Type>(other.z)};
}
}
#endif #endif
}; };
} // namespace omath } // namespace omath