diff --git a/src/Magnum/Math/Test/VectorTest.cpp b/src/Magnum/Math/Test/VectorTest.cpp index 5ce3e22a1..64c6ec747 100644 --- a/src/Magnum/Math/Test/VectorTest.cpp +++ b/src/Magnum/Math/Test/VectorTest.cpp @@ -68,7 +68,8 @@ struct VectorTest: Corrade::TestSuite::Tester { void constructCopy(); void convert(); - void isZero(); + void isZeroFloat(); + void isZeroInteger(); void isNormalized(); void data(); @@ -125,7 +126,8 @@ VectorTest::VectorTest() { &VectorTest::constructCopy, &VectorTest::convert, - &VectorTest::isZero, + &VectorTest::isZeroFloat, + &VectorTest::isZeroInteger, &VectorTest::isNormalized, &VectorTest::data, @@ -256,11 +258,17 @@ void VectorTest::convert() { CORRADE_VERIFY(!(std::is_convertible::value)); } -void VectorTest::isZero() { +void VectorTest::isZeroFloat() { CORRADE_VERIFY(!Vector3(0.01f, 0.0f, 0.0f).isZero()); + CORRADE_VERIFY(Vector3(0.0f, Math::TypeTraits::epsilon()/2.0f, 0.0f).isZero()); CORRADE_VERIFY(Vector3(0.0f, 0.0f, 0.0f).isZero()); } +void VectorTest::isZeroInteger() { + CORRADE_VERIFY(!(Math::Vector<3, Int>{0, 1, 0}.isZero())); + CORRADE_VERIFY((Math::Vector<3, Int>{0, 0, 0}.isZero())); +} + void VectorTest::isNormalized() { CORRADE_VERIFY(!Vector3(1.0f, 2.0f, -1.0f).isNormalized()); CORRADE_VERIFY(Vector3(0.0f, 1.0f, 0.0f).isNormalized()); diff --git a/src/Magnum/Math/TypeTraits.h b/src/Magnum/Math/TypeTraits.h index 9c22105a9..7a081dc94 100644 --- a/src/Magnum/Math/TypeTraits.h +++ b/src/Magnum/Math/TypeTraits.h @@ -198,12 +198,6 @@ template<> struct TypeTraits: Implementation::TypeTraitsFloatingPoi namespace Implementation { -/* Proper comparison should be with epsilon^2, but the value is not - representable in given precision. Comparing to epsilon instead. */ -template inline bool isZeroSquared(T lengthSquared) { - return std::abs(lengthSquared) < TypeTraits::epsilon(); -} - /* Comparing squared length to 1 is not sufficient to compare within range [1 - epsilon, 1 + epsilon], as e.g. Quaternion with dot() = 1 + 1e-7 when converted to matrix has column vectors with dot() = 1 + 1e-6, which is just diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index cc10cccc3..8d8fc5bcf 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -54,6 +54,20 @@ namespace Implementation { template T lerp(const T& a, const T& b, U t) { return T((U(1) - t)*a + t*b); } + + template struct IsZero; + template<> struct IsZero { + template bool operator()(const Vector& vec) const { + /* Proper comparison should be with epsilon^2, but the value is not + representable in given precision. Comparing to epsilon instead. */ + return std::abs(vec.dot()) < TypeTraits::epsilon(); + } + }; + template<> struct IsZero { + template bool operator()(const Vector& vec) const { + return vec == Vector{}; + } + }; } /** @relatesalso Vector @@ -262,7 +276,7 @@ template class Vector { * @see @ref dot(), @ref normalized() */ bool isZero() const { - return Implementation::isZeroSquared(dot()); + return Implementation::IsZero::value>{}(*this); } /**