OpenGL面片揀選

OpenGL中,對象本身經過世界變換、觀察變換、投影變換、剪切變換,顯示到屏幕。通過鼠標點擊,獲取的是屏幕座標系的二維座標(x,y)。需要將屏幕座標反變換,計算世界座標系中揀選射線方程。

(1)建立屏幕ndc座標,即將整個屏幕進行映射,x方向範圍-1到1,中心爲0,y方向範圍-1到1,中心爲0。注意:x方向右正左負,y方向上正下負。

ndcx = (2.0f * x) / fWidth - 1.0f;
ndcy = 1.0f - (2.0f * y) / fHeight;

ndcz = 1.0f;

(2)將投影變換的逆變換作用在該座標系上。若mxPorj爲投影矩陣,則:

        mxInvProj=mxProj.inversed();

        v4World=mxInvProj*QVector4D(ndcx,ndcy,ndcz,1.0);

這裏,我們將變換後的向量寫爲v4World,是指該向量含義在世界座標系中意義非常清晰:可理解爲將攝像機置於世界座標系原點,鼠標在遠平面上的揀選點。so,揀選向量即爲:v4World前三維座標單位化,記爲n。

(3)假設模型在繪圖前使用了mxTrans=mxView*mxModel進行了變換,將其放在我們能看到的地方,而實際上,模型真正的位置在其本身節點座標描述的位置。因此,我們需要將揀選射線進行變換,逆着mxTrans變換後,作用於揀選射線上。如,我們讓模型右上角對着攝像機,可以理解爲將攝像機轉動到模型右上角。

視點:vCam,原點,重組爲4維向量,w=1,變換爲v4Eye=mxTrans(-1)*vCam;

揀選方向:n,重組爲4維向量,w=0(不參與平移變換),變換爲v4To=mxTrans(-1)*n

(4)計算射線與面片交點。變換後,用v4Eye中的w值除前三個座標,重組爲三維向量P,該項量爲座標系中眼睛的位置;v4To區前三維座標整理爲m,並單位化,該項量爲眼睛觀察的方向。

(5)揀選面片。使用模型本身節點數據,無需任何變換。若有面,過空間一點Q,法線方向爲k。則首先將直線方程寫爲:

x=p1+m1*r

y=p2+m2*r

z=p3+m3*r

平面方程爲:

k1*(q1-p1)+k2*(q2-p2)+k3*(q3-p3)=0

聯立上述方程得到 r=(Q-P)*k/(m*k),均爲向量運算,*爲點乘。

理解r的幾何意義爲:從P點想m方向行走的距離,因此,r應當爲正值才和麪片有真正的交點(r爲負時,表示射線反向與面片相交,顯然不是我們想要的結果)

(5)判斷交點是否在面片內。

如上圖,H1和H2有什麼不同?我們用向量與向量的叉乘解決問題。

內部點H1,向量H1P1×P1P2、H1P2×P2P3、H1P3×P3P1 方向均指向 外面,而外部點H2,向量H2P1×P1P2、H2P2×P2P3、H2P3×P3P1,總有一個方向指向 裏面。注意叉乘順序,按照規則始終沿着同樣的方向叉乘,叉乘後單位化,判斷三個向量是否均相同,如果有一個和另外兩個不一樣,則是外點。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章