瀏覽代碼

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

code for all matrices.
legacy
Sam Hocevar sam 13 年之前
父節點
當前提交
eb51928415
共有 7 個文件被更改,包括 306 次插入106 次删除
  1. +23
    -18
      src/lol/math/vector.h
  2. +109
    -6
      src/math/vector.cpp
  3. +2
    -2
      test/Makefile.am
  4. +2
    -2
      test/benchmark/vector.cpp
  5. +167
    -0
      test/unit/matrix.cpp
  6. +1
    -77
      test/unit/vector.cpp
  7. +2
    -1
      win32/testsuite.vcxproj

+ 23
- 18
src/lol/math/vector.h 查看文件

@@ -1354,9 +1354,6 @@ template <typename T> struct Mat2
inline Vec2<T>& operator[](size_t n) { return (&v0)[n]; } inline Vec2<T>& operator[](size_t n) { return (&v0)[n]; }
inline Vec2<T> const& operator[](size_t n) const { return (&v0)[n]; } inline Vec2<T> const& operator[](size_t n) const { return (&v0)[n]; }


T det() const;
Mat2<T> invert() const;

/* Helpers for transformation matrices */ /* Helpers for transformation matrices */
static Mat2<T> rotate(T angle); static Mat2<T> rotate(T angle);


@@ -1436,9 +1433,6 @@ template <typename T> struct Mat3
inline Vec3<T>& operator[](size_t n) { return (&v0)[n]; } inline Vec3<T>& operator[](size_t n) { return (&v0)[n]; }
inline Vec3<T> const& operator[](size_t n) const { return (&v0)[n]; } inline Vec3<T> const& operator[](size_t n) const { return (&v0)[n]; }


T det() const;
Mat3<T> invert() const;

/* Helpers for transformation matrices */ /* Helpers for transformation matrices */
static Mat3<T> rotate(T angle, T x, T y, T z); static Mat3<T> rotate(T angle, T x, T y, T z);
static Mat3<T> rotate(T angle, Vec3<T> v); static Mat3<T> rotate(T angle, Vec3<T> v);
@@ -1521,9 +1515,6 @@ template <typename T> struct Mat4
inline Vec4<T>& operator[](size_t n) { return (&v0)[n]; } inline Vec4<T>& operator[](size_t n) { return (&v0)[n]; }
inline Vec4<T> const& operator[](size_t n) const { return (&v0)[n]; } inline Vec4<T> const& operator[](size_t n) const { return (&v0)[n]; }


T det() const;
Mat4<T> invert() const;

/* Helpers for transformation matrices */ /* Helpers for transformation matrices */
static Mat4<T> translate(T x, T y, T z); static Mat4<T> translate(T x, T y, T z);
static Mat4<T> translate(Vec3<T> v); static Mat4<T> translate(Vec3<T> v);
@@ -1531,16 +1522,18 @@ template <typename T> struct Mat4
static Mat4<T> rotate(T angle, Vec3<T> v); static Mat4<T> rotate(T angle, Vec3<T> v);
static Mat4<T> rotate(Quat<T> q); static Mat4<T> rotate(Quat<T> q);


static inline Mat4<T> translate(Mat4<T> mat, Vec3<T> v)
static inline Mat4<T> translate(Mat4<T> const &mat, Vec3<T> v)
{ {
return translate(v) * mat; return translate(v) * mat;
} }


static inline Mat4<T> rotate(Mat4<T> mat, T angle, Vec3<T> v)
static inline Mat4<T> rotate(Mat4<T> &mat, T angle, Vec3<T> v)
{ {
return rotate(angle, v) * mat; return rotate(angle, v) * mat;
} }


static Mat3<T> normal(Mat4<T> const &mat);

/* Helpers for view matrices */ /* Helpers for view matrices */
static Mat4<T> lookat(Vec3<T> eye, Vec3<T> center, Vec3<T> up); static Mat4<T> lookat(Vec3<T> eye, Vec3<T> center, Vec3<T> up);


@@ -1556,37 +1549,37 @@ template <typename T> struct Mat4
friend std::ostream &operator<<(std::ostream &stream, Mat4<U> const &m); friend std::ostream &operator<<(std::ostream &stream, Mat4<U> const &m);
#endif #endif


inline Mat4<T> operator +(Mat4<T> const m) const
inline Mat4<T> operator +(Mat4<T> const &m) const
{ {
return Mat4<T>(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]); return Mat4<T>(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]);
} }


inline Mat4<T> operator +=(Mat4<T> const m)
inline Mat4<T> operator +=(Mat4<T> const &m)
{ {
return *this = *this + m; return *this = *this + m;
} }


inline Mat4<T> operator -(Mat4<T> const m) const
inline Mat4<T> operator -(Mat4<T> const &m) const
{ {
return Mat4<T>(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]); return Mat4<T>(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]);
} }


