簡體   English   中英

我的相機出了什么問題?

[英]What's wrong with my camera?

我正在使用VS2010和C#以及XNA 4.0。 我正在關注Aaron Reed的“學習XNA 4.0”一書。 我將相機游戲組件添加到我的項目中,但這個相機表現得非常奇怪。 移動鼠標使其“跳躍”然后崩潰。 我不知道造成這種情況的原因。 它看起來代碼與書中的代碼幾乎完全相同。 它工作得更早,但現在不是,雖然我不記得我是否改變了它(我想不是)。 請注意,我只在游戲中注冊此組件,僅此而已。 它應該工作,但事實並非如此。 任何幫助都會很棒。 這是代碼:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace MyGame
{
    public class Camera : Microsoft.Xna.Framework.GameComponent
    {

        public Matrix View { get; protected set; }
        public Matrix Projection { get; protected set; }
        public Vector3 CameraPosition { get; protected set; }
        public Vector3 CameraDirection { get; protected set; }
        public Vector3 CameraUp { get; protected set; }
        private MouseState prevMouseState;

        public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up)
            : base(game)
        {
            // Some initialization of camera.
            CameraPosition = pos;
            CameraDirection = target - pos;
            CameraDirection.Normalize();
            CameraUp = up;
            CreateLookAt();

            Projection = Matrix.CreatePerspectiveFieldOfView(
                MathHelper.PiOver4,                
                (float)Game.Window.ClientBounds.Width /
                (float)Game.Window.ClientBounds.Height,
                1f, 3000f);
        }

        public override void Initialize()
        {
            // Set mouse position and do initial get state.
            Mouse.SetPosition(Game.Window.ClientBounds.Width / 2,
                Game.Window.ClientBounds.Height / 2);
            prevMouseState = Mouse.GetState();

            base.Initialize();
        }


        public override void Update(GameTime gameTime)
        {
            // Standard WSAD keyboard movement.
            if (Keyboard.GetState().IsKeyDown(Keys.W))
                CameraPosition += CameraDirection;
            if (Keyboard.GetState().IsKeyDown(Keys.S))
                CameraPosition -= CameraDirection;
            if (Keyboard.GetState( ).IsKeyDown(Keys.A))
                CameraPosition += Vector3.Cross(CameraUp, CameraDirection);
            if (Keyboard.GetState().IsKeyDown(Keys.D))
                CameraPosition -= Vector3.Cross(CameraUp, CameraDirection);

            // Yaw rotation (via mouse).
            CameraDirection = Vector3.Transform(CameraDirection,
                Matrix.CreateFromAxisAngle(CameraUp, (-MathHelper.PiOver4 / 150) *
                (Mouse.GetState().X - prevMouseState.X) 
                ));

            // Pitch rotation (via mouse).
            CameraDirection = Vector3.Transform(CameraDirection,
                Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
                (MathHelper.PiOver4 / 100) *
                (Mouse.GetState().Y - prevMouseState.Y) 
                ));

            CameraUp = Vector3.Transform(CameraUp,
                Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
                (MathHelper.PiOver4 / 100) *
                (Mouse.GetState().Y - prevMouseState.Y)
                ));

            prevMouseState = Mouse.GetState();

            CreateLookAt();
            base.Update(gameTime);
        }

        private void CreateLookAt()
        {
            View = Matrix.CreateLookAt(CameraPosition,
                CameraPosition + CameraDirection, CameraUp);
        }
    }
}

有人可以檢查一下這段代碼是否適用於他? 任何想法都會很棒!

//編輯1:在游戲初始化中我使用代碼:

Camera cam = new Camera(this, new Vector3(0, 0, 100), Vector3.Zero, Vector3.Up);
Components.Add(cam);

然后我畫模型。 我在模型的BasicEffect中使用了cam的視圖和投影矩陣。

//編輯2:有些事情嚴重錯誤。 我做了一些調試,似乎在某些時候,這些Vector3對象的X,Y,Z屬性設置為NaN。 我無法知道如何以及何時。 在運行一段時間之后(也許這沒什么)游戲時間顯示經過的游戲時間只有16毫秒(就像它跳過幀?)並且游戲運行緩慢。 無論我何時調試,這16毫秒總是相同的。

有可能我以某種方式弄亂了XNA / C#設置嗎? 如果是這樣,有人可以給我任何暗示現在該做什么嗎?

    // Pitch rotation (via mouse).
    CameraDirection = Vector3.Transform(CameraDirection,
        Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
        (MathHelper.PiOver4 / 100) *
        (Mouse.GetState().Y - prevMouseState.Y) 
        ));

    CameraUp = Vector3.Transform(CameraUp,
        Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection),
        (MathHelper.PiOver4 / 100) *
        (Mouse.GetState().Y - prevMouseState.Y)
        ));

無論何時使用CreateFromAxisAngle,第一個參數(軸)都需要是單位長度向量。 如果它不是單位長度矢量,則會導致失真(傾斜)矩陣和超過(或不足)旋轉的矩陣。

每當你越過兩個向量時,結果很少是單位長度向量。 產生橫向單位長度的結果。 嘗試這個:

Vector3.Transform(CameraDirection, Matrix.CreateFromAxisAngle(Vector3.Normalize(Vector3.Cross(CameraUp, CameraDirection)), ...

通過添加'Normalize',它使得交叉的結果成為單位長度向量。 不要忘記對偏航線也這樣做。

暫無
暫無

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

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