From 5819dd4bd71a81ca363043770d4c12b7f144f1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 27 Jan 2013 00:44:42 +0100 Subject: [PATCH] Math: matrix/vector rework, part 3: conversion as explicit constructor. Also updated all dependent classes to follow the change, such as Color and Rectangle. Backwards compatibility for GCC 4.6 (with lack of support for delegating constructors) will be done as non-constexpr constructor using operator=(). --- doc/matrix-vector.dox | 4 +-- src/Color.h | 6 ++++ src/Math/Functions.h | 6 ++-- src/Math/Geometry/Rectangle.h | 37 ++++++++++++------------ src/Math/Geometry/Test/RectangleTest.cpp | 3 +- src/Math/Matrix.h | 3 ++ src/Math/Matrix3.h | 3 ++ src/Math/Matrix4.h | 3 ++ src/Math/Point2D.h | 3 ++ src/Math/Point3D.h | 3 ++ src/Math/RectangularMatrix.h | 37 ++++++++++-------------- src/Math/Test/RectangularMatrixTest.cpp | 4 +-- src/Math/Test/VectorTest.cpp | 4 +-- src/Math/Vector.h | 37 ++++++++++-------------- src/Math/Vector2.h | 3 ++ src/Math/Vector3.h | 3 ++ src/Math/Vector4.h | 3 ++ src/SceneGraph/AbstractCamera.hpp | 2 +- src/Text/Font.cpp | 6 ++-- 19 files changed, 93 insertions(+), 77 deletions(-) diff --git a/doc/matrix-vector.dox b/doc/matrix-vector.dox index 6c50d5b33..81ecf0cf6 100644 --- a/doc/matrix-vector.dox +++ b/doc/matrix-vector.dox @@ -99,10 +99,10 @@ RectangularMatrix<2, 3, int>::from(mat) *= 2; // mat == { 4, 8, 12, 2, 6, 10 } Note that unlike constructors, this function has no way to check whether the array is long enough to contain all elements, so use with caution. -You can also convert between data types: +You can also *explicitly* convert between data types: @code Vector4 floating(1.3f, 2.7f, -15.0f, 7.0f); -Vector4 integral(Vector4::from(floating)); // {1, 2, -15, 7} +Vector4 integral(floating); // {1, 2, -15, 7} @endcode @section matrix-vector-component-access Accessing matrix and vector components diff --git a/src/Color.h b/src/Color.h index 483137267..145a6c5bc 100644 --- a/src/Color.h +++ b/src/Color.h @@ -195,6 +195,9 @@ class Color3: public Math::Vector3 { */ inline constexpr /*implicit*/ Color3(T r, T g, T b): Math::Vector3(r, g, b) {} + /** @copydoc Math::Vector::Vector(const Vector&) */ + template inline constexpr explicit Color3(const Math::Vector<3, U>& other): Math::Vector3(other) {} + /** @brief Copy constructor */ inline constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3(other) {} @@ -322,6 +325,9 @@ class Color4: public Math::Vector4 { is fairly common, nearly always with A set to 1 */ inline constexpr /*implicit*/ Color4(const Math::Vector3& rgb, T a = Implementation::defaultAlpha()): Math::Vector4(rgb[0], rgb[1], rgb[2], a) {} + /** @copydoc Math::Vector::Vector(const Vector&) */ + template inline constexpr explicit Color4(const Math::Vector<4, U>& other): Math::Vector4(other) {} + /** @brief Copy constructor */ inline constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4(other) {} diff --git a/src/Math/Functions.h b/src/Math/Functions.h index e4416e90d..fe767f915 100644 --- a/src/Math/Functions.h +++ b/src/Math/Functions.h @@ -177,12 +177,12 @@ template inline typename std::enable_if inline typename std::enable_if::value, FloatingPoint>::type normalize(const Integral& value) { static_assert(std::is_floating_point::value && std::is_integral::value, "Math::normalize(): normalization must be done from integral to floating-point type"); - return FloatingPoint::from(value)/typename FloatingPoint::Type(std::numeric_limits::max()); + return FloatingPoint(value)/typename FloatingPoint::Type(std::numeric_limits::max()); } template inline typename std::enable_if::value, FloatingPoint>::type normalize(const Integral& value) { static_assert(std::is_floating_point::value && std::is_integral::value, "Math::normalize(): normalization must be done from integral to floating-point type"); - return Math::max(FloatingPoint::from(value)/typename FloatingPoint::Type(std::numeric_limits::max()), FloatingPoint(-1)); + return Math::max(FloatingPoint(value)/typename FloatingPoint::Type(std::numeric_limits::max()), FloatingPoint(-1)); } #endif @@ -213,7 +213,7 @@ template inline typename std::enable_if inline typename std::enable_if::value, Integral>::type denormalize(const FloatingPoint& value) { static_assert(std::is_floating_point::value && std::is_integral::value, "Math::denormalize(): denormalization must be done from floating-point to integral type"); - return Integral::from(value*std::numeric_limits::max()); + return Integral(value*std::numeric_limits::max()); } #endif diff --git a/src/Math/Geometry/Rectangle.h b/src/Math/Geometry/Rectangle.h index 66bf161f4..1ca5275e7 100644 --- a/src/Math/Geometry/Rectangle.h +++ b/src/Math/Geometry/Rectangle.h @@ -32,6 +32,8 @@ are inclusive, while top/right positions are exclusive. @see Magnum::Rectangle, Magnum::Rectanglei */ template class Rectangle { + template friend class Rectangle; + public: /** * Create rectangle from position and size @@ -43,33 +45,32 @@ template class Rectangle { } /** - * @brief %Rectangle from another of different type + * @brief Construct zero rectangle + * + * Construct zero-area rectangle positioned at origin. + */ + inline constexpr Rectangle() = default; + + /** @brief Construct rectangle from two corners */ + inline constexpr Rectangle(const Vector2& bottomLeft, const Vector2& topRight): _bottomLeft(bottomLeft), _topRight(topRight) {} + + /** + * @brief Construct rectangle from another of different type * * Performs only default casting on the values, no rounding or * anything else. Example usage: * @code * Rectangle floatingPoint({1.3f, 2.7f}, {-15.0f, 7.0f}); - * auto integral = Rectangle::from(floatingPoint); - * // integral == {{1, 2}, {-15, 7}} + * Rectangle integral(floatingPoint); // {{1, 2}, {-15, 7}} * @endcode */ - template inline constexpr static Rectangle from(const Rectangle& other) { - return {Vector2::from(other.bottomLeft()), Vector2::from(other.topRight())}; - } + template inline constexpr explicit Rectangle(const Rectangle& other): _bottomLeft(other._bottomLeft), _topRight(other._topRight) {} - /** - * @brief Default constructor - * - * Construct zero-area rectangle positioned at origin. - */ - inline constexpr Rectangle() = default; + /** @brief Copy constructor */ + inline constexpr Rectangle(const Rectangle&) = default; - /** - * @brief Constructor - * @param bottomLeft Bottom left rectangle corner - * @param topRight Top right rectangle corner - */ - inline constexpr Rectangle(const Vector2& bottomLeft, const Vector2& topRight): _bottomLeft(bottomLeft), _topRight(topRight) {} + /** @brief Assignment operator */ + inline Rectangle& operator=(const Rectangle&) = default; /** @brief Equality operator */ inline constexpr bool operator==(const Rectangle& other) const { diff --git a/src/Math/Geometry/Test/RectangleTest.cpp b/src/Math/Geometry/Test/RectangleTest.cpp index 20562c860..267dc724b 100644 --- a/src/Math/Geometry/Test/RectangleTest.cpp +++ b/src/Math/Geometry/Test/RectangleTest.cpp @@ -74,8 +74,7 @@ void RectangleTest::compare() { void RectangleTest::construct() { CORRADE_COMPARE(Rectanglei(), Rectanglei({0, 0}, {0, 0})); CORRADE_COMPARE(Rectanglei::fromSize({3, 5}, {23, 78}), Rectanglei({3, 5}, {26, 83})); - CORRADE_COMPARE(Rectanglei::from(Rectangle({1.3f, 2.7f}, {-15.0f, 7.0f})), - Rectanglei({1, 2}, {-15, 7})); + CORRADE_COMPARE(Rectanglei(Rectangle({1.3f, 2.7f}, {-15.0f, 7.0f})), Rectanglei({1, 2}, {-15, 7})); } void RectangleTest::size() { diff --git a/src/Math/Matrix.h b/src/Math/Matrix.h index e73930c58..c0687e0a0 100644 --- a/src/Math/Matrix.h +++ b/src/Math/Matrix.h @@ -74,6 +74,9 @@ template class Matrix: public RectangularMatrix inline constexpr /*implicit*/ Matrix(const Vector& first, const U&... next): RectangularMatrix(first, next...) {} + /** @copydoc RectangularMatrix::RectangularMatrix(const RectangularMatrix&) */ + template inline constexpr explicit Matrix(const RectangularMatrix& other): RectangularMatrix(other) {} + /** @brief Copy constructor */ inline constexpr Matrix(const RectangularMatrix& other): RectangularMatrix(other) {} diff --git a/src/Math/Matrix3.h b/src/Math/Matrix3.h index 832e02347..5a648fe7d 100644 --- a/src/Math/Matrix3.h +++ b/src/Math/Matrix3.h @@ -128,6 +128,9 @@ template class Matrix3: public Matrix<3, T> { /** @brief %Matrix from column vectors */ inline constexpr /*implicit*/ Matrix3(const Vector3& first, const Vector3& second, const Vector3& third): Matrix<3, T>(first, second, third) {} + /** @copydoc Matrix::Matrix(const RectangularMatrix&) */ + template inline constexpr explicit Matrix3(const RectangularMatrix<3, 3, U>& other): Matrix<3, T>(other) {} + /** @brief Copy constructor */ inline constexpr Matrix3(const RectangularMatrix<3, 3, T>& other): Matrix<3, T>(other) {} diff --git a/src/Math/Matrix4.h b/src/Math/Matrix4.h index cbfa7ca4e..5ac26b89b 100644 --- a/src/Math/Matrix4.h +++ b/src/Math/Matrix4.h @@ -253,6 +253,9 @@ template class Matrix4: public Matrix<4, T> { /** @brief %Matrix from column vectors */ inline constexpr /*implicit*/ Matrix4(const Vector4& first, const Vector4& second, const Vector4& third, const Vector4& fourth): Matrix<4, T>(first, second, third, fourth) {} + /** @copydoc Matrix::Matrix(const RectangularMatrix&) */ + template inline constexpr explicit Matrix4(const RectangularMatrix<4, 4, U>& other): Matrix<4, T>(other) {} + /** @brief Copy constructor */ inline constexpr Matrix4(const RectangularMatrix<4, 4, T>& other): Matrix<4, T>(other) {} diff --git a/src/Math/Point2D.h b/src/Math/Point2D.h index 53fbc9b21..702eea7e3 100644 --- a/src/Math/Point2D.h +++ b/src/Math/Point2D.h @@ -56,6 +56,9 @@ template class Point2D: public Vector3 { */ inline constexpr /*implicit*/ Point2D(const Vector2& xy, T z = T(1)): Vector3(xy, z) {} + /** @copydoc Vector::Vector(const Vector&) */ + template inline constexpr explicit Point2D(const Vector<3, U>& other): Vector3(other) {} + /** @brief Copy constructor */ inline constexpr Point2D(const Vector<3, T>& other): Vector3(other) {} diff --git a/src/Math/Point3D.h b/src/Math/Point3D.h index ca4588a8b..13ff4c473 100644 --- a/src/Math/Point3D.h +++ b/src/Math/Point3D.h @@ -57,6 +57,9 @@ template class Point3D: public Vector4 { */ inline constexpr /*implicit*/ Point3D(const Vector3& xyz, T w = T(1)): Vector4(xyz, w) {} + /** @copydoc Vector::Vector(const Vector&) */ + template inline constexpr explicit Point3D(const Vector<4, U>& other): Vector4(other) {} + /** @brief Copy constructor */ inline constexpr Point3D(const Vector<4, T>& other): Vector4(other) {} diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index 4667af89f..176c6c742 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -62,21 +62,6 @@ template class RectangularMatrix { return *reinterpret_cast*>(data); } - /** - * @brief %Matrix from another of different type - * - * Performs only default casting on the values, no rounding or - * anything else. Example usage: - * @code - * RectangularMatrix<4, 1, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); - * RectangularMatrix<4, 1, std::int8_t> integral(RectangularMatrix<4, 1, std::int8_t>::from(floatingPoint)); - * // integral == {1, 2, -15, 7} - * @endcode - */ - template inline constexpr static RectangularMatrix from(const RectangularMatrix& other) { - return from(typename Implementation::GenerateSequence::Type(), other); - } - /** @brief Construct zero-filled matrix */ inline constexpr /*implicit*/ RectangularMatrix() {} @@ -91,6 +76,19 @@ template class RectangularMatrix { static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to RectangularMatrix constructor"); } + /** + * @brief Construct matrix from another of different type + * + * Performs only default casting on the values, no rounding or + * anything else. Example usage: + * @code + * RectangularMatrix<4, 1, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); + * RectangularMatrix<4, 1, std::int8_t> integral(floatingPoint); + * // integral == {1, 2, -15, 7} + * @endcode + */ + template inline constexpr explicit RectangularMatrix(const RectangularMatrix& other): RectangularMatrix(typename Implementation::GenerateSequence::Type(), other) {} + /** @brief Copy constructor */ inline constexpr RectangularMatrix(const RectangularMatrix&) = default; @@ -310,10 +308,8 @@ template class RectangularMatrix { } private: - /* Implementation for RectangularMatrix::from(const RectangularMatrix&) */ - template inline constexpr static Math::RectangularMatrix from(Implementation::Sequence, const Math::RectangularMatrix& matrix) { - return {Vector::from(matrix[sequence])...}; - } + /* Implementation for RectangularMatrix::RectangularMatrix(const RectangularMatrix&) */ + template inline constexpr explicit RectangularMatrix(Implementation::Sequence, const RectangularMatrix& matrix): _data{Vector(matrix[sequence])...} {} Vector _data[cols]; }; @@ -414,9 +410,6 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit } \ inline constexpr static const __VA_ARGS__& from(const T* data) { \ return *reinterpret_cast(data); \ - } \ - template inline constexpr static RectangularMatrix from(const Math::RectangularMatrix& other) { \ - return Math::RectangularMatrix::from(other); \ } \ \ inline __VA_ARGS__& operator=(const Math::RectangularMatrix& other) { \ diff --git a/src/Math/Test/RectangularMatrixTest.cpp b/src/Math/Test/RectangularMatrixTest.cpp index 60f00e421..730b2c3e8 100644 --- a/src/Math/Test/RectangularMatrixTest.cpp +++ b/src/Math/Test/RectangularMatrixTest.cpp @@ -108,8 +108,8 @@ void RectangularMatrixTest::constructConversion() { Matrix2i integral(Vector2i( 1, 2), Vector2i(-15, 7)); - CORRADE_COMPARE(Matrix2i::from(floatingPoint), integral); - CORRADE_COMPARE(Matrix2::from(integral), floatingPointRounded); + CORRADE_COMPARE(Matrix2i(floatingPoint), integral); + CORRADE_COMPARE(Matrix2(integral), floatingPointRounded); } void RectangularMatrixTest::constructFromVectors() { diff --git a/src/Math/Test/VectorTest.cpp b/src/Math/Test/VectorTest.cpp index 03fead6d7..bf42ef228 100644 --- a/src/Math/Test/VectorTest.cpp +++ b/src/Math/Test/VectorTest.cpp @@ -109,8 +109,8 @@ void VectorTest::constructConversion() { Vector4 floatingPointRounded(1.0f, 2.0f, -15.0f, 7.0f); Vector4i integral(1, 2, -15, 7); - CORRADE_COMPARE(Vector4i::from(floatingPoint), integral); - CORRADE_COMPARE(Vector4::from(integral), floatingPointRounded); + CORRADE_COMPARE(Vector4i(floatingPoint), integral); + CORRADE_COMPARE(Vector4(integral), floatingPointRounded); } void VectorTest::data() { diff --git a/src/Math/Vector.h b/src/Math/Vector.h index b85b65739..a8f912ca3 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -78,21 +78,6 @@ template class Vector { return *reinterpret_cast*>(data); } - /** - * @brief %Vector from another of different type - * - * Performs only default casting on the values, no rounding or - * anything else. Example usage: - * @code - * Vector<4, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); - * Vector<4, std::int8_t> integral(Vector<4, std::int8_t>::from(floatingPoint)); - * // integral == {1, 2, -15, 7} - * @endcode - */ - template inline constexpr static Vector from(const Vector& other) { - return from(typename Implementation::GenerateSequence::Type(), other); - } - /** * @brief Dot product * @@ -163,6 +148,19 @@ template class Vector { _data[i] = value; } + /** + * @brief Construct vector from another of different type + * + * Performs only default casting on the values, no rounding or + * anything else. Example usage: + * @code + * Vector<4, float> floatingPoint(1.3f, 2.7f, -15.0f, 7.0f); + * Vector<4, std::int8_t> integral(floatingPoint); + * // integral == {1, 2, -15, 7} + * @endcode + */ + template inline constexpr explicit Vector(const Vector& other): Vector(typename Implementation::GenerateSequence::Type(), other) {} + /** @brief Copy constructor */ inline constexpr Vector(const Vector&) = default; @@ -500,10 +498,8 @@ template class Vector { } private: - /* Implementation for from(const Vector&) */ - template inline constexpr static Vector from(Implementation::Sequence, const Vector& vector) { - return {T(vector.data()[sequence])...}; - } + /* Implementation for Vector::Vector(const Vector&) */ + template inline constexpr explicit Vector(Implementation::Sequence, const Vector& vector): _data{T(vector.data()[sequence])...} {} T _data[size]; }; @@ -581,9 +577,6 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit inline constexpr static const Type& from(const T* data) { \ return *reinterpret_cast*>(data); \ } \ - template inline constexpr static Type from(const Math::Vector& other) { \ - return Math::Vector::from(other); \ - } \ template inline static const Type lerp(const Math::Vector& a, const Math::Vector& b, U t) { \ return Math::Vector::lerp(a, b, t); \ } \ diff --git a/src/Math/Vector2.h b/src/Math/Vector2.h index ffd13751e..0cf539a8c 100644 --- a/src/Math/Vector2.h +++ b/src/Math/Vector2.h @@ -84,6 +84,9 @@ template class Vector2: public Vector<2, T> { */ inline constexpr /*implicit*/ Vector2(T x, T y): Vector<2, T>(x, y) {} + /** @copydoc Vector::Vector(const Vector&) */ + template inline constexpr explicit Vector2(const Vector<2, U>& other): Vector<2, T>(other) {} + /** @brief Copy constructor */ inline constexpr Vector2(const Vector<2, T>& other): Vector<2, T>(other) {} diff --git a/src/Math/Vector3.h b/src/Math/Vector3.h index 3897a726e..5a7a2354d 100644 --- a/src/Math/Vector3.h +++ b/src/Math/Vector3.h @@ -125,6 +125,9 @@ template class Vector3: public Vector<3, T> { */ inline constexpr /*implicit*/ Vector3(const Vector2& xy, T z): Vector<3, T>(xy[0], xy[1], z) {} + /** @copydoc Vector::Vector(const Vector&) */ + template inline constexpr explicit Vector3(const Vector<3, U>& other): Vector<3, T>(other) {} + /** @brief Copy constructor */ inline constexpr Vector3(const Vector<3, T>& other): Vector<3, T>(other) {} diff --git a/src/Math/Vector4.h b/src/Math/Vector4.h index 8d93a6609..1c0963f5f 100644 --- a/src/Math/Vector4.h +++ b/src/Math/Vector4.h @@ -56,6 +56,9 @@ template class Vector4: public Vector<4, T> { */ inline constexpr /*implicit*/ Vector4(const Vector3& xyz, T w): Vector<4, T>(xyz[0], xyz[1], xyz[2], w) {} + /** @copydoc Vector::Vector(const Vector&) */ + template inline constexpr explicit Vector4(const Vector<4, U>& other): Vector<4, T>(other) {} + /** @brief Copy constructor */ inline constexpr Vector4(const Vector<4, T>& other): Vector<4, T>(other) {} diff --git a/src/SceneGraph/AbstractCamera.hpp b/src/SceneGraph/AbstractCamera.hpp index 934dad4a3..a39f85ab9 100644 --- a/src/SceneGraph/AbstractCamera.hpp +++ b/src/SceneGraph/AbstractCamera.hpp @@ -50,7 +50,7 @@ template typename DimensionTraits relativeAspectRatio = Math::Vector2::from(viewport)*projectionScale; + Math::Vector2 relativeAspectRatio = Math::Vector2(viewport)*projectionScale; /* Extend on larger side = scale larger side down Clip on smaller side = scale smaller side up */ diff --git a/src/Text/Font.cpp b/src/Text/Font.cpp index c294641ee..8a6130fcd 100644 --- a/src/Text/Font.cpp +++ b/src/Text/Font.cpp @@ -80,9 +80,9 @@ Font::Font(FontRenderer& renderer, const std::string& fontFile, GLfloat size, co /* Save character texture position and texture coordinates for given character index */ glyphs.insert({charIndices[i], std::make_tuple( Rectangle::fromSize(Vector2(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height())/size, - Vector2::from(charPositions[i].size())/size), - Rectangle(Vector2::from(charPositions[i].bottomLeft())/atlasSize, - Vector2::from(charPositions[i].topRight())/atlasSize) + Vector2(charPositions[i].size())/size), + Rectangle(Vector2(charPositions[i].bottomLeft())/atlasSize, + Vector2(charPositions[i].topRight())/atlasSize) )}); }