2012-03-14 73 views
3

所以我有一個對象,我試圖根據Yaw,Pitch and Roll方案旋轉,相對於對象本身的軸而不是全局空間的軸。根據this,我需要按順序執行旋轉。我的解釋是:OpenGL旋轉 - 局部與全局軸

glRotatef(m_Rotation.y, 0.0, 1.0, 0.0); 
glRotatef(m_Rotation.z, 0.0, 0.0, 1.0); 
glRotatef(m_Rotation.x, 1.0, 0.0, 0.0); 

但是,圍繞Y軸和Z軸的旋轉不起作用。圍繞Y軸的旋轉總是相對於全局空間,圍繞X軸旋轉的z軸旋轉角度爲0,否則會混亂。

可以肯定的是,我也嘗試了相反的順序,但那也行不通。我想我也嘗試了其他所有的命令,所以問題一定是別的。它可能是?

這是我獲得的旋轉:

///ROTATIONS 
    sf::Vector3<float> Rotation; 
    Rotation.x = 0; 
    Rotation.y = 0; 
    Rotation.z = 0; 
    //ROLL 
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Up) == true) 
    { 
     Rotation.x -= TurnSpeed; 
    } 
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Down) == true) 
    { 
     Rotation.x += TurnSpeed; 
    } 
    //YAW 
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Left) == true) 
    { 
     Rotation.y -= TurnSpeed; 
    } 
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Right) == true) 
    { 
     Rotation.y += TurnSpeed; 
    } 
    //PITCH 
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Q) == true) 
    { 
     Rotation.z -= TurnSpeed; 
    } 
    if (m_pApp->GetInput().IsKeyDown(sf::Key::E) == true) 
    { 
     Rotation.z += TurnSpeed; 
    } 

然後將它們添加到m_Rotation這樣:

//Rotation 
m_Rotation.x += Angle.x; 
m_Rotation.y += Angle.y; 
m_Rotation.z += Angle.z; 

(它們被傳遞到內部的東西的功能被四處移動,但沒有別的事情與他們做)。

的思考?還有什麼我應該調用以確保所有正在旋轉的軸都是局部軸?

+2

無論如何可能更好地使用旋轉矩陣。 – Lalaland 2012-03-14 13:39:51

+0

您是否嘗試過P-> R-> Y作爲順序?你有沒有考慮到,一旦你旋轉,新的旋轉應用的軸是*新的*,我的意思是原始軸旋轉了一定角度? – Saphrosit 2012-03-14 14:02:54

+0

是的,我已經嘗試了P-R-Y,但是這也沒有幫助 - 滾動貼到全局座標軸。我沒有使用變換矩陣的經驗 - 他們會完全避免這種麻煩嗎?我是不是還需要三次glRotatef()調用並將它們以某種順序或另一種順序放置? – GarrickW 2012-03-14 15:25:13

回答

1

加瑞克,

當調用glRotate(角度,X,Y,Z),它是圍繞要傳遞到glRotate載體旋轉。矢量從(0,0,0)到(x,y,z)。

如果要圍繞對象的本地軸旋轉對象,則需要glTranslate對象到原點,執行旋轉,然後將其轉換回其來源。

下面是一個例子:

//Assume your object has the following properties 
sf::Vector3<float> m_rotation; 
sf::Vector3<float> m_center; 

//Here would be the rotate method 
public void DrawRotated(sf::Vector<float> degrees) { 
    //Store our current matrix 
    glPushMatrix(); 

    //Everything will happen in the reverse order... 
    //Step 3: Translate back to where this object came from 
    glTranslatef(m_center.x, m_center.y, m_center.z); 

    //Step 2: Rotate this object about it's local axis 
    glRotatef(degrees.y, 0, 1.0, 0); 
    glRotatef(degrees.z, 0, 0, 1.0); 
    glRotatef(degrees.x, 1.0, 0, 0); 

    //Step 1: Translate this object to the origin 
    glTranslatef(-1*m_center.x, -1*m_center.y, -1*m_center.z); 

    //Render this object rotated by degrees 
    Render(); 

    //Pop this matrix so that everything we render after this 
    // is not also rotated 
    glPopMatrix(); 
} 
0

你的問題是,你存儲你的X,Y,Z旋轉和累加給他們。然後,當您渲染時,您正在對單位矩陣執行總累積旋轉(您正在全局執行所有旋轉)。從您的渲染循環中註釋掉您的身份呼叫。並確保您在初始化函數中設置標識。 然後

rotate as normal 
m_Rotation.x = m_Rotation.y = m_Rotation.z = 0.0f; 
//clear your rotations you don't want them to accumulate between frames 
glpush 
translate as normal 
(all other stuff) 
glpop 
//you should be back to just the rotations 
//glclear and start next frame as usual 

正如我敢肯定,你發現你接受了原來的答覆後。旋轉或平移的順序不會影響旋轉發生在哪個軸上,而是影響旋轉的點。例如,旋轉一個行星15度將使其在全局軸上旋轉15度。將它從原點轉換回原點,然後旋轉它將使它在原平移距離處(如果與旋轉軸相同,則在x軸上平移,然後在y軸上旋轉不會產生任何混淆效果)。