[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中矩阵运算规则:
- 上文已经指出,OSG矩阵变换使用如下公式:V' = V * M 其中,V是变换前的节点坐标,M是变换矩阵,V'是变换后的节点坐标,三者均为世界坐标系下的表示。
- 设变换矩阵M由M1、M2两个变换矩阵组合而成,即 M = M1 * M2,则 V'= V * M1 * M2,对应到OSG节点树结构,则是:MT2->MT1->GEODE。
对于变换几何意义的理解,可以以从左向右(矩阵相乘)/从下向上(节点树结构)的顺序,此时每个变换都是以世界坐标系为参考的;也可以以从右向左/从上向下的顺序理解,此时变换都是以模型坐标系(变换过程中的临时坐标系)为参考的。 - 对于平移T、旋转R、缩放S三种变换矩阵的组合,应该按如下顺序:M = S * R * T。
- 变换矩阵与坐标系的关系,已知变换矩阵
,则变换矩阵对应的坐标系的三个坐标轴为
[OSG]矩阵运算的更多相关文章
- osg实例介绍
osg实例介绍 转自:http://blog.csdn.net/yungis/article/list/1 [原]osgmotionblur例子 该例子演示了运动模糊的效果.一下内容是转自网上的:原理 ...
- osg 笔记一 (转)
场景图形采用一种自顶向下的,分层的树状数据结构来组织空间数据集,以提高渲染的效率 场景图形树结构的顶部是一个根节点,从根节点向下延伸,各个组节点中均包含了几何信息和用于控制其外观的渲染状态信息.根节点 ...
- OSG的组成结构
OSG的组成结构 核心结构 OSG的功能类采用“命名空间+类名称”的形式来命名.命名空间的命名方式为:第一个单词小写,后继单词的首字母大写,例如osg.osgUtil.osgViewer等:类的名称则 ...
- OSG计时器与时间戳
static osg::Timer* sendMsgTimer = new osg::Timer; if (sendMsgTimer->time_m()>100)//100ms {// d ...
- OSG消息机制之消息分析
OSG消息接收在头文件有各种事件的相关参数
- OSG消息机制之事件处理概述
OSG的消息机制包括好多个头文件预定义及多个类. 首先,消息接收相关的类当属osgGA::GUIEventHandler和osgGA::GUIEventAdapter这两个类了.前者处理OSG程序与用 ...
- OSG 3D场景渲染编程概述
OSG是Open Scene Graphic的缩写,是基于C++平台的使用OpenGL技术的开源3D场景开发. vs环境安装或者是在Ubuntu中环境的安装网上教程很多,都是大同小异的,认真操作容易成 ...
- OSG透明代码
//关闭灯光 state->setMode(GL_LIGHTING,osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED); //打开混 ...
- [Python学习] python 科学计算库NumPy—矩阵运算
NumPy库的核心是矩阵及其运算. 使用array()函数可以将python的array_like数据转变成数组形式,使用matrix()函数转变成矩阵形式. 基于习惯,在实际使用中较常用array而 ...
随机推荐
- 利用navicat创建存储过程、触发器和使用游标的简单实例
利用navicat创建存储过程.触发器和使用游标的简单实例 标签: navicat存储过程触发器mysql游标 2013-08-03 21:34 15516人阅读 评论(1) 收藏 举报 分类: 数 ...
- JAVA(IO流)文件复制
package com.am; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOEx ...
- webkitTransitionEnd webkitAnimationEnd事件
在CSS 3中,可以通过使用keyframe样式属性与animation样式属性实现animation动画,使用transition样式属性实现transition动画. 在WebKit引擎的浏览器( ...
- sqlserver 索引的一些总结【转】
1.1.1 摘要 如果说要对数据库进行优化,我们主要可以通过以下五种方法,对数据库系统进行优化. 1. 计算机硬件调优 2. 应用程序调优 3. 数据库索引优化 4. SQL语句优化 5. 事务处理调 ...
- visual studio快捷键
进行自动对齐操作[ctrl+k+f] 使用组合键“Ctrl+J”可以在不完全输入关键词时系统自动添加提示 注释用组合键“Ctrl+K+C” 取消注释用组合键“Ctrl+K+U” 设置断点---F9 启 ...
- 论文笔记(1)——《Where's Wally?Precise User Discovery Attacks in Location Proximity Services》
Abstract: 位置相近服务在社交和移动网络的广泛使用是基于可用性和用户隐私的平衡,但引发了三角定位攻击的风险.文章系统化地讨论了此类攻击的防范,包括问题在不同临近模型下的形式化,针对不同模型的有 ...
- 在Ubuntu上安装网易云音乐
对于网易,我只服云音乐,业界良心,用过的人都知道.我最喜欢的就是歌曲的评论功能,还有朋友圈子.里面有很多好段子,还有很多的好故事,基本上,不是分手,就是回忆初恋,还有吐槽的.我认为音乐带给人的不仅是耳 ...
- oracle 关键字
Oracle 关键字(保留字) DBA账户下执行SQL语句:select * from v$reserved_words ; 可得到所有的关键字: 1 ! 1 2 & 1 3 ( 1 4 ...
- 【原】使用Xfermode正确的绘制出遮罩效果
以前写as3的时候,遮罩效果一个mask属性就搞定了,真是方便. 转到android上以后,发现要实现类似的效果,可以使用Xfermode,android一共提供了三种: AvoidXfermode; ...
- java new Date()得到的时间和系统时间不一样
造成这种问题的原因是:操作系统时区跟JVM的时区不一致. [root@paas244 ~]# timedatectl Local time: Thu 2016-12-29 15:35:44 CST U ...