OpenGL 数学 (GLM)是基于OpenGL 着色语言 (GLSL). What glm::translate实际上就是建立一个平移矩阵并将输入矩阵乘以平移。它计算m*t
的意思是GLSL 向量和矩阵运算:
mat<4, 4, T, Q> Result(m);
Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
(在下面的Result
被替换为R
)
Note, m[0] * v[0]
将该列的每个分量相乘m[0]
由标量v[0]
。结果是向量(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]
是相同的
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
实际上计算:
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 )
上面的代码计算点积的行数来自m
, by vh
. vh
是翻译的第四列t
。注意平移矩阵t
定义为:
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
4x4 矩阵的串联 (R = m*t
) 是个点积的行数m
和列t
并可表示为:
(看OpenGL 着色语言 4.60 规范 - 5.10。向量和矩阵运算)
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第-行m
and
t[i]
is i第 列t
.
For glm::translate
复制就足够了R[0]
, R[1]
and R[2]
from m[0]
, m[1]
and m[2]
.
例如为了 (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矩阵(如 OpenGL 矩阵)按列主序存储。如果您在调试器中研究矩阵,可能会导致混乱。
如果你有矩阵
c0 c1 c2 c3
-------------------
r0: Xx Yx Zx Tx
r1: Xy Yy Zy Ty
r2: Xz Yz Zz Tz
r3: 0 0 0 1
那么 4*4 OpenGL 矩阵的内存图像如下所示:
Xx, Xy, Xz, 0, Yx, Yy, Yz, 0, Zx, Zy, Zz, 0, Tx, Ty, Tz, 1
如果您在调试器中调查它,它可能看起来像:
[ [ Xx, Xy, Xz, 0 ],
[ Yx, Yy, Yz, 0 ],
[ Zx, Zy, Zz, 0 ],
[ Tx, Ty, Tz, 1 ] ]