Browse Source

New base for matrices and vectors: RectangularMatrix.

Currently moved only non-square functionality from Matrix there. Also
static constant members such as row/column count and size are now
lowercase, as they are variables, not types.
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
90881e7337
  1. 8
      src/Color.h
  2. 1
      src/Math/CMakeLists.txt
  3. 218
      src/Math/Matrix.h
  4. 4
      src/Math/Matrix3.h
  5. 4
      src/Math/Matrix4.h
  6. 284
      src/Math/RectangularMatrix.h
  7. 2
      src/Math/Test/CMakeLists.txt
  8. 137
      src/Math/Test/MatrixTest.cpp
  9. 7
      src/Math/Test/MatrixTest.h
  10. 187
      src/Math/Test/RectangularMatrixTest.cpp
  11. 39
      src/Math/Test/RectangularMatrixTest.h
  12. 32
      src/Math/Test/VectorTest.cpp
  13. 2
      src/Math/Test/VectorTest.h
  14. 87
      src/Math/Vector.h
  15. 4
      src/Math/Vector2.h
  16. 4
      src/Math/Vector3.h
  17. 4
      src/Math/Vector4.h
  18. 8
      src/MeshTools/Clean.h
  19. 2
      src/MeshTools/Test/CleanTest.h
  20. 2
      src/MeshTools/Test/SubdivideTest.h
  21. 2
      src/SceneGraph/Camera.cpp
  22. 2
      src/Swizzle.h

8
src/Color.h

