how does GLM handle translation

后端 未结 2 1831
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-15 09:41

The OpenGL maths library(GLM) uses the following algorithm to compute the translation matrix:

//taken from source code
template

        
2条回答
  •  忘掉有多难
    2021-01-15 10:04

    OpenGL Mathematics (GLM) is based on the OpenGL Shading Language (GLSL). What glm::translate actually does is to set up a translation matrix and multiply the input matrix by the translation. It computes m*t in the meaning of GLSL Vector and Matrix Operations:

    mat<4, 4, T, Q> Result(m);
    Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
    

    (In the following Result is substituted by R)

    Note, m[0] * v[0] multiplies each component of the column m[0] by the scalar v[0]. The result is the vector (m[0][0]*v[0], m[0][1]*v[0], m[0][2]*v[0], m[0][3]*v[0]).

    So R[3] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2] + m[3] is the same as

    R[3][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0]
    R[3][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1]
    R[3][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2]
    R[3][3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3]
    

    glm::translate actually calculates:

    vh = (v[0], v[1], v[2], 1)
    R = m
    R[3][0] = dot( (m[0][0], m[1][0], m[2][0], m[3][0]), vh )
    R[3][1] = dot( (m[0][1], m[1][1], m[2][1], m[3][1]), vh )
    R[3][2] = dot( (m[0][2], m[1][2], m[2][2], m[3][2]), vh )
    R[3][3] = dot( (m[0][3], m[1][3], m[2][3], m[3][3]), vh )
    

    The code above computes the Dot product of the rows from m, by vh. vh is the 4th column of the translation t. Note the translation matrix t is defined as:

         c0  c1  c2  c3 
    ---------------------  
    r0:   1   0   0  v[0]  
    r1:   0   1   0  v[1]
    r2:   0   0   0  v[2]
    r3:   0   0   0  1  
    

    A concatenation of 4x4 matrices (R = m*t) is the Dot product of the rows of m and the columns of t and can be expressed as: (See OpenGL Shading Language 4.60 Specification - 5.10. Vector and Matrix Operations)

    for i from 0 to 3
        for j fro 0 to 3
            R[i][j] = dot( (m[0][j], m[1][j], m[2][j], m[3][j]), t[i] )
    

    Where dot(a, b) == a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3],
    (m[0][j], m[1][j], m[2][j], m[3][j]) is the j-th row of m and
    t[i] is i-th column of t.

    For glm::translate it is sufficient to copy R[0], R[1] and R[2] from m[0], m[1] and m[2].

    e.g. for (i=0, j=0):

    R[0][0] = dot( (m[0][0], m[1][0], m[2][0], m[3][0]), t[0] )
    R[0][0] = dot( (m[0][0], m[1][0], m[2][0], m[3][0]), (1, 0, 0, 0) )
    R[0][0] = m[0][0] * 1 + m[1][0] * 0 + m[2][0] * 0 + m[3][0]) * 0
    R[0][0] = m[0][0]
    

    GLM matrices (as OpenGL matrices) are stored in column major order. If you investigate matrices in the debugger that may lead to confusions.

    If you have the matrix

         c0  c1  c2  c3 
    -------------------  
    r0:  Xx  Yx  Zx  Tx  
    r1:  Xy  Yy  Zy  Ty 
    r2:  Xz  Yz  Zz  Tz  
    r3:   0   0   0   1  
    

    then the memory image of a 4*4 OpenGL matrix looks like this:

    Xx, Xy, Xz, 0, Yx, Yy, Yz, 0, Zx, Zy, Zz, 0, Tx, Ty, Tz, 1
    

    If you investigate it in a debugger, it may look like:

    [ [ Xx, Xy, Xz, 0 ],
      [ Yx, Yy, Yz, 0 ],
      [ Zx, Zy, Zz, 0 ],
      [ Tx, Ty, Tz, 1 ] ]
    

提交回复
热议问题