2012-06-11 25 views
9

私はXNAを初めて使い、単純なゲームを作成しています。申し訳ありませんが、これはおそらく本当に簡単ですが、私はそれについて助けを見つけることができません。ゲームにはBlenderで作った船があります。船のX、Y、Z軸を回転させることで船をコントロールしたいと考えています。私が持っているコードは次のとおりです。XNAで3Dモデルを回転

protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 
    RotationMatrix = Matrix.CreateRotationY(MathHelper.PiOver2) * Matrix.CreateRotationY (rotationY) * Matrix.CreateRotationX(rotationX) * Matrix.CreateRotationZ(rotationZ); 

     Matrix shipTransformMatrix = RotationMatrix * Matrix.CreateTranslation(ship.Position); 

         DrawModel(ship.Model, shipTransformMatrix, ship.Transforms); 
     // TODO: Add your drawing code here 


     base.Draw(gameTime); 
    } 

    public void DrawModel(Model model, Matrix modelTransform, Matrix[] absoluteBoneTransforms) 
    { 
     //Draw the model, a model can have multiple meshes, so loop 
     foreach (ModelMesh mesh in model.Meshes) 
     { 
      //This is where the mesh orientation is set 
      foreach (BasicEffect effect in mesh.Effects) 
      { 

       effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * modelTransform; 
       effect.Projection = projectionMatrix; 
       effect.View = viewMatrix; 

      } 

      //Draw the mesh, will use the effects set above. 
      mesh.Draw(); 
     } 
    } 

これは、船の軸に沿ってではなく、船を回転させます。 Y軸を(回転Yの値を変更して)回転させると、船はY軸に沿って回転します。しかし、X軸またはZ軸を回転させると、船は世界のX軸とZ軸に応じて回転します。どのように私はそれを作るために、船は自分の軸で回転するのですか?行列とは何か違うことをする必要がありますか? おかげ

答えて

6

は、世界中の回転を適用しますか、グローバル軸。つまり、オブジェクトのローカル軸ではなく、ワールド/グローバル軸の周りを回転するだけです。

CreateFromAxisAngleを使用すると、船の独自のローカル軸を含む任意の回転軸を入力できます。

しかし、たとえば船のUpのような任意の軸を中心に回転させると、3つの角度値が同時に変更される可能性があるため、全体的な回転パラダイムのシフトが必要になります。不必要に困難なことすべてを把握する。より簡単な方法があります:

3つの角度の代わりに行列(または四元数)形式で回転を保存するだけです。ここで

+0

ありがとう。 CreateFromAxisAngleで船の回転軸を定義するにはどうすればよいですか?私は試してみました。行列に回転を保存するにはどうすればよいですか?それは私がやろうとしていることです。 – davidsbro

+0

ちょうど私はそれについてのブログ記事を書いた。 http://stevehazen.wordpress.com/2010/02/15/matrix-basics-how-to-step-away-from-storing-an-orientation-as-3-angles/ –

+0

ありがとうございました。私はあなたがそれを置く直前にあなたが置いたリンクを見つけました。笑。私はそれを読んで問題を解決することができました。ありがとうございました!本当に分かりやすくて本当に役に立ちました – davidsbro

2

EDIT:は(私は3Dの数学の多くをしたので、しばらくして、素晴らしい答えメイト)を以下のスティーブにここにいくつかのクレジットを与えます。

このチュートリアルでは、Steveが提案した設定方法を説明します。

http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/Rotation_-_translation.php

オリジナルポスト:

は、私はあなたのBasicEffectループでeffect.Rotationを作成するために持っていると信じています。

これはすべてMSDNの基本チュートリアルでカバーされています。あなたのコードはそこから来たように見えます。

http://msdn.microsoft.com/en-us/library/bb203897(v=xnagamestudio.31)

ない場合は、このリンクをチェックアウトし、ライマーを開始するために知っておく価値3Dですべてをカバー:CreateRotationX、CreateRotationY、& CreateRotationZすべてを使用して

http://www.riemers.net/eng/Tutorials/XNA/Csharp/series1.php

+0

感謝を。私は効果を作成しようとしました。私のBasicEffectループで回転しましたが、効果のRotationプロパティはありませんでした。私のプロブレンはモデルを回転させていない、私はそれを行うことができます、それはモデル軸をモデルと一緒に回転させることです。私が 'RotationMatrix = Matrix.CreateRotationY(MathHelper.PiOver2)* Matrix.CreateRotationY(rotationY)* Matrix.CreateRotationX(rotationX)* Matrix.CreateRotationZ(rotationZ);'を実行すると、最初に船で回転する軸を作成する軸しかし、それ以降の2つはありません。私はモデルを使って回転させるために行列を複数倍しなければならないのですか? – davidsbro

+0

注文は本当に問題にはなりません(私が気づいた限り)。 しかし、そこにあなたの問題があります。 RotationMatrix = Matrix.CreateRotationY(rotationY)* Matrix.CreateRotationX(rotationX)* Matrix.CreateRotationZ(rotationZ);次の操作を行います。 –

+0

私は、MathHelper.PiOver2があなたの船をある角度に事前調整することを推測していました。 代わりに、開始時に回転Y、X、Zを最初に設定したい値に設定してください。 これは、あなたが探しているローテーションを作成するはずです。それはその中心軸を中心に回転します。 –

1

は、私はケースにちょうど他の誰をやってしまったものです私が行ったように立ち往生:

Matrix RotationMatrix; 
//every time I wanted to rotate around an axis, I would do something like this: 
protected void rotateY() 
    { 
     RotationMatrix *= Matrix.CreateFromAxisAngle(RotationMatrix.Up, MathHelper.ToRadians(1.0f)); 
     //For the X axis I used RotationMatrix.Right, and for the Z RotationMatrix.Forward 
    } 
protected override void Draw(GameTime gameTime) 
    { 
     GraphicsDevice.Clear(Color.CornflowerBlue); 


    Matrix shipTransformMatrix = RotationMatrix * Matrix.CreateTranslation(ship.Position); 

        DrawModel(ship.Model, shipTransformMatrix, ship.Transforms); 
    // TODO: Add your drawing code here 


    base.Draw(gameTime); 
} 

public void DrawModel(Model model, Matrix modelTransform, Matrix[] absoluteBoneTransforms) 
{ 
    //Draw the model, a model can have multiple meshes, so loop 
    foreach (ModelMesh mesh in model.Meshes) 
    { 
     //This is where the mesh orientation is set 
     foreach (BasicEffect effect in mesh.Effects) 
     { 

      effect.World = absoluteBoneTransforms[mesh.ParentBone.Index] * modelTransform; 
      effect.Projection = projectionMatrix; 
      effect.View = viewMatrix; 

     } 

     //Draw the mesh, will use the effects set above. 
     mesh.Draw(); 
    } 
} 
関連する問題