# Changeset 1257 for trunkTweet

Ignore:
Timestamp:
Apr 21, 2012, 6:58:26 PM (8 years ago)
Message:

math: add inversion code for 2×2 and 3×3 matrices, and transposition
code for all matrices.

Location:
trunk
Files:
6 edited

Unmodified
Removed
• ## trunk/src/lol/math/vector.h

 r1232 inline Vec2 const& operator[](size_t n) const { return (&v0)[n]; } T det() const; Mat2 invert() const; /* Helpers for transformation matrices */ static Mat2 rotate(T angle); inline Vec3 const& operator[](size_t n) const { return (&v0)[n]; } T det() const; Mat3 invert() const; /* Helpers for transformation matrices */ static Mat3 rotate(T angle, T x, T y, T z); inline Vec4 const& operator[](size_t n) const { return (&v0)[n]; } T det() const; Mat4 invert() const; /* Helpers for transformation matrices */ static Mat4 translate(T x, T y, T z); static Mat4 rotate(Quat q); static inline Mat4 translate(Mat4 mat, Vec3 v) static inline Mat4 translate(Mat4 const &mat, Vec3 v) { return translate(v) * mat; } static inline Mat4 rotate(Mat4 mat, T angle, Vec3 v) static inline Mat4 rotate(Mat4 &mat, T angle, Vec3 v) { return rotate(angle, v) * mat; } static Mat3 normal(Mat4 const &mat); /* Helpers for view matrices */ #endif inline Mat4 operator +(Mat4 const m) const inline Mat4 operator +(Mat4 const &m) const { return Mat4(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]); } inline Mat4 operator +=(Mat4 const m) inline Mat4 operator +=(Mat4 const &m) { return *this = *this + m; } inline Mat4 operator -(Mat4 const m) const inline Mat4 operator -(Mat4 const &m) const { return Mat4(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]); } inline Mat4 operator -=(Mat4 const m) inline Mat4 operator -=(Mat4 const &m) { return *this = *this - m; } inline Mat4 operator *(Mat4 const m) const inline Mat4 operator *(Mat4 const &m) const { return Mat4(*this * m[0], *this * m[1], *this * m[2], *this * m[3]); } inline Mat4 operator *=(Mat4 const m) inline Mat4 operator *=(Mat4 const &m) { return *this = *this * m; } inline Vec4 operator *(Vec4 const m) const inline Vec4 operator *(Vec4 const &m) const { Vec4 ret; Vec4 v0, v1, v2, v3; }; template T determinant(Mat2 const &); template T determinant(Mat3 const &); template T determinant(Mat4 const &); template Mat2 transpose(Mat2 const &); template Mat3 transpose(Mat3 const &); template Mat4 transpose(Mat4 const &); template Mat2 inverse(Mat2 const &); template Mat3 inverse(Mat3 const &); template Mat4 inverse(Mat4 const &); /*
• ## trunk/src/math/vector.cpp

 r1180 { static inline float det2(float a, float b, float c, float d) { return a * d - b * c; } static inline float det3(float a, float b, float c, float d, float e, float f, } static inline float cofact3(mat4 const &mat, int i, int j) static inline float cofact(mat2 const &mat, int i, int j) { return mat[(i + 1) & 1][(j + 1) & 1] * (((i + j) & 1) ? -1.0f : 1.0f); } static inline float cofact(mat3 const &mat, int i, int j) { return det2(mat[(i + 1) % 3][(j + 1) % 3], mat[(i + 2) % 3][(j + 1) % 3], mat[(i + 1) % 3][(j + 2) % 3], mat[(i + 2) % 3][(j + 2) % 3]); } static inline float cofact(mat4 const &mat, int i, int j) { return det3(mat[(i + 1) & 3][(j + 1) & 3], } template<> float mat4::det() const template<> float determinant(mat2 const &mat) { return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; } template<> mat2 transpose(mat2 const &mat) { mat2 ret; for (int j = 0; j < 2; j++) for (int i = 0; i < 2; i++) ret[j][i] = mat[i][j]; return ret; } template<> mat2 inverse(mat2 const &mat) { mat2 ret; float d = determinant(mat); if (d) { d = 1.0f / d; for (int j = 0; j < 2; j++) for (int i = 0; i < 2; i++) ret[j][i] = cofact(mat, i, j) * d; } return ret; } template<> float determinant(mat3 const &mat) { return det3(mat[0][0], mat[0][1], mat[0][2], mat[1][0], mat[1][1], mat[1][2], mat[2][0], mat[2][1], mat[2][2]); } template<> mat3 transpose(mat3 const &mat) { mat3 ret; for (int j = 0; j < 3; j++) for (int i = 0; i < 3; i++) ret[j][i] = mat[i][j]; return ret; } template<> mat3 inverse(mat3 const &mat) { mat3 ret; float d = determinant(mat); if (d) { d = 1.0f / d; for (int j = 0; j < 3; j++) for (int i = 0; i < 3; i++) ret[j][i] = cofact(mat, i, j) * d; } return ret; } template<> float determinant(mat4 const &mat) { float ret = 0; for (int n = 0; n < 4; n++) ret += (*this)[n][0] * cofact3(*this, n, 0); return ret; } template<> mat4 mat4::invert() const ret += mat[n][0] * cofact(mat, n, 0); return ret; } template<> mat4 transpose(mat4 const &mat) { mat4 ret; float d = det(); for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) ret[j][i] = mat[i][j]; return ret; } template<> mat4 inverse(mat4 const &mat) { mat4 ret; float d = determinant(mat); if (d) { for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) ret[j][i] = cofact3(*this, i, j) * d; ret[j][i] = cofact(mat, i, j) * d; } return ret; { Log::Debug("[ %6.6f %6.6f %6.6f %6.6f ]\n", x, y, z, w); } template<> void mat2::printf() const { mat2 const &p = *this; Log::Debug("[ %6.6f %6.6f\n", p[0][0], p[1][0]); Log::Debug("  %6.6f %6.6f ]\n", p[0][1], p[1][1]); } template<> void mat3::printf() const { mat3 const &p = *this; Log::Debug("[ %6.6f %6.6f %6.6f\n", p[0][0], p[1][0], p[2][0]); Log::Debug("  %6.6f %6.6f %6.6f\n", p[0][1], p[1][1], p[2][1]); Log::Debug("  %6.6f %6.6f %6.6f ]\n", p[0][2], p[1][2], p[2][2]); }
