2014-07-08 67 views
0

我已經閱讀了各種各樣的方法來確定兩個向量之間的角度,我真的很困惑,所以我需要一些幫助來理解我需要做什麼。確定兩個Vector3點之間的偏航和俯仰

下面是我的第一人稱視角碼

public class FPSCamera : Engine3DObject 
{ 
    public Matrix View { get; private set; } 
    public Matrix Projeciton { get; private set; } 

    private Quaternion rotation; 
    private float yaw; 
    private float pitch; 
    private bool isViewDirty; 
    private bool isRotationDirty; 

    public BoundingFrustum Frustum { get; private set; } 

    public bool Changed { get; private set; } 

    public Vector3 ForwardVector 
    { 
     get 
     { 
      return this.View.Forward; 
     } 
    } 

    public FPSCamera() 
     : base() 
    { 
     this.Position = Vector3.Zero; 
     this.rotation = Quaternion.Identity; 
     this.yaw = this.pitch = 0; 
     this.isViewDirty = true; 
     this.isRotationDirty = false; 


    } 

    public void SetPosition(Vector3 position) 
    { 
     this.Position = position; 
     this.isViewDirty = true; 
     this.Update(null); 
    } 

    public void Initialize(float aspectRatio) 
    { 
     this.Projeciton = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1f, 1000f); 
    } 

    public void Update(GameTime gameTime) 
    { 
     this.Changed = false; 

     if (isRotationDirty) 
     { 
      if (yaw > MathHelper.TwoPi) 
      { 
       yaw = yaw - MathHelper.TwoPi; 
      } 

      if (yaw < -MathHelper.TwoPi) 
      { 
       yaw = yaw + MathHelper.TwoPi; 
      } 

      if (pitch > MathHelper.TwoPi) 
      { 
       pitch = pitch - MathHelper.TwoPi; 
      } 

      if (pitch < -MathHelper.TwoPi) 
      { 
       pitch = pitch + MathHelper.TwoPi; 
      } 

      this.rotation = Quaternion.CreateFromYawPitchRoll(yaw, pitch, 0); 
      this.isRotationDirty = false; 
      this.isViewDirty = true; 
      this.Changed = true; 
     } 

     if (isViewDirty) 
     { 
      Vector3 up = Vector3.Transform(Vector3.Up, rotation); 
      Vector3 target = Vector3.Transform(Vector3.Forward, rotation) + Position; 
      this.View = Matrix.CreateLookAt(this.Position, target, up); 
      this.isViewDirty = false; 

      if (this.Frustum == null) 
      { 
       this.Frustum = new BoundingFrustum(this.View * this.Projeciton); 
      } 
      else 
      { 
       this.Frustum.Matrix = (this.View * this.Projeciton); 
      } 

      this.Changed = true; 
     } 
    } 

    public void Move(Vector3 distance) 
    { 
     this.Position += Vector3.Transform(distance, rotation); 
     this.isViewDirty = true; 
    } 

    public void Rotate(float yaw, float pitch) 
    { 
     this.yaw += yaw; 
     this.pitch += pitch; 
     this.isRotationDirty = true; 
    } 

    public void LookAt(Vector3 lookAt) 
    { 

    } 
} 

的「LOOKAT」方法是空的,因爲我試圖找出如何做到這一點。我移動相機使其位置是(500,500,500),並需要它看(0,0,0),但我無法弄清楚如何獲得它們之間的偏轉和俯仰,以便我可以正確設置旋轉角度。我已經閱讀了關於歸一化矢量並使用交叉和點積的方法,但由於它沒有方向,所以我不能正常化(0,0,0),所以我對於該怎麼做有點失落。任何幫助,將不勝感激。

回答

0

好像你希望能夠操縱你的相機在2周不同的方式:

1.)增加或減少一點偏航或俯仰,讓攝像機做出相應的響應。
2.)讓攝像機查看已知位置,然後計算俯仰角和偏航角,以便在後續幀上進行#1操作(如果需要)。

我覺得讓你感到困難的是你想存儲整個音高和偏航角度以備後用。你可能會聽到一些有經驗的3D程序說如果你認爲你需要存儲角度,你可能會做錯事(last paragraph in this blog)。無論如何,如果你可以放棄這些角度,你的相機類會簡單得多。這是一個例子。這兩種公開的方法可讓您通過以下兩種方法來處理相機:1)添加音高,偏航或翻譯,或2)將其設置爲查看世界中的特定點。它也允許你隨時使用任何一種方法。通過不擔心絕對俯仰和偏航角度,代碼更簡單。

namespace WindowsGame1 
{ 
    class FPSCamera 
    { 
     public Matrix View; 
     public Matrix Proj; 
     public Vector3 Position, Target; 


     public FPSCamera(float aspect) 
     { 

      Proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect, 1f, 1000f); 
      Target = Vector3.Forward; 
      SetViewMatrix(); 
     } 

     public void UpdateCameraByPitchYawTranslation(float amountToPitchThisFrame, float amountToYawThisFrame, Vector3 amountToTranslateThisFrame) 
     { 
      Position += amountToTranslateThisFrame; 
      Target += amountToTranslateThisFrame; 

      Matrix camera = Matrix.Invert(View); 
      Target = Vector3.Transform(Target - Position, Matrix.CreateFromAxisAngle(camera.Right, amountToPitchThisFrame)) + Position; 
      Target = Vector3.Transform(Target - Position, Matrix.CreateFromAxisAngle(Vector3.Up, amountToYawThisFrame)) + Position; 

      SetViewMatrix(); 
     } 

     public void SetCameraToLookAtSpecificSpot(Vector3 spotToLookAt) 
     { 
      Target = spotToLookAt; 
      SetViewMatrix(); 
     } 

     private void SetViewMatrix() 
     { 
      View = Matrix.CreateLookAt(Position, Target, Vector3.Up); 
     } 

    } 
} 

如果您願意,您還可以製作一個公開的方法將相機位置設置到特定位置。

+0

好的,我明白了......我想過簡化它,因爲它看起來有點臃腫和不必要。我會執行它,看看它是如何發展。 – mikelomaxxx14

+0

如何向前移動相機(即其朝向的方向?)。此刻,如果我傳入運動矢量,它將移動相機,但只能在軸上移動,而不是相機朝向的方式。我還需要弄清楚相機面對其他功能所面臨的角度,但我相信我能以某種方式使用目標進行拍攝。 – mikelomaxxx14

+0

你可以添加一個像這樣的方法來前進或後退。 http://pastebin.com/YPKnM2ye –

0

首先你已經有了一個計算適當矩陣的方法Matrix.CreateLookAt(this.Position, target, up)。這種方法創建適當的矩陣。

除了你想要的工作不是一個從攝像頭到觀察點的相當方向的觀察位置點。所以在你的情況下,它會是[0,0,0] - [500,500,500]。你還需要「向上」的方向來確定角度的纏繞方向。

在這裏,您有相關discusscion: Calculating a LookAt matrix

在這裏你有關於變換矩陣進一步的解釋: http://www.math.washington.edu/~king/coursedir/m308a01/Projects/m308a01-pdf/yip.pdf

相關問題