matrix: parameterise on dimension
This commit is contained in:
parent
fe7e3e9c6f
commit
176b33604b
278
matrix.cpp
278
matrix.cpp
@ -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>&);
|
||||||
|
78
matrix.hpp
78
matrix.hpp
@ -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"
|
||||||
|
10
matrix.ipp
10
matrix.ipp
@ -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)
|
||||||
|
@ -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 },
|
||||||
|
Loading…
Reference in New Issue
Block a user