• ## trunk/test/Makefile.am

 r1139 testsuite_SOURCES = testsuite.cpp \ unit/vector.cpp unit/half.cpp unit/trig.cpp unit/build.cpp \ unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp unit/vector.cpp unit/matrix.cpp unit/half.cpp unit/trig.cpp \ unit/build.cpp unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp testsuite_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@ testsuite_LDFLAGS = \$(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@
• ## trunk/test/benchmark/vector.cpp

 r1139 timer.GetMs(); for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) pf[i] = pm[i].det(); pf[i] = determinant(pm[i]); result[1] += timer.GetMs(); timer.GetMs(); for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) pm[i] = pm[i].invert(); pm[i] = inverse(pm[i]); result[4] += timer.GetMs(); }
• ## trunk/test/unit/vector.cpp

 r1139 LOLUNIT_FIXTURE(VectorTest) { void SetUp() { identity = mat4(1.0f); triangular = mat4(vec4(1.0f, 0.0f, 0.0f, 0.0f), vec4(7.0f, 2.0f, 0.0f, 0.0f), vec4(1.0f, 5.0f, 3.0f, 0.0f), vec4(8.0f, 9.0f, 2.0f, 4.0f)); invertible = mat4(vec4( 1.0f,  1.0f,  2.0f, -1.0f), vec4(-2.0f, -1.0f, -2.0f,  2.0f), vec4( 4.0f,  2.0f,  5.0f, -4.0f), vec4( 5.0f, -3.0f, -7.0f, -6.0f)); } void SetUp() {} void TearDown() {} LOLUNIT_ASSERT_EQUAL(a3, a1); } LOLUNIT_TEST(MatrixDeterminant) { float d1 = triangular.det(); LOLUNIT_ASSERT_EQUAL(d1, 24.0f); float d2 = invertible.det(); LOLUNIT_ASSERT_EQUAL(d2, -1.0f); } LOLUNIT_TEST(MatrixMultiplication) { mat4 m0 = identity; mat4 m1 = identity; mat4 m2 = m0 * m1; LOLUNIT_ASSERT_EQUAL(m2[0][0], 1.0f); LOLUNIT_ASSERT_EQUAL(m2[1][0], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[2][0], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[3][0], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[0][1], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[1][1], 1.0f); LOLUNIT_ASSERT_EQUAL(m2[2][1], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[3][1], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[0][2], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[1][2], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[2][2], 1.0f); LOLUNIT_ASSERT_EQUAL(m2[3][2], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[0][3], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[1][3], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[2][3], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[3][3], 1.0f); } LOLUNIT_TEST(MatrixInverse) { mat4 m0 = invertible; mat4 m1 = m0.invert(); mat4 m2 = m0 * m1; LOLUNIT_ASSERT_EQUAL(m2[0][0], 1.0f); LOLUNIT_ASSERT_EQUAL(m2[1][0], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[2][0], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[3][0], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[0][1], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[1][1], 1.0f); LOLUNIT_ASSERT_EQUAL(m2[2][1], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[3][1], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[0][2], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[1][2], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[2][2], 1.0f); LOLUNIT_ASSERT_EQUAL(m2[3][2], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[0][3], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[1][3], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[2][3], 0.0f); LOLUNIT_ASSERT_EQUAL(m2[3][3], 1.0f); } mat4 triangular, identity, invertible; };
• ## trunk/win32/testsuite.vcxproj

 r1210
Note: See TracChangeset for help on using the changeset viewer.