From a56d1e339aa7693e92eeb1ada6b25bc65fdbceb9 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Tue, 21 Feb 2017 21:19:28 +1100 Subject: [PATCH] matrix: parameterise on rows+cols+type --- matrix.cpp | 225 ++++++++++++++++++++-------------------------------- matrix.hpp | 147 +++++++++++++++++----------------- matrix.ipp | 203 ++++++++++++++++++++++++++--------------------- matrix2.cpp | 28 +++---- matrix3.cpp | 30 +++---- matrix4.cpp | 28 +++---- 6 files changed, 319 insertions(+), 342 deletions(-) diff --git a/matrix.cpp b/matrix.cpp index 0bbcc8b0..dea7a429 100644 --- a/matrix.cpp +++ b/matrix.cpp @@ -23,41 +23,13 @@ #include #include -using namespace util; +using util::matrix; /////////////////////////////////////////////////////////////////////////////// -template -matrix -matrix::transposed (void) const -{ - matrix m; - - for (size_t i = 0; i < S; ++i) - for (size_t j = 0; j < S; ++j) - m.values[i][j] = values[j][i]; - - return m; -} - - -//----------------------------------------------------------------------------- -template -matrix& -matrix::transpose (void) -{ - for (size_t i = 0; i < S; ++i) - for (size_t j = i + 1; j < S; ++j) - std::swap (values[i][j], values[j][i]); - - return *this; -} - - -//----------------------------------------------------------------------------- -template -matrix& -matrix::invert (void) +template +matrix& +matrix::invert (void) { return *this = inverse (); } @@ -113,32 +85,32 @@ matrix::invert (void) //----------------------------------------------------------------------------- -template +template T -util::matrix::determinant (void) const +util::matrix::determinant (void) const { return util::determinant (*this); } //----------------------------------------------------------------------------- -template -util::matrix -util::matrix::inverse (void) const +template +util::matrix +util::matrix::inverse (void) const { return util::inverse (*this); } /////////////////////////////////////////////////////////////////////////////// -template -matrix -util::transposed (const matrix &m) +template +matrix +util::transposed (const matrix &m) { - util::matrix res; + util::matrix res; - for (size_t y = 0; y < S; ++y) - for (size_t x = 0; x < S; ++x) + for (size_t y = 0; y < Rows; ++y) + for (size_t x = 0; x < Cols; ++x) res[y][x] = m[x][y]; return res; @@ -146,47 +118,18 @@ util::transposed (const matrix &m) //----------------------------------------------------------------------------- -template matrix3f util::transposed (const matrix3f&); -template matrix4f util::transposed (const matrix4f&); +template util::matrix3f util::transposed (const matrix3f&); +template util::matrix4f util::transposed (const matrix4f&); /////////////////////////////////////////////////////////////////////////////// -template -matrix -matrix::operator* (const matrix &rhs) const +template +util::vector +matrix::operator* (const vector &rhs) const { - matrix m; + vector out; - for (unsigned row = 0; row < S; ++row) { - for (unsigned col = 0; col < S; ++col) { - m.values[row][col] = T {0}; - - for (unsigned inner = 0; inner < S; ++inner) - m.values[row][col] += values[row][inner] * rhs.values[inner][col]; - } - } - - return m; -} - - -//----------------------------------------------------------------------------- -template -matrix& -matrix::operator*=(const matrix &rhs) -{ - return *this = *this * rhs; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -vector -matrix::operator* (const vector &rhs) const -{ - vector out; - - for (size_t i = 0; i < S; ++i) + for (size_t i = 0; i < Rows; ++i) out[i] = dot (rhs, values[i]); return out; @@ -194,13 +137,13 @@ matrix::operator* (const vector &rhs) const //----------------------------------------------------------------------------- -template -point -matrix::operator* (const point &rhs) const +template +util::point +matrix::operator* (const point &rhs) const { - point out; + point out; - for (size_t i = 0; i < S; ++i) + for (size_t i = 0; i < Rows; ++i) out[i] = dot (rhs, values[i]); return out; @@ -208,24 +151,27 @@ matrix::operator* (const point &rhs) const //----------------------------------------------------------------------------- -template +template bool -matrix::is_affine (void) const +matrix::is_affine (void) const { - for (size_t i = 0; i < S - 1; ++i) - if (!exactly_zero (values[S-1][i])) + if (Rows != Cols) + return false; + + for (size_t i = 0; i < Rows - 1; ++i) + if (!exactly_zero (values[Rows-1][i])) return false; - return exactly_equal (values[S-1][S-1], T{1}); + return exactly_equal (values[Rows-1][Rows-1], T{1}); } //----------------------------------------------------------------------------- -template -matrix4 -matrix::ortho (T left, T right, - T bottom, T top, - T near, T far) +template +util::matrix4 +matrix::ortho (T left, T right, + T bottom, T top, + T near, T far) { CHECK_GT (far, near); @@ -247,19 +193,19 @@ matrix::ortho (T left, T right, //----------------------------------------------------------------------------- -template -matrix4 -matrix::ortho2D (T left, T right, - T bottom, T top) +template +util::matrix4 +matrix::ortho2D (T left , T right, + T bottom, T top) { return ortho (left, right, bottom, top, -1, 1); } //----------------------------------------------------------------------------- -template -matrix4 -matrix::perspective (T fov, T aspect, range Z) +template +util::matrix4 +matrix::perspective (T fov, T aspect, range Z) { CHECK_GE (Z.lo, 0); CHECK_GE (Z.hi, 0); @@ -288,11 +234,11 @@ matrix::perspective (T fov, T aspect, range Z) // Implemented for right handed world coordinates. // // Assumes 'up' is normalised. -template -matrix4 -matrix::look_at (const util::point<3,T> eye, - const util::point<3,T> centre, - const util::vector<3,T> up) +template +util::matrix4 +matrix::look_at (const util::point<3,T> eye, + const util::point<3,T> centre, + const util::vector<3,T> up) { CHECK (is_normalised (up)); @@ -312,18 +258,18 @@ matrix::look_at (const util::point<3,T> eye, //----------------------------------------------------------------------------- -template -matrix4 -matrix::translation (util::vector<2,T> v) +template +util::matrix4 +matrix::translation (util::vector<2,T> v) { return translation ({v.x, v.y, 0}); } //----------------------------------------------------------------------------- -template -matrix4 -matrix::translation (util::vector<3,T> v) +template +util::matrix4 +matrix::translation (util::vector<3,T> v) { return { { { 1.f, 0.f, 0.f, v.x }, @@ -335,17 +281,17 @@ matrix::translation (util::vector<3,T> v) //----------------------------------------------------------------------------- -template -matrix4 -matrix::scale (T mag) +template +util::matrix4 +matrix::scale (T mag) { return scale (vector<3,T> (mag)); } //----------------------------------------------------------------------------- -template -matrix4 -matrix::scale (util::vector<3,T> v) +template +util::matrix4 +matrix::scale (util::vector<3,T> v) { return { { { v.x, 0.f, 0.f, 0.f }, @@ -357,9 +303,9 @@ matrix::scale (util::vector<3,T> v) //----------------------------------------------------------------------------- -template -matrix4 -matrix::rotation (T angle, util::vector<3,T> about) +template +util::matrix4 +matrix::rotation (T angle, util::vector<3,T> about) { CHECK (is_normalised (about)); @@ -394,25 +340,26 @@ matrix::rotation (T angle, util::vector<3,T> about) //----------------------------------------------------------------------------- -template struct util::matrix<2,float>; -template struct util::matrix<2,double>; +template struct util::matrix<2,2,float>; +template struct util::matrix<2,2,double>; -template struct util::matrix<3,float>; -template struct util::matrix<3,double>; +template struct util::matrix<3,3,float>; +template struct util::matrix<3,3,double>; -template struct util::matrix<4,float>; -template struct util::matrix<4,double>; +template struct util::matrix<4,4,float>; +template struct util::matrix<4,4,double>; /////////////////////////////////////////////////////////////////////////////// // Uses the algorithm from: // "Extracting Euler Angles from a Rotation Matrix" by // Mike Day, Insomniac Games. -template +template util::vector<3,T> -util::to_euler (const matrix &m) +util::to_euler (const matrix &m) { - static_assert (S == 3 || S == 4, "only defined for 3d affine transforms"); + static_assert (Rows == Cols && (Rows == 3 || Rows == 4), + "only defined for 3d affine transforms"); const auto theta0 = std::atan2 (m[2][1], m[2][2]); @@ -431,21 +378,21 @@ util::to_euler (const matrix &m) //----------------------------------------------------------------------------- -template util::vector<3,float> util::to_euler (const matrix<3,float>&); -template util::vector<3,float> util::to_euler (const matrix<4,float>&); +template util::vector<3,float> util::to_euler (const matrix<3,3,float>&); +template util::vector<3,float> util::to_euler (const matrix<4,4,float>&); /////////////////////////////////////////////////////////////////////////////// -template +template std::ostream& -util::operator<< (std::ostream &os, const matrix &m) +util::operator<< (std::ostream &os, const matrix &m) { os << "{ "; - for (size_t i = 0; i < S; ++i) { + for (size_t i = 0; i < Rows; ++i) { os << "{ "; - std::copy (m[i], m[i]+S, util::infix_iterator (os, ", ")); - os << ((i == S - 1) ? " }" : " }, "); + std::copy_n (m[i], Cols, util::infix_iterator (os, ", ")); + os << ((i == Rows - 1) ? " }" : " }, "); } return os << " }"; @@ -453,5 +400,5 @@ util::operator<< (std::ostream &os, const matrix &m) //----------------------------------------------------------------------------- -template std::ostream& util::operator<< (std::ostream&, const matrix<4,float>&); -template std::ostream& util::operator<< (std::ostream&, const matrix<4,double>&); +template std::ostream& util::operator<< (std::ostream&, const matrix<4,4,float>&); +template std::ostream& util::operator<< (std::ostream&, const matrix<4,4,double>&); diff --git a/matrix.hpp b/matrix.hpp index 47e0bca1..05463b5b 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -21,14 +21,15 @@ #include "range.hpp" #include +#include namespace util { - template + template struct matrix { - T values[S][S]; + static constexpr auto rows = Rows; + static constexpr auto cols = Cols; - static constexpr size_t rows = S; - static constexpr size_t cols = S; + T values[Rows][Cols]; // index operators return a pointer into the data array so that // multidimensional array syntax can be used transparently on this @@ -46,9 +47,6 @@ namespace util { const T* cbegin (void) const; const T* cend (void) const; - matrix& transpose (void); - matrix transposed (void) const; - T determinant (void) const; matrix inverse (void) const; @@ -56,29 +54,27 @@ namespace util { matrix inverse_affine (void) const; matrix& invert_affine (void); - matrix operator* (const matrix&) const; - matrix& operator*=(const matrix&); - - vector operator* (const vector&) const; - point operator* (const point &) const; + vector operator* (const vector&) const; + point operator* (const point &) const; bool is_affine (void) const; template - matrix cast (void) const; + matrix + cast (void) const; // Perspective matrices - static matrix<4,T> ortho (T left, T right, T bottom, T top, T near, T far); - static matrix<4,T> ortho2D (T left, T right, T bottom, T top); - static matrix<4,T> perspective (T fov, T aspect, range Z); - static matrix<4,T> look_at (point<3,T> eye, point<3,T> target, vector<3,T> up); + static matrix<4,4,T> ortho (T left, T right, T bottom, T top, T near, T far); + static matrix<4,4,T> ortho2D (T left, T right, T bottom, T top); + static matrix<4,4,T> perspective (T fov, T aspect, range Z); + static matrix<4,4,T> look_at (point<3,T> eye, point<3,T> target, vector<3,T> up); // Affine matrices - static matrix<4,T> translation (util::vector<2,T>); - static matrix<4,T> translation (util::vector<3,T>); - static matrix<4,T> scale (util::vector<3,T>); - static matrix<4,T> scale (T); - static matrix<4,T> rotation (T angle, util::vector<3,T> about); + static matrix<4,4,T> translation (util::vector<2,T>); + static matrix<4,4,T> translation (util::vector<3,T>); + static matrix<4,4,T> scale (util::vector<3,T>); + static matrix<4,4,T> scale (T); + static matrix<4,4,T> rotation (T angle, util::vector<3,T> about); // Constant matrices static constexpr matrix identity (); @@ -91,101 +87,110 @@ namespace util { // // Results are undefined if the matrix is not purely a rotation matrix, // or if the dimension is not 3x3 or 4x4. - template + template vector<3,T> - to_euler (const matrix&); + to_euler (const matrix&); /////////////////////////////////////////////////////////////////////////// // logical operations - template + template constexpr bool - operator== (const matrix&, const matrix&); + operator== (const matrix&, const matrix&); - template + template constexpr bool - operator!= (const matrix&, const matrix&); + operator!= (const matrix&, const matrix&); /////////////////////////////////////////////////////////////////////////// // element operations - template + template constexpr - matrix - operator+ (const matrix&, const matrix&); + matrix + operator+ (const matrix&, const matrix&); - template + template constexpr - matrix - operator- (const matrix&, const matrix&); + matrix + operator- (const matrix&, const matrix&); /////////////////////////////////////////////////////////////////////////// // scalar operations - template constexpr matrix operator* (const matrix&, T); - template constexpr matrix operator/ (const matrix&, T); - template constexpr matrix operator+ (const matrix&, T); - template constexpr matrix operator- (const matrix&, T); + template constexpr matrix operator* (const matrix&, T); + template constexpr matrix operator/ (const matrix&, T); + template constexpr matrix operator+ (const matrix&, T); + template constexpr matrix operator- (const matrix&, T); - template constexpr matrix operator* (T, const matrix&); - template constexpr matrix operator/ (T, const matrix&); - template constexpr matrix operator+ (T, const matrix&); - template constexpr matrix operator- (T, const matrix&); + template constexpr matrix operator* (T, const matrix&); + template constexpr matrix operator/ (T, const matrix&); + template constexpr matrix operator+ (T, const matrix&); + template constexpr matrix operator- (T, const matrix&); - template constexpr matrix& operator*= (matrix&, T); - template constexpr matrix& operator/= (matrix&, T); - template constexpr matrix& operator+= (matrix&, T); - template constexpr matrix& operator-= (matrix&, T); + template constexpr matrix& operator*= (matrix&, T); + template constexpr matrix& operator/= (matrix&, T); + template constexpr matrix& operator+= (matrix&, T); + template constexpr matrix& operator-= (matrix&, T); /////////////////////////////////////////////////////////////////////////// - template + // matrix operations + template < + size_t R1, size_t C1, + size_t R2, size_t C2, + typename T + > constexpr matrix operator* (const matrix&, const matrix&); + + + /////////////////////////////////////////////////////////////////////////// + template T - determinant (const matrix&); + determinant (const matrix&); - template - matrix - inverse (const matrix&); + template + matrix + inverse (const matrix&); - template - matrix - transposed (const matrix&); + template + matrix + transposed (const matrix&); /////////////////////////////////////////////////////////////////////////// - template - matrix - abs (const matrix&); + template + matrix + abs (const matrix&); - template + template constexpr T - sum (const matrix&); + sum (const matrix&); /////////////////////////////////////////////////////////////////////////// - template using matrix3 = matrix<3,T>; - template using matrix4 = matrix<4,T>; + template using matrix3 = matrix<3,3,T>; + template using matrix4 = matrix<4,4,T>; - template using matrixf = matrix; - template using matrixd = matrix; + template using matrixf = matrix; + template using matrixd = matrix; - typedef matrix<2,float> matrix2f; - typedef matrix<2,double> matrix2d; + typedef matrix<2,2,float> matrix2f; + typedef matrix<2,2,double> matrix2d; - typedef matrix<3,float> matrix3f; - typedef matrix<3,double> matrix3d; + typedef matrix<3,3,float> matrix3f; + typedef matrix<3,3,double> matrix3d; - typedef matrix<4,float> matrix4f; - typedef matrix<4,double> matrix4d; + typedef matrix<4,4,float> matrix4f; + typedef matrix<4,4,double> matrix4d; /////////////////////////////////////////////////////////////////////////// - template - std::ostream& operator<< (std::ostream&, const matrix&); + template + std::ostream& operator<< (std::ostream&, const matrix&); } #include "matrix.ipp" diff --git a/matrix.ipp b/matrix.ipp index 0ab88a2f..1f3f53f8 100644 --- a/matrix.ipp +++ b/matrix.ipp @@ -23,102 +23,102 @@ /////////////////////////////////////////////////////////////////////////////// -template +template T* -util::matrix::operator[] (size_t idx) +util::matrix::operator[] (size_t idx) { return this->values[idx]; } //----------------------------------------------------------------------------- -template +template const T* -util::matrix::operator[] (size_t idx) const +util::matrix::operator[] (size_t idx) const { return this->values[idx]; } //----------------------------------------------------------------------------- -template +template T* -util::matrix::data (void) +util::matrix::data (void) { return begin (); } //----------------------------------------------------------------------------- -template +template const T* -util::matrix::data (void) const +util::matrix::data (void) const { return begin (); } //----------------------------------------------------------------------------- -template +template const T* -util::matrix::begin (void) const +util::matrix::begin (void) const { return &(*this)[0][0]; } //----------------------------------------------------------------------------- -template +template const T* -util::matrix::end (void) const +util::matrix::end (void) const { - return &(*this)[S][0]; + return &(*this)[Rows][0]; } //----------------------------------------------------------------------------- -template +template const T* -util::matrix::cbegin (void) const +util::matrix::cbegin (void) const { return begin (); } //----------------------------------------------------------------------------- -template +template const T* -util::matrix::cend (void) const +util::matrix::cend (void) const { return end (); } //----------------------------------------------------------------------------- -template +template T* -util::matrix::begin (void) +util::matrix::begin (void) { return &(*this)[0][0]; } //----------------------------------------------------------------------------- -template +template T* -util::matrix::end (void) +util::matrix::end (void) { - return &(*this)[S][0]; + return &(*this)[Rows][0]; } /////////////////////////////////////////////////////////////////////////////// -template +template template -util::matrix -util::matrix::cast (void) const +util::matrix +util::matrix::cast (void) const { - util::matrix out; + util::matrix out; std::copy (cbegin (), cend (), std::begin (out)); return out; } @@ -126,14 +126,14 @@ util::matrix::cast (void) const /////////////////////////////////////////////////////////////////////////////// #define MATRIX_ELEMENT_OP(OP) \ -template \ +template \ constexpr \ -util::matrix \ +util::matrix \ util::operator OP ( \ - const util::matrix &a, \ - const util::matrix &b) \ + const util::matrix &a, \ + const util::matrix &b) \ { \ - util::matrix res {}; \ + util::matrix res {}; \ \ for (size_t i = 0; i < a.rows; ++i) \ for (size_t j = 0; j < a.cols; ++j) \ @@ -149,47 +149,47 @@ MATRIX_ELEMENT_OP(+) /////////////////////////////////////////////////////////////////////////////// -#define MATRIX_SCALAR_OP(OP) \ -template \ -constexpr \ -util::matrix \ -util::operator OP (const util::matrix &m, const T t) \ -{ \ - util::matrix res {}; \ - \ - std::transform ( \ - std::cbegin (m), \ - std::cend (m), \ - std::begin (res), \ - [&t] (auto x) { return x OP t; } \ - ); \ - \ - return res; \ -} \ - \ - \ -template \ -constexpr \ -util::matrix \ -util::operator OP (const T t, const util::matrix &m) \ -{ \ - return m OP t; \ -} \ - \ - \ -template \ -constexpr \ -util::matrix& \ -util::operator OP##= (util::matrix &m, T t) \ -{ \ - std::transform ( \ - std::cbegin (m), \ - std::cend (m), \ - std::begin (m), \ - [&t] (auto x) { return x OP t; } \ - ); \ - \ - return m; \ +#define MATRIX_SCALAR_OP(OP) \ +template \ +constexpr \ +util::matrix \ +util::operator OP (const util::matrix &m, const T t) \ +{ \ + util::matrix res {}; \ + \ + std::transform ( \ + std::cbegin (m), \ + std::cend (m), \ + std::begin (res), \ + [&t] (auto x) { return x OP t; } \ + ); \ + \ + return res; \ +} \ + \ + \ +template \ +constexpr \ +util::matrix \ +util::operator OP (const T t, const util::matrix &m) \ +{ \ + return m OP t; \ +} \ + \ + \ +template \ +constexpr \ +util::matrix& \ +util::operator OP##= (util::matrix &m, T t) \ +{ \ + std::transform ( \ + std::cbegin (m), \ + std::cend (m), \ + std::begin (m), \ + [&t] (auto x) { return x OP t; } \ + ); \ + \ + return m; \ } @@ -202,64 +202,89 @@ MATRIX_SCALAR_OP(-) /////////////////////////////////////////////////////////////////////////////// -template +template < + std::size_t R1, std::size_t C1, + std::size_t R2, std::size_t C2, + typename T +> constexpr -util::matrix -util::matrix::zeroes (void) +util::matrix +util::operator* (const matrix &a, const matrix &b) +{ + static_assert (R2 == C1); + + matrix res {0}; + + for (size_t r = 0; r < R1; ++r) + for (size_t c = 0; c < C2; ++c) + for (size_t i = 0; i < R2; ++i) + res[r][c] += a[r][i] * b[i][c]; + + return res; +} + + +/////////////////////////////////////////////////////////////////////////////// +template +constexpr +util::matrix +util::matrix::zeroes (void) { return {0}; } /////////////////////////////////////////////////////////////////////////////// -template +template constexpr -util::matrix -util::matrix::identity (void) +util::matrix +util::matrix::identity (void) { + static_assert (Rows == Cols); + auto m = zeroes (); - for (size_t i = 0; i < S; ++i) + for (size_t i = 0; i < Rows; ++i) m[i][i] = 1; return m; } /////////////////////////////////////////////////////////////////////////////// -template +template constexpr bool -util::operator== (const matrix &a, const matrix &b) +util::operator== (const matrix &a, const matrix &b) { return std::equal (std::cbegin (a), std::cend (a), std::cbegin (b)); } //----------------------------------------------------------------------------- -template +template constexpr bool -util::operator!= (const matrix &a, const matrix &b) +util::operator!= (const matrix &a, const matrix &b) { return !(a == b); } /////////////////////////////////////////////////////////////////////////////// -template -util::matrix -util::abs (const util::matrix &src) +template +util::matrix +util::abs (const util::matrix &src) { - util::matrix dst; + util::matrix dst; std::transform (std::cbegin (src), std::cend (src), std::begin (dst), util::abs); return dst; } /////////////////////////////////////////////////////////////////////////////// -template +template constexpr T -util::sum (const util::matrix &src) +util::sum (const util::matrix &src) { return sum (std::cbegin (src), std::cend (src)); } diff --git a/matrix2.cpp b/matrix2.cpp index 4bb7f2f4..393066a4 100644 --- a/matrix2.cpp +++ b/matrix2.cpp @@ -20,27 +20,27 @@ using util::matrix; /////////////////////////////////////////////////////////////////////////////// -template +template T -util::determinant (const matrix &m) +util::determinant (const matrix &m) { - static_assert (S == 2, "partial specialization for 2 dimensions"); + static_assert (Rows == 2 && Cols == 2); return m[0][0] * m[1][1] - m[0][1] * m[1][0]; } -template float util::determinant (const matrix<2,float>&); -template double util::determinant (const matrix<2,double>&); +template float util::determinant (const matrix<2,2,float>&); +template double util::determinant (const matrix<2,2,double>&); /////////////////////////////////////////////////////////////////////////////// -template -matrix -util::inverse (const matrix &m) +template +matrix +util::inverse (const matrix &m) { - static_assert (S == 2, "partial specialization for 2 dimensions"); + static_assert (Rows == 2 && Cols == 2); - return matrix { + return matrix<2,2,T> { m[1][1], -m[0][1], -m[1][0], m[0][0] } / determinant (m); @@ -48,10 +48,10 @@ util::inverse (const matrix &m) //----------------------------------------------------------------------------- -template util::matrix<2,float> util::inverse (const matrix<2,float>&); -template util::matrix<2,double> util::inverse (const matrix<2,double>&); +template util::matrix<2,2,float> util::inverse (const matrix<2,2,float>&); +template util::matrix<2,2,double> util::inverse (const matrix<2,2,double>&); /////////////////////////////////////////////////////////////////////////////// -template struct util::matrix<2,float>; -template struct util::matrix<2,double>; +template struct util::matrix<2,2,float>; +template struct util::matrix<2,2,double>; diff --git a/matrix3.cpp b/matrix3.cpp index 4e9d232c..64b0b678 100644 --- a/matrix3.cpp +++ b/matrix3.cpp @@ -20,29 +20,29 @@ using util::matrix; /////////////////////////////////////////////////////////////////////////////// -template +template T -util::determinant (const matrix& m) +util::determinant (const matrix& m) { - static_assert (S == 3, "hard coded 3x3 specialisation"); + static_assert (Rows == 3 && Cols == 3); return m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) - m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]) + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); } -template float util::determinant (const matrix<3,float>&); -template double util::determinant (const matrix<3,double>&); +template float util::determinant (const matrix<3,3,float>&); +template double util::determinant (const matrix<3,3,double>&); //----------------------------------------------------------------------------- -template -matrix -util::inverse (const matrix &m) +template +matrix +util::inverse (const matrix &m) { - static_assert (S == 3, "hard coded 3x3 specialisation"); - - return matrix { + static_assert (Rows == 3 && Cols == 3); + + return matrix<3,3,T> { m[1][1] * m[2][2] - m[2][1] * m[1][2], m[0][2] * m[2][1] - m[0][1] * m[2][2], m[0][1] * m[1][2] - m[0][2] * m[1][1], @@ -57,10 +57,10 @@ util::inverse (const matrix &m) } / determinant (m); } -template util::matrix<3,float> util::inverse (const matrix<3,float>&); -template util::matrix<3,double> util::inverse (const matrix<3,double>&); +template util::matrix<3,3,float> util::inverse (const matrix<3,3,float>&); +template util::matrix<3,3,double> util::inverse (const matrix<3,3,double>&); /////////////////////////////////////////////////////////////////////////////// -template struct util::matrix<3,float>; -template struct util::matrix<3,double>; +template struct util::matrix<3,3,float>; +template struct util::matrix<3,3,double>; diff --git a/matrix4.cpp b/matrix4.cpp index efa1b9d5..bbaca1be 100644 --- a/matrix4.cpp +++ b/matrix4.cpp @@ -20,11 +20,11 @@ using util::matrix; //----------------------------------------------------------------------------- -template +template T -util::determinant (const matrix &m) +util::determinant (const matrix &m) { - static_assert (S == 4, "hard coded 4x4 specialisation"); + static_assert (Rows == 4 && Cols == 4); return m[0][3] * m[1][2] * m[2][1] * m[3][0] - m[0][2] * m[1][3] * m[2][1] * m[3][0] - m[0][3] * m[1][1] * m[2][2] * m[3][0] + m[0][1] * m[1][3] * m[2][2] * m[3][0] + @@ -40,18 +40,18 @@ util::determinant (const matrix &m) m[0][1] * m[1][0] * m[2][2] * m[3][3] + m[0][0] * m[1][1] * m[2][2] * m[3][3]; } -template float util::determinant (const matrix<4,float>&); -template double util::determinant (const matrix<4,double>&); +template float util::determinant (const matrix<4,4,float>&); +template double util::determinant (const matrix<4,4,double>&); //----------------------------------------------------------------------------- -template -matrix -util::inverse (const matrix &m) +template +matrix +util::inverse (const matrix &m) { - static_assert (S == 4, "hard coded 4x4 specialisation"); + static_assert (Rows == 4 && Cols == 4); - return matrix { + return matrix<4,4,T> { m[1][2]*m[2][3]*m[3][1] - m[1][3]*m[2][2]*m[3][1] + m[1][3]*m[2][1]*m[3][2] - m[1][1]*m[2][3]*m[3][2] - m[1][2]*m[2][1]*m[3][3] + m[1][1]*m[2][2]*m[3][3], m[0][3]*m[2][2]*m[3][1] - m[0][2]*m[2][3]*m[3][1] - m[0][3]*m[2][1]*m[3][2] + m[0][1]*m[2][3]*m[3][2] + m[0][2]*m[2][1]*m[3][3] - m[0][1]*m[2][2]*m[3][3], m[0][2]*m[1][3]*m[3][1] - m[0][3]*m[1][2]*m[3][1] + m[0][3]*m[1][1]*m[3][2] - m[0][1]*m[1][3]*m[3][2] - m[0][2]*m[1][1]*m[3][3] + m[0][1]*m[1][2]*m[3][3], @@ -71,10 +71,10 @@ util::inverse (const matrix &m) } / determinant (m); } -template util::matrix<4,float> util::inverse (const matrix<4,float>&); -template util::matrix<4,double> util::inverse (const matrix<4,double>&); +template util::matrix<4,4,float> util::inverse (const matrix<4,4,float>&); +template util::matrix<4,4,double> util::inverse (const matrix<4,4,double>&); /////////////////////////////////////////////////////////////////////////////// -template struct util::matrix<4,float>; -template struct util::matrix<4,double>; +template struct util::matrix<4,4,float>; +template struct util::matrix<4,4,double>;