Browse Source

Math: renamed MathTypeTraits to TypeTraits.

As there is no Magnum::TypeTraits struct anymore, there is no need to
have redundant name in it. Hopefully Doxygen will handle the difference
between this and Corrade's TypeTraits.h properly.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
408f40a908
  1. 2
      src/Color.h
  2. 6
      src/DebugTools/Implementation/ForceRendererTransformation.h
  3. 2
      src/Math/Algorithms/GaussJordan.h
  4. 6
      src/Math/Algorithms/Svd.h
  5. 2
      src/Math/CMakeLists.txt
  6. 8
      src/Math/Complex.h
  7. 2
      src/Math/Constants.h
  8. 6
      src/Math/Dual.h
  9. 2
      src/Math/Matrix3.h
  10. 4
      src/Math/Matrix4.h
  11. 20
      src/Math/Quaternion.h
  12. 2
      src/Math/Test/CMakeLists.txt
  13. 8
      src/Math/Test/ComplexTest.cpp
  14. 8
      src/Math/Test/DualTest.cpp
  15. 8
      src/Math/Test/QuaternionTest.cpp
  16. 4
      src/Math/Test/RectangularMatrixTest.cpp
  17. 32
      src/Math/Test/TypeTraitsTest.cpp
  18. 4
      src/Math/Test/UnitTest.cpp
  19. 4
      src/Math/Test/VectorTest.cpp
  20. 42
      src/Math/TypeTraits.h
  21. 4
      src/Math/Unit.h
  22. 8
      src/Math/Vector.h
  23. 4
      src/MeshTools/Clean.h

2
src/Color.h