inline Mat4<T> operator -=(Mat4<T> const m)
inline Mat4<T> operator -=(Mat4<T> const &m)
{ {
return *this = *this - m; return *this = *this - m;
} }


inline Mat4<T> operator *(Mat4<T> const m) const
inline Mat4<T> operator *(Mat4<T> const &m) const
{ {
return Mat4<T>(*this * m[0], *this * m[1], *this * m[2], *this * m[3]); return Mat4<T>(*this * m[0], *this * m[1], *this * m[2], *this * m[3]);
} }


inline Mat4<T> operator *=(Mat4<T> const m)
inline Mat4<T> operator *=(Mat4<T> const &m)
{ {
return *this = *this * m; return *this = *this * m;
} }


inline Vec4<T> operator *(Vec4<T> const m) const
inline Vec4<T> operator *(Vec4<T> const &m) const
{ {
Vec4<T> ret; Vec4<T> ret;
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
@@ -1602,6 +1595,18 @@ template <typename T> struct Mat4
Vec4<T> v0, v1, v2, v3; Vec4<T> v0, v1, v2, v3;
}; };


template<typename T> T determinant(Mat2<T> const &);
template<typename T> T determinant(Mat3<T> const &);
template<typename T> T determinant(Mat4<T> const &);

template<typename T> Mat2<T> transpose(Mat2<T> const &);
template<typename T> Mat3<T> transpose(Mat3<T> const &);
template<typename T> Mat4<T> transpose(Mat4<T> const &);

template<typename T> Mat2<T> inverse(Mat2<T> const &);
template<typename T> Mat3<T> inverse(Mat3<T> const &);
template<typename T> Mat4<T> inverse(Mat4<T> const &);

/* /*
* Arbitrarily-sized square matrices; for now this only supports * Arbitrarily-sized square matrices; for now this only supports
* naive inversion and is used for the Remez inversion method. * naive inversion and is used for the Remez inversion method.


+ 109
- 6
src/math/vector.cpp 查看文件

@@ -36,6 +36,12 @@ using namespace std;
namespace lol namespace lol
{ {


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, static inline float det3(float a, float b, float c,
float d, float e, float f, float d, float e, float f,
float g, float h, float i) float g, float h, float i)
@@ -45,7 +51,20 @@ static inline float det3(float a, float b, float c,
+ c * (d * h - g * e); + c * (d * h - g * e);
} }


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], return det3(mat[(i + 1) & 3][(j + 1) & 3],
mat[(i + 2) & 3][(j + 1) & 3], mat[(i + 2) & 3][(j + 1) & 3],
@@ -58,24 +77,91 @@ static inline float cofact3(mat4 const &mat, int i, int j)
mat[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f); mat[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f);
} }


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; float ret = 0;
for (int n = 0; n < 4; n++) for (int n = 0; n < 4; n++)
ret += (*this)[n][0] * cofact3(*this, n, 0);
ret += mat[n][0] * cofact(mat, n, 0);
return ret; return ret;
} }


template<> mat4 mat4::invert() const
template<> mat4 transpose(mat4 const &mat)
{ {
mat4 ret; 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) if (d)
{ {
d = 1.0f / d; d = 1.0f / d;
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; j++)
for (int i = 0; i < 4; i++) 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; return ret;
} }
@@ -120,6 +206,23 @@ template<> void quat::printf() const
Log::Debug("[ %6.6f %6.6f %6.6f %6.6f ]\n", x, y, z, w); 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]);
}

template<> void mat4::printf() const template<> void mat4::printf() const
{ {
mat4 const &p = *this; mat4 const &p = *this;


+ 2
- 2
test/Makefile.am 查看文件

@@ -22,8 +22,8 @@ noinst_PROGRAMS = quad benchsuite testsuite
TESTS = testsuite TESTS = testsuite


testsuite_SOURCES = testsuite.cpp \ 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_CPPFLAGS = @LOL_CFLAGS@ @PIPI_CFLAGS@
testsuite_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@ testsuite_LDFLAGS = $(top_builddir)/src/liblol.a @LOL_LIBS@ @PIPI_LIBS@
testsuite_DEPENDENCIES = $(top_builddir)/src/liblol.a testsuite_DEPENDENCIES = $(top_builddir)/src/liblol.a


+ 2
- 2
test/benchmark/vector.cpp 查看文件

@@ -52,7 +52,7 @@ void bench_matrix(int mode)
/* Determinant */ /* Determinant */
timer.GetMs(); timer.GetMs();
for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
pf[i] = pm[i].det();
pf[i] = determinant(pm[i]);
result[1] += timer.GetMs(); result[1] += timer.GetMs();


