Blame c++/perspective/src/matrix.cpp

Ivan Mahonin 14f971
#include "matrix.h"
Ivan Mahonin 14f971
Ivan Mahonin 14f971
Ivan Mahonin 14f971
// remove from sequence 0, 1, 2, 3, two numbers, see following
Ivan Mahonin 14f971
// example:
Ivan Mahonin 14f971
//   r0 = 1, r1 = 2
Ivan Mahonin 14f971
// initial sequence:
Ivan Mahonin 14f971
//   0, 1, 2, 3
Ivan Mahonin 14f971
// remove number at place r0 (1 for ex):
Ivan Mahonin 14f971
//   0, 2, 3
Ivan Mahonin 14f971
// remove number at place r1 (2 for ex):
Ivan Mahonin 14f971
//   0, 2
Ivan Mahonin 14f971
// so result for index0(1, 2) is 0
Ivan Mahonin 14f971
//       and for index1(1, 2) is 2
Ivan Mahonin 14f971
//
Ivan Mahonin fdabb2
// r1\r0 :  0    1    2    3
Ivan Mahonin fdabb2
// ---------------------------
Ivan Mahonin fdabb2
//    -- : _123 0_23 01_3 012_
Ivan Mahonin fdabb2
//     0 : _.23 ._23 .1_3 .12_
Ivan Mahonin fdabb2
//     1 : _1.3 0_.3 0._3 0.2_
Ivan Mahonin fdabb2
//     2 : _12. 0_2. 01_. 01._
Ivan Mahonin fdabb2
// ---------------------------
Ivan Mahonin fdabb2
//     0 :  23   23   13   12
Ivan Mahonin fdabb2
//     1 :  13   03   03   02
Ivan Mahonin fdabb2
//     2 :  12   02   01   01
Ivan Mahonin fdabb2
Ivan Mahonin 14f971
static inline int index0(int r0, int r1)
Ivan Mahonin fdabb2
	{ return r1 ? (r0 ? 0 : 1) : (r0 > 1 ? 1 : 2); }
Ivan Mahonin 14f971
static inline int index1(int r0, int r1)
Ivan Mahonin 14f971
	{ return r1 < 2 ? (r0 < 3 ? 3 : 2) : (r0 > 1 ? 1 : 2); }
Ivan Mahonin fdabb2
static inline int index0(int r)
Ivan Mahonin a1942e
	{ return r > 0 ? 0 : 1; }
Ivan Mahonin fdabb2
static inline int index1(int r)
Ivan Mahonin a1942e
	{ return r > 1 ? 1 : 2; }
Ivan Mahonin fdabb2
static inline int index2(int r)
Ivan Mahonin a1942e
	{ return r > 2 ? 2 : 3; }
Ivan Mahonin 14f971
Ivan Mahonin 14f971
static inline Real det2(const Matrix4 &m, int r, int c, int rr, int cc) {
Ivan Mahonin 14f971
	const int r0 = index0(r, rr);
Ivan Mahonin 14f971
	const int r1 = index1(r, rr);
Ivan Mahonin 14f971
	const int c0 = index0(c, cc);
Ivan Mahonin 14f971
	const int c1 = index1(c, cc);
Ivan Mahonin 14f971
	return m[r0][c0]*m[r1][c1] - m[r0][c1]*m[r1][c0];
Ivan Mahonin 14f971
}
Ivan Mahonin fdabb2
Ivan Mahonin fdabb2
static inline Real det3(const Matrix4 &m, int r, int c) {
Ivan Mahonin fdabb2
	const int r0 = index0(r);
Ivan Mahonin fdabb2
	return m[r0][index0(c)] * det2(m, r, c, 0, 0)
Ivan Mahonin fdabb2
	     - m[r0][index1(c)] * det2(m, r, c, 0, 1)
Ivan Mahonin fdabb2
		 + m[r0][index2(c)] * det2(m, r, c, 0, 2);
Ivan Mahonin fdabb2
}
Ivan Mahonin 14f971
Ivan Mahonin 14f971
Ivan Mahonin 14f971
Real
Ivan Mahonin 14f971
Matrix4::det() const
Ivan Mahonin fdabb2
	{ return m00*det3(*this, 0, 0) - m01*det3(*this, 0, 1) + m02*det3(*this, 0, 2) - m03*det3(*this, 0, 3); }
Ivan Mahonin 14f971
Ivan Mahonin 14f971
Matrix4
Ivan Mahonin a1942e
Matrix4::inverted() const {
Ivan Mahonin 14f971
	Vector4 dv(
Ivan Mahonin 14f971
		 det3(*this, 0, 0),
Ivan Mahonin 14f971
		-det3(*this, 0, 1),
Ivan Mahonin 14f971
		 det3(*this, 0, 2),
Ivan Mahonin 14f971
		-det3(*this, 0, 3) );
Ivan Mahonin a1942e
	Real d = m00*dv.x + m01*dv.y + m02*dv.z + m03*dv.w;
Ivan Mahonin fdabb2
	if (fabs(d) <= real_precision)
Ivan Mahonin 14f971
		return zero();
Ivan Mahonin 14f971
Ivan Mahonin 14f971
	d = 1.0/d;
Ivan Mahonin 14f971
	return Matrix4(
Ivan Mahonin 14f971
		Vector4(dv.x, -det3(*this, 1, 0), det3(*this, 2, 0), -det3(*this, 3, 0))*d,
Ivan Mahonin 14f971
		Vector4(dv.y,  det3(*this, 1, 1),-det3(*this, 2, 1),  det3(*this, 3, 1))*d,
Ivan Mahonin 14f971
		Vector4(dv.z, -det3(*this, 1, 2), det3(*this, 2, 2), -det3(*this, 3, 2))*d,
Ivan Mahonin 14f971
		Vector4(dv.w,  det3(*this, 1, 3),-det3(*this, 2, 3),  det3(*this, 3, 3))*d );
Ivan Mahonin 14f971
}