4

私は次のことを正しく行っていますか?

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

vector3 の位置とフロートの回転角度を持つボックス モデルがあるとします。ボックス モデルの方を指している円錐台型のモデルもあります。その位置は、ボックス モデルから 50 単位と言えます。錐台には、vector3 の位置とクォータニオンの回転もあります。

シナリオ 1 では、ボックスとフラスタムは「回転していません」。これはすべて問題ありません。シナリオ 2 では、ボックスのみを回転させ、フラスタムを常にボックスを直接指し、ボックスから回転していない距離と同じ距離で回転させて (チェイス カメラのようなもの) フラスタムを回転させます。明らかに、ボックスと錐台の両方に Matrix.CreateRotationY() を使用してモデルと錐台を回転させると、錐台は横にわずかにオフセットされます。

それで、ボックスの周りの錐台のクォータニオン回転が最適だと思いましたか? この目的のために、私は次のことを試しましたが、うまくいきませんでした。モデルを画面に描画しますが、巨大なボックスのように見えるものも画面に描画し、カメラをどれだけ遠くに移動しても、ボックスは常に邪魔になります

テストの目的で、3 つのボックスとそれに関連付けられた 3 つの錐台があります。Game1 クラスでは、ボックス [0] を位置と回転で初期化します。

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 つのボックスはすべて同じ位置に異なる角度で描画されます。次に、錐台を作成するために、それらの位置を開始します。

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);

そして最後に、モデルを描画するために、GameModel クラスでそれらを Draw() します。

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 = transforms[myMesh.ParentBone.Index] * Matrix.CreateRotationY(Rotation) * Matrix.CreateFromQuaternion(ModelRotation) * Matrix.CreateTranslation(Position);

4

1 に答える 1

5

一見すると、 などの静的作成メソッドを使用してクォータニオンを作成するのが最善Quaternion.CreateFromAxisAngle(Vector3. UnitY, rotation)です。クォータニオンの X、Y、Z、および W の値は、位置とはまったく関係ありません。便利な静的メソッドは、トリッキーな計算を処理します。

あなたの状況では、ボックスが回転するときに錐台をボックスの同じ側に向けたままにして、錐台をボックスの周りに回転させたいように見えます。これには、描画メソッドで行われる変換に対して、わずかに異なるアプローチが必要です。

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

したがって、あなたの状況では、このようなものがそれを行うはずです(テストされていないサンプルコードに従う必要があります)。

// 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);

仮定:

  • 箱はそれ自体の中心を中心に回転します
  • 錐台はボックスに面したままで、ボックスの中心を中心に回転します

お役に立てれば。

于 2012-04-30T02:39:46.840 に答える