@ -158,7 +158,7 @@ template<class T = Float>
class Color3: public Math::Vector3<T> { class Color3: public Math::Vector3<T> {
public: public:
/** @brief Corresponding floating-point type for HSV computation */ /** @brief Corresponding floating-point type for HSV computation */
typedef typename Math::MathTypeTraits<T>::FloatingPointType FloatingPointType; typedef typename Math::TypeTraits<T>::FloatingPointType FloatingPointType;
/** /**
* @brief Type for storing HSV values * @brief Type for storing HSV values

6
src/DebugTools/Implementation/ForceRendererTransformation.h

@ -42,17 +42,17 @@ template<> inline Matrix4 forceRendererTransformation<3>(const Vector3& forcePos
const Float forceLength = force.length(); const Float forceLength = force.length();
/* Zero length, zero scaling */ /* Zero length, zero scaling */
if(forceLength < Math::MathTypeTraits<Float>::epsilon()) if(forceLength < Math::TypeTraits<Float>::epsilon())
return translation*Matrix4::scaling(Vector3(0.0f)); return translation*Matrix4::scaling(Vector3(0.0f));
const Float dot = Vector3::dot(force/forceLength, Vector3::xAxis()); const Float dot = Vector3::dot(force/forceLength, Vector3::xAxis());
/* Force is parallel to X axis, just scaling */ /* Force is parallel to X axis, just scaling */
if(dot > 1.0f - Math::MathTypeTraits<Float>::epsilon()) if(dot > 1.0f - Math::TypeTraits<Float>::epsilon())
return translation*Matrix4::scaling(Vector3(forceLength)); return translation*Matrix4::scaling(Vector3(forceLength));
/* Force is antiparallel to X axis, scaling inverted on X */ /* Force is antiparallel to X axis, scaling inverted on X */
if(-dot > 1.0f - Math::MathTypeTraits<Float>::epsilon()) if(-dot > 1.0f - Math::TypeTraits<Float>::epsilon())
return translation*Matrix4::scaling({-forceLength, forceLength, forceLength}); return translation*Matrix4::scaling({-forceLength, forceLength, forceLength});
/* Normal of plane going through force vector and X axis vector */ /* Normal of plane going through force vector and X axis vector */

2
src/Math/Algorithms/GaussJordan.h

@ -64,7 +64,7 @@ template<std::size_t size, std::size_t rows, class T> bool gaussJordanInPlaceTra
std::swap(t[row], t[rowMax]); std::swap(t[row], t[rowMax]);
/* Singular */ /* Singular */
if(MathTypeTraits<T>::equals(a[row][row], T(0))) if(TypeTraits<T>::equals(a[row][row], T(0)))
return false; return false;
/* Eliminate column */ /* Eliminate column */

6
src/Math/Algorithms/Svd.h

@ -96,8 +96,8 @@ decomposition and least squares solutions"*.
/* The matrix is passed by value because it is changed inside */ /* The matrix is passed by value because it is changed inside */
template<std::size_t cols, std::size_t rows, class T> std::tuple<RectangularMatrix<cols, rows, T>, Vector<cols, T>, Matrix<cols, T>> svd(RectangularMatrix<cols, rows, T> m) { template<std::size_t cols, std::size_t rows, class T> std::tuple<RectangularMatrix<cols, rows, T>, Vector<cols, T>, Matrix<cols, T>> svd(RectangularMatrix<cols, rows, T> m) {
static_assert(rows >= cols, "Unsupported matrix aspect ratio"); static_assert(rows >= cols, "Unsupported matrix aspect ratio");
static_assert(T(1)+MathTypeTraits<T>::epsilon() > T(1), "Epsilon too small"); static_assert(T(1)+TypeTraits<T>::epsilon() > T(1), "Epsilon too small");
constexpr T tol = Implementation::smallestDelta<T>()/MathTypeTraits<T>::epsilon(); constexpr T tol = Implementation::smallestDelta<T>()/TypeTraits<T>::epsilon();
static_assert(tol > T(0), "Tol too small"); static_assert(tol > T(0), "Tol too small");
constexpr std::size_t maxIterations = 50; constexpr std::size_t maxIterations = 50;
@ -212,7 +212,7 @@ template<std::size_t cols, std::size_t rows, class T> std::tuple<RectangularMatr
} }
/* Diagonalization of the bidiagonal form */ /* Diagonalization of the bidiagonal form */
const T epsilon = MathTypeTraits<T>::epsilon()*epsilonX; const T epsilon = TypeTraits<T>::epsilon()*epsilonX;
for(std::size_t k2 = cols; k2 != 0; --k2) { for(std::size_t k2 = cols; k2 != 0; --k2) {
const std::size_t k = k2 - 1; const std::size_t k = k2 - 1;

2
src/Math/CMakeLists.txt

@ -32,7 +32,7 @@ set(MagnumMath_HEADERS
DualQuaternion.h DualQuaternion.h
Functions.h Functions.h
Math.h Math.h
MathTypeTraits.h TypeTraits.h
Matrix.h Matrix.h
Matrix3.h Matrix3.h
Matrix4.h Matrix4.h

8
src/Math/Complex.h

@ -69,7 +69,7 @@ template<class T> class Complex {
* @see Quaternion::angle(), Vector::angle() * @see Quaternion::angle(), Vector::angle()
*/ */
inline static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) { inline static Rad<T> angle(const Complex<T>& normalizedA, const Complex<T>& normalizedB) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
"Math::Complex::angle(): complex numbers must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN())); "Math::Complex::angle(): complex numbers must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(std::acos(normalizedA._real*normalizedB._real + normalizedA._imaginary*normalizedB._imaginary)); return Rad<T>(std::acos(normalizedA._real*normalizedB._real + normalizedA._imaginary*normalizedB._imaginary));
} }
@ -117,8 +117,8 @@ template<class T> class Complex {
/** @brief Equality comparison */ /** @brief Equality comparison */
inline bool operator==(const Complex<T>& other) const { inline bool operator==(const Complex<T>& other) const {
return MathTypeTraits<T>::equals(_real, other._real) && return TypeTraits<T>::equals(_real, other._real) &&
MathTypeTraits<T>::equals(_imaginary, other._imaginary); TypeTraits<T>::equals(_imaginary, other._imaginary);
} }
/** @brief Non-equality comparison */ /** @brief Non-equality comparison */
@ -345,7 +345,7 @@ template<class T> class Complex {
* @see inverted() * @see inverted()
*/ */
inline Complex<T> invertedNormalized() const { inline Complex<T> invertedNormalized() const {
CORRADE_ASSERT(MathTypeTraits<T>::equals(dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(dot(), T(1)),
"Math::Complex::invertedNormalized(): complex number must be normalized", "Math::Complex::invertedNormalized(): complex number must be normalized",
Complex<T>(std::numeric_limits<T>::quiet_NaN(), {})); Complex<T>(std::numeric_limits<T>::quiet_NaN(), {}));
return conjugated(); return conjugated();

2
src/Math/Constants.h

@ -40,7 +40,7 @@ namespace Magnum { namespace Math {
template<class T> struct Constants { template<class T> struct Constants {
Constants() = delete; Constants() = delete;
/* See MathTypeTraits for answer why these are functions and not constants. */ /* See TypeTraits for answer why these are functions and not constants. */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
/** /**
* @brief Pi * @brief Pi

6
src/Math/Dual.h

@ -31,7 +31,7 @@
#include <cmath> #include <cmath>
#include <Utility/Debug.h> #include <Utility/Debug.h>
#include "Math/MathTypeTraits.h" #include "Math/TypeTraits.h"
namespace Magnum { namespace Math { namespace Magnum { namespace Math {
@ -63,8 +63,8 @@ template<class T> class Dual {
/** @brief Equality comparison */ /** @brief Equality comparison */
inline bool operator==(const Dual<T>& other) const { inline bool operator==(const Dual<T>& other) const {
return MathTypeTraits<T>::equals(_real, other._real) && return TypeTraits<T>::equals(_real, other._real) &&
MathTypeTraits<T>::equals(_dual, other._dual); TypeTraits<T>::equals(_dual, other._dual);
} }
/** @brief Non-equality comparison */ /** @brief Non-equality comparison */

2
src/Math/Matrix3.h

@ -96,7 +96,7 @@ template<class T> class Matrix3: public Matrix<3, T> {
* @see Matrix4::reflection() * @see Matrix4::reflection()
*/ */
static Matrix3<T> reflection(const Vector2<T>& normal) { static Matrix3<T> reflection(const Vector2<T>& normal) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normal.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normal.dot(), T(1)),
"Math::Matrix3::reflection(): normal must be normalized", {}); "Math::Matrix3::reflection(): normal must be normalized", {});
return from(Matrix<2, T>() - T(2)*normal*RectangularMatrix<1, 2, T>(normal).transposed(), {}); return from(Matrix<2, T>() - T(2)*normal*RectangularMatrix<1, 2, T>(normal).transposed(), {});
} }

4
src/Math/Matrix4.h

@ -91,7 +91,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* Vector3::zAxis() * Vector3::zAxis()
*/ */
static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) { static Matrix4<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedAxis.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedAxis.dot(), T(1)),
"Math::Matrix4::rotation(): axis must be normalized", {}); "Math::Matrix4::rotation(): axis must be normalized", {});
T sine = std::sin(T(angle)); T sine = std::sin(T(angle));
@ -184,7 +184,7 @@ template<class T> class Matrix4: public Matrix<4, T> {
* @see Matrix3::reflection() * @see Matrix3::reflection()
*/ */
static Matrix4<T> reflection(const Vector3<T>& normal) { static Matrix4<T> reflection(const Vector3<T>& normal) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normal.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normal.dot(), T(1)),
"Math::Matrix4::reflection(): normal must be normalized", {}); "Math::Matrix4::reflection(): normal must be normalized", {});
return from(Matrix<3, T>() - T(2)*normal*RectangularMatrix<1, 3, T>(normal).transposed(), {}); return from(Matrix<3, T>() - T(2)*normal*RectangularMatrix<1, 3, T>(normal).transposed(), {});
} }

20
src/Math/Quaternion.h

@ -32,7 +32,7 @@
#include <Utility/Assert.h> #include <Utility/Assert.h>
#include <Utility/Debug.h> #include <Utility/Debug.h>
#include "Math/MathTypeTraits.h" #include "Math/TypeTraits.h"
#include "Math/Matrix.h" #include "Math/Matrix.h"
#include "Math/Vector3.h" #include "Math/Vector3.h"
@ -71,7 +71,7 @@ template<class T> class Quaternion {
* @see Complex::angle(), Vector::angle() * @see Complex::angle(), Vector::angle()
*/ */
inline static Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB) { inline static Rad<T> angle(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
"Math::Quaternion::angle(): quaternions must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN())); "Math::Quaternion::angle(): quaternions must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(angleInternal(normalizedA, normalizedB)); return Rad<T>(angleInternal(normalizedA, normalizedB));
} }
@ -88,7 +88,7 @@ template<class T> class Quaternion {
* @see slerp(), Math::lerp() * @see slerp(), Math::lerp()
*/ */
inline static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) { inline static Quaternion<T> lerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
"Math::Quaternion::lerp(): quaternions must be normalized", "Math::Quaternion::lerp(): quaternions must be normalized",
Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN())); Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN()));
return ((T(1) - t)*normalizedA + t*normalizedB).normalized(); return ((T(1) - t)*normalizedA + t*normalizedB).normalized();
@ -108,7 +108,7 @@ template<class T> class Quaternion {
* @see lerp() * @see lerp()
*/ */
inline static Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) { inline static Quaternion<T> slerp(const Quaternion<T>& normalizedA, const Quaternion<T>& normalizedB, T t) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
"Math::Quaternion::slerp(): quaternions must be normalized", "Math::Quaternion::slerp(): quaternions must be normalized",
Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN())); Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN()));
T a = angleInternal(normalizedA, normalizedB); T a = angleInternal(normalizedA, normalizedB);
@ -128,7 +128,7 @@ template<class T> class Quaternion {
* Vector3::yAxis(), Vector3::zAxis() * Vector3::yAxis(), Vector3::zAxis()
*/ */
inline static Quaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) { inline static Quaternion<T> rotation(Rad<T> angle, const Vector3<T>& normalizedAxis) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedAxis.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedAxis.dot(), T(1)),
"Math::Quaternion::rotation(): axis must be normalized", {}); "Math::Quaternion::rotation(): axis must be normalized", {});
return {normalizedAxis*std::sin(T(angle)/2), std::cos(T(angle)/2)}; return {normalizedAxis*std::sin(T(angle)/2), std::cos(T(angle)/2)};
@ -164,7 +164,7 @@ template<class T> class Quaternion {
/** @brief Equality comparison */ /** @brief Equality comparison */
inline bool operator==(const Quaternion<T>& other) const { inline bool operator==(const Quaternion<T>& other) const {
return _vector == other._vector && MathTypeTraits<T>::equals(_scalar, other._scalar); return _vector == other._vector && TypeTraits<T>::equals(_scalar, other._scalar);
} }
/** @brief Non-equality comparison */ /** @brief Non-equality comparison */
@ -187,7 +187,7 @@ template<class T> class Quaternion {
* @see rotationAxis(), rotation(), DualQuaternion::rotationAngle() * @see rotationAxis(), rotation(), DualQuaternion::rotationAngle()
*/ */
inline Rad<T> rotationAngle() const { inline Rad<T> rotationAngle() const {
CORRADE_ASSERT(MathTypeTraits<T>::equals(dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(dot(), T(1)),
"Math::Quaternion::rotationAngle(): quaternion must be normalized", "Math::Quaternion::rotationAngle(): quaternion must be normalized",
Rad<T>(std::numeric_limits<T>::quiet_NaN())); Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(T(2)*std::acos(_scalar)); return Rad<T>(T(2)*std::acos(_scalar));
@ -204,7 +204,7 @@ template<class T> class Quaternion {
* @see rotationAngle(), rotation() * @see rotationAngle(), rotation()
*/ */
inline Vector3<T> rotationAxis() const { inline Vector3<T> rotationAxis() const {
CORRADE_ASSERT(MathTypeTraits<T>::equals(dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(dot(), T(1)),
"Math::Quaternion::rotationAxis(): quaternion must be normalized", "Math::Quaternion::rotationAxis(): quaternion must be normalized",
{}); {});
return _vector/std::sqrt(1-pow2(_scalar)); return _vector/std::sqrt(1-pow2(_scalar));
@ -404,7 +404,7 @@ template<class T> class Quaternion {
* @see inverted() * @see inverted()
*/ */
inline Quaternion<T> invertedNormalized() const { inline Quaternion<T> invertedNormalized() const {
CORRADE_ASSERT(MathTypeTraits<T>::equals(dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(dot(), T(1)),
"Math::Quaternion::invertedNormalized(): quaternion must be normalized", "Math::Quaternion::invertedNormalized(): quaternion must be normalized",
Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN())); Quaternion<T>({}, std::numeric_limits<T>::quiet_NaN()));
return conjugated(); return conjugated();
@ -435,7 +435,7 @@ template<class T> class Quaternion {
* DualQuaternion::transformPointNormalized(), Complex::transformVector() * DualQuaternion::transformPointNormalized(), Complex::transformVector()
*/ */
inline Vector3<T> transformVectorNormalized(const Vector3<T>& vector) const { inline Vector3<T> transformVectorNormalized(const Vector3<T>& vector) const {
CORRADE_ASSERT(MathTypeTraits<T>::equals(dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(dot(), T(1)),
"Math::Quaternion::transformVectorNormalized(): quaternion must be normalized", "Math::Quaternion::transformVectorNormalized(): quaternion must be normalized",
Vector3<T>(std::numeric_limits<T>::quiet_NaN())); Vector3<T>(std::numeric_limits<T>::quiet_NaN()));
return ((*this)*Quaternion<T>(vector)*conjugated()).vector(); return ((*this)*Quaternion<T>(vector)*conjugated()).vector();

2
src/Math/Test/CMakeLists.txt

@ -25,7 +25,7 @@
corrade_add_test(MathBoolVectorTest BoolVectorTest.cpp) corrade_add_test(MathBoolVectorTest BoolVectorTest.cpp)
corrade_add_test(MathConstantsTest ConstantsTest.cpp) corrade_add_test(MathConstantsTest ConstantsTest.cpp)
corrade_add_test(MathFunctionsTest FunctionsTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathFunctionsTest FunctionsTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathMathTypeTraitsTest MathTypeTraitsTest.cpp) corrade_add_test(MathTypeTraitsTest TypeTraitsTest.cpp)
corrade_add_test(MathVectorTest VectorTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVectorTest VectorTest.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVector2Test Vector2Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVector2Test Vector2Test.cpp LIBRARIES MagnumMathTestLib)

8
src/Math/Test/ComplexTest.cpp

@ -120,10 +120,10 @@ void ComplexTest::constructFromVector() {
} }
void ComplexTest::compare() { void ComplexTest::compare() {
CORRADE_VERIFY(Complex(3.7f, -1.0f+MathTypeTraits<Float>::epsilon()/2) == Complex(3.7f, -1.0f)); CORRADE_VERIFY(Complex(3.7f, -1.0f+TypeTraits<Float>::epsilon()/2) == Complex(3.7f, -1.0f));
CORRADE_VERIFY(Complex(3.7f, -1.0f+MathTypeTraits<Float>::epsilon()*2) != Complex(3.7f, -1.0f)); CORRADE_VERIFY(Complex(3.7f, -1.0f+TypeTraits<Float>::epsilon()*2) != Complex(3.7f, -1.0f));
CORRADE_VERIFY(Complex(1.0f+MathTypeTraits<Float>::epsilon()/2, 3.7f) == Complex(1.0f, 3.7f)); CORRADE_VERIFY(Complex(1.0f+TypeTraits<Float>::epsilon()/2, 3.7f) == Complex(1.0f, 3.7f));
CORRADE_VERIFY(Complex(1.0f+MathTypeTraits<Float>::epsilon()*2, 3.7f) != Complex(1.0f, 3.7f)); CORRADE_VERIFY(Complex(1.0f+TypeTraits<Float>::epsilon()*2, 3.7f) != Complex(1.0f, 3.7f));
} }
void ComplexTest::constExpressions() { void ComplexTest::constExpressions() {

8
src/Math/Test/DualTest.cpp

@ -83,10 +83,10 @@ void DualTest::constructDefault() {
} }
void DualTest::compare() { void DualTest::compare() {
CORRADE_VERIFY(Dual(1.0f, 1.0f+MathTypeTraits<Float>::epsilon()/2) == Dual(1.0f, 1.0f)); CORRADE_VERIFY(Dual(1.0f, 1.0f+TypeTraits<Float>::epsilon()/2) == Dual(1.0f, 1.0f));
CORRADE_VERIFY(Dual(1.0f, 1.0f+MathTypeTraits<Float>::epsilon()*2) != Dual(1.0f, 1.0f)); CORRADE_VERIFY(Dual(1.0f, 1.0f+TypeTraits<Float>::epsilon()*2) != Dual(1.0f, 1.0f));
CORRADE_VERIFY(Dual(1.0f+MathTypeTraits<Float>::epsilon()/2, 1.0f) == Dual(1.0f, 1.0f)); CORRADE_VERIFY(Dual(1.0f+TypeTraits<Float>::epsilon()/2, 1.0f) == Dual(1.0f, 1.0f));
CORRADE_VERIFY(Dual(1.0f+MathTypeTraits<Float>::epsilon()*2, 1.0f) != Dual(1.0f, 1.0f)); CORRADE_VERIFY(Dual(1.0f+TypeTraits<Float>::epsilon()*2, 1.0f) != Dual(1.0f, 1.0f));
/* Compare to real part only */ /* Compare to real part only */
CORRADE_VERIFY(Dual(1.0f, 0.0f) == 1.0f); CORRADE_VERIFY(Dual(1.0f, 0.0f) == 1.0f);

8
src/Math/Test/QuaternionTest.cpp

@ -123,10 +123,10 @@ void QuaternionTest::constructFromVector() {
} }
void QuaternionTest::compare() { void QuaternionTest::compare() {
CORRADE_VERIFY(Quaternion({1.0f+MathTypeTraits<Float>::epsilon()/2, 2.0f, 3.0f}, -4.0f) == Quaternion({1.0f, 2.0f, 3.0f}, -4.0f)); CORRADE_VERIFY(Quaternion({1.0f+TypeTraits<Float>::epsilon()/2, 2.0f, 3.0f}, -4.0f) == Quaternion({1.0f, 2.0f, 3.0f}, -4.0f));
CORRADE_VERIFY(Quaternion({1.0f+MathTypeTraits<Float>::epsilon()*2, 2.0f, 3.0f}, -4.0f) != Quaternion({1.0f, 2.0f, 3.0f}, -4.0f)); CORRADE_VERIFY(Quaternion({1.0f+TypeTraits<Float>::epsilon()*2, 2.0f, 3.0f}, -4.0f) != Quaternion({1.0f, 2.0f, 3.0f}, -4.0f));
CORRADE_VERIFY(Quaternion({4.0f, 2.0f, 3.0f}, -1.0f+MathTypeTraits<Float>::epsilon()/2) == Quaternion({4.0f, 2.0f, 3.0f}, -1.0f)); CORRADE_VERIFY(Quaternion({4.0f, 2.0f, 3.0f}, -1.0f+TypeTraits<Float>::epsilon()/2) == Quaternion({4.0f, 2.0f, 3.0f}, -1.0f));
CORRADE_VERIFY(Quaternion({4.0f, 2.0f, 3.0f}, -1.0f+MathTypeTraits<Float>::epsilon()*2) != Quaternion({4.0f, 2.0f, 3.0f}, -1.0f)); CORRADE_VERIFY(Quaternion({4.0f, 2.0f, 3.0f}, -1.0f+TypeTraits<Float>::epsilon()*2) != Quaternion({4.0f, 2.0f, 3.0f}, -1.0f));
} }
void QuaternionTest::constExpressions() { void QuaternionTest::constExpressions() {

4
src/Math/Test/RectangularMatrixTest.cpp

@ -214,9 +214,9 @@ void RectangularMatrixTest::row() {
void RectangularMatrixTest::compare() { void RectangularMatrixTest::compare() {
Matrix2 a(Vector2(1.0f, -3.0f), Matrix2 a(Vector2(1.0f, -3.0f),
Vector2(5.0f, -10.0f)); Vector2(5.0f, -10.0f));
Matrix2 b(Vector2(1.0f + MathTypeTraits<Float>::epsilon()/2, -3.0f), Matrix2 b(Vector2(1.0f + TypeTraits<Float>::epsilon()/2, -3.0f),
Vector2(5.0f, -10.0f)); Vector2(5.0f, -10.0f));
Matrix2 c(Vector2(1.0f, -1.0f + MathTypeTraits<Float>::epsilon()*2), Matrix2 c(Vector2(1.0f, -1.0f + TypeTraits<Float>::epsilon()*2),
Vector2(5.0f, -10.0f)); Vector2(5.0f, -10.0f));
CORRADE_VERIFY(a == b); CORRADE_VERIFY(a == b);
CORRADE_VERIFY(a != c); CORRADE_VERIFY(a != c);

32
src/Math/Test/MathTypeTraitsTest.cpp → src/Math/Test/TypeTraitsTest.cpp

@ -25,13 +25,13 @@
#include <limits> #include <limits>
#include <TestSuite/Tester.h> #include <TestSuite/Tester.h>
#include "Math/MathTypeTraits.h" #include "Math/TypeTraits.h"
namespace Magnum { namespace Math { namespace Test { namespace Magnum { namespace Math { namespace Test {
class MathTypeTraitsTest: public Corrade::TestSuite::Tester { class TypeTraitsTest: public Corrade::TestSuite::Tester {
public: public:
MathTypeTraitsTest(); TypeTraitsTest();
void equalsFloatingPoint(); void equalsFloatingPoint();
void equalsIntegral(); void equalsIntegral();
@ -41,12 +41,12 @@ class MathTypeTraitsTest: public Corrade::TestSuite::Tester {
template<class T> void _equalsIntegral(); template<class T> void _equalsIntegral();
}; };
MathTypeTraitsTest::MathTypeTraitsTest() { TypeTraitsTest::TypeTraitsTest() {
addTests({&MathTypeTraitsTest::equalsIntegral, addTests({&TypeTraitsTest::equalsIntegral,
&MathTypeTraitsTest::equalsFloatingPoint}); &TypeTraitsTest::equalsFloatingPoint});
} }
void MathTypeTraitsTest::equalsIntegral() { void TypeTraitsTest::equalsIntegral() {
_equalsIntegral<UnsignedByte>(); _equalsIntegral<UnsignedByte>();
_equalsIntegral<Byte>(); _equalsIntegral<Byte>();
_equalsIntegral<UnsignedShort>(); _equalsIntegral<UnsignedShort>();
@ -57,29 +57,29 @@ void MathTypeTraitsTest::equalsIntegral() {
_equalsIntegral<Long>(); _equalsIntegral<Long>();
} }
void MathTypeTraitsTest::equalsFloatingPoint() { void TypeTraitsTest::equalsFloatingPoint() {
_equalsFloatingPoint<Float>(); _equalsFloatingPoint<Float>();
_equalsFloatingPoint<Double>(); _equalsFloatingPoint<Double>();
} }
template<class T> void MathTypeTraitsTest::_equalsIntegral() { template<class T> void TypeTraitsTest::_equalsIntegral() {
CORRADE_VERIFY(!MathTypeTraits<T>::equals(1, 1+MathTypeTraits<T>::epsilon())); CORRADE_VERIFY(!TypeTraits<T>::equals(1, 1+TypeTraits<T>::epsilon()));
} }
template<class T> void MathTypeTraitsTest::_equalsFloatingPoint() { template<class T> void TypeTraitsTest::_equalsFloatingPoint() {
CORRADE_VERIFY(MathTypeTraits<T>::equals(T(1)+MathTypeTraits<T>::epsilon()/T(2), T(1))); CORRADE_VERIFY(TypeTraits<T>::equals(T(1)+TypeTraits<T>::epsilon()/T(2), T(1)));
CORRADE_VERIFY(!MathTypeTraits<T>::equals(T(1)+MathTypeTraits<T>::epsilon()*T(2), T(1))); CORRADE_VERIFY(!TypeTraits<T>::equals(T(1)+TypeTraits<T>::epsilon()*T(2), T(1)));
{ {
CORRADE_EXPECT_FAIL("Comparing to infinity is broken"); CORRADE_EXPECT_FAIL("Comparing to infinity is broken");
CORRADE_VERIFY(MathTypeTraits<T>::equals(std::numeric_limits<T>::infinity(), CORRADE_VERIFY(TypeTraits<T>::equals(std::numeric_limits<T>::infinity(),
std::numeric_limits<T>::infinity())); std::numeric_limits<T>::infinity()));
} }
CORRADE_VERIFY(!MathTypeTraits<T>::equals(std::numeric_limits<T>::quiet_NaN(), CORRADE_VERIFY(!TypeTraits<T>::equals(std::numeric_limits<T>::quiet_NaN(),
std::numeric_limits<T>::quiet_NaN())); std::numeric_limits<T>::quiet_NaN()));
} }
}}} }}}
CORRADE_TEST_MAIN(Magnum::Math::Test::MathTypeTraitsTest) CORRADE_TEST_MAIN(Magnum::Math::Test::TypeTraitsTest)

4
src/Math/Test/UnitTest.cpp

@ -78,8 +78,8 @@ void UnitTest::constructConversion() {
} }
void UnitTest::compare() { void UnitTest::compare() {
CORRADE_VERIFY(Sec(25.0f + MathTypeTraits<Float>::epsilon()/2) == Sec(25.0f)); CORRADE_VERIFY(Sec(25.0f + TypeTraits<Float>::epsilon()/2) == Sec(25.0f));
CORRADE_VERIFY(Sec(25.0f + MathTypeTraits<Float>::epsilon()*2) != Sec(25.0f)); CORRADE_VERIFY(Sec(25.0f + TypeTraits<Float>::epsilon()*2) != Sec(25.0f));
constexpr bool c = Sec(3.0f) < Sec(3.0f); constexpr bool c = Sec(3.0f) < Sec(3.0f);
constexpr bool d = Sec(3.0f) <= Sec(3.0f); constexpr bool d = Sec(3.0f) <= Sec(3.0f);

4
src/Math/Test/VectorTest.cpp

@ -215,8 +215,8 @@ void VectorTest::data() {
} }
void VectorTest::compare() { void VectorTest::compare() {
CORRADE_VERIFY(Vector4(1.0f, -3.5f, 5.0f, -10.0f) == Vector4(1.0f + MathTypeTraits<Float>::epsilon()/2, -3.5f, 5.0f, -10.0f)); CORRADE_VERIFY(Vector4(1.0f, -3.5f, 5.0f, -10.0f) == Vector4(1.0f + TypeTraits<Float>::epsilon()/2, -3.5f, 5.0f, -10.0f));
CORRADE_VERIFY(Vector4(1.0f, -1.0f, 5.0f, -10.0f) != Vector4(1.0f, -1.0f + MathTypeTraits<Float>::epsilon()*2, 5.0f, -10.0f)); CORRADE_VERIFY(Vector4(1.0f, -1.0f, 5.0f, -10.0f) != Vector4(1.0f, -1.0f + TypeTraits<Float>::epsilon()*2, 5.0f, -10.0f));
CORRADE_VERIFY(Vector4i(1, -3, 5, -10) == Vector4i(1, -3, 5, -10)); CORRADE_VERIFY(Vector4i(1, -3, 5, -10) == Vector4i(1, -3, 5, -10));
CORRADE_VERIFY(Vector4i(1, -3, 5, -10) != Vector4i(1, -2, 5, -10)); CORRADE_VERIFY(Vector4i(1, -3, 5, -10) != Vector4i(1, -2, 5, -10));

42
src/Math/MathTypeTraits.h → src/Math/TypeTraits.h

@ -1,5 +1,5 @@
#ifndef Magnum_Math_MathTypeTraits_h #ifndef Magnum_Math_TypeTraits_h
#define Magnum_Math_MathTypeTraits_h #define Magnum_Math_TypeTraits_h
/* /*
This file is part of Magnum. This file is part of Magnum.
@ -25,7 +25,7 @@
*/ */
/** @file /** @file
* @brief Class Magnum::Math::MathTypeTraits * @brief Class Magnum::Math::TypeTraits
*/ */
#include <cmath> #include <cmath>
@ -54,8 +54,8 @@ namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation { namespace Implementation {
template<class T> struct MathTypeTraitsDefault { template<class T> struct TypeTraitsDefault {
MathTypeTraitsDefault() = delete; TypeTraitsDefault() = delete;
inline constexpr static bool equals(T a, T b) { inline constexpr static bool equals(T a, T b) {
return a == b; return a == b;
@ -71,7 +71,7 @@ Traits classes are usable for detecting type features at compile time without
the need for repeated code such as method overloading or template the need for repeated code such as method overloading or template
specialization for given types. specialization for given types.
*/ */
template<class T> struct MathTypeTraits: Implementation::MathTypeTraitsDefault<T> { template<class T> struct TypeTraits: Implementation::TypeTraitsDefault<T> {
/* /*
* The following values are implemented as inline functions, not as * The following values are implemented as inline functions, not as
* static const variables, because the compiler will inline the return * static const variables, because the compiler will inline the return
@ -118,58 +118,58 @@ template<class T> struct MathTypeTraits: Implementation::MathTypeTraitsDefault<T
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* Integral scalar types */ /* Integral scalar types */
namespace Implementation { namespace Implementation {
template<class T> struct MathTypeTraitsIntegral: MathTypeTraitsDefault<T> { template<class T> struct TypeTraitsIntegral: TypeTraitsDefault<T> {
inline constexpr static T epsilon() { return T(1); } inline constexpr static T epsilon() { return T(1); }
}; };
} }
template<> struct MathTypeTraits<UnsignedByte>: Implementation::MathTypeTraitsIntegral<UnsignedByte> { template<> struct TypeTraits<UnsignedByte>: Implementation::TypeTraitsIntegral<UnsignedByte> {
typedef Float FloatingPointType; typedef Float FloatingPointType;
}; };
template<> struct MathTypeTraits<Byte>: Implementation::MathTypeTraitsIntegral<Byte> { template<> struct TypeTraits<Byte>: Implementation::TypeTraitsIntegral<Byte> {
typedef Float FloatingPointType; typedef Float FloatingPointType;
}; };
template<> struct MathTypeTraits<UnsignedShort>: Implementation::MathTypeTraitsIntegral<UnsignedShort> { template<> struct TypeTraits<UnsignedShort>: Implementation::TypeTraitsIntegral<UnsignedShort> {
typedef Float FloatingPointType; typedef Float FloatingPointType;
}; };
template<> struct MathTypeTraits<Short>: Implementation::MathTypeTraitsIntegral<Short> { template<> struct TypeTraits<Short>: Implementation::TypeTraitsIntegral<Short> {
typedef Float FloatingPointType; typedef Float FloatingPointType;
}; };
template<> struct MathTypeTraits<UnsignedInt>: Implementation::MathTypeTraitsIntegral<UnsignedInt> { template<> struct TypeTraits<UnsignedInt>: Implementation::TypeTraitsIntegral<UnsignedInt> {
typedef Double FloatingPointType; typedef Double FloatingPointType;
}; };
template<> struct MathTypeTraits<Int>: Implementation::MathTypeTraitsIntegral<Int> { template<> struct TypeTraits<Int>: Implementation::TypeTraitsIntegral<Int> {
typedef Double FloatingPointType; typedef Double FloatingPointType;
}; };
template<> struct MathTypeTraits<UnsignedLong>: Implementation::MathTypeTraitsIntegral<UnsignedLong> { template<> struct TypeTraits<UnsignedLong>: Implementation::TypeTraitsIntegral<UnsignedLong> {
typedef long double FloatingPointType; typedef long double FloatingPointType;
}; };
template<> struct MathTypeTraits<Long>: Implementation::MathTypeTraitsIntegral<Long> { template<> struct TypeTraits<Long>: Implementation::TypeTraitsIntegral<Long> {
typedef long double FloatingPointType; typedef long double FloatingPointType;
}; };
/* Floating-point scalar types */ /* Floating-point scalar types */
namespace Implementation { namespace Implementation {
template<class T> struct MathTypeTraitsFloatingPoint { template<class T> struct TypeTraitsFloatingPoint {
MathTypeTraitsFloatingPoint() = delete; TypeTraitsFloatingPoint() = delete;
inline static bool equals(T a, T b) { inline static bool equals(T a, T b) {
return std::abs(a - b) < MathTypeTraits<T>::epsilon(); return std::abs(a - b) < TypeTraits<T>::epsilon();
} }
}; };
} }
template<> struct MathTypeTraits<Float>: Implementation::MathTypeTraitsFloatingPoint<Float> { template<> struct TypeTraits<Float>: Implementation::TypeTraitsFloatingPoint<Float> {
typedef Float FloatingPointType; typedef Float FloatingPointType;
inline constexpr static Float epsilon() { return FLOAT_EQUALITY_PRECISION; } inline constexpr static Float epsilon() { return FLOAT_EQUALITY_PRECISION; }
}; };
template<> struct MathTypeTraits<Double>: Implementation::MathTypeTraitsFloatingPoint<Double> { template<> struct TypeTraits<Double>: Implementation::TypeTraitsFloatingPoint<Double> {
typedef Double FloatingPointType; typedef Double FloatingPointType;
inline constexpr static Double epsilon() { return DOUBLE_EQUALITY_PRECISION; } inline constexpr static Double epsilon() { return DOUBLE_EQUALITY_PRECISION; }
}; };
template<> struct MathTypeTraits<long double>: Implementation::MathTypeTraitsFloatingPoint<long double> { template<> struct TypeTraits<long double>: Implementation::TypeTraitsFloatingPoint<long double> {
typedef long double FloatingPointType; typedef long double FloatingPointType;
inline constexpr static long double epsilon() { return LONG_DOUBLE_EQUALITY_PRECISION; } inline constexpr static long double epsilon() { return LONG_DOUBLE_EQUALITY_PRECISION; }

4
src/Math/Unit.h

@ -28,7 +28,7 @@
* @brief Class Magnum::Math::Unit * @brief Class Magnum::Math::Unit
*/ */
#include "Math/MathTypeTraits.h" #include "Math/TypeTraits.h"
namespace Magnum { namespace Math { namespace Magnum { namespace Math {
@ -58,7 +58,7 @@ template<template<class> class Derived, class T> class Unit {
/** @brief Equality comparison */ /** @brief Equality comparison */
inline constexpr bool operator==(Unit<Derived, T> other) const { inline constexpr bool operator==(Unit<Derived, T> other) const {
return MathTypeTraits<T>::equals(value, other.value); return TypeTraits<T>::equals(value, other.value);
} }
/** @brief Non-equality comparison */ /** @brief Non-equality comparison */

8
src/Math/Vector.h

@ -36,7 +36,7 @@
#include "Math/Angle.h" #include "Math/Angle.h"
#include "Math/BoolVector.h" #include "Math/BoolVector.h"
#include "Math/MathTypeTraits.h" #include "Math/TypeTraits.h"
#include "magnumVisibility.h" #include "magnumVisibility.h"
@ -102,7 +102,7 @@ template<std::size_t size, class T> class Vector {
* @see Quaternion::angle(), Complex::angle() * @see Quaternion::angle(), Complex::angle()
*/ */
inline static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB) { inline static Rad<T> angle(const Vector<size, T>& normalizedA, const Vector<size, T>& normalizedB) {
CORRADE_ASSERT(MathTypeTraits<T>::equals(normalizedA.dot(), T(1)) && MathTypeTraits<T>::equals(normalizedB.dot(), T(1)), CORRADE_ASSERT(TypeTraits<T>::equals(normalizedA.dot(), T(1)) && TypeTraits<T>::equals(normalizedB.dot(), T(1)),
"Math::Vector::angle(): vectors must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN())); "Math::Vector::angle(): vectors must be normalized", Rad<T>(std::numeric_limits<T>::quiet_NaN()));
return Rad<T>(std::acos(dot(normalizedA, normalizedB))); return Rad<T>(std::acos(dot(normalizedA, normalizedB)));
} }
@ -195,7 +195,7 @@ template<std::size_t size, class T> class Vector {
/** @brief Equality comparison */ /** @brief Equality comparison */
inline bool operator==(const Vector<size, T>& other) const { inline bool operator==(const Vector<size, T>& other) const {
for(std::size_t i = 0; i != size; ++i) for(std::size_t i = 0; i != size; ++i)
if(!MathTypeTraits<T>::equals(_data[i], other._data[i])) return false; if(!TypeTraits<T>::equals(_data[i], other._data[i])) return false;
return true; return true;
} }
@ -468,7 +468,7 @@ template<std::size_t size, class T> class Vector {
* @f] * @f]
*/ */
inline Vector<size, T> projectedOntoNormalized(const Vector<size, T>& line) const { inline Vector<size, T> projectedOntoNormalized(const Vector<size, T>& line) const {
CORRADE_ASSERT(MathTypeTraits<T>::equals(line.dot(), T(1)), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector<size, T>(std::numeric_limits<T>::quiet_NaN()))); CORRADE_ASSERT(TypeTraits<T>::equals(line.dot(), T(1)), "Math::Vector::projectedOntoNormalized(): line must be normalized", (Vector<size, T>(std::numeric_limits<T>::quiet_NaN())));
return line*dot(*this, line); return line*dot(*this, line);
} }

4
src/MeshTools/Clean.h

@ -43,7 +43,7 @@ template<class Vertex, std::size_t vertexSize = Vertex::Size> class Clean {
public: public:
inline Clean(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {} inline Clean(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
void operator()(typename Vertex::Type epsilon = Math::MathTypeTraits<typename Vertex::Type>::epsilon()) { void operator()(typename Vertex::Type epsilon = Math::TypeTraits<typename Vertex::Type>::epsilon()) {
if(indices.empty()) return; if(indices.empty()) return;
/* Get mesh bounds */ /* Get mesh bounds */
@ -145,7 +145,7 @@ Removes duplicate vertices from the mesh.
@todo Interpolate vertices, not collapse them to first in the cell @todo Interpolate vertices, not collapse them to first in the cell
@todo Ability to specify other attributes for interpolation @todo Ability to specify other attributes for interpolation
*/ */
template<class Vertex, std::size_t vertexSize = Vertex::Size> inline void clean(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices, typename Vertex::Type epsilon = Math::MathTypeTraits<typename Vertex::Type>::epsilon()) { template<class Vertex, std::size_t vertexSize = Vertex::Size> inline void clean(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices, typename Vertex::Type epsilon = Math::TypeTraits<typename Vertex::Type>::epsilon()) {
Implementation::Clean<Vertex, vertexSize>(indices, vertices)(epsilon); Implementation::Clean<Vertex, vertexSize>(indices, vertices)(epsilon);
} }

Loading…
Cancel
Save