Changeset 1257 for trunk


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

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

Location:
trunk
Files:
1 added
6 edited

Legend:

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

    r1232 r1257  
    13551355    inline Vec2<T> const& operator[](size_t n) const { return (&v0)[n]; }
    13561356
    1357     T det() const;
    1358     Mat2<T> invert() const;
    1359 
    13601357    /* Helpers for transformation matrices */
    13611358    static Mat2<T> rotate(T angle);
     
    14371434    inline Vec3<T> const& operator[](size_t n) const { return (&v0)[n]; }
    14381435
    1439     T det() const;
    1440     Mat3<T> invert() const;
    1441 
    14421436    /* Helpers for transformation matrices */
    14431437    static Mat3<T> rotate(T angle, T x, T y, T z);
     
    15221516    inline Vec4<T> const& operator[](size_t n) const { return (&v0)[n]; }
    15231517
    1524     T det() const;
    1525     Mat4<T> invert() const;
    1526 
    15271518    /* Helpers for transformation matrices */
    15281519    static Mat4<T> translate(T x, T y, T z);
     
    15321523    static Mat4<T> rotate(Quat<T> q);
    15331524
    1534     static inline Mat4<T> translate(Mat4<T> mat, Vec3<T> v)
     1525    static inline Mat4<T> translate(Mat4<T> const &mat, Vec3<T> v)
    15351526    {
    15361527        return translate(v) * mat;
    15371528    }
    15381529
    1539     static inline Mat4<T> rotate(Mat4<T> mat, T angle, Vec3<T> v)
     1530    static inline Mat4<T> rotate(Mat4<T> &mat, T angle, Vec3<T> v)
    15401531    {
    15411532        return rotate(angle, v) * mat;
    15421533    }
     1534
     1535    static Mat3<T> normal(Mat4<T> const &mat);
    15431536
    15441537    /* Helpers for view matrices */
     
    15571550#endif
    15581551
    1559     inline Mat4<T> operator +(Mat4<T> const m) const
     1552    inline Mat4<T> operator +(Mat4<T> const &m) const
    15601553    {
    15611554        return Mat4<T>(v0 + m[0], v1 + m[1], v2 + m[2], v3 + m[3]);
    15621555    }
    15631556
    1564     inline Mat4<T> operator +=(Mat4<T> const m)
     1557    inline Mat4<T> operator +=(Mat4<T> const &m)
    15651558    {
    15661559        return *this = *this + m;
    15671560    }
    15681561
    1569     inline Mat4<T> operator -(Mat4<T> const m) const
     1562    inline Mat4<T> operator -(Mat4<T> const &m) const
    15701563    {
    15711564        return Mat4<T>(v0 - m[0], v1 - m[1], v2 - m[2], v3 - m[3]);
    15721565    }
    15731566
    1574     inline Mat4<T> operator -=(Mat4<T> const m)
     1567    inline Mat4<T> operator -=(Mat4<T> const &m)
    15751568    {
    15761569        return *this = *this - m;
    15771570    }
    15781571
    1579     inline Mat4<T> operator *(Mat4<T> const m) const
     1572    inline Mat4<T> operator *(Mat4<T> const &m) const
    15801573    {
    15811574        return Mat4<T>(*this * m[0], *this * m[1], *this * m[2], *this * m[3]);
    15821575    }
    15831576
    1584     inline Mat4<T> operator *=(Mat4<T> const m)
     1577    inline Mat4<T> operator *=(Mat4<T> const &m)
    15851578    {
    15861579        return *this = *this * m;
    15871580    }
    15881581
    1589     inline Vec4<T> operator *(Vec4<T> const m) const
     1582    inline Vec4<T> operator *(Vec4<T> const &m) const
    15901583    {
    15911584        Vec4<T> ret;
     
    16021595    Vec4<T> v0, v1, v2, v3;
    16031596};
     1597
     1598template<typename T> T determinant(Mat2<T> const &);
     1599template<typename T> T determinant(Mat3<T> const &);
     1600template<typename T> T determinant(Mat4<T> const &);
     1601
     1602template<typename T> Mat2<T> transpose(Mat2<T> const &);
     1603template<typename T> Mat3<T> transpose(Mat3<T> const &);
     1604template<typename T> Mat4<T> transpose(Mat4<T> const &);
     1605
     1606template<typename T> Mat2<T> inverse(Mat2<T> const &);
     1607template<typename T> Mat3<T> inverse(Mat3<T> const &);
     1608template<typename T> Mat4<T> inverse(Mat4<T> const &);
    16041609
    16051610/*
  • trunk/src/math/vector.cpp

    r1180 r1257  
    3737{
    3838
     39static inline float det2(float a, float b,
     40                         float c, float d)
     41{
     42    return a * d - b * c;
     43}
     44
    3945static inline float det3(float a, float b, float c,
    4046                         float d, float e, float f,
     
    4652}
    4753
    48 static inline float cofact3(mat4 const &mat, int i, int j)
     54static inline float cofact(mat2 const &mat, int i, int j)
     55{
     56    return mat[(i + 1) & 1][(j + 1) & 1] * (((i + j) & 1) ? -1.0f : 1.0f);
     57}
     58
     59static inline float cofact(mat3 const &mat, int i, int j)
     60{
     61    return det2(mat[(i + 1) % 3][(j + 1) % 3],
     62                mat[(i + 2) % 3][(j + 1) % 3],
     63                mat[(i + 1) % 3][(j + 2) % 3],
     64                mat[(i + 2) % 3][(j + 2) % 3]);
     65}
     66
     67static inline float cofact(mat4 const &mat, int i, int j)
    4968{
    5069    return det3(mat[(i + 1) & 3][(j + 1) & 3],
     
    5978}
    6079
    61 template<> float mat4::det() const
     80template<> float determinant(mat2 const &mat)
     81{
     82    return mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
     83}
     84
     85template<> mat2 transpose(mat2 const &mat)
     86{
     87    mat2 ret;
     88    for (int j = 0; j < 2; j++)
     89        for (int i = 0; i < 2; i++)
     90            ret[j][i] = mat[i][j];
     91    return ret;
     92}
     93
     94template<> mat2 inverse(mat2 const &mat)
     95{
     96    mat2 ret;
     97    float d = determinant(mat);
     98    if (d)
     99    {
     100        d = 1.0f / d;
     101        for (int j = 0; j < 2; j++)
     102            for (int i = 0; i < 2; i++)
     103                ret[j][i] = cofact(mat, i, j) * d;
     104    }
     105    return ret;
     106}
     107
     108template<> float determinant(mat3 const &mat)
     109{
     110    return det3(mat[0][0], mat[0][1], mat[0][2],
     111                mat[1][0], mat[1][1], mat[1][2],
     112                mat[2][0], mat[2][1], mat[2][2]);
     113}
     114
     115template<> mat3 transpose(mat3 const &mat)
     116{
     117    mat3 ret;
     118    for (int j = 0; j < 3; j++)
     119        for (int i = 0; i < 3; i++)
     120            ret[j][i] = mat[i][j];
     121    return ret;
     122}
     123
     124template<> mat3 inverse(mat3 const &mat)
     125{
     126    mat3 ret;
     127    float d = determinant(mat);
     128    if (d)
     129    {
     130        d = 1.0f / d;
     131        for (int j = 0; j < 3; j++)
     132            for (int i = 0; i < 3; i++)
     133                ret[j][i] = cofact(mat, i, j) * d;
     134    }
     135    return ret;
     136}
     137
     138template<> float determinant(mat4 const &mat)
    62139{
    63140    float ret = 0;
    64141    for (int n = 0; n < 4; n++)
    65         ret += (*this)[n][0] * cofact3(*this, n, 0);
    66     return ret;
    67 }
    68 
    69 template<> mat4 mat4::invert() const
     142        ret += mat[n][0] * cofact(mat, n, 0);
     143    return ret;
     144}
     145
     146template<> mat4 transpose(mat4 const &mat)
    70147{
    71148    mat4 ret;
    72     float d = det();
     149    for (int j = 0; j < 4; j++)
     150        for (int i = 0; i < 4; i++)
     151            ret[j][i] = mat[i][j];
     152    return ret;
     153}
     154
     155template<> mat4 inverse(mat4 const &mat)
     156{
     157    mat4 ret;
     158    float d = determinant(mat);
    73159    if (d)
    74160    {
     
    76162        for (int j = 0; j < 4; j++)
    77163            for (int i = 0; i < 4; i++)
    78                 ret[j][i] = cofact3(*this, i, j) * d;
     164                ret[j][i] = cofact(mat, i, j) * d;
    79165    }
    80166    return ret;
     
    119205{
    120206    Log::Debug("[ %6.6f %6.6f %6.6f %6.6f ]\n", x, y, z, w);
     207}
     208
     209template<> void mat2::printf() const
     210{
     211    mat2 const &p = *this;
     212
     213    Log::Debug("[ %6.6f %6.6f\n", p[0][0], p[1][0]);
     214    Log::Debug("  %6.6f %6.6f ]\n", p[0][1], p[1][1]);
     215}
     216
     217template<> void mat3::printf() const
     218{
     219    mat3 const &p = *this;
     220
     221    Log::Debug("[ %6.6f %6.6f %6.6f\n", p[0][0], p[1][0], p[2][0]);
     222    Log::Debug("  %6.6f %6.6f %6.6f\n", p[0][1], p[1][1], p[2][1]);
     223    Log::Debug("  %6.6f %6.6f %6.6f ]\n", p[0][2], p[1][2], p[2][2]);
    121224}
    122225
  • trunk/test/Makefile.am

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

    r1139 r1257  
    5353        timer.GetMs();
    5454        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
    55             pf[i] = pm[i].det();
     55            pf[i] = determinant(pm[i]);
    5656        result[1] += timer.GetMs();
    5757
     
    7171        timer.GetMs();
    7272        for (size_t i = 0; i < MATRIX_TABLE_SIZE; i++)
    73             pm[i] = pm[i].invert();
     73            pm[i] = inverse(pm[i]);
    7474        result[4] += timer.GetMs();
    7575    }
  • trunk/test/unit/vector.cpp

    r1139 r1257  
    2121LOLUNIT_FIXTURE(VectorTest)
    2222{
    23     void SetUp()
    24     {
    25         identity = mat4(1.0f);
    26         triangular = mat4(vec4(1.0f, 0.0f, 0.0f, 0.0f),
    27                           vec4(7.0f, 2.0f, 0.0f, 0.0f),
    28                           vec4(1.0f, 5.0f, 3.0f, 0.0f),
    29                           vec4(8.0f, 9.0f, 2.0f, 4.0f));
    30         invertible = mat4(vec4( 1.0f,  1.0f,  2.0f, -1.0f),
    31                           vec4(-2.0f, -1.0f, -2.0f,  2.0f),
    32                           vec4( 4.0f,  2.0f,  5.0f, -4.0f),
    33                           vec4( 5.0f, -3.0f, -7.0f, -6.0f));
    34     }
     23    void SetUp() {}
    3524
    3625    void TearDown() {}
     
    136125        LOLUNIT_ASSERT_EQUAL(a3, a1);
    137126    }
    138 
    139     LOLUNIT_TEST(MatrixDeterminant)
    140     {
    141         float d1 = triangular.det();
    142         LOLUNIT_ASSERT_EQUAL(d1, 24.0f);
    143         float d2 = invertible.det();
    144         LOLUNIT_ASSERT_EQUAL(d2, -1.0f);
    145     }
    146 
    147     LOLUNIT_TEST(MatrixMultiplication)
    148     {
    149         mat4 m0 = identity;
    150         mat4 m1 = identity;
    151         mat4 m2 = m0 * m1;
    152 
    153         LOLUNIT_ASSERT_EQUAL(m2[0][0], 1.0f);
    154         LOLUNIT_ASSERT_EQUAL(m2[1][0], 0.0f);
    155         LOLUNIT_ASSERT_EQUAL(m2[2][0], 0.0f);
    156         LOLUNIT_ASSERT_EQUAL(m2[3][0], 0.0f);
    157 
    158         LOLUNIT_ASSERT_EQUAL(m2[0][1], 0.0f);
    159         LOLUNIT_ASSERT_EQUAL(m2[1][1], 1.0f);
    160         LOLUNIT_ASSERT_EQUAL(m2[2][1], 0.0f);
    161         LOLUNIT_ASSERT_EQUAL(m2[3][1], 0.0f);
    162 
    163         LOLUNIT_ASSERT_EQUAL(m2[0][2], 0.0f);
    164         LOLUNIT_ASSERT_EQUAL(m2[1][2], 0.0f);
    165         LOLUNIT_ASSERT_EQUAL(m2[2][2], 1.0f);
    166         LOLUNIT_ASSERT_EQUAL(m2[3][2], 0.0f);
    167 
    168         LOLUNIT_ASSERT_EQUAL(m2[0][3], 0.0f);
    169         LOLUNIT_ASSERT_EQUAL(m2[1][3], 0.0f);
    170         LOLUNIT_ASSERT_EQUAL(m2[2][3], 0.0f);
    171         LOLUNIT_ASSERT_EQUAL(m2[3][3], 1.0f);
    172     }
    173 
    174     LOLUNIT_TEST(MatrixInverse)
    175     {
    176         mat4 m0 = invertible;
    177         mat4 m1 = m0.invert();
    178 
    179         mat4 m2 = m0 * m1;
    180 
    181         LOLUNIT_ASSERT_EQUAL(m2[0][0], 1.0f);
    182         LOLUNIT_ASSERT_EQUAL(m2[1][0], 0.0f);
    183         LOLUNIT_ASSERT_EQUAL(m2[2][0], 0.0f);
    184         LOLUNIT_ASSERT_EQUAL(m2[3][0], 0.0f);
    185 
    186         LOLUNIT_ASSERT_EQUAL(m2[0][1], 0.0f);
    187         LOLUNIT_ASSERT_EQUAL(m2[1][1], 1.0f);
    188         LOLUNIT_ASSERT_EQUAL(m2[2][1], 0.0f);
    189         LOLUNIT_ASSERT_EQUAL(m2[3][1], 0.0f);
    190 
    191         LOLUNIT_ASSERT_EQUAL(m2[0][2], 0.0f);
    192         LOLUNIT_ASSERT_EQUAL(m2[1][2], 0.0f);
    193         LOLUNIT_ASSERT_EQUAL(m2[2][2], 1.0f);
    194         LOLUNIT_ASSERT_EQUAL(m2[3][2], 0.0f);
    195 
    196         LOLUNIT_ASSERT_EQUAL(m2[0][3], 0.0f);
    197         LOLUNIT_ASSERT_EQUAL(m2[1][3], 0.0f);
    198         LOLUNIT_ASSERT_EQUAL(m2[2][3], 0.0f);
    199         LOLUNIT_ASSERT_EQUAL(m2[3][3], 1.0f);
    200     }
    201 
    202     mat4 triangular, identity, invertible;
    203127};
    204128
  • trunk/win32/testsuite.vcxproj

    r1210 r1257  
    3333    <ClCompile Include="..\test\unit\half.cpp" />
    3434    <ClCompile Include="..\test\unit\image.cpp" />
     35    <ClCompile Include="..\test\unit\matrix.cpp" />
    3536    <ClCompile Include="..\test\unit\quat.cpp" />
    3637    <ClCompile Include="..\test\unit\real.cpp" />
Note: See TracChangeset for help on using the changeset viewer.