2011-08-02 10 views
1

XNAに飛行シミュレータプログラム(Star Fox 64に似ています)を書いていますが、私の回転に問題があります。私の考えは、位置の速度とベクトルのベクトルを持つことです。私が許可しているコントロールは、オイラーの角度が問題を引き起こすようにするので、私はクォータニオンを使いたいと思っています。XNA Quaternion.createFromAxisAngle

私はグラフィックスレンダリングに精通していませんが、Quaternion.createFromAxisAngle(ベクタ、ロール)(ベロシティベクタの周りを回転しているロール)を使用できますが、正しく動作していないと思います。基本的にピッチやヨーを回転しようとすると、何も起こりません。私が転がすとき、それはうまくいくが、私が期待した通りではない。これはcreateFromAxisAngleメソッドの適切な使用ですか?ありがとう。ここで

は私の船の更新位置コードです:

public override void UpdatePositions() 
    { 
     float sinRoll = (float)Math.Sin(roll); 
     float cosRoll = (float)Math.Cos(roll); 
     float sinPitch = (float)Math.Sin(pitch); 
     float cosPitch = (float)Math.Cos(pitch); 
     float sinYaw = (float)Math.Sin(yaw); 
     float cosYaw = (float)Math.Cos(yaw); 

     m_Velocity.X = (sinRoll * sinPitch - sinRoll * sinYaw * cosPitch - sinYaw * cosPitch); 
     m_Velocity.Y = sinPitch * cosRoll; 
     m_Velocity.Z = (sinRoll * sinPitch + sinRoll * cosYaw * cosPitch + cosYaw * cosPitch); 
     if (m_Velocity.X == 0 && m_Velocity.Y == 0 && m_Velocity.Z == 0) 
      m_Velocity = new Vector3(0f,0f,1f); 
     m_Rotation = new Vector3((float)pitch, (float)yaw, (float)roll); 

     m_Velocity.Normalize(); 
     //m_QRotation = Quaternion.CreateFromYawPitchRoll((float)yaw,(float)pitch,(float)roll); This line works for the most part but doesn't allow you to pitch up correctly while banking. 
     m_QRotation = Quaternion.CreateFromAxisAngle(m_Velocity,(float)roll); 
     m_Velocity = Vector3.Multiply(m_Velocity, shipSpeed); 

     m_Position += m_Velocity; 
    } 

答えて

2

あなたは、ヨー、ピッチ、ロール&変数としてあなたの船の向きを格納について断固ていますか?そうでない場合は、四元数または行列にオリエンテーションを格納することで、ここでの課題を大幅に簡素化できます。

フレームの最後に、ワールド空間方向&船の位置を表す行列effect.Worldを送信します。その行列の前方の性質は、ここであなたが速度として計算したベクトルと同じです。その行列をeffect.Worldから保存しないと、次のフレームはその行列を自らの順方向ベクトル(ロール用)で回転させ、それ自身のforwardプロパティ(forwardプロパティ* shipSpeed)に基づいてTranslationプロパティを進め、次のフレームの効果。これにより、船の実際のヨー、ピッチ、&ロール角を「知る」ことができなくなります。しかし、ほとんどの場合、3Dプログラミングでは、あなたが何かの角度を知る必要があると思うなら、あなたはおそらく間違った方向に向かっているでしょう。

あなたが望むなら、あなたがこの方向に向かうための行列を使ったスニペットです。

//class scope field 
Matrix orientation = Matrix.Identity; 


//in the update 
Matrix changesThisFrame = Matrix.Identity; 

//for yaw 
changesThisFrame *= Matrix.CreatFromAxisAngle(orientation.Up, inputtedYawAmount);//consider tempering the inputted amounts by time since last update. 

//for pitch 
changesThisFrame *= Matrix.CreateFromAxisAngle(orientation.Right, inputtedPitchAmount); 

//for roll 
changesThisFrame *= Matrix.CreateFromAxisAngle(orientation.Forward, inputtedRollAmount); 

orientation *= changesThisFrame; 

orientation.Translation += orientation.Forward * shipSpeed; 


//then, somewhere in the ship's draw call 

effect.World = orientation; 
1

XNAで作業して3Dで回転させたいですか?それから読む:http://stevehazen.wordpress.com/2010/02/15/matrix-basics-how-to-step-away-from-storing-an-orientation-as-3-angles/

十分にお勧めできません。

+2

ありがとうSeb、それは私のブログです! =)私はそれをある日書きましたが、どれだけ多くの人が役に立つと思っているのか驚いていました。 thattolleyguyの質問に対する私の答えは、ブログの本質のミニバージョンでした。 –