@ -213,8 +213,8 @@ template<class T> class Color3: public Math::Vector3<T> {
*/
inline constexpr explicit Color3(T rgb): Math::Vector3<T>(rgb) {}
/** @copydoc Math::Vector::Vector(const Vector&) */
inline constexpr Color3(const Math::Vector<3, T>& other): Math::Vector3<T>(other) {}
/** @brief Copy constructor */
inline constexpr Color3(const Math::RectangularMatrix<1, 3, T>& other): Math::Vector3<T>(other) {}
/**
* @brief Constructor
@ -335,8 +335,8 @@ template<class T> class Color4: public Math::Vector4<T> {
*/
inline constexpr explicit Color4(T rgb, T alpha = Implementation::defaultAlpha<T>()): Math::Vector4<T>(rgb, rgb, rgb, alpha) {}
/** @copydoc Math::Vector::Vector(const Vector&) */
inline constexpr Color4(const Math::Vector<4, T>& other): Math::Vector4<T>(other) {}
/** @brief Copy constructor */
inline constexpr Color4(const Math::RectangularMatrix<1, 4, T>& other): Math::Vector4<T>(other) {}
/**
* @brief Constructor

1
src/Math/CMakeLists.txt

@ -6,6 +6,7 @@ set(MagnumMath_HEADERS
Matrix.h
Matrix3.h
Matrix4.h
RectangularMatrix.h
Vector.h
Vector2.h
Vector3.h

218
src/Math/Matrix.h

@ -19,7 +19,7 @@
* @brief Class Magnum::Math::Matrix
*/
#include "Vector.h"
#include "RectangularMatrix.h"
namespace Magnum { namespace Math {
@ -30,44 +30,16 @@ namespace Implementation {
#endif
/**
@brief %Matrix
@brief Square matrix
@tparam s %Matrix size
@configurationvalueref{Magnum::Math::Matrix}
@todo @c PERFORMANCE - loop unrolling for Matrix<3, T> and Matrix<4, T>
@todo first col, then row (cache adjacency)
*/
template<size_t size, class T> class Matrix {
static_assert(size != 0, "Matrix cannot have zero elements");
template<size_t s, class T> class Matrix: public RectangularMatrix<s, s, T> {
public:
const static size_t Size = size; /**< @brief %Matrix size */
typedef T Type; /**< @brief %Matrix data type */
/**
* @brief %Matrix from array
* @return Reference to the data as if it was Matrix, thus doesn't
* perform any copying.
*
* @attention Use with caution, the function doesn't check whether the
* array is long enough.
*/
inline constexpr static Matrix<size, T>& from(T* data) {
return *reinterpret_cast<Matrix<size, T>*>(data);
}
/** @overload */
inline constexpr static const Matrix<size, T>& from(const T* data) {
return *reinterpret_cast<const Matrix<size, T>*>(data);
}
/**
* @brief %Matrix from column vectors
* @param first First column vector
* @param next Next column vectors
*/
template<class ...U> inline constexpr static Matrix<size, T> from(const Vector<size, T>& first, const U&... next) {
static_assert(sizeof...(next)+1 == size, "Improper number of arguments passed to Matrix from Vector constructor");
return from(typename Implementation::GenerateSequence<size>::Type(), first, next...);
}
const static size_t size = s; /**< @brief %Matrix size */
/** @brief Pass to constructor to create zero-filled matrix */
enum ZeroType { Zero };
@ -77,7 +49,7 @@ template<size_t size, class T> class Matrix {
*
* Use this constructor by calling `Matrix m(Matrix::Zero);`.
*/
inline constexpr explicit Matrix(ZeroType): _data() {}
inline constexpr explicit Matrix(ZeroType) {}
/** @brief Pass to constructor to create identity matrix */
enum IdentityType { Identity };
@ -89,121 +61,26 @@ template<size_t size, class T> class Matrix {
* `Matrix m(Matrix::Identity);`. Optional parameter @p value allows
* you to specify value on diagonal.
*/
inline explicit Matrix(IdentityType = Identity, T value = T(1)): _data() {
inline explicit Matrix(IdentityType = Identity, T value = T(1)) {
for(size_t i = 0; i != size; ++i)
_data[size*i+i] = value;
(*this)(i, i) = value;
}
/**
* @brief Initializer-list constructor
* @param first First value
* @param next Next values
*
* Note that the values are in column-major order.
* @todoc Remove workaround when Doxygen supports uniform initialization
*/
/** @copydoc RectangularMatrix::RectangularMatrix(T, U...) */
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class ...U> inline constexpr Matrix(T first, U... next): _data{first, next...} {
static_assert(sizeof...(next)+1 == size*size, "Improper number of arguments passed to Matrix constructor");
}
template<class ...U> inline constexpr Matrix(T first, U... next): RectangularMatrix<size, size, T>(first, next...) {}
#else
template<class ...U> inline constexpr Matrix(T first, U... next);
#endif
/** @brief Copy constructor */
inline constexpr Matrix(const Matrix<size, T>&) = default;
/** @brief Assignment operator */
inline Matrix<size, T>& operator=(const Matrix<size, T>&) = default;
/**
* @brief Raw data
* @return One-dimensional array of `size*size` length in column-major
* order.
*/
inline T* data() { return _data; }
inline constexpr const T* data() const { return _data; } /**< @overload */
/**
* @brief %Matrix column
*
* For accessing individual elements prefer to use operator(), as it
* is guaranteed to not involve unnecessary conversions.
*/
inline Vector<size, T>& operator[](size_t col) {
return Vector<size, T>::from(_data+col*size);
}
/** @overload */
inline constexpr const Vector<size, T>& operator[](size_t col) const {
return Vector<size, T>::from(_data+col*size);
}
/**
* @brief Element on given position
*
* Prefer this instead of using `[][]`.
* @see operator[]
*/
inline T& operator()(size_t col, size_t row) {
return _data[col*size+row];
}
/** @overload */
inline constexpr const T& operator()(size_t col, size_t row) const {
return _data[col*size+row];
}
/** @brief Equality operator */
inline bool operator==(const Matrix<size, T>& other) const {
for(size_t i = 0; i != size*size; ++i)
if(!MathTypeTraits<T>::equals(_data[i], other._data[i])) return false;
return true;
}
/** @brief Non-equality operator */
inline constexpr bool operator!=(const Matrix<size, T>& other) const {
return !operator==(other);
}
/** @brief Multiply matrix operator */
Matrix<size, T> operator*(const Matrix<size, T>& other) const {
Matrix<size, T> out(Zero);
for(size_t row = 0; row != size; ++row)
for(size_t col = 0; col != size; ++col)
for(size_t pos = 0; pos != size; ++pos)
out(col, row) += (*this)(pos, row)*other(col, pos);
return out;
}
inline constexpr Matrix(const RectangularMatrix<size, size, T>& other): RectangularMatrix<size, size, T>(other) {}
/** @brief Multiply and assign matrix operator */
inline Matrix<size, T>& operator*=(const Matrix<size, T>& other) {
inline Matrix<size, T>& operator*=(const RectangularMatrix<size, size, T>& other) {
return (*this = *this*other);
}
/** @brief Multiply vector operator */
Vector<size, T> operator*(const Vector<size, T>& other) const {
Vector<size, T> out;
for(size_t row = 0; row != size; ++row)
for(size_t pos = 0; pos != size; ++pos)
out[row] += (*this)(pos, row)*other[pos];
return out;
}
/** @brief Transposed matrix */
Matrix<size, T> transposed() const {
Matrix<size, T> out(Zero);
for(size_t row = 0; row != size; ++row)
for(size_t col = 0; col != size; ++col)
out(row, col) = (*this)(col, row);
return out;
}
/** @brief %Matrix without given column and row */
Matrix<size-1, T> ij(size_t skipCol, size_t skipRow) const {
Matrix<size-1, T> out(Matrix<size-1, T>::Zero);
@ -252,32 +129,24 @@ template<size_t size, class T> class Matrix {
return out;
}
private:
template<size_t ...sequence, class ...U> inline constexpr static Matrix<size, T> from(Implementation::Sequence<sequence...> s, const Vector<size, T>& first, U... next) {
return from(s, next..., first[sequence]...);
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Reimplementation of functions to return correct type */
inline Matrix<size, T> operator*(const Matrix<size, T>& other) const {
return RectangularMatrix<size, size, T>::operator*(other);
}
template<size_t ...sequence, class ...U> inline constexpr static Matrix<size, T> from(Implementation::Sequence<sequence...>, T first, U... next) {
return Matrix<size, T>(first, next...);
template<size_t otherCols> inline RectangularMatrix<otherCols, size, T> operator*(const RectangularMatrix<otherCols, size, T>& other) const {
return RectangularMatrix<size, size, T>::operator*(other);
}
T _data[size*size];
inline Vector<size, T> operator*(const Vector<size, T>& other) const {
return RectangularMatrix<size, size, T>::operator*(other);
}
#endif
MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(size, size, Matrix<size, T>)
};
/** @debugoperator{Magnum::Math::Matrix} */
template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Matrix<size, T>& value) {
debug << "Matrix(";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false);
for(size_t row = 0; row != size; ++row) {
if(row != 0) debug << ",\n ";
for(size_t col = 0; col != size; ++col) {
if(col != 0) debug << ", ";
debug << typename MathTypeTraits<T>::NumericType(value[col][row]);
}
}
debug << ')';
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true);
return debug;
return debug << static_cast<const Magnum::Math::RectangularMatrix<size, size, T>&>(value);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
@ -311,6 +180,9 @@ template<size_t size, class T> Corrade::Utility::Debug operator<<(Corrade::Utili
Matrix<size, T>::operator*=(other); \
return *this; \
} \
template<size_t otherCols> inline RectangularMatrix<otherCols, size, T> operator*(const RectangularMatrix<otherCols, size, T>& other) const { \
return Matrix<size, T>::operator*(other); \
} \
inline VectorType<T> operator*(const Vector<size, T>& other) const { \
return Matrix<size, T>::operator*(other); \
} \
@ -355,40 +227,8 @@ template<class T> class MatrixDeterminant<1, T> {
}}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Math::Matrix} */
template<size_t size, class T> struct ConfigurationValue<Magnum::Math::Matrix<size, T>> {
/** @brief Writes elements separated with spaces */
static std::string toString(const Magnum::Math::Matrix<size, T>& value, int flags = 0) {
std::string output;
for(size_t row = 0; row != size; ++row) {
for(size_t col = 0; col != size; ++col) {
if(!output.empty()) output += ' ';
output += ConfigurationValue<T>::toString(value(col, row), flags);
}
}
return output;
}
/** @brief Reads elements separated with whitespace */
static Magnum::Math::Matrix<size, T> fromString(const std::string& stringValue, int flags = 0) {
Magnum::Math::Matrix<size, T> result(Magnum::Math::Matrix<size, T>::Zero);
std::istringstream in(stringValue);
for(size_t row = 0; row != size; ++row) {
for(size_t col = 0; col != size; ++col) {
std::string num;
in >> num;
result(col, row) = ConfigurationValue<T>::fromString(num, flags);
}
}
return result;
}
};
/** @configurationvalue{Magnum::Math::Matrix} */
template<size_t size, class T> struct ConfigurationValue<Magnum::Math::Matrix<size, T>>: public ConfigurationValue<Magnum::Math::RectangularMatrix<size, size, T>> {};
}}
#endif

4
src/Math/Matrix3.h

@ -92,8 +92,8 @@ template<class T> class Matrix3: public Matrix<3, T> {
template<class ...U> inline constexpr Matrix3(T first, U... next) {}
#endif
/** @copydoc Matrix::Matrix(const Matrix<size, T>&) */
inline constexpr Matrix3(const Matrix<3, T>& other): Matrix<3, T>(other) {}
/** @brief Copy constructor */
inline constexpr Matrix3(const RectangularMatrix<3, 3, T>& other): Matrix<3, T>(other) {}
MAGNUM_MATRIX_SUBCLASS_IMPLEMENTATION(Matrix3, Vector3, 3)
};

4
src/Math/Matrix4.h

@ -122,8 +122,8 @@ template<class T> class Matrix4: public Matrix<4, T> {
template<class ...U> inline constexpr Matrix4(T first, U... next) {}
#endif
/** @copydoc Matrix::Matrix(const Matrix<size, T>&) */
inline constexpr Matrix4(const Matrix<4, T>& other): Matrix<4, T>(other) {}
/** @brief Copy constructor */
inline constexpr Matrix4(const RectangularMatrix<4, 4, T>& other): Matrix<4, T>(other) {}
/** @copydoc Matrix::ij() */
inline Matrix3<T> ij(size_t skipRow, size_t skipCol) const { return Matrix<4, T>::ij(skipRow, skipCol); }

284
src/Math/RectangularMatrix.h

@ -0,0 +1,284 @@
#ifndef Magnum_Math_RectangularMatrix_h
#define Magnum_Math_RectangularMatrix_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Math::RectangularMatrix
*/
#include <cmath>
#include <limits>
#include <Utility/Debug.h>
#include <Utility/Configuration.h>
#include "MathTypeTraits.h"
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<size_t ...> struct Sequence {};
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<size_t N, size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
template<size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
}
#endif
template<size_t size, class T> class Vector;
/**
@brief Rectangular matrix
@tparam c Column count
@tparam r Row count
See also Matrix (square) and Vector.
*/
template<size_t c, size_t r, class T> class RectangularMatrix {
static_assert(c != 0 && r != 0, "Matrix cannot have zero elements");
friend class Vector<r, T>;
public:
typedef T Type; /**< @brief Data type */
const static size_t cols = c; /**< @brief %Matrix column count */
const static size_t rows = r; /**< @brief %Matrix row count */
/**
* @brief %Matrix from array
* @return Reference to the data as if it was Matrix, thus doesn't
* perform any copying.
*
* @attention Use with caution, the function doesn't check whether the
* array is long enough.
*/
inline constexpr static RectangularMatrix<cols, rows, T>& from(T* data) {
return *reinterpret_cast<RectangularMatrix<cols, rows, T>*>(data);
}
/** @overload */
inline constexpr static const RectangularMatrix<cols, rows, T>& from(const T* data) {
return *reinterpret_cast<const RectangularMatrix<cols, rows, T>*>(data);
}
/**
* @brief %Matrix from column vectors
* @param first First column vector
* @param next Next column vectors
*/
template<class ...U> inline constexpr static RectangularMatrix<cols, rows, T> from(const Vector<rows, T>& first, const U&... next) {
static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to Matrix from Vector constructor");
return from(typename Implementation::GenerateSequence<rows>::Type(), first, next...);
}
/** @brief Zero-filled matrix constructor */
inline constexpr RectangularMatrix(): _data() {}
/**
* @brief Initializer-list constructor
* @param first First value
* @param next Next values
*
* Note that the values are in column-major order.
* @todoc Remove workaround when Doxygen supports uniform initialization
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class ...U> inline constexpr RectangularMatrix(T first, U... next): _data{first, next...} {
static_assert(sizeof...(next)+1 == cols*rows, "Improper number of arguments passed to Matrix constructor");
}
#else
template<class ...U> inline constexpr RectangularMatrix(T first, U... next);
#endif
/** @brief Copy constructor */
inline constexpr RectangularMatrix(const RectangularMatrix<c, r, T>&) = default;
/** @brief Assignment operator */
inline RectangularMatrix<c, r, T>& operator=(const RectangularMatrix<c, r, T>&) = default;
/**
* @brief Raw data
* @return One-dimensional array of `size*size` length in column-major
* order.
*/
inline T* data() { return _data; }
inline constexpr const T* data() const { return _data; } /**< @overload */
/**
* @brief %Matrix column
*
* For accessing individual elements prefer to use operator(), as it
* is guaranteed to not involve unnecessary conversions.
*/
inline Vector<rows, T>& operator[](size_t col) {
return Vector<rows, T>::from(_data+col*rows);
}
/** @overload */
inline constexpr const Vector<rows, T>& operator[](size_t col) const {
return Vector<rows, T>::from(_data+col*rows);
}
/**
* @brief Element on given position
*
* Prefer this instead of using `[][]`.
* @see operator[]
*/
inline T& operator()(size_t col, size_t row) {
return _data[col*rows+row];
}
/** @overload */
inline constexpr const T& operator()(size_t col, size_t row) const {
return _data[col*rows+row];
}
/** @brief Equality operator */
inline bool operator==(const RectangularMatrix<cols, rows, T>& other) const {
for(size_t i = 0; i != cols*rows; ++i)
if(!MathTypeTraits<T>::equals(_data[i], other._data[i])) return false;
return true;
}
/** @brief Non-equality operator */
inline constexpr bool operator!=(const RectangularMatrix<cols, rows, T>& other) const {
return !operator==(other);
}
/** @brief Multiply matrix */
template<size_t size> RectangularMatrix<size, rows, T> operator*(const RectangularMatrix<size, cols, T>& other) const {
RectangularMatrix<size, rows, T> out;
for(size_t row = 0; row != rows; ++row)
for(size_t col = 0; col != size; ++col) /** @todo swap */
for(size_t pos = 0; pos != cols; ++pos)
out(col, row) += (*this)(pos, row)*other(col, pos);
return out;
}
/**
* @brief Multiply vector
*
* Internally the same as multiplying with one-column matrix, but
* returns vector.
*/
Vector<rows, T> operator*(const Vector<rows, T>& other) const {
return operator*(static_cast<RectangularMatrix<1, rows, T>>(other));
}
/** @brief Transposed matrix */
RectangularMatrix<rows, cols, T> transposed() const {
RectangularMatrix<rows, cols, T> out;
for(size_t col = 0; col != cols; ++col)
for(size_t row = 0; row != rows; ++row)
out(row, col) = (*this)(col, row);
return out;
}
private:
template<size_t ...sequence, class ...U> inline constexpr static RectangularMatrix<cols, rows, T> from(Implementation::Sequence<sequence...> s, const Vector<rows, T>& first, U... next) {
return from(s, next..., first[sequence]...);
}
template<size_t ...sequence, class ...U> inline constexpr static RectangularMatrix<cols, rows, T> from(Implementation::Sequence<sequence...>, T first, U... next) {
return RectangularMatrix<cols, rows, T>(first, next...);
}
T _data[rows*cols];
};
/** @debugoperator{Magnum::Math::RectangularMatrix} */
template<size_t cols, size_t rows, class T> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::RectangularMatrix<cols, rows, T>& value) {
debug << "Matrix(";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false);
for(size_t row = 0; row != rows; ++row) {
if(row != 0) debug << ",\n ";
for(size_t col = 0; col != cols; ++col) {
if(col != 0) debug << ", ";
debug << typename MathTypeTraits<T>::NumericType(value[col][row]);
}
}
debug << ')';
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true);
return debug;
}
#ifndef DOXYGEN_GENERATING_OUTPUT
#define MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(cols, rows, ...) \
inline constexpr static __VA_ARGS__& from(T* data) { \
return *reinterpret_cast<__VA_ARGS__*>(data); \
} \
inline constexpr static const __VA_ARGS__& from(const T* data) { \
return *reinterpret_cast<const __VA_ARGS__*>(data); \
} \
template<class ...U> inline constexpr static __VA_ARGS__ from(const Vector<rows, T>& first, const U&... next) { \
return RectangularMatrix<cols, rows, T>::from(first, next...); \
} \
\
inline __VA_ARGS__& operator=(const RectangularMatrix<cols, rows, T>& other) { \
RectangularMatrix<cols, rows, T>::operator=(other); \
return *this; \
}
#endif
}}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::Math::RectangularMatrix} */
template<size_t cols, size_t rows, class T> struct ConfigurationValue<Magnum::Math::RectangularMatrix<cols, rows, T>> {
/** @brief Writes elements separated with spaces */
static std::string toString(const Magnum::Math::RectangularMatrix<cols, rows, T>& value, int flags = 0) {
std::string output;
for(size_t row = 0; row != rows; ++row) {
for(size_t col = 0; col != cols; ++col) {
if(!output.empty()) output += ' ';
output += ConfigurationValue<T>::toString(value(col, row), flags);
}
}
return output;
}
/** @brief Reads elements separated with whitespace */
static Magnum::Math::RectangularMatrix<cols, rows, T> fromString(const std::string& stringValue, int flags = 0) {
Magnum::Math::RectangularMatrix<cols, rows, T> result;
std::istringstream in(stringValue);
for(size_t row = 0; row != rows; ++row) {
for(size_t col = 0; col != cols; ++col) {
std::string num;
in >> num;
result(col, row) = ConfigurationValue<T>::fromString(num, flags);
}
}
return result;
}
};
}}
/* Include also Vector, so the definition is complete */
#include "Vector.h"
#endif

