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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章