/*
* matrix3.cpp
* Copyright (C) Andrew Tridgell 2012
*
* This file is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This file 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#pragma GCC optimize("O2")
#include "AP_Math.h"
// multiplication by a vector
template
Vector4 Matrix4::operator *(const Vector4 &v) const
{
return Vector4(a.M0 * v.M0 + a.M1 * v.M1 + a.M2 * v.M2 + a.M3 * v.M3,
b.M0 * v.M0 + b.M1 * v.M1 + b.M2 * v.M2 + b.M3 * v.M3,
c.M0 * v.M0 + c.M1 * v.M1 + c.M2 * v.M2 + c.M3 * v.M3,
d.M0 * v.M0 + d.M1 * v.M1 + d.M2 * v.M2 + d.M3 * v.M3);
}
template
T Matrix4::det() const
{
Matrix3 m11(b.M1, b.M2, b.M3,
c.M1, c.M2, c.M3,
d.M1, d.M2, d.M3);
Matrix3 m12(b.M0, b.M2, b.M3,
c.M0, c.M2, c.M3,
d.M0, d.M2, d.M3);
Matrix3 m13(b.M0, b.M1, b.M3,
c.M0, c.M1, c.M3,
d.M0, d.M1, d.M3);
Matrix3 m14(b.M0, b.M1, b.M2,
c.M0, c.M1, c.M2,
d.M0, d.M1, d.M2);
T Matrix_det = a.M0*(m11.det())
-a.M1*(m12.det())
+a.M2*(m13.det())
-a.M3*(m14.det());
return Matrix_det;
}
template
bool Matrix4::inverse(Matrix4& inv) const
{
const T d_val = det();
if (is_zero(d_val)) {
return false;
}
//1 lie
Matrix3 m11(b.M1, b.M2, b.M3,
c.M1, c.M2, c.M3,
d.M1, d.M2, d.M3);
inv.a.M0 = m11.det()/d_val;
Matrix3 m12(b.M0, b.M2, b.M3,
c.M0, c.M2, c.M3,
d.M0, d.M2, d.M3);
inv.b.M0 = -m12.det()/d_val;
Matrix3 m13(b.M0, b.M1, b.M3,
c.M0, c.M1, c.M3,
d.M0, d.M1, d.M3);
inv.c.M0 = m13.det()/d_val;
Matrix3 m14(b.M0, b.M1, b.M2,
c.M0, c.M1, c.M2,
d.M0, d.M1, d.M2);
inv.d.M0 = -m14.det()/d_val;
//2 lie----------------
Matrix3 m21(a.M1, a.M2, a.M3,
c.M1, c.M2, c.M3,
d.M1, d.M2, d.M3);
inv.a.M1 = -m21.det()/d_val;
Matrix3 m22(a.M0, a.M2, a.M3,
c.M0, c.M2, c.M3,
d.M0, d.M2, d.M3);
inv.b.M1 = m22.det()/d_val;
Matrix3 m23(a.M0, a.M1, a.M3,
c.M0, c.M1, c.M3,
d.M0, d.M1, d.M3);
inv.c.M1 = -m23.det()/d_val;
Matrix3 m24(a.M0, a.M1, a.M2,
c.M0, c.M1, c.M2,
d.M0, d.M1, d.M2);
inv.d.M1 = m24.det()/d_val;
//3 lie---------------------
Matrix3 m31(a.M1, a.M2, a.M3,
b.M1, b.M2, b.M3,
d.M1, d.M2, d.M3);
inv.a.M2 = m31.det()/d_val;
Matrix3 m32(a.M0, a.M2, a.M3,
b.M0, b.M2, b.M3,
d.M0, d.M2, d.M3);
inv.b.M2 = -m32.det()/d_val;
Matrix3 m33(a.M0, a.M1, a.M3,
b.M0, b.M1, b.M3,
d.M0, d.M1, d.M3);
inv.c.M2 = m33.det()/d_val;
Matrix3 m34(a.M0, a.M1, a.M2,
b.M0, b.M1, b.M2,
d.M0, d.M1, d.M2);
inv.d.M2 = -m34.det()/d_val;
//4 lie---------------------
Matrix3 m41(a.M1, a.M2, a.M3,
b.M1, b.M2, b.M3,
c.M1, c.M2, c.M3);
inv.a.M3 = -m41.det()/d_val;
Matrix3 m42(a.M0, a.M2, a.M3,
b.M0, b.M2, b.M3,
c.M0, c.M2, c.M3);
inv.b.M3 = m42.det()/d_val;
Matrix3 m43(a.M0, a.M1, a.M3,
b.M0, b.M1, b.M3,
c.M0, c.M1, c.M3);
inv.c.M3 = -m43.det()/d_val;
Matrix3 m44(a.M0, a.M1, a.M2,
b.M0, b.M1, b.M2,
c.M0, c.M1, c.M2);
inv.d.M3 = m44.det()/d_val;
return true;
}
template
void Matrix4::zero(void)
{
a.M0 = a.M1 = a.M2 = a.M3 = 0;
b.M0 = b.M1 = b.M2 = b.M3 = 0;
c.M0 = c.M1 = c.M2 = c.M3 = 0;
d.M0 = d.M1 = d.M2 = d.M3 = 0;
}
// only define for float
template void Matrix4::zero(void);
template Vector4 Matrix4::operator *(const Vector4 &v) const;
template float Matrix4::det() const;
template bool Matrix4::inverse(Matrix4& inv) const;