Changeset 1349


Ignore:
Timestamp:
May 8, 2012, 1:56:39 PM (7 years ago)
Author:
sam
Message:

math: support all Tait-Bryan angle combinations in quaternions.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/orbital/orbital.cpp

    r1344 r1349  
    144144    }
    145145
    146     quat q = quat::rotate(-90.f, 0.f, 0.f, 1.f);
    147     mat4 anim = mat4(~q * quat::fromeuler(m_angle) * q);
     146    /* Yaw around Y, Pitch around X, Roll around Z */
     147    mat4 anim = mat4(quat::fromeuler_zxy(m_angle.zyx));
    148148#endif
    149149
  • trunk/src/lol/math/vector.h

    r1341 r1349  
    926926    static Quat<T> rotate(T angle, T x, T y, T z);
    927927    static Quat<T> rotate(T angle, Vec3<T> const &v);
    928     static Quat<T> fromeuler(T x, T y, T z);
    929     static Quat<T> fromeuler(Vec3<T> const &v);
     928
     929    /* Convert from Tait-Bryan angles (incorrectly called Euler angles,
     930     * but since everyone does it…). The axes in fromeuler_xyz are
     931     * x, then y', then z", ie. the axes are attached to the model.
     932     * If you want to apply yaw around x, pitch around y, and roll
     933     * around z, use fromeuler_xyz.
     934     * If you want to rotate around static axes, reverse the order in
     935     * the function name (_zyx instead of _xyz) AND reverse the order
     936     * of the arguments. */
     937    static Quat<T> fromeuler_xyz(Vec3<T> const &v);
     938    static Quat<T> fromeuler_xzy(Vec3<T> const &v);
     939    static Quat<T> fromeuler_yxz(Vec3<T> const &v);
     940    static Quat<T> fromeuler_yzx(Vec3<T> const &v);
     941    static Quat<T> fromeuler_zxy(Vec3<T> const &v);
     942    static Quat<T> fromeuler_zyx(Vec3<T> const &v);
     943    static Quat<T> fromeuler_xyz(T phi, T theta, T psi);
     944    static Quat<T> fromeuler_xzy(T phi, T theta, T psi);
     945    static Quat<T> fromeuler_yxz(T phi, T theta, T psi);
     946    static Quat<T> fromeuler_yzx(T phi, T theta, T psi);
     947    static Quat<T> fromeuler_zxy(T phi, T theta, T psi);
     948    static Quat<T> fromeuler_zyx(T phi, T theta, T psi);
    930949
    931950    inline Quat<T> operator *(Quat<T> const &val) const
  • trunk/src/math/vector.cpp

    r1322 r1349  
    539539}
    540540
    541 template<> quat quat::fromeuler(vec3 const &v)
     541static inline quat fromeuler_generic(vec3 const &v, int s, int i, int j, int k)
    542542{
    543543    using std::sin;
     
    545545
    546546    vec3 half_angles = (M_PI / 360.0f) * v;
    547     float sx = sin(half_angles.x), cx = cos(half_angles.x);
    548     float sy = sin(half_angles.y), cy = cos(half_angles.y);
    549     float sz = sin(half_angles.z), cz = cos(half_angles.z);
    550 
    551     return quat(cx * cy * cz + sx * sy * sz,
    552                 sx * cy * cz - cx * sy * sz,
    553                 cx * sy * cz + sx * cy * sz,
    554                 cx * cy * sz - sx * sy * cz);
    555 }
    556 
    557 template<> quat quat::fromeuler(float x, float y, float z)
    558 {
    559     return quat::fromeuler(vec3(x, y, z));
     547    float s0 = sin(half_angles[0]), c0 = cos(half_angles[0]);
     548    float s1 = sin(half_angles[1]), c1 = cos(half_angles[1]);
     549    float s2 = sin(half_angles[2]), c2 = cos(half_angles[2]);
     550
     551    vec4 v1(c0 * c1 * c2,  c0 * c1 * s2, c0 * s1 * c2,  s0 * c1 * c2);
     552    vec4 v2(s0 * s1 * s2, -s0 * s1 * c2, s0 * c1 * s2, -c0 * s1 * s2);
     553
     554    if (s > 0)
     555        v1 += v2;
     556    else
     557        v1 -= v2;
     558
     559    return quat(v1[0], v1[i], v1[j], v1[k]);
     560}
     561
     562template<> quat quat::fromeuler_xyz(vec3 const &v)
     563{
     564    return fromeuler_generic(v, -1, 3, 2, 1);
     565}
     566
     567template<> quat quat::fromeuler_xzy(vec3 const &v)
     568{
     569    return fromeuler_generic(v, 1, 3, 1, 2);
     570}
     571
     572template<> quat quat::fromeuler_yxz(vec3 const &v)
     573{
     574    return fromeuler_generic(v, 1, 2, 3, 1);
     575}
     576
     577template<> quat quat::fromeuler_yzx(vec3 const &v)
     578{
     579    return fromeuler_generic(v, -1, 1, 3, 2);
     580}
     581
     582template<> quat quat::fromeuler_zxy(vec3 const &v)
     583{
     584    return fromeuler_generic(v, -1, 2, 1, 3);
     585}
     586
     587template<> quat quat::fromeuler_zyx(vec3 const &v)
     588{
     589    return fromeuler_generic(v, 1, 1, 2, 3);
     590}
     591
     592template<> quat quat::fromeuler_xyz(float phi, float theta, float psi)
     593{
     594    return quat::fromeuler_zyx(vec3(phi, theta, psi));
     595}
     596
     597template<> quat quat::fromeuler_xzy(float phi, float theta, float psi)
     598{
     599    return quat::fromeuler_yxz(vec3(phi, theta, psi));
     600}
     601
     602template<> quat quat::fromeuler_yxz(float phi, float theta, float psi)
     603{
     604    return quat::fromeuler_yxz(vec3(phi, theta, psi));
     605}
     606
     607template<> quat quat::fromeuler_yzx(float phi, float theta, float psi)
     608{
     609    return quat::fromeuler_yxz(vec3(phi, theta, psi));
     610}
     611
     612template<> quat quat::fromeuler_zxy(float phi, float theta, float psi)
     613{
     614    return quat::fromeuler_yxz(vec3(phi, theta, psi));
     615}
     616
     617template<> quat quat::fromeuler_zyx(float phi, float theta, float psi)
     618{
     619    return quat::fromeuler_yxz(vec3(phi, theta, psi));
    560620}
    561621
Note: See TracChangeset for help on using the changeset viewer.