2012-04-25 17 views
4

次のことは正しいですか?XNAでのクォータニオンの回転

私はここで質問を投稿するつもりはありませんが、別のモデルの周りにモデルのクォータニオン回転をしようとしています。

私は、ベクトル3の位置とフロートの回転角度を持つボックスモデルを持っていると言います。 私は箱モデルに向かっている錐台形状のモデルを持っています。その位置はボックスモデルから50単位を示します。錐台にはベクトル3の位置とクォータニオンの回転もあります。

シナリオ1では、ボックスと錐台が「回転していません」。これはすべて上質で良いです。 シナリオ2では、ボックスのみを回転させ、錐台がいつもボックスを直接指し、回転していない距離のようにボックスから同じ距離を置いて、錐台が回転します(ちょっとしたカメラのように)。明らかに、ボックスと錐台の両方にMatrix.CreateRotationY()を使用してモデルと錐台を回転させただけでは、錐台はわずかに側面にオフセットされます。

私はボックスの周りの円錐台の四元数回転が一番良いと思いましたか? この目的のために私は運がないと次のように試しました。それは私のモデルをスクリーンに描きますが、画面に巨大な箱のように見えます。カメラをどこまで移動させても、箱は常に途中にあります。

テスト目的のために、位置や回転

boxObject[0].Position = new Vector3(10, 10, 10); 
boxObject[1].Position = new Vector3(10, 10, 10); 
boxObject[2].Position = new Vector3(10, 10, 10); 

boxObject[0].Rotation = 0.0f; 
boxObject[1].Rotation = 45.0f; 
boxObject[2].Rotation = -45.0f; 

同じ位置ではなく、異なる角度で描かれたので、すべて3箱と私のGame1クラスで3箱とその3つの関連する円錐台 私はボックスを初期化する[0]。その後、

float f = 50.0f; 
frustumObject[0].Position = new Vector3(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f); 
frustumObject[1].Position = new Vector3(boxObject[1].Position.X, 
      boxObject[1].Position.Y, boxObject[1].Position.Z + f); 
frustumObject[2].Position = new Vector3(boxObject[2].Position.X, 
      boxObject[2].Position.Y, boxObject[2].Position.Z + f); 

そしてしようとすると、それに関連するボックスモデルの周りを回転: は、次に円錐台を行うために、私は彼らの位置開始)

frustumObject[0].ModelRotation = new Quaternion(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f, 0); 
frustumObject[0].ModelRotation = new Quaternion(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f, 45); 
frustumObject[0].ModelRotation = new Quaternion(boxObject[0].Position.X, 
      boxObject[0].Position.Y, boxObject[0].Position.Z + f, -45); 

をそして最後に、モデルを描画するために、私は(ドローそれら

public Model CameraModel { get; set; } 
public Vector3 Position { get; set; } 
public float Rotation { get; set; } 
public Quaternion ModelRotation { get; set; } 

public void Draw(Matrix view, Matrix projection) 
    { 
     transforms = new Matrix[CameraModel.Bones.Count]; 
     CameraModel.CopyAbsoluteBoneTransformsTo(transforms); 

     // Draw the model 
     foreach (ModelMesh myMesh in CameraModel.Meshes) 
     { 
      foreach (BasicEffect myEffect in myMesh.Effects) 
      { 
       // IS THIS CORRECT????? 
       myEffect.World = transforms[myMesh.ParentBone.Index] * 
        Matrix.CreateRotationY(Rotation) * Matrix.CreateFromQuaternion(ModelRotation) * Matrix.CreateTranslation(Position); 

       myEffect.View = view; 
       myEffect.Projection = projection; 

       myEffect.EnableDefaultLighting(); 
       myEffect.SpecularColor = new Vector3(0.25f); 
       myEffect.SpecularPower = 16; 
      } 

      myMesh.Draw(); 
     } 
    } 

私が間違っている場所を誰にでも見分けることができますか?私はDraw()の2種類の回転をしているからですか?

はmyEffect.World =変換[myMesh.ParentBone.Index] * Matrix.CreateRotationY(回転)* Matrix.CreateFromQuaternion(ModelRotation)* Matrix.CreateTranslation(位置)。

+1

コードに深く掘り下げなければ、私に打撃を与える最初のことは(愚かな可能性があります)行列の順序です。私はquaternionが翻訳の後にあるべきだと思います。これはおそらくそれを修正することはありませんが、試してみる価値があります。 – annonymously

+0

ありがとう、病気これを試して、私がどのように乗っているかを教えてください。 – heyred

+0

いいえ、申し訳ありませんがトリックもしません。 2つの異なるDraw()メソッドを試してみてください.1つはボックス用、もう1つは錐台用です(錐台描画のDrawとQuartenionの回転ボックスでの通常の回転)。 – heyred

答えて

4

Quaternion.CreateFromAxisAngle(Vector3. UnitY, rotation)のような静的作成メソッドを使用してクォータニオンを作成するのが最適です。クォータニオンのX、Y、Z、Wの値は、どのような方法でも位置に関係しません。便利な静的メソッドはトリッキーな数学を扱います。

あなたの状況では、箱が回転しているのでボックスの同じ側を指しているので、箱の周りに錐台が回転しているように見えます。これには、drawメソッドで行われる変換とは少し異なるアプローチが必要です。

オブジェクトを別のオブジェクトの周りで回転させるには、最初にオブジェクトを平行移動して、回転の中心が原点になるようにする必要があります。次に、オブジェクトを回転させ、最初のステップと同じ量だけオブジェクトを元に戻します。

あなたの状況では、このようなものが必要です(テストされていないサンプルコード)。

// Construct the objects 

boxObject.Position = new Vector3(10, 10, 10); 
boxObject.Rotation = 45.0f; 

frustumObject.Position = new Vector3(0, 0, 50f); // Note: this will be relative to the box (makes the math a bit simpler) 
frustumObject.TargetPosition = boxObject.Position; 
frustumObject.ModelRotation = Quaternion.CreateFromAxisAngle(Vector3. UnitY, boxObject.Rotation); // Note: this rotation angle may need to be in radians. 


// Box Draw() 
// Draw the box at its position, rotated about its centre. 
myEffect.World = transforms[myMesh.ParentBone.Index] * Matrix.CreateTranslation(Position) * Matrix.CreateRotationY(Rotation); 

// Frustum Draw() 
// Draw the frustum facing the box and rotated about the boxes centre. 
myEffect.World = transforms[myMesh.ParentBone.Index] * Matrix.CreateTranslation(Position) * Matrix.CreateFromQuaternion(ModelRotation) * Matrix.CreateTranslation(TargetPosition); 

仮定:

  • ボックスが
  • 錐台が箱に直面したままで、ボックスの中心の周りに回転させ、独自の中心の周りを回転する

・ホープこれは役に立ちます。

関連する問題