matrix: parameterise on dimension

This commit is contained in:
Danny Robson 2015-10-30 23:40:13 +11:00
parent fe7e3e9c6f
commit 176b33604b
4 changed files with 196 additions and 190 deletions

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2011-2014 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2015 Danny Robson <danny@nerdcruft.net>
*/ */
#include "matrix.hpp" #include "matrix.hpp"
@ -26,25 +26,25 @@ using namespace util;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix<S,T>
matrix<T>::transposed (void) const matrix<S,T>::transposed (void) const
{ {
matrix<T> m; matrix<S,T> m;
for (size_t i = 0; i < 4; ++i) for (size_t i = 0; i < S; ++i)
for (size_t j = 0; j < 4; ++j) for (size_t j = 0; j < S; ++j)
m.values[i][j] = values[j][i]; m.values[i][j] = values[j][i];
return m; return m;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T>& matrix<S,T>&
matrix<T>::transpose (void) matrix<S,T>::transpose (void)
{ {
for (size_t i = 0; i < 4; ++i) for (size_t i = 0; i < S; ++i)
for (size_t j = i + 1; j < 4; ++j) for (size_t j = i + 1; j < S; ++j)
std::swap (values[i][j], values[j][i]); std::swap (values[i][j], values[j][i]);
return *this; return *this;
@ -52,9 +52,11 @@ matrix<T>::transpose (void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix<S,T>
matrix<T>::inverse (void) const { matrix<S,T>::inverse (void) const {
static_assert (S == 4, "assuming 4x4 matrices");
// GLM's implementation of 4x4 matrix inversion. Should allow use of // GLM's implementation of 4x4 matrix inversion. Should allow use of
// vector instructions. // vector instructions.
const auto &m = values; const auto &m = values;
@ -104,10 +106,10 @@ matrix<T>::inverse (void) const {
vector<4,T> SignA(+1, -1, +1, -1); vector<4,T> SignA(+1, -1, +1, -1);
vector<4,T> SignB(-1, +1, -1, +1); vector<4,T> SignB(-1, +1, -1, +1);
//matrix<T> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB); //matrix<T> Inverse(Inv0 * SignA, Inv1 * SignB, Inv2 * SignA, Inv3 * SignB);
matrix<T> Inverse = { { { Inv0.x * SignA.x, Inv0.y * SignA.y, Inv0.z * SignA.z, Inv0.w * SignA.w }, matrix<4,T> Inverse = { { { Inv0.x * SignA.x, Inv0.y * SignA.y, Inv0.z * SignA.z, Inv0.w * SignA.w },
{ Inv1.x * SignB.x, Inv1.y * SignB.y, Inv1.z * SignB.z, Inv1.w * SignB.w }, { Inv1.x * SignB.x, Inv1.y * SignB.y, Inv1.z * SignB.z, Inv1.w * SignB.w },
{ Inv2.x * SignA.x, Inv2.y * SignA.y, Inv2.z * SignA.z, Inv2.w * SignA.w }, { Inv2.x * SignA.x, Inv2.y * SignA.y, Inv2.z * SignA.z, Inv2.w * SignA.w },
{ Inv3.x * SignB.x, Inv3.y * SignB.y, Inv3.z * SignB.z, Inv3.w * SignB.w } } }; { Inv3.x * SignB.x, Inv3.y * SignB.y, Inv3.z * SignB.z, Inv3.w * SignB.w } } };
vector<4,T> Row0(Inverse.values[0][0], Inverse.values[1][0], Inverse.values[2][0], Inverse.values[3][0]); vector<4,T> Row0(Inverse.values[0][0], Inverse.values[1][0], Inverse.values[2][0], Inverse.values[3][0]);
@ -127,25 +129,25 @@ matrix<T>::inverse (void) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T>& matrix<S,T>&
matrix<T>::invert (void) { matrix<S,T>::invert (void) {
return *this = inverse (); return *this = inverse ();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix<S,T>
matrix<T>::inverse_affine (void) const { matrix<S,T>::inverse_affine (void) const {
return matrix<T>(*this).invert_affine (); return matrix<S,T>(*this).invert_affine ();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T>& matrix<S,T>&
matrix<T>::invert_affine (void) { matrix<S,T>::invert_affine (void) {
CHECK (is_affine ()); CHECK (is_affine ());
// inv ([ M b ] == [ inv(M) -inv(M).b ] // inv ([ M b ] == [ inv(M) -inv(M).b ]
@ -191,9 +193,9 @@ matrix<T>::invert_affine (void) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
T T
matrix<T>::det (void) const { matrix<S,T>::det (void) const {
return values[0][3] * values[1][2] * values[2][1] * values[3][0] - return values[0][3] * values[1][2] * values[2][1] * values[3][0] -
values[0][2] * values[1][3] * values[2][1] * values[3][0] - values[0][2] * values[1][3] * values[2][1] * values[3][0] -
values[0][3] * values[1][1] * values[2][2] * values[3][0] + values[0][3] * values[1][1] * values[2][2] * values[3][0] +
@ -225,16 +227,16 @@ matrix<T>::det (void) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix<S,T>
matrix<T>::operator* (const matrix<T> &rhs) const { matrix<S,T>::operator* (const matrix<S,T> &rhs) const {
matrix<T> m; matrix<S,T> m;
for (unsigned row = 0; row < 4; ++row) { for (unsigned row = 0; row < S; ++row) {
for (unsigned col = 0; col < 4; ++col) { for (unsigned col = 0; col < S; ++col) {
m.values[row][col] = T {0}; m.values[row][col] = T {0};
for (unsigned inner = 0; inner < 4; ++inner) for (unsigned inner = 0; inner < S; ++inner)
m.values[row][col] += values[row][inner] * rhs.values[inner][col]; m.values[row][col] += values[row][inner] * rhs.values[inner][col];
} }
} }
@ -244,38 +246,38 @@ matrix<T>::operator* (const matrix<T> &rhs) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T>& matrix<S,T>&
matrix<T>::operator*=(const matrix<T> &rhs) { matrix<S,T>::operator*=(const matrix<S,T> &rhs) {
return *this = *this * rhs; return *this = *this * rhs;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <typename T> //template <size_t S, typename T>
vector<3,T> //vector<3,T>
matrix<T>::operator* (vector<3,T> v) const //matrix<S,T>::operator* (vector<3,T> v) const
{ //{
return ( // return (
*this * v.template homog<4> () // *this * v.template homog<S> ()
).template redim<3> (); // ).template redim<3> ();
} //}
//
//
////-----------------------------------------------------------------------------
//template <size_t S, typename T>
//point<3,T>
//matrix<S,T>::operator* (point<3,T> p) const
//{
// return (*this * p.template homog<S> ()).template redim<3> ();
//}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
point<3,T> vector<S,T>
matrix<T>::operator* (point<3,T> p) const matrix<S,T>::operator* (const vector<S,T> &rhs) const {
{ return vector<S,T> {
return (*this * p.template homog<4> ()).template redim<3> ();
}
//-----------------------------------------------------------------------------
template <typename T>
vector<4,T>
matrix<T>::operator* (const vector<4,T> &rhs) const {
return vector<4,T> {
values[0][0] * rhs.x + values[0][1] * rhs.y + values[0][2] * rhs.z + values[0][3] * rhs.w, values[0][0] * rhs.x + values[0][1] * rhs.y + values[0][2] * rhs.z + values[0][3] * rhs.w,
values[1][0] * rhs.x + values[1][1] * rhs.y + values[1][2] * rhs.z + values[1][3] * rhs.w, values[1][0] * rhs.x + values[1][1] * rhs.y + values[1][2] * rhs.z + values[1][3] * rhs.w,
values[2][0] * rhs.x + values[2][1] * rhs.y + values[2][2] * rhs.z + values[2][3] * rhs.w, values[2][0] * rhs.x + values[2][1] * rhs.y + values[2][2] * rhs.z + values[2][3] * rhs.w,
@ -285,11 +287,11 @@ matrix<T>::operator* (const vector<4,T> &rhs) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
point<4,T> point<S,T>
matrix<T>::operator* (const point<4,T> &rhs) const matrix<S,T>::operator* (const point<S,T> &rhs) const
{ {
return point<4,T> { return point<S,T> {
values[0][0] * rhs.x + values[0][1] * rhs.y + values[0][2] * rhs.z + values[0][3] * rhs.w, values[0][0] * rhs.x + values[0][1] * rhs.y + values[0][2] * rhs.z + values[0][3] * rhs.w,
values[1][0] * rhs.x + values[1][1] * rhs.y + values[1][2] * rhs.z + values[1][3] * rhs.w, values[1][0] * rhs.x + values[1][1] * rhs.y + values[1][2] * rhs.z + values[1][3] * rhs.w,
values[2][0] * rhs.x + values[2][1] * rhs.y + values[2][2] * rhs.z + values[2][3] * rhs.w, values[2][0] * rhs.x + values[2][1] * rhs.y + values[2][2] * rhs.z + values[2][3] * rhs.w,
@ -299,14 +301,14 @@ matrix<T>::operator* (const point<4,T> &rhs) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix<S,T>
matrix<T>::operator* (T f) const matrix<S,T>::operator* (T f) const
{ {
matrix<T> out; matrix<S,T> out;
for (size_t i = 0; i < 4; ++i) for (size_t i = 0; i < S; ++i)
for (size_t j = 0; j < 4; ++j) for (size_t j = 0; j < S; ++j)
out.values[i][j] = values[i][j] * f; out.values[i][j] = values[i][j] * f;
return out; return out;
@ -314,11 +316,11 @@ matrix<T>::operator* (T f) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T>& matrix<S,T>&
matrix<T>::operator*= (T f){ matrix<S,T>::operator*= (T f){
for (size_t i = 0; i < 4; ++i) for (size_t i = 0; i < S; ++i)
for (size_t j = 0; j < 4; ++j) for (size_t j = 0; j < S; ++j)
values[i][j] *= f; values[i][j] *= f;
return *this; return *this;
@ -326,10 +328,10 @@ matrix<T>::operator*= (T f){
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix<S,T>
matrix<T>::operator/ (T s) const { matrix<S,T>::operator/ (T s) const {
matrix<T> m; matrix<S,T> m;
for (size_t r = 0; r < m.rows; ++r) for (size_t r = 0; r < m.rows; ++r)
for (size_t c = 0; c < m.cols; ++c) for (size_t c = 0; c < m.cols; ++c)
@ -340,9 +342,9 @@ matrix<T>::operator/ (T s) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T>& matrix<S,T>&
matrix<T>::operator/= (T s) { matrix<S,T>::operator/= (T s) {
for (size_t r = 0; r < rows; ++r) for (size_t r = 0; r < rows; ++r)
for (size_t c = 0; c < cols; ++c) for (size_t c = 0; c < cols; ++c)
values[r][c] /= s; values[r][c] /= s;
@ -352,9 +354,9 @@ matrix<T>::operator/= (T s) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
bool bool
matrix<T>::operator== (const matrix<T> &rhs) const { matrix<S,T>::operator== (const matrix<S,T> &rhs) const {
for (size_t r = 0; r < rows; ++r) for (size_t r = 0; r < rows; ++r)
for (size_t c = 0; c < cols; ++c) for (size_t c = 0; c < cols; ++c)
if (!almost_equal (rhs.values[r][c], values[r][c])) if (!almost_equal (rhs.values[r][c], values[r][c]))
@ -364,9 +366,9 @@ matrix<T>::operator== (const matrix<T> &rhs) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
bool bool
matrix<T>::is_affine (void) const { matrix<S,T>::is_affine (void) const {
return exactly_equal (values[3][0], T {0}) && return exactly_equal (values[3][0], T {0}) &&
exactly_equal (values[3][1], T {0}) && exactly_equal (values[3][1], T {0}) &&
exactly_equal (values[3][2], T {0}) && exactly_equal (values[3][2], T {0}) &&
@ -375,11 +377,11 @@ matrix<T>::is_affine (void) const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::ortho (T left, T right, matrix<S,T>::ortho (T left, T right,
T bottom, T top, T bottom, T top,
T near, T far) T near, T far)
{ {
CHECK_GT (far, near); CHECK_GT (far, near);
@ -401,19 +403,19 @@ matrix<T>::ortho (T left, T right,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::ortho2D (T left, T right, matrix<S,T>::ortho2D (T left, T right,
T bottom, T top) T bottom, T top)
{ {
return ortho (left, right, bottom, top, -1, 1); return ortho (left, right, bottom, top, -1, 1);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::perspective (T fov, T aspect, T near, T far) matrix<S,T>::perspective (T fov, T aspect, T near, T far)
{ {
T f = std::tan (fov / 2); T f = std::tan (fov / 2);
@ -433,11 +435,11 @@ matrix<T>::perspective (T fov, T aspect, T near, T far)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Emulates gluLookAt // Emulates gluLookAt
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::look_at (util::point<3,T> eye, matrix<S,T>::look_at (util::point<3,T> eye,
util::point<3,T> centre, util::point<3,T> centre,
util::vector<3,T> up) util::vector<3,T> up)
{ {
const auto f = (centre - eye).normalise (); const auto f = (centre - eye).normalise ();
const auto s = cross (f, up).normalise (); const auto s = cross (f, up).normalise ();
@ -453,18 +455,18 @@ matrix<T>::look_at (util::point<3,T> eye,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::translate (util::vector<2,T> v) matrix<S,T>::translate (util::vector<2,T> v)
{ {
return translate ({v.x, v.y, 0}); return translate ({v.x, v.y, 0});
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::translate (util::vector<3,T> v) matrix<S,T>::translate (util::vector<3,T> v)
{ {
return { { return { {
{ 1.f, 0.f, 0.f, v.x }, { 1.f, 0.f, 0.f, v.x },
@ -476,17 +478,17 @@ matrix<T>::translate (util::vector<3,T> v)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::scale (T mag) matrix<S,T>::scale (T mag)
{ {
return scale (vector<3,T> (mag)); return scale (vector<3,T> (mag));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::scale (util::vector<3,T> v) matrix<S,T>::scale (util::vector<3,T> v)
{ {
return { { return { {
{ v.x, 0.f, 0.f, 0.f }, { v.x, 0.f, 0.f, 0.f },
@ -498,9 +500,9 @@ matrix<T>::scale (util::vector<3,T> v)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
matrix<T> matrix4<T>
matrix<T>::rotate (T angle, util::vector<3,T> about) matrix<S,T>::rotate (T angle, util::vector<3,T> about)
{ {
about.normalise (); about.normalise ();
@ -534,33 +536,33 @@ matrix<T>::rotate (T angle, util::vector<3,T> about)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <size_t S, typename T>
const matrix<T> const matrix<S,T>
matrix<T>::IDENTITY = { { { 1, 0, 0, 0 }, matrix<S,T>::IDENTITY = { { { 1, 0, 0, 0 },
{ 0, 1, 0, 0 }, { 0, 1, 0, 0 },
{ 0, 0, 1, 0 }, { 0, 0, 1, 0 },
{ 0, 0, 0, 1 } } }; { 0, 0, 0, 1 } } };
template <typename T> template <size_t S, typename T>
const matrix<T> const matrix<S,T>
matrix<T>::ZEROES = { { { 0, 0, 0, 0 }, matrix<S,T>::ZEROES = { { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 0, 0, 0, 0 } } }; { 0, 0, 0, 0 } } };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
namespace util { namespace util {
template struct matrix<float>; template struct matrix<4,float>;
template struct matrix<double>; template struct matrix<4,double>;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
namespace util { namespace util {
template <typename T> template <size_t S, typename T>
std::ostream& std::ostream&
operator<< (std::ostream &os, const matrix<T> &m) { operator<< (std::ostream &os, const matrix<S,T> &m) {
os << "{ {" << m.values[0][0] << ", " os << "{ {" << m.values[0][0] << ", "
<< m.values[0][1] << ", " << m.values[0][1] << ", "
<< m.values[0][2] << ", " << m.values[0][2] << ", "
@ -582,5 +584,5 @@ namespace util {
} }
} }
template std::ostream& util::operator<< (std::ostream&, const matrix<float>&); template std::ostream& util::operator<< (std::ostream&, const matrix<4,float>&);
template std::ostream& util::operator<< (std::ostream&, const matrix<double>&); template std::ostream& util::operator<< (std::ostream&, const matrix<4,double>&);

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2011-2014 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2015 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_MATRIX_HPP #ifndef __UTIL_MATRIX_HPP
@ -22,69 +22,73 @@
#include <iostream> #include <iostream>
namespace util { namespace util {
template <typename T> template <size_t S, typename T>
struct matrix { struct matrix {
T values[4][4]; T values[S][S];
static const size_t rows = 4; static const size_t rows = S;
static const size_t cols = 4; static const size_t cols = S;
matrix& transpose (void); matrix& transpose (void);
matrix transposed (void) const; matrix transposed (void) const;
matrix<T> inverse (void) const; matrix inverse (void) const;
matrix<T>& invert (void); matrix& invert (void);
matrix<T> inverse_affine (void) const; matrix inverse_affine (void) const;
matrix<T>& invert_affine (void); matrix& invert_affine (void);
T det (void) const; T det (void) const;
matrix<T> operator* (const matrix<T>&) const; matrix operator* (const matrix&) const;
matrix<T>& operator*=(const matrix<T>&); matrix& operator*=(const matrix&);
vector<3,T> operator* (vector<3,T>) const; //vector<3,T> operator* (vector<3,T>) const;
point<3,T> operator* (point<3,T>) const; //point<3,T> operator* (point<3,T>) const;
vector<4,T> operator* (const vector<4,T>&) const; vector<S,T> operator* (const vector<S,T>&) const;
point<4,T> operator* (const point<4,T> &) const; point<S,T> operator* (const point<S,T> &) const;
matrix<T> operator* (T) const; matrix operator* (T) const;
matrix<T>& operator*= (T); matrix& operator*= (T);
matrix<T> operator/ (T) const; matrix operator/ (T) const;
matrix<T>& operator/= (T); matrix& operator/= (T);
bool operator== (const matrix<T>&) const; bool operator== (const matrix&) const;
bool is_affine (void) const; bool is_affine (void) const;
template <typename U> template <typename U>
matrix<U> cast (void) const; matrix<S,U> cast (void) const;
// Perspective matrices // Perspective matrices
static matrix<T> ortho (T left, T right, T bottom, T top, T near, T far); static matrix<4,T> ortho (T left, T right, T bottom, T top, T near, T far);
static matrix<T> ortho2D (T left, T right, T bottom, T top); static matrix<4,T> ortho2D (T left, T right, T bottom, T top);
static matrix<T> perspective (T fov, T aspect, T near, T far); static matrix<4,T> perspective (T fov, T aspect, T near, T far);
static matrix<T> look_at (point<3,T> eye, point<3,T> centre, vector<3,T> up); static matrix<4,T> look_at (point<3,T> eye, point<3,T> centre, vector<3,T> up);
// Affine matrices // Affine matrices
static matrix<T> translate (util::vector<2,T>); static matrix<4,T> translate (util::vector<2,T>);
static matrix<T> translate (util::vector<3,T>); static matrix<4,T> translate (util::vector<3,T>);
static matrix<T> scale (util::vector<3,T>); static matrix<4,T> scale (util::vector<3,T>);
static matrix<T> scale (T); static matrix<4,T> scale (T);
static matrix<T> rotate (T angle, util::vector<3,T> about); static matrix<4,T> rotate (T angle, util::vector<3,T> about);
// Constant matrices // Constant matrices
static const matrix<T> IDENTITY; static const matrix IDENTITY;
static const matrix<T> ZEROES; static const matrix ZEROES;
}; };
template <typename T> using matrix4 = matrix<T>; template <typename T> using matrix3 = matrix<3,T>;
template <typename T> using matrix4 = matrix<4,T>;
typedef matrix<float> matrixf; template <size_t S> using matrixf = matrix<S,float>;
typedef matrix<float> matrix4f; template <size_t S> using matrixd = matrix<S,double>;
template <typename T> typedef matrix<4,float> matrix4f;
std::ostream& operator<< (std::ostream&, const matrix<T>&); typedef matrix<4,double> matrix4d;
template <size_t S, typename T>
std::ostream& operator<< (std::ostream&, const matrix<S,T>&);
} }
#include "matrix.ipp" #include "matrix.ipp"

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
* Copyright 2011-2014 Danny Robson <danny@nerdcruft.net> * Copyright 2011-2015 Danny Robson <danny@nerdcruft.net>
*/ */
@ -21,12 +21,12 @@
#define __UTIL_MATRIX_IPP #define __UTIL_MATRIX_IPP
template <typename T> template <size_t S, typename T>
template <typename U> template <typename U>
util::matrix<U> util::matrix<S,U>
util::matrix<T>::cast (void) const util::matrix<S,T>::cast (void) const
{ {
util::matrix<U> out; util::matrix<S,U> out;
for (size_t i = 0; i < rows; ++i) for (size_t i = 0; i < rows; ++i)
for (size_t j = 0; j < cols; ++j) for (size_t j = 0; j < cols; ++j)

View File

@ -13,14 +13,14 @@ main (void)
{ {
// Identity matrix-vector multiplication // Identity matrix-vector multiplication
auto v = util::vector<4,float> { 1.f, 2.f, 3.f, 4.f }; auto v = util::vector4f { 1.f, 2.f, 3.f, 4.f };
auto r = util::matrix<float>::IDENTITY * v; auto r = util::matrix4f::IDENTITY * v;
tap.expect_eq (r, v, "identity matrix-vector multiplication"); tap.expect_eq (r, v, "identity matrix-vector multiplication");
} }
{ {
// Simple matrix-vector multiplication // Simple matrix-vector multiplication
util::matrix<float> m { { util::matrix4f m { {
{ 1, 2, 3, 4 }, { 1, 2, 3, 4 },
{ 5, 6, 7, 8 }, { 5, 6, 7, 8 },
{ 9, 10, 11, 12 }, { 9, 10, 11, 12 },
@ -42,28 +42,28 @@ main (void)
{ {
// Simple matrix-matrix multiplication // Simple matrix-matrix multiplication
util::matrix<float> a { { util::matrix4f a { {
{ 1, 2, 3, 4 }, { 1, 2, 3, 4 },
{ 5, 6, 7, 8 }, { 5, 6, 7, 8 },
{ 9, 10, 11, 12 }, { 9, 10, 11, 12 },
{ 13, 14, 15, 16 }, { 13, 14, 15, 16 },
} }; } };
util::matrix<float> b { { util::matrix4f b { {
{ 17, 18, 19, 20 }, { 17, 18, 19, 20 },
{ 21, 22, 23, 24 }, { 21, 22, 23, 24 },
{ -1, -2, -3, -4 }, { -1, -2, -3, -4 },
{ -5, -6, -7, -8 } { -5, -6, -7, -8 }
} }; } };
util::matrix<float> ab { { util::matrix4f ab { {
{ 9, 8, 7, 6 }, { 9, 8, 7, 6 },
{ 41, 40, 39, 38 }, { 41, 40, 39, 38 },
{ 73, 72, 71, 70 }, { 73, 72, 71, 70 },
{ 105, 104, 103, 102 }, { 105, 104, 103, 102 },
} }; } };
ab *= 4; ab *= 4.f;
auto res = a * b; auto res = a * b;
@ -75,7 +75,7 @@ main (void)
bool success = true; bool success = true;
// Ensure identity inverts to identity // Ensure identity inverts to identity
auto m = util::matrix<float>::IDENTITY.inverse (); auto m = util::matrix4f::IDENTITY.inverse ();
for (size_t r = 0; r < m.rows; ++r) for (size_t r = 0; r < m.rows; ++r)
for (size_t c = 0; c < m.cols; ++c) for (size_t c = 0; c < m.cols; ++c)
if (r == c) if (r == c)
@ -88,14 +88,14 @@ main (void)
{ {
// Simple inversion test // Simple inversion test
util::matrix<float> m { { util::matrix4f m { {
{ 4, 1, 2, 3 }, { 4, 1, 2, 3 },
{ 2, 3, 4, 1 }, { 2, 3, 4, 1 },
{ 3, 4, 1, 2 }, { 3, 4, 1, 2 },
{ 1, 2, 3, 4 } { 1, 2, 3, 4 }
} }; } };
util::matrix<float> r { { util::matrix4f r { {
{ 11, 1, 1, -9 }, { 11, 1, 1, -9 },
{ -9, 1, 11, 1 }, { -9, 1, 11, 1 },
{ 1, 11, -9, 1 }, { 1, 11, -9, 1 },