/* Multiply matrices */ /* Multiply matrices */
@@ -70,7 +70,7 @@ void bench_matrix(int mode)
/* Invert matrix */ /* Invert matrix */
timer.GetMs(); timer.GetMs();
for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++) for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
pm[i] = pm[i].invert();
pm[i] = inverse(pm[i]);
result[4] += timer.GetMs(); result[4] += timer.GetMs();
} }




+ 167
- 0
test/unit/matrix.cpp 查看文件

@@ -0,0 +1,167 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/projects/COPYING.WTFPL for more details.
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include "core.h"
#include "lol/unit.h"

namespace lol
{

LOLUNIT_FIXTURE(MatrixTest)
{
void SetUp()
{
id2 = mat2(1.0f);
tri2 = mat2(vec2(1.0f, 0.0f),
vec2(7.0f, 2.0f));
inv2 = mat2(vec2(4.0f, 3.0f),
vec2(3.0f, 2.0f));

id3 = mat3(1.0f);
tri3 = mat3(vec3(1.0f, 0.0f, 0.0f),
vec3(7.0f, 2.0f, 0.0f),
vec3(1.0f, 5.0f, 3.0f));
inv3 = mat3(vec3(2.0f, 3.0f, 5.0f),
vec3(3.0f, 2.0f, 3.0f),
vec3(9.0f, 5.0f, 7.0f));

id4 = mat4(1.0f);
tri4 = 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));
inv4 = 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 TearDown() {}

LOLUNIT_TEST(Determinant)
{
float d1, d2;

d1 = determinant(tri2);
LOLUNIT_ASSERT_EQUAL(d1, 2.0f);
d2 = determinant(inv2);
LOLUNIT_ASSERT_EQUAL(d2, -1.0f);

d1 = determinant(tri3);
LOLUNIT_ASSERT_EQUAL(d1, 6.0f);
d2 = determinant(inv3);
LOLUNIT_ASSERT_EQUAL(d2, 1.0f);

d1 = determinant(tri4);
LOLUNIT_ASSERT_EQUAL(d1, 24.0f);
d2 = determinant(inv4);
LOLUNIT_ASSERT_EQUAL(d2, -1.0f);
}

LOLUNIT_TEST(Multiplication)
{
mat4 m0 = id4;
mat4 m1 = id4;
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(Inverse2x2)
{
mat2 m0 = inv2;
mat2 m1 = inverse(m0);

mat2 m2 = m0 * m1;

LOLUNIT_ASSERT_EQUAL(m2[0][0], 1.0f);
LOLUNIT_ASSERT_EQUAL(m2[1][0], 0.0f);

LOLUNIT_ASSERT_EQUAL(m2[0][1], 0.0f);
LOLUNIT_ASSERT_EQUAL(m2[1][1], 1.0f);
}

LOLUNIT_TEST(Inverse3x3)
{
mat3 m0 = inv3;
mat3 m1 = inverse(m0);

mat3 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[0][1], 0.0f);
LOLUNIT_ASSERT_EQUAL(m2[1][1], 1.0f);
LOLUNIT_ASSERT_EQUAL(m2[2][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_TEST(Inverse4x4)
{
mat4 m0 = inv4;
mat4 m1 = inverse(m0);

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);
}

mat2 tri2, id2, inv2;
mat3 tri3, id3, inv3;
mat4 tri4, id4, inv4;
};

} /* namespace lol */


+ 1
- 77
test/unit/vector.cpp 查看文件

@@ -20,18 +20,7 @@ namespace lol


LOLUNIT_FIXTURE(VectorTest) 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() {} void TearDown() {}


@@ -135,71 +124,6 @@ LOLUNIT_FIXTURE(VectorTest)
LOLUNIT_ASSERT_EQUAL(c.w, 0.0f); LOLUNIT_ASSERT_EQUAL(c.w, 0.0f);
LOLUNIT_ASSERT_EQUAL(a3, a1); 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;
}; };


} /* namespace lol */ } /* namespace lol */


+ 2
- 1
win32/testsuite.vcxproj 查看文件

@@ -32,6 +32,7 @@
<ClCompile Include="..\test\unit\cmplx.cpp" /> <ClCompile Include="..\test\unit\cmplx.cpp" />
<ClCompile Include="..\test\unit\half.cpp" /> <ClCompile Include="..\test\unit\half.cpp" />
<ClCompile Include="..\test\unit\image.cpp" /> <ClCompile Include="..\test\unit\image.cpp" />
<ClCompile Include="..\test\unit\matrix.cpp" />
<ClCompile Include="..\test\unit\quat.cpp" /> <ClCompile Include="..\test\unit\quat.cpp" />
<ClCompile Include="..\test\unit\real.cpp" /> <ClCompile Include="..\test\unit\real.cpp" />
<ClCompile Include="..\test\unit\trig.cpp" /> <ClCompile Include="..\test\unit\trig.cpp" />
@@ -60,4 +61,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project>
</Project>

Loading…
取消
儲存