现在的位置: 首页 > 综合 > 正文

OSG坐标系解释????????

2013年09月18日 ⁄ 综合 ⁄ 共 1550字 ⁄ 字号 评论关闭

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

tankXform->setPosition( osg::Vec3(0,60,8) );

// 相机位于坦克后方 60个单元,上方 7个单元。

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中分别通过glTranslatefglRotatef对当前局部坐标系进行变换:v=T*R*v,表明是先对局部坐标系平移(T),再对局部坐标系旋转(R)v=T*R*v也可以想象成是单纯的点v在世界坐标系中的坐标变化,要注意的是点v没有局部坐标系,只有一个固定的世界坐标系,点v的每次变化都是以这个固定的世界坐标系为参考》。如图:

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

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

setViewMatrix(inverse(A)*X轴旋转-90),这样可以把A看作是MatrixManipulatorZ向上的坐标系(即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变换。

 

抱歉!评论已关闭.