Search code examples
c++opengltransformationglm-math

rotation calculation in GLM


the source code for GLM rotation is done as so:

template<typename T, qualifier Q>
    GLM_FUNC_QUALIFIER mat<4, 4, T, Q> rotate(mat<4, 4, T, Q> const& m, T angle, vec<3, T, Q> const& v)
    {
        T const a = angle;
        T const c = cos(a);
        T const s = sin(a);

        vec<3, T, Q> axis(normalize(v));
        vec<3, T, Q> temp((T(1) - c) * axis);

        mat<4, 4, T, Q> Rotate;
        Rotate[0][0] = c + temp[0] * axis[0];
        Rotate[0][1] = temp[0] * axis[1] + s * axis[2];
        Rotate[0][2] = temp[0] * axis[2] - s * axis[1];

        Rotate[1][0] = temp[1] * axis[0] - s * axis[2];
        Rotate[1][1] = c + temp[1] * axis[1];
        Rotate[1][2] = temp[1] * axis[2] + s * axis[0];

        Rotate[2][0] = temp[2] * axis[0] + s * axis[1];
        Rotate[2][1] = temp[2] * axis[1] - s * axis[0];
        Rotate[2][2] = c + temp[2] * axis[2];

        mat<4, 4, T, Q> Result;
        Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
        Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
        Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
        Result[3] = m[3];
        return Result;
    }  

does anyone know any explanation of how the rotation is being calculated here? Which technique is being used particularly?

Since rotation around pivot point is not used, there's no translation needed, but the general form to calculate rotation around an arbitrary axis would be something like this:

enter image description here

which I don't know is the case above. Particularly I don't get from the point where temp((T(1)-c)*axis) is defined, which is something I never did in linear algebra.


Solution

  • What glm::rotate actually does is to set up a rotation matrix and multiply the input matrix by the roation. It computes m*r in the meaning of GLSL Vector and Matrix Operations.
    It operates in the same way as it is discussed for glm::translate in one of your previous questions: How does GLM handle translation.

    The input parameters angle (the rotation angle) and v (the rotation axis), define a 3x3 rotation matrix as described in the wikipedia article Rotation matrix from axis and angle:
    (the mathematical explanation to this formula would be a question for Mathematics)

    c = cos(angle); s = sin(angle)
    x = v.x; y = v.y; z = v.z
    
              | x*x*(1-c)+c      x*y*(1-c)-z*s    x*z*(1-c)+y*s |
    Rotate  = | y*x*(1-c)+z*s    y*y*(1-c)+c      y*z*(1-c)-x*s |
              | z*x*(1-c)-y*s    z*y*(1-c)+x*s    z*z*(1-c)+c   |
    

    This matrix is implicitly extended to a 4x4 matrix. FInally the input matrix (m) is multiplied by Roatate and assigned to Result:

    Result = m * Roatate