2012-03-14 12 views
3

私は、グローバル空間の軸ではなく、オブジェクト自身のローカル軸を基準にして、Yaw、Pitch and Rollスキームに従って回転しようとしているオブジェクトを持っています。 thisによれば、私はこの順番で回転を行う必要があります。これを意味すると解釈しました。OpenGL Rotation - Local vs Global Axes

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ですが、それ以外の場合は上がります。

逆の順序も試みましたが、どちらも問題ありません。私は他のすべての命令も試したと思うので、問題は他のものでなければならない。そうかもしれない? 、

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

(彼らは周りに移動される事に内部関数に渡されます。

///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に追加されます。

は、これは私が回転を入手する方法ですそれ以外は何もしません)。

思考?すべての軸が回転しているかどうかを確認するために何か必要なものがありますか?

+2

おそらく回転行列を使用するほうがよいでしょう。 – Lalaland

+0

P-> R-> Yを試しましたか?あなたが回転したら、新しい回転が適用される軸は*新しい*軸ですが、元の軸はある角度だけ回転していることを考慮しましたか? – Saphrosit

+0

はい、私はP-R-Yを試しましたが、それはどちらも役に立ちません - ロールはグローバル軸に固執します。私は変換行列の使用経験がありません - これらの混乱を避けるのでしょうか?私はまだ3つのglRotatef()コールを持っていなければならないでしょうか? – GarrickW

答えて

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軸を回転させると混乱することはありません)。