2
src/Math/Test/CMakeLists.txt

@ -1,5 +1,7 @@
corrade_add_test2(MathMathTypeTraitsTest MathTypeTraitsTest.cpp)
corrade_add_test2(MathRectangularMatrixTest RectangularMatrixTest.cpp)
corrade_add_test2(MathVectorTest VectorTest.cpp)
set_target_properties(MathVectorTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)
corrade_add_test2(MathVector2Test Vector2Test.cpp)

137
src/Math/Test/MatrixTest.cpp

@ -32,15 +32,8 @@ typedef Vector<4, float> Vector4;
MatrixTest::MatrixTest() {
addTests(&MatrixTest::construct,
&MatrixTest::constructFromVectors,
&MatrixTest::constructIdentity,
&MatrixTest::constructZero,
&MatrixTest::data,
&MatrixTest::copy,
&MatrixTest::multiplyIdentity,
&MatrixTest::multiply,
&MatrixTest::multiplyVector,
&MatrixTest::transposed,
&MatrixTest::ij,
&MatrixTest::determinant,
&MatrixTest::inverted,
@ -66,20 +59,6 @@ void MatrixTest::construct() {
CORRADE_COMPARE(Matrix4::from(m), expected);
}
void MatrixTest::constructFromVectors() {
Matrix4 actual = Matrix4::from(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f),
Vector4(13.0f, 14.0f, 15.0f, 16.0f));
Matrix4 expected(1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f,
9.0f, 10.0f, 11.0f, 12.0f,
13.0f, 14.0f, 15.0f, 16.0f);
CORRADE_COMPARE(actual, expected);
}
void MatrixTest::constructIdentity() {
Matrix4 identity;
Matrix4 identity2(Matrix4::Identity);
@ -117,122 +96,6 @@ void MatrixTest::constructZero() {
CORRADE_COMPARE(zero, zeroExpected);
}
void MatrixTest::data() {
Matrix4 m(Matrix4::Zero);
Vector4 vector(4.0f, 5.0f, 6.0f, 7.0f);
m[3] = vector;
m[2][1] = 1.0f;
m(1, 2) = 1.5f;
CORRADE_COMPARE(m(2, 1), 1.0f);
CORRADE_COMPARE(m[1][2], 1.5f);
CORRADE_COMPARE(m[3], vector);
Matrix4 expected(
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.5f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
4.0f, 5.0f, 6.0f, 7.0f
);
CORRADE_COMPARE(m, expected);
}
void MatrixTest::copy() {
Matrix4 m1(Matrix4::Zero);
m1(2, 3) = 1.0f;
/* Copy */
Matrix4 m2(m1);
Matrix4 m3;
m3(0, 0) = 1.0f; /* this line is here so it's not optimized to Matrix4 m3(m1) */
m3 = m1;
/* Change original */
m1(3, 2) = 1.0f;
/* Verify the copy is the same as original */
Matrix4 original(Matrix4::Zero);
original(2, 3) = 1.0f;
CORRADE_COMPARE(m2, original);
CORRADE_COMPARE(m3, original);
}
void MatrixTest::multiplyIdentity() {
Matrix4 values(
0.0f, 1.0f, 2.0f, 3.0f,
4.0f, 5.0f, 6.0f, 7.0f,
8.0f, 9.0f, 10.0f, 11.0f,
12.0f, 13.0f, 14.0f, 15.0f
);
CORRADE_COMPARE(Matrix4()*values, values);
CORRADE_COMPARE(values*Matrix4(), values);
}
void MatrixTest::multiply() {
Matrix<5, int> left(
-3, -3, -1, 3, -5,
-1, -3, -5, 2, 3,
-1, -4, 3, -1, -2,
-5, -5, -1, -4, -1,
1, 3, -3, -4, -1
);
Matrix<5, int> right(
0, 5, 3, 4, 4,
5, 5, 0, 0, -2,
3, 2, -4, -3, 0,
-3, 0, -1, 2, -1,
0, -1, -4, 4, 3
);
Matrix<5, int> expected(
-24, -35, -32, -25, 1,
-22, -36, -24, 33, -8,
8, 16, -22, 29, 2,
-1, 0, 1, -12, 16,
-12, 8, -20, -26, -2
);
CORRADE_COMPARE((left *= right), expected);
}
void MatrixTest::multiplyVector() {
Matrix<5, int> matrix(
-3, -3, -1, 3, -5,
-1, -3, -5, 2, 3,
-1, -4, 3, -1, -2,
-5, -5, -1, -4, -1,
1, 3, -3, -4, -1
);
CORRADE_COMPARE((matrix*Vector<5, int>(0, 5, 3, 4, 4)), (Vector<5, int>(-24, -35, -32, -25, 1)));
}
void MatrixTest::transposed() {
Matrix4 original(
0.0f, 1.0f, 2.0f, 3.0f,
4.0f, 5.0f, 6.0f, 7.0f,
8.0f, 9.0f, 10.0f, 11.0f,
12.0f, 13.0f, 14.0f, 15.0f
);
Matrix4 transposed(
0.0f, 4.0f, 8.0f, 12.0f,
1.0f, 5.0f, 9.0f, 13.0f,
2.0f, 6.0f, 10.0f, 14.0f,
3.0f, 7.0f, 11.0f, 15.0f
);
CORRADE_COMPARE(original.transposed(), transposed);
}
void MatrixTest::ij() {
Matrix4 original(
0.0f, 1.0f, 2.0f, 3.0f,

7
src/Math/Test/MatrixTest.h

@ -24,15 +24,8 @@ class MatrixTest: public Corrade::TestSuite::Tester<MatrixTest> {
MatrixTest();
void construct();
void constructFromVectors();
void constructIdentity();
void constructZero();
void data();
void copy();
void multiplyIdentity();
void multiply();
void multiplyVector();
void transposed();
void ij();
void determinant();
void inverted();

187
src/Math/Test/RectangularMatrixTest.cpp

@ -0,0 +1,187 @@
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "RectangularMatrixTest.h"
#include <sstream>
#include "RectangularMatrix.h"
CORRADE_TEST_MAIN(Magnum::Math::Test::RectangularMatrixTest)
using namespace std;
using namespace Corrade::Utility;
namespace Magnum { namespace Math { namespace Test {
typedef RectangularMatrix<4, 3, float> Matrix4x3;
typedef RectangularMatrix<3, 4, float> Matrix3x4;
typedef Vector<4, float> Vector4;
RectangularMatrixTest::RectangularMatrixTest() {
addTests(&RectangularMatrixTest::construct,
&RectangularMatrixTest::constructFromVectors,
&RectangularMatrixTest::constructZero,
&RectangularMatrixTest::data,
&RectangularMatrixTest::multiply,
&RectangularMatrixTest::transposed,
&RectangularMatrixTest::debug,
&RectangularMatrixTest::configuration);
}
void RectangularMatrixTest::construct() {
float m[] = {
3.0f, 5.0f, 8.0f, 4.0f,
4.0f, 4.0f, 7.0f, 3.0f,
7.0f, -1.0f, 8.0f, 0.0f
};
Matrix3x4 expected(
3.0f, 5.0f, 8.0f, 4.0f,
4.0f, 4.0f, 7.0f, 3.0f,
7.0f, -1.0f, 8.0f, 0.0f
);
CORRADE_COMPARE(Matrix3x4::from(m), expected);
}
void RectangularMatrixTest::constructFromVectors() {
Matrix3x4 actual = Matrix3x4::from(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f));
Matrix3x4 expected(1.0f, 2.0f, 3.0f, 4.0f,
5.0f, 6.0f, 7.0f, 8.0f,
9.0f, 10.0f, 11.0f, 12.0f);
CORRADE_COMPARE(actual, expected);
}
void RectangularMatrixTest::constructZero() {
Matrix4x3 zero;
Matrix4x3 zeroExpected(
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
);
CORRADE_COMPARE(zero, zeroExpected);
}
void RectangularMatrixTest::data() {
Matrix3x4 m;
Vector4 vector(4.0f, 5.0f, 6.0f, 7.0f);
m[2] = vector;
m[1][1] = 1.0f;
m(0, 2) = 1.5f;
CORRADE_COMPARE(m(1, 1), 1.0f);
CORRADE_COMPARE(m[0][2], 1.5f);
CORRADE_COMPARE(m[2], vector);
Matrix3x4 expected(
0.0f, 0.0f, 1.5f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
4.0f, 5.0f, 6.0f, 7.0f
);
CORRADE_COMPARE(m, expected);
}
void RectangularMatrixTest::multiply() {
RectangularMatrix<4, 6, int> left(
-5, 27, 10, 33, 0, -15,
7, 56, 66, 1, 0, -24,
4, 41, 4, 0, 1, -4,
9, -100, 19, -49, 1, 9
);
RectangularMatrix<5, 4, int> right(
1, -7, 0, 158,
2, 24, -3, 40,
3, -15, -2, -50,
4, 17, -1, -284,
5, 30, 4, 18
);
RectangularMatrix<5, 6, int> expected(
1368, -16165, 2550, -7716, 158, 1575,
506, -2725, 2352, -1870, 37, -234,
-578, 4159, -1918, 2534, -52, -127,
-2461, 29419, -4238, 14065, -285, -3020,
363, 179, 2388, -687, 22, -649
);
CORRADE_COMPARE(left*right, expected);
}
void RectangularMatrixTest::transposed() {
Matrix4x3 original(
0.0f, 1.0f, 3.0f,
4.0f, 5.0f, 7.0f,
8.0f, 9.0f, 11.0f,
12.0f, 13.0f, 15.0f
);
Matrix3x4 transposed(
0.0f, 4.0f, 8.0f, 12.0f,
1.0f, 5.0f, 9.0f, 13.0f,
3.0f, 7.0f, 11.0f, 15.0f
);
CORRADE_COMPARE(original.transposed(), transposed);
}
void RectangularMatrixTest::debug() {
Matrix3x4 m(
3.0f, 5.0f, 8.0f, 4.0f,
4.0f, 4.0f, 7.0f, 3.0f,
7.0f, -1.0f, 8.0f, 0.0f
);
ostringstream o;
Debug(&o) << m;
CORRADE_COMPARE(o.str(), "Matrix(3, 4, 7,\n"
" 5, 4, -1,\n"
" 8, 7, 8,\n"
" 4, 3, 0)\n");
o.str("");
Debug(&o) << "a" << Matrix3x4() << "b" << RectangularMatrix<4, 3, char>();
CORRADE_COMPARE(o.str(), "a Matrix(0, 0, 0,\n"
" 0, 0, 0,\n"
" 0, 0, 0,\n"
" 0, 0, 0) b Matrix(0, 0, 0, 0,\n"
" 0, 0, 0, 0,\n"
" 0, 0, 0, 0)\n");
}
void RectangularMatrixTest::configuration() {
Matrix3x4 m(
3.0f, 5.0f, 8.0f, 4.0f,
4.0f, 4.0f, 7.0f, 3.125f,
7.0f, -1.0f, 8.0f, 9.55f
);
string value("3 4 7 5 4 -1 8 7 8 4 3.125 9.55");
CORRADE_COMPARE(ConfigurationValue<Matrix3x4>::toString(m), value);
CORRADE_COMPARE(ConfigurationValue<Matrix3x4>::fromString(value), m);
}
}}}

39
src/Math/Test/RectangularMatrixTest.h

@ -0,0 +1,39 @@
#ifndef Magnum_Math_Test_RectangularMatrixTest_h
#define Magnum_Math_Test_RectangularMatrixTest_h
/*
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include <TestSuite/Tester.h>
namespace Magnum { namespace Math { namespace Test {
class RectangularMatrixTest: public Corrade::TestSuite::Tester<RectangularMatrixTest> {
public:
RectangularMatrixTest();
void construct();
void constructFromVectors();
void constructZero();
void data();
void multiply();
void transposed();
void debug();
void configuration();
};
}}}
#endif

32
src/Math/Test/VectorTest.cpp

@ -34,8 +34,6 @@ typedef Vector<3, float> Vector3;
VectorTest::VectorTest() {
addTests(&VectorTest::construct,
&VectorTest::constructFrom,
&VectorTest::data,
&VectorTest::copy,
&VectorTest::dot,
&VectorTest::multiplyDivide,
&VectorTest::multiplyDivideComponentWise,
@ -69,36 +67,6 @@ void VectorTest::constructFrom() {
CORRADE_COMPARE(Vector4::from(integral), floatingPointRounded);
}
void VectorTest::data() {
Vector4 v;
v[2] = 1.5f;
v[0] = 1.0f;
CORRADE_COMPARE(v, Vector4(1.0f, 0.0f, 1.5f, 0.0f));
}
void VectorTest::copy() {
Vector4 v1;
v1[3] = 1.0f;
Vector4 v2(v1);
Vector4 v3;
v3[0] = 0.0f; /* this line is here so it's not optimized to Vector4 v3(v1) */
v3 = v1;
/* Change original */
v1[2] = 1.0f;
/* Verify the copy is the same as original original */
Vector4 original;
original[3] = 1.0f;
CORRADE_COMPARE(v2, original);
CORRADE_COMPARE(v3, original);
}
void VectorTest::dot() {
CORRADE_COMPARE(Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}), 15.25f);
}

2
src/Math/Test/VectorTest.h

@ -25,8 +25,6 @@ class VectorTest: public Corrade::TestSuite::Tester<VectorTest> {
void construct();
void constructFrom();
void data();
void copy();
void dot();
void multiplyDivide();
void multiplyDivideComponentWise();

87
src/Math/Vector.h

@ -19,12 +19,7 @@
* @brief Class Magnum::Math::Vector
*/
#include <cmath>
#include <limits>
#include <Utility/Debug.h>
#include <Utility/Configuration.h>
#include "MathTypeTraits.h"
#include "RectangularMatrix.h"
namespace Magnum { namespace Math {
@ -32,16 +27,6 @@ template<size_t size, class T> class Vector;
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<size_t ...> struct Sequence {};
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<size_t N, size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
template<size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
/* Implementation for Vector<size, T>::from(const Vector<size, U>&) */
template<class T, class U, size_t ...sequence> inline constexpr Math::Vector<sizeof...(sequence), T> vectorFrom(Sequence<sequence...>, const Math::Vector<sizeof...(sequence), U>& vector) {
return {T(vector[sequence])...};
@ -55,28 +40,9 @@ namespace Implementation {
@configurationvalueref{Magnum::Math::Vector}
@todo Constexprize all for loops
*/
template<size_t size, class T> class Vector {
static_assert(size != 0, "Vector cannot have zero elements");
template<size_t s, class T> class Vector: public RectangularMatrix<1, s, T> {
public:
const static size_t Size = size; /**< @brief %Vector size */
typedef T Type; /**< @brief %Vector data type */
/**
* @brief %Vector from array
* @return Reference to the data as if it was Vector, thus doesn't
* perform any copying.
*
* @attention Use with caution, the function doesn't check whether the
* array is long enough.
*/
inline constexpr static Vector<size, T>& from(T* data) {
return *reinterpret_cast<Vector<size, T>*>(data);
}
/** @overload */
inline constexpr static const Vector<size, T>& from(const T* data) {
return *reinterpret_cast<const Vector<size, T>*>(data);
}
const static size_t size = s; /**< @brief %Vector size */
/**
* @brief %Vector from another of different type
@ -126,19 +92,15 @@ template<size_t size, class T> class Vector {
}
/** @brief Default constructor */
inline constexpr Vector(): _data() {}
inline constexpr Vector() {}
/**
* @brief Initializer-list constructor
* @param first First value
* @param next Next values
*
* @todoc Remove workaround when Doxygen supports uniform initialization
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class ...U> inline constexpr Vector(T first, U... next): _data{first, next...} {
static_assert(sizeof...(next)+1 == size, "Improper number of arguments passed to Vector constructor");
}
template<class ...U> inline constexpr Vector(T first, U... next): RectangularMatrix<1, size, T>(first, next...) {}
#else
template<class ...U> inline constexpr Vector(T first, U... next);
#endif
@ -153,38 +115,15 @@ template<size_t size, class T> class Vector {
inline explicit Vector(T value) {
#endif
for(size_t i = 0; i != size; ++i)
_data[i] = value;
(*this)[i] = value;
}
/** @brief Copy constructor */
inline constexpr Vector(const Vector<size, T>&) = default;
/** @brief Assignment operator */
inline Vector<size, T>& operator=(const Vector<size, T>&) = default;
/**
* @brief Raw data
* @return Array with the same size as the vector
*/
inline T* data() { return _data; }
inline constexpr const T* data() const { return _data; } /**< @overload */
inline constexpr Vector(const RectangularMatrix<1, size, T>& other): RectangularMatrix<1, size, T>(other) {}
/** @brief Value at given position */
inline T& operator[](size_t pos) { return _data[pos]; }
inline constexpr T operator[](size_t pos) const { return _data[pos]; } /**< @overload */
/** @brief Equality operator */
inline bool operator==(const Vector<size, T>& other) const {
for(size_t pos = 0; pos != size; ++pos)
if(!MathTypeTraits<T>::equals((*this)[pos], other[pos])) return false;
return true;
}
/** @brief Non-equality operator */
inline bool operator!=(const Vector<size, T>& other) const {
return !operator==(other);
}
inline T& operator[](size_t pos) { return RectangularMatrix<1, size, T>::_data[pos]; }
inline constexpr T operator[](size_t pos) const { return RectangularMatrix<1, size, T>::_data[pos]; } /**< @overload */
/**
* @brief Multiply vector
@ -404,8 +343,14 @@ template<size_t size, class T> class Vector {
return out;
}
MAGNUM_RECTANGULARMATRIX_SUBCLASS_IMPLEMENTATION(1, size, Vector<size, T>)
private:
T _data[size];
/* Hiding unused things from RectangularMatrix */
using RectangularMatrix<1, size, T>::cols;
using RectangularMatrix<1, size, T>::rows;
using RectangularMatrix<1, size, T>::operator[];
using RectangularMatrix<1, size, T>::operator();
};
/** @relates Vector

4
src/Math/Vector2.h

@ -71,8 +71,8 @@ template<class T> class Vector2: public Vector<2, T> {
/** @copydoc Vector::Vector(T) */
inline constexpr explicit Vector2(T value = T()): Vector<2, T>(value, value) {}
/** @copydoc Vector::Vector(const Vector&) */
inline constexpr Vector2(const Vector<2, T>& other): Vector<2, T>(other) {}
/** @brief Copy constructor */
inline constexpr Vector2(const RectangularMatrix<1, 2, T>& other): Vector<2, T>(other) {}
/**
* @brief Constructor

4
src/Math/Vector3.h

@ -105,8 +105,8 @@ template<class T> class Vector3: public Vector<3, T> {
/** @copydoc Vector::Vector(T) */
inline constexpr explicit Vector3(T value): Vector<3, T>(value, value, value) {}
/** @copydoc Vector::Vector(const Vector&) */
inline constexpr Vector3(const Vector<3, T>& other): Vector<3, T>(other) {}
/** @brief Copy constructor */
inline constexpr Vector3(const RectangularMatrix<1, 3, T>& other): Vector<3, T>(other) {}
/**
* @brief Constructor

4
src/Math/Vector4.h

@ -40,8 +40,8 @@ template<class T> class Vector4: public Vector<4, T> {
/** @copydoc Vector::Vector(T) */
inline constexpr explicit Vector4(T value): Vector<4, T>(value, value, value, value) {}
/** @copydoc Vector::Vector(const Vector&) */
inline constexpr Vector4(const Vector<4, T>& other): Vector<4, T>(other) {}
/** @brief Copy constructor */
inline constexpr Vector4(const RectangularMatrix<1, 4, T>& other): Vector<4, T>(other) {}
/**
* @brief Constructor

8
src/MeshTools/Clean.h

@ -39,7 +39,7 @@ template<class Vertex, size_t vertexSize = Vertex::Size> class Clean {
/* Get mesh bounds */
Vertex min, max;
for(size_t i = 0; i != Vertex::Size; ++i) {
for(size_t i = 0; i != Vertex::size; ++i) {
min[i] = std::numeric_limits<typename Vertex::Type>::max();
max[i] = std::numeric_limits<typename Vertex::Type>::min();
}
@ -53,7 +53,7 @@ template<class Vertex, size_t vertexSize = Vertex::Size> class Clean {
/* Make epsilon so large that size_t can index all vertices inside
mesh bounds. */
Vertex size = max-min;
for(size_t i = 0; i != Vertex::Size; ++i)
for(size_t i = 0; i != Vertex::size; ++i)
if(static_cast<typename Vertex::Type>(size[i]/std::numeric_limits<size_t>::max()) > epsilon)
epsilon = static_cast<typename Vertex::Type>(size[i]/std::numeric_limits<size_t>::max());
@ -91,7 +91,7 @@ template<class Vertex, size_t vertexSize = Vertex::Size> class Clean {
std::swap(newVertices, vertices);
/* Move vertex coordinates by epsilon/2 in next direction */
if(moving != Vertex::Size) {
if(moving != Vertex::size) {
moved = Vertex();
moved[moving] = epsilon/2;
}
@ -136,7 +136,7 @@ Removes duplicate vertices from the mesh.
@todo Interpolate vertices, not collapse them to first in the cell
@todo Ability to specify other attributes for interpolation
*/
template<class Vertex, size_t vertexSize = Vertex::Size> inline void clean(std::vector<unsigned int>& indices, std::vector<Vertex>& vertices, typename Vertex::Type epsilon = TypeTraits<typename Vertex::Type>::epsilon()) {
template<class Vertex, size_t vertexSize = Vertex::size> inline void clean(std::vector<unsigned int>& indices, std::vector<Vertex>& vertices, typename Vertex::Type epsilon = TypeTraits<typename Vertex::Type>::epsilon()) {
Implementation::Clean<Vertex, vertexSize>(indices, vertices)(epsilon);
}

2
src/MeshTools/Test/CleanTest.h

@ -28,7 +28,7 @@ class CleanTest: public Corrade::TestSuite::Tester<CleanTest> {
private:
class Vector1 {
public:
static const size_t Size = 1;
static const size_t size = 1;
typedef int Type;
Vector1(): data(0) {}

2
src/MeshTools/Test/SubdivideTest.h

@ -29,7 +29,7 @@ class SubdivideTest: public Corrade::TestSuite::Tester<SubdivideTest> {
private:
class Vector1 {
public:
static const size_t Size = 1;
static const size_t size = 1;
typedef int Type;
Vector1(): data(0) {}

2
src/SceneGraph/Camera.cpp

@ -33,7 +33,7 @@ template<class MatrixType> MatrixType aspectRatioFix(AspectRatioPolicy aspectRat
/* Extend on larger side = scale larger side down
Clip on smaller side = scale smaller side up */
return Camera<MatrixType::Size-1>::aspectRatioScale(
return Camera<MatrixType::size-1>::aspectRatioScale(
(relativeAspectRatio.x() > relativeAspectRatio.y()) == (aspectRatioPolicy == AspectRatioPolicy::Extend) ?
Vector2(relativeAspectRatio.y()/relativeAspectRatio.x(), 1.0f) :
Vector2(1.0f, relativeAspectRatio.x()/relativeAspectRatio.y()));

2
src/Swizzle.h

@ -100,7 +100,7 @@ instead of at runtime.
@see Vector4::xyz(), Vector4::rgb(), Vector4::xy(), Vector3::xy()
*/
template<char ...components, class T> inline constexpr typename Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector) {
return {vector[Implementation::GetComponent<T::Size, components>::value()]...};
return {vector[Implementation::GetComponent<T::size, components>::value()]...};
}
/**

Loading…
Cancel
Save