簡體   English   中英

XNA(3D-游戲)中的矩陣用於相機旋轉

[英]Matrices in XNA (3D - Game) for Camera rotation

我已經編寫了用於旋轉和移動相機的代碼。
不幸的是,由於我幾天前才開始對矩陣和3D編程不熟悉,所以:

plLookAt = new Vector3(plPos.X, plPos.Y, plPos.Z - 20);    
if (kb.IsKeyDown(Keys.W))
        {
            plPos.Z++;
        }
        if (kb.IsKeyDown(Keys.A))
        {
            plPos.X++;
        }
        if (kb.IsKeyDown(Keys.S))
        {
            plPos.Z--;
        }
        if (kb.IsKeyDown(Keys.D))
        {
            plPos.X--;
        }
        view = Matrix.CreateLookAt(new Vector3(0, 0, 0), plLookAt, Vector3.UnitY);
        view = view * Matrix.CreateRotationY(MathHelper.ToRadians(rotations.Y)) * Matrix.CreateRotationX(MathHelper.ToRadians(rotations.X));
        view = view *Matrix.CreateTranslation(plPos);

        if (PrMS.X < ms.X)
        {
            rotations.Y++;
        }
        else if (PrMS.X > ms.X)
        {
            rotations.Y--;
        }
        if (PrMS.Y < ms.Y)
        {
            rotations.X++;
        }
        else if (PrMS.Y > ms.Y)
        {
            rotations.X--;
        }    

plPos是播放器(相機)位置
view是視圖矩陣
rotations是保存相機旋轉的位置(Vector3)
PrMS是上一幀的MouseState。
這段代碼不起作用,我認為這是因為順序是乘法的順序,但是我不確定。 旋轉相機的最佳方法是什么,這樣它才能實際工作,並且我可以朝相機所面對的方向走。 先感謝您!

您的問題不是矩陣乘法的順序,而是您的旋轉必須圍繞攝像機局部軸,而您要圍繞世界局部軸進行旋轉。

我認為您所期望的是應用.CreateRotationX(rotations.X).CreateRotationY(rotationsY)會導致相機改變俯仰並圍繞其自身的本地軸偏航。 但是這些旋轉總是導致繞着世界軸旋轉。 如果您攝像機的局部X軸恰好與世界X軸對齊,並且您執行了.CreateRotationX() ,則它將按預期工作。 但是在您的情況下,您首先要繞Y軸旋轉照相機,這會使照相機的局部X軸與世界X軸不對齊,因此下一次旋轉(X)將不會如預期那樣進行。 即使您先執行X,然后執行Y,X也會將Y甩掉。 盡管矩陣乘法的順序通常很重要,但是在您的特定情況下,問題是旋轉軸。

看來您正在制作的相機位於播放器的位置,但是可以通過鼠標控制向左/向右,向上/向下看。 這是一類,提供了一種不同的方法來處理該標准:

class Camera
{
    public Matrix View { get; set; }
    public Matrix Projection { get; set; }

    Vector2 centerOfScreen;// the current camera's lookAt in screen space (since the mouse coords are also in screen space)
    Vector3 lookAt;

    float cameraRotationSpeed;



    public Camera()
    {
        //initialize Projection matrix here
        //initialize view matrix here 
        //initialize centerOfScreen here like this:  new Vector2(screenWidth/2, screenHeihgt/2); 
        cameraRotationSpeed = 0.01f;//set to taste
    }



    public void Update(Vector3 playerPosition, MouseState currentMouse)
    {
        Matrix cameraWorld = Matrix.Invert(View);

        Vector2 changeThisFrame = new Vector2(currentMouse.X, currentMouse.Y) - centerOfScreen;

        Vector3 axis = (cameraWorld.Right * changeThisFrame.X) + (cameraWorld.Up * changeThisFrame.Y);//builds a rotation axis based on camera's local axis, not world axis

        float angle = axis.Length() * cameraRotationSpeed;
        axis.Normalize();

        //rotate the lookAt around the camera's position
        lookAt = Vector3.Transform(lookAt - playerPosition, Matrix.CreateFromAxisAngle(axis, angle)) + playerPosition;//this line does the typical "translate to origin, rotate, then translate back" routine

        View = Matrix.CreateLookAt(playerPosition, lookAt, Vector3.Up);// your new view matrix that is rotated per the mouse input

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM