osg座标系理解

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

// 相机位於坦克后方60个单元,上方7个单元。
tankXform->setPosition( osg::Vec3(0,60,8) );
T.makeTranslate(0, 0, 15);        //沿Z平移+15
A= 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变换。

发布了82 篇原创文章 · 获赞 58 · 访问量 18万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章