[OSG]矩阵运算

我们都知道,OpenGL规定矩阵使用列主序存储,即glLoadMatrix等函数要求输入的数组是按列主序存储的矩阵。然而,一个很奇怪的事实是,OSG中矩阵存储是使用的标准C二维数组(行主序),并且也是直接将行主序存储的矩阵元素作为参数传递给glLoadMatrix调用的。
  另外一个奇怪的事实是,OpenGL规定的对顶点应用矩阵变换使用左乘(即把顶点坐标看做列向量,变换写做M*P),而OSG规定使用右乘(即把顶点坐标看作行向量,变换写做P*M)。
  然而,这两个奇怪的事实绝不是OSG设计上的失误,而是有意为之!
  在了解OSG的这一设计的目的及原理之前,先回忆一下矩阵运算的一些基础知识。
  我们知道,把一个一维向量看做行向量与看做列向量,从几何意义上来讲是没有差别的,但是,对它们进行相同的空间变换(平移、旋转),所需要的变换矩阵却是不同的(它们互为转置)。通常情况下,我们习惯把顶点坐标看待成行向量,即矩阵变换为V*M,因为在此情况下的平移矩阵是我们所习惯看到的,而对于列向量的平移矩阵则是
  然而,由于OpenGL规定对顶点的矩阵变换使用左乘,即顶点坐标被看做列向量。
  为了使引擎的使用者能够面向形如的平移矩阵,OSG做了这样的设计:首先,由于在矩阵变换应用顺序上与OpenGL使用了相反的规定(OSG的右乘对OpenGL的左乘),导致OSG计算得到的矩阵正好是OpenGL需要的矩阵的转置;然后,和在矩阵元素传递上再次使用了与OpenGL相反的规定(OSG的行主序对OpenGL的列主序),由于对同一个一维数组按行主序解析与按列主序解析得到的矩阵正好互为转置,所以OSG传递给OpenGL的矩阵被再一次转置;两次转置相抵消,使得最终OpenGL收到的矩阵正是引擎调用者所理解的矩阵。

  以上对OSG设计动机的解释纯属个人理解,重点在于对其计算逻辑正确性的推理。

  接下来说一下OSG中矩阵运算规则:

    1. 上文已经指出,OSG矩阵变换使用如下公式:V' = V * M  其中,V是变换前的节点坐标,M是变换矩阵,V'是变换后的节点坐标,三者均为世界坐标系下的表示。
    2. 设变换矩阵M由M1、M2两个变换矩阵组合而成,即 M = M1 * M2,则 V'= V * M1 * M2,对应到OSG节点树结构,则是:MT2->MT1->GEODE。
      对于变换几何意义的理解,可以以从左向右(矩阵相乘)/从下向上(节点树结构)的顺序,此时每个变换都是以世界坐标系为参考的;也可以以从右向左/从上向下的顺序理解,此时变换都是以模型坐标系(变换过程中的临时坐标系)为参考的。
    3. 对于平移T、旋转R、缩放S三种变换矩阵的组合,应该按如下顺序:M = S * R * T
    4. 变换矩阵与坐标系的关系,已知变换矩阵,则变换矩阵对应的坐标系的三个坐标轴为
posted @ 2016-12-26 17:10  南水之源  阅读(663)  评论(0编辑  收藏  举报