Changeset 1352


Ignore:
Timestamp:
May 9, 2012, 12:03:04 AM (7 years ago)
Author:
sam
Message:

math: implement all Euler conversions for 3×3 matrices.

Location:
trunk/src
Files:
2 edited

Legend:

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

    r1351 r1352  
    16771677    static Mat3<T> rotate(T angle, T x, T y, T z);
    16781678    static Mat3<T> rotate(T angle, Vec3<T> v);
    1679     static Mat3<T> fromeuler(T x, T y, T z);
    1680     static Mat3<T> fromeuler(Vec3<T> const &v);
     1679
     1680    static Mat3<T> fromeuler_xyz(Vec3<T> const &v);
     1681    static Mat3<T> fromeuler_xzy(Vec3<T> const &v);
     1682    static Mat3<T> fromeuler_yxz(Vec3<T> const &v);
     1683    static Mat3<T> fromeuler_yzx(Vec3<T> const &v);
     1684    static Mat3<T> fromeuler_zxy(Vec3<T> const &v);
     1685    static Mat3<T> fromeuler_zyx(Vec3<T> const &v);
     1686    static Mat3<T> fromeuler_xyz(T phi, T theta, T psi);
     1687    static Mat3<T> fromeuler_xzy(T phi, T theta, T psi);
     1688    static Mat3<T> fromeuler_yxz(T phi, T theta, T psi);
     1689    static Mat3<T> fromeuler_yzx(T phi, T theta, T psi);
     1690    static Mat3<T> fromeuler_zxy(T phi, T theta, T psi);
     1691    static Mat3<T> fromeuler_zyx(T phi, T theta, T psi);
     1692
     1693    static Mat3<T> fromeuler_xyx(Vec3<T> const &v);
     1694    static Mat3<T> fromeuler_xzx(Vec3<T> const &v);
     1695    static Mat3<T> fromeuler_yxy(Vec3<T> const &v);
     1696    static Mat3<T> fromeuler_yzy(Vec3<T> const &v);
     1697    static Mat3<T> fromeuler_zxz(Vec3<T> const &v);
     1698    static Mat3<T> fromeuler_zyz(Vec3<T> const &v);
     1699    static Mat3<T> fromeuler_xyx(T phi, T theta, T psi);
     1700    static Mat3<T> fromeuler_xzx(T phi, T theta, T psi);
     1701    static Mat3<T> fromeuler_yxy(T phi, T theta, T psi);
     1702    static Mat3<T> fromeuler_yzy(T phi, T theta, T psi);
     1703    static Mat3<T> fromeuler_zxz(T phi, T theta, T psi);
     1704    static Mat3<T> fromeuler_zyz(T phi, T theta, T psi);
    16811705
    16821706    static inline Mat3<T> rotate(Mat3<T> mat, T angle, Vec3<T> v)
     
    18171841    }
    18181842
    1819     static inline Mat4<T> fromeuler(T x, T y, T z)
    1820     {
    1821         return Mat4<T>(Mat3<T>::fromeuler(x, y, z), (T)1);
    1822     }
    1823 
    1824     static inline Mat4<T> fromeuler(Vec3<T> const &v)
    1825     {
    1826         return Mat4<T>(Mat3<T>::fromeuler(v), (T)1);
    1827     }
     1843    static Mat4<T> fromeuler_xyz(Vec3<T> const &v);
     1844    static Mat4<T> fromeuler_xzy(Vec3<T> const &v);
     1845    static Mat4<T> fromeuler_yxz(Vec3<T> const &v);
     1846    static Mat4<T> fromeuler_yzx(Vec3<T> const &v);
     1847    static Mat4<T> fromeuler_zxy(Vec3<T> const &v);
     1848    static Mat4<T> fromeuler_zyx(Vec3<T> const &v);
     1849    static Mat4<T> fromeuler_xyz(T phi, T theta, T psi);
     1850    static Mat4<T> fromeuler_xzy(T phi, T theta, T psi);
     1851    static Mat4<T> fromeuler_yxz(T phi, T theta, T psi);
     1852    static Mat4<T> fromeuler_yzx(T phi, T theta, T psi);
     1853    static Mat4<T> fromeuler_zxy(T phi, T theta, T psi);
     1854    static Mat4<T> fromeuler_zyx(T phi, T theta, T psi);
     1855
     1856    static Mat4<T> fromeuler_xyx(Vec3<T> const &v);
     1857    static Mat4<T> fromeuler_xzx(Vec3<T> const &v);
     1858    static Mat4<T> fromeuler_yxy(Vec3<T> const &v);
     1859    static Mat4<T> fromeuler_yzy(Vec3<T> const &v);
     1860    static Mat4<T> fromeuler_zxz(Vec3<T> const &v);
     1861    static Mat4<T> fromeuler_zyz(Vec3<T> const &v);
     1862    static Mat4<T> fromeuler_xyx(T phi, T theta, T psi);
     1863    static Mat4<T> fromeuler_xzx(T phi, T theta, T psi);
     1864    static Mat4<T> fromeuler_yxy(T phi, T theta, T psi);
     1865    static Mat4<T> fromeuler_yzy(T phi, T theta, T psi);
     1866    static Mat4<T> fromeuler_zxz(T phi, T theta, T psi);
     1867    static Mat4<T> fromeuler_zyz(T phi, T theta, T psi);
    18281868
    18291869    /* Helpers for view matrices */
  • trunk/src/math/vector.cpp

    r1351 r1352  
    507507}
    508508
    509 template<> mat3 mat3::fromeuler(vec3 const &v)
     509static inline mat3 mat3_fromeuler_generic(vec3 const &v, int i, int j, int k)
    510510{
    511511    using std::sin;
    512512    using std::cos;
    513 
    514513    mat3 ret;
    515514
    516515    vec3 radians = (M_PI / 180.0f) * v;
    517     float sx = sin(radians.x), cx = cos(radians.x);
    518     float sy = sin(radians.y), cy = cos(radians.y);
    519     float sz = sin(radians.z), cz = cos(radians.z);
    520 
    521     ret[0][0] =   cy * cz;
    522     ret[1][0] = - cx * sz + sx * sy * cz;
    523     ret[2][0] =   sx * sz + cx * sy * cz;
    524 
    525     ret[0][1] =   cy * sz;
    526     ret[1][1] =   cx * cz + sx * sy * sz;
    527     ret[2][1] = - sx * cz + cx * sy * sz;
    528 
    529     ret[0][2] = - sy;
    530     ret[1][2] =   sx * cy;
    531     ret[2][2] =   cx * cy;
    532 
    533     return ret;
    534 }
    535 
    536 template<> mat3 mat3::fromeuler(float x, float y, float z)
    537 {
    538     return mat3::fromeuler(vec3(x, y, z));
     516    float s0 = sin(radians[0]), c0 = cos(radians[0]);
     517    float s1 = sin(radians[1]), c1 = cos(radians[1]);
     518    float s2 = sin(radians[2]), c2 = cos(radians[2]);
     519
     520    if (k == i)
     521    {
     522        k = 3 - i - j;
     523
     524        ret[i][i] =   c1;
     525        ret[j][i] =   s1 * s2;
     526        ret[i][j] =   s0 * s1;
     527        ret[j][j] =   c0 * c2 - s0 * c1 * s2;
     528        ret[k][k] = - s0 * s2 + c0 * c1 * c2;
     529
     530        if ((2 + i - j) % 3)
     531        {
     532            ret[k][i] =   s1 * c2;
     533            ret[k][j] = - c0 * s2 - s0 * c1 * c2;
     534            ret[i][k] = - c0 * s1;
     535            ret[j][k] =   s0 * c2 + c0 * c1 * s2;
     536        }
     537        else
     538        {
     539            ret[k][i] = - s1 * c2;
     540            ret[k][j] =   c0 * s2 + s0 * c1 * c2;
     541            ret[i][k] =   c0 * s1;
     542            ret[j][k] = - s0 * c2 - c0 * c1 * s2;
     543        }
     544    }
     545    else
     546    {
     547        ret[i][i] =   c1 * c2;
     548        ret[k][k] =   c0 * c1;
     549
     550        if ((2 + i - j) % 3)
     551        {
     552            ret[j][i] = - c1 * s2;
     553            ret[k][i] =   s1;
     554
     555            ret[i][j] =   c0 * s2 + s0 * s1 * c2;
     556            ret[j][j] =   c0 * c2 - s0 * s1 * s2;
     557            ret[k][j] = - s0 * c1;
     558
     559            ret[i][k] =   s0 * s2 - c0 * s1 * c2;
     560            ret[j][k] =   s0 * c2 + c0 * s1 * s2;
     561        }
     562        else
     563        {
     564            ret[j][i] =   c1 * s2;
     565            ret[k][i] = - s1;
     566
     567            ret[i][j] = - c0 * s2 + s0 * s1 * c2;
     568            ret[j][j] =   c0 * c2 + s0 * s1 * s2;
     569            ret[k][j] =   s0 * c1;
     570
     571            ret[i][k] =   s0 * s2 + c0 * s1 * c2;
     572            ret[j][k] = - s0 * c2 + c0 * s1 * s2;
     573        }
     574    }
     575
     576    return ret;
    539577}
    540578
     
    551589    quat ret;
    552590
    553     if (i == k)
    554     {
     591    if (k == i)
     592    {
     593        k = 3 - i - j;
     594
    555595        ret[0] = c1 * (c0 * c2 - s0 * s2);
    556596        ret[1 + i] = c1 * (c0 * s2 + s0 * c2);
    557597        ret[1 + j] = s1 * (c0 * c2 + s0 * s2);
    558         if ((2 + i - j) % 3)
    559             ret[4 - i - j] = s1 * (s0 * c2 - c0 * s2);
    560         else
    561             ret[4 - i - j] = s1 * (c0 * s2 - s0 * c2);
     598        ret[1 + k] = ((2 + i - j) % 3) ? s1 * (s0 * c2 - c0 * s2)
     599                                       : s1 * (c0 * s2 - s0 * c2);
    562600    }
    563601    else
     
    574612        ret[1 + i] = v1[1];
    575613        ret[1 + j] = v1[2];
    576         ret[4 - i - j] = v1[3];
    577     }
    578 
    579     return ret;
    580 }
    581 
    582 #define QUAT_FROMEULER_GENERIC(name, i, j, k) \
     614        ret[1 + k] = v1[3];
     615    }
     616
     617    return ret;
     618}
     619
     620#define DEFINE_FROMEULER_GENERIC(name, i, j, k) \
    583621    template<> quat quat::fromeuler_##name(vec3 const &v) \
    584622    { \
     
    589627    { \
    590628        return quat::fromeuler_##name(vec3(phi, theta, psi)); \
    591     }
    592 
    593 QUAT_FROMEULER_GENERIC(xyx, 0, 1, 0)
    594 QUAT_FROMEULER_GENERIC(xzx, 0, 2, 0)
    595 QUAT_FROMEULER_GENERIC(yxy, 1, 0, 1)
    596 QUAT_FROMEULER_GENERIC(yzy, 1, 2, 1)
    597 QUAT_FROMEULER_GENERIC(zxz, 2, 0, 2)
    598 QUAT_FROMEULER_GENERIC(zyz, 2, 1, 2)
    599 
    600 QUAT_FROMEULER_GENERIC(xyz, 0, 1, 2)
    601 QUAT_FROMEULER_GENERIC(xzy, 0, 2, 1)
    602 QUAT_FROMEULER_GENERIC(yxz, 1, 0, 2)
    603 QUAT_FROMEULER_GENERIC(yzx, 1, 2, 0)
    604 QUAT_FROMEULER_GENERIC(zxy, 2, 0, 1)
    605 QUAT_FROMEULER_GENERIC(zyx, 2, 1, 0)
    606 
    607 #undef QUAT_FROMEULER_GENERIC
     629    } \
     630    \
     631    template<> mat3 mat3::fromeuler_##name(vec3 const &v) \
     632    { \
     633        return mat3_fromeuler_generic(v, i, j, k); \
     634    } \
     635    \
     636    template<> mat3 mat3::fromeuler_##name(float phi, float theta, float psi) \
     637    { \
     638        return mat3::fromeuler_##name(vec3(phi, theta, psi)); \
     639    } \
     640    \
     641    template<> mat4 mat4::fromeuler_##name(vec3 const &v) \
     642    { \
     643        return mat4(mat3_fromeuler_generic(v, i, j, k), 1.f); \
     644    } \
     645    \
     646    template<> mat4 mat4::fromeuler_##name(float phi, float theta, float psi) \
     647    { \
     648        return mat4::fromeuler_##name(vec3(phi, theta, psi)); \
     649    }
     650
     651DEFINE_FROMEULER_GENERIC(xyx, 0, 1, 0)
     652DEFINE_FROMEULER_GENERIC(xzx, 0, 2, 0)
     653DEFINE_FROMEULER_GENERIC(yxy, 1, 0, 1)
     654DEFINE_FROMEULER_GENERIC(yzy, 1, 2, 1)
     655DEFINE_FROMEULER_GENERIC(zxz, 2, 0, 2)
     656DEFINE_FROMEULER_GENERIC(zyz, 2, 1, 2)
     657
     658DEFINE_FROMEULER_GENERIC(xyz, 0, 1, 2)
     659DEFINE_FROMEULER_GENERIC(xzy, 0, 2, 1)
     660DEFINE_FROMEULER_GENERIC(yxz, 1, 0, 2)
     661DEFINE_FROMEULER_GENERIC(yzx, 1, 2, 0)
     662DEFINE_FROMEULER_GENERIC(zxy, 2, 0, 1)
     663DEFINE_FROMEULER_GENERIC(zyx, 2, 1, 0)
     664
     665#undef DEFINE_FROMEULER_GENERIC
    608666
    609667template<> mat4 mat4::lookat(vec3 eye, vec3 center, vec3 up)
Note: See TracChangeset for help on using the changeset viewer.