Changeset 1315


Ignore:
Timestamp:
Apr 30, 2012, 1:36:23 PM (9 years ago)
Author:
sam
Message:

math: add methods to convert from a quaternion to Euler angles and from
Euler angles to a rotation matrix. Also fix quat::rotate() which was not
building the correct quaternion.

Location:
trunk/src
Files:
2 edited

Legend:

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

    r1314 r1315  
    489489    explicit inline Vec3(XVec3<U, N> const &v)
    490490      : BVec3<T>(v[0], v[1], v[2]) {}
     491
     492    static Vec3<T> toeuler(Quat<T> const &q);
    491493
    492494    DECLARE_MEMBER_OPS(Vec3)
     
    15661568    static Mat3<T> rotate(T angle, Vec3<T> v);
    15671569    static Mat3<T> rotate(Quat<T> q);
     1570    static Mat3<T> fromeuler(T x, T y, T z);
     1571    static Mat3<T> fromeuler(Vec3<T> const &v);
    15681572
    15691573    static inline Mat3<T> rotate(Mat3<T> mat, T angle, Vec3<T> v)
     
    17051709    {
    17061710        return rotate(angle, v) * mat;
     1711    }
     1712
     1713    static inline Mat4<T> fromeuler(T x, T y, T z)
     1714    {
     1715        return Mat4<T>(Mat3<T>::fromeuler(x, y, z), (T)1);
     1716    }
     1717
     1718    static inline Mat4<T> fromeuler(Vec3<T> const &v)
     1719    {
     1720        return Mat4<T>(Mat3<T>::fromeuler(v), (T)1);
    17071721    }
    17081722
  • trunk/src/math/vector.cpp

    r1314 r1315  
    463463    vec3 tmp = normalize(v) * std::sin(angle);
    464464
    465     return quat(tmp.x, tmp.y, tmp.z, std::cos(angle));
     465    return quat(std::cos(angle), tmp.x, tmp.y, tmp.z);
    466466}
    467467
     
    469469{
    470470    return quat::rotate(angle, vec3(x, y, z));
     471}
     472
     473template<> vec3 vec3::toeuler(quat const &q)
     474{
     475    using std::atan2;
     476    using std::asin;
     477
     478    float n = norm(q);
     479
     480    if (!n)
     481        return vec3(0.f);
     482
     483    vec3 ret(atan2(2.f * (q.w * q.x + q.y * q.z),
     484                   1.f - 2.f * (q.x * q.x + q.y * q.y)),
     485             asin(2.f * (q.w * q.y - q.z * q.x)),
     486             atan2(2.f * (q.w * q.z + q.y * q.x),
     487                   1.f - 2.f * (q.z * q.z + q.y * q.y)));
     488
     489    return (180.0f / M_PI / n) * ret;
     490}
     491
     492template<> mat3 mat3::fromeuler(vec3 const &v)
     493{
     494    using std::sin;
     495    using std::cos;
     496
     497    mat3 ret;
     498
     499    vec3 radians = (M_PI / 180.0f) * v;
     500    float sx = sin(radians.x), cx = cos(radians.x);
     501    float sy = sin(radians.y), cy = cos(radians.y);
     502    float sz = sin(radians.z), cz = cos(radians.z);
     503
     504    ret[0][0] =   cy * cz;
     505    ret[1][0] =   cx * sz - sx * sy * sz;
     506    ret[2][0] =   sx * sz - cx * sy * cz;
     507
     508    ret[0][1] = - cy * sz;
     509    ret[1][1] =   cx * cz - sx * sy * sz;
     510    ret[2][1] =   sx * cz + cx * sy * sz;
     511
     512    ret[0][2] =   sy;
     513    ret[1][2] = - sx * cy;
     514    ret[2][2] =   cx * cy;
     515
     516    return ret;
     517}
     518
     519template<> mat3 mat3::fromeuler(float x, float y, float z)
     520{
     521    return mat3::fromeuler(vec3(x, y, z));
    471522}
    472523
Note: See TracChangeset for help on using the changeset viewer.