osg坐标系理解

来源:互联网 发布:温度控制pid算法c程序 编辑:程序博客网 时间:2024/05/16 06:34

对于下面的代码(选自《OSG海军教程》第十课第一节 使用自定义矩阵来放置相机,但数据有更改):

// 相机位于坦克后方60个单元,上方7个单元。tankXform->setPosition( osg::Vec3(0,60,8) );T.makeTranslate(0, 0, 15);        //沿Z平移+15A= R * T;                         //设R是绕Y轴旋转+20度的矩阵C= osg::Matrixf::makeRotate(-M_PI/2.0, 1, 0, 0);//C是绕X轴旋转-90度while( !viewer.done() ){ //不用默认的TrackballManipulator,自定义视图矩阵 viewer.getCamera()->setViewMatrix(osg::Matrixf::inverse(A)* C); viewer.frame();}

在底层,最终全是Opengl坐标系(Y向上)。设A的逆为A~,MV= A~* C,而最终显示效果使用的是MV~=( A~* C)~=C~*A=C~*(R*T),即(绕X轴转+90度 绕Y轴转+20度 沿Z平移15),则新的视点位置v’=v*MV~,使用的是行向量,即从后往前对视点坐标系进行变换,即将视点坐标系先沿Z平移15,再绕Y轴转+20度,最后绕X轴转+90度。《这就像是opengl中分别通过glTranslatef、glRotatef对当前局部坐标系进行变换:v’=T*R*v,表明是先对局部坐标系平移(即T),再对局部坐标系旋转(即R)。v’=T*R*v也可以想象成是单纯的点v在世界坐标系中的坐标变化,要注意的是点v没有局部坐标系,只有一个固定的世界坐标系,点v的每次变化都是以这个固定的世界坐标系为参考》。如图:
这里写图片描述

上图中,绿色的XYZ坐标轴是标准的Opengl坐标轴,先沿Z平移15,再绕Y轴转+20度,变成黑色的XrYrZr坐标系,再绕X轴转90度,变成最终的红色,X’Y’Z’坐标系,此时视线(蓝色的线)朝Z’轴负向。在底层始终是Opengl坐标系,但上层我们看到的效果是:在Z向上的坐标系下,把视点移动到Z=15处,看下方Z=8、前方Y=60的坦克。

特别注意:Camera:: setViewMatrix()只改变视点坐标系(包括视点的坐标),其他坐标系不变,仍是Opengl坐标系。而且setViewMatrix(mv)最终显示的是mv的逆矩阵得到的效果,所以一定要注意。可以这样:

setViewMatrix(inverse(A)*绕X轴旋转-90度),这样可以把A看作是MatrixManipulator的Z向上的坐标系(即Z向上,Y向里,视线朝Y轴正向)。且可看作是在Z向上的坐标系下(视线为Y轴正向,即垂直XZ平面朝里),把视点按A变换,且此时,而且外面的一些变换也可以看作是Z向上的坐标系,如tankXform->setPosition( osg::Vec3(0,60,8) );此时相当于是在Z轴正向上移动了8,即往上移动了8,且在Y轴上移动了60,即朝内移动60。
记住:上面的只是看作(想像)Z向上的坐标系,实质仍是Opengl坐标系,可只用Opengl坐标系来看,以免出错。

总结:
(1)对setViewMatrix(A~),可以这样分析:视点v和几何体坐标点p都在opengl坐标下,且对视点进行A(连同视点的局部opengl坐标系)变换,然后看点p在A的视线上的位置。

(2)viewer.getCamera()->setViewMatrix(osg::Matrixf::inverse(osg::Matrix::rotate(osg::PI/2.0, 1, 0, 0 ) R T ));则可以把视点v和几何体坐标点p都放在osg坐标下,且对视点R * T变换。

原创粉丝点击