2009-08-01 11 views
2

私はいつかスペースシムに取り組んでいました。 最初は自分の3Dエンジンにソフトウェアラスタライザを使用していました。スペースシミュレーター/ゲーム用の宇宙船モデルを回転する

しかし、テクスチャを実装する時間が間に合うと、私は諦めました。 今私はもういつか始めて、今は3DモデルをレンダリングするためにOpenGL(SDL)を使用しています。

しかし、今私は別のレンガの壁に当たった。

正しい回転方法を理解できません。その後、 私はモデル(宇宙船)を回転させる場合、私は

glRotatef(angleX, 1.0f, 0.0f, 0.0f); 
glRotatef(angleY, 0.0f, 1.0f, 0.0f); 
glRotatef(angleZ, 0.0f, 0.0f, 1.0f); 

または類似を使用してflighsim

と同様のコントロールをしたいスペース・シミュレーターなので、
が正常に動作しない最初の90度左にとそれを "上に"回転させます。 代わりにロールします。

ここに私の問題を説明するイメージがあります。

Image Link

私はこれを試してみて、対抗するために、いくつかのトリックを試みたが、どういうわけか私は何かが足りない感じ。 シミュレータのスタイルの回転の例がほとんど見つからないことを助けるものではありません。

私は、例、リンク、3Dモデルを回転させる理論(宇宙船、飛行機など)を探しています。

3つのベクトル(左、上、前方)を向きに使うべきでしょうか?また、スラスタからの加速度や回転(向き?)やモデルから変化するものを計算する必要がありますロケットエンジンのような方向の視点。私は数学とソリューションはちょうどあなたがここで使用したいとしているどのような頭痛

+0

私はついにそれを裂く! 私は、モデルの向きを表す行列を使用します。 上のキーを押すと、回転行列を作成する関数が呼び出されます。これは、xの周りを希望の量だけ回転させ、それをモデルの向き行列に掛けます。 – kvasan

答えて

2

を与える視覚化しようとしていると非常によくないよ

は四元です。彼らはあなたが経験している奇妙な行動を排除します。同様の機能を持つステロイドのマトリックスとしてそれらを考える。特定の回転軸ベクトル上に回転行列を作成することができるOpenGLの機能を使用することで、上記のコードではより良い行列を使用することができますが、quaternionsはを将来の変更のために保存します。たとえば、アイデンティティ四元数で始まり、特定の軸ベクトル上で回転させます。四元数はオブジェクトの世界行列に変換されますが、四元数はオブジェクト内に保存されます。次回回転を行う必要がある場合は、X、Y、Z軸の回転角度などを調べる代わりに、四元数をさらに変更する必要があります。

私の経験はDirectXの範囲内ですここでの経験)、床や壁などに遭遇したときに、部屋の周りを跳ね返っていたビーチボールを回転させようとしていたときに、私はあなたの問題に遭遇しました。

Googleは「OpenGLのクォータニオン」のオプションの束を持っているが、これは、特に、優れた源であると表示されます。

http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation

あなたは今では想像のとおり、四元数は最適ですあなたの環境内のカメラを扱う。ここでは素晴らしいチュートリアルです:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class

4

私は、私は完全に状況を理解していないが、あなたはgimbal lockを記述される可能性がありますように聞こえます。あなたの回転を表すためにquaternionsを使用して見たいかもしれません。

+0

私は以前に四元数を試していましたが、もう一度試しました。 回転をより正確にするようですが、回転させると少し歪んでしまいます。 – kvasan

4

この権利を取得することは難しいことです。あなたが直面していると思う問題は、「船」がすでにどのように向き合っているかにかかわらず、同じ回転行列を使用していることです。しかし、あなたは船が前方に向いているときにどのように回転するかに基づいて船を回転させたくないとき、あなたはそれが直面している方向に基づいて回転したいと思う。これを行うには、あなたがあなたの船を変えるのと同じ方法で、制御されたターンマトリックスを変える必要があります。

たとえば、3つの行列があり、それぞれがターンの種類を表しているとします。

float theta = 10.0*(pi/180.0) 

matrix<float> roll = [[ cos(theta), sin(theta), 0] 
         [ -sin(theta), cos(theta), 0] 
         [ 0, 0, 1] 

matrix<float> pitch = [[ cos(theta), 0, sin(theta)] 
         [ 0, 1, 0] 
         [ -sin(theta), 0, cos(theta)] 

matrix<float> yaw = [[1, 0, 0] 
        [0, cos(theta), sin(theta)] 
        [0, -sin(theta), cos(theta)]] 

matrix<float> orientation = [[1, 0, 0] 
          [0, 1, 0] 
          [0, 0, 1]] 

それぞれは、3つの飛行姿勢軸のそれぞれを横切る10度の回転を表す。また、私たちはあなたの船のオリエンテーションのための行列を持っています。船の頂点をその向きの行列で変換して表示します。

ターン終了後に方向を取得するには、最初に姿勢制御行列をプレイヤーの座標に変換してから方向に適用して、新しい方向を得る:

function do_roll(float amount): 
    matrix<float> local_roll = amount * (roll * orientation) 
    orientation = orientation * local_roll 

function do_pitch(float amount): 
    matrix<float> local_pitch = amount * (pitch * orientation) 
    orientation = orientation * pitch_roll 

function do_yaw(float amount): 
    matrix<float> local_yaw = amount * (yaw * orientation) 
    orientation = orientation * local_yaw 

このように、ある方法や別の方法で回転させるたびに、それらの機能のうちの1つを呼び出すことができます。

1

クォータニオンが役立つかもしれませんが、より簡単な解決策は、厳密な回転順序を観察することです。あなたはyの周りを回っていて、xの周りを回っているように聞こえます。常にxを最初に、次にyを、次にzを回転させる必要があります。あなたがそのようにすれば、ローテーションはあなたが彼らが働くことを期待する方法に少し近づく傾向があります。

編集:少し明確にするために、ゲーム内で累積的に時間を遡って回転させるべきではありません。各フレームでは、モデルを同一位置で開始し、x、y、zをそのフレームの新しい位置に回転する必要があります。

+0

damnit私は一度だけこれに投票することができます –

1

一般的な回転は困難です。物理学者は、それらを記述するためにいわゆるEuler anglesのいくつかのセットを使用する傾向があります。この方法では、一般的な回転は、固定された連続した約3軸の3つの角度によって記述される。しかし、3つの軸は元のフレームのX、Y、Z軸ではありません。それらはしばしば元のフレームのZ軸、Y軸、Z軸(実際は完全に一般的です)、または元のフレームから2軸、中間フレームの軸が続きます。多くの選択肢があり、同じコンベンションに従っていることを確認することは本当に面倒なことがあります。

2

回転を制御する方法をより深く理解できるように、3D数学を学習する必要があります。理論を知らなければ、正しくコピーして貼り付けることが難しいかもしれません。3D数学の入門書(Amazon)や、http://gamemath.comなどの関連するサイトは、プロジェクト(および将来のすべてのもの)を大きく助けます。

私は今、数学が好きではないかもしれないと理解していますが、関連する算術を学ぶことがあなたの問題に対する最良の解決策になります。

+0

私は既に3D数学入門書を持っており、私が始めたときに多くの助けになりました。 いつか私はそれを読んで、それを再び読む必要があるように見える。 – kvasan

関連する問題