2014-07-08 6 views
0

두 가지 벡터 사이의 각도를 결정하는 데 필요한 여러 가지 방법을 모두 읽었으며 정말 혼란 스럽습니다. 그래서 내가해야 할 일을 이해하는 데 도움이 필요합니다.두 벡터 사이의 요와 피치 결정

다음은 내 첫 인칭 카메라 코드

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

    } 
} 

은 "바라"방법은 내가 그것을 수행하는 방법을 알아 내려고 노력하고 있기 때문에 빈입니다. 카메라를 움직여서 위치가 (500,500,500)이고 (0, 0, 0)을 볼 필요가 있지만, 회전을 올바르게 설정할 수 있도록 요와 피치를 가져 오는 방법을 알아낼 수 없습니다. 벡터를 정규화하고 십자가 및 점을 사용하는 방법에 대해 읽었습니다. 그러나 방향이 없으므로 (0,0,0)을 정규화 할 수 없으므로 어떻게 해야할지를 놓쳤습니다. 어떤 도움을 주시면 감사하겠습니다.

답변

0

당신이 2 개 가지 방법으로 카메라를 조작 할 수 있도록하려는 것 같다 :

1. 약간의 요 또는 피치를 더하거나 뺍니다. 그에 따라 카메라가 응답하도록하십시오.
2. 카메라가 알려진 위치를 보도록 한 다음 원하는 경우 후속 프레임에서 # 1을 수행 할 수 있도록 피치 및 요우 각을 계산합니다.

나는 당신이 어렵게 만드는 것은 나중에 사용하기 위해 전체 피치와 요 각도를 저장하려고한다는 것입니다. 경험 많은 3D 프로그램에서 앵글을 저장할 필요가 있다고 생각하면 아마 뭔가 잘못하고 있다고 들으실 것입니다 (last paragraph in this blog). 어쨌든, 당신이 그 각도를 놓을 수 있다면, 당신은 카메라 클래스가 훨씬 간단합니다. 다음은 그 예입니다. 이 두 가지 공개 방법을 통해 1. 피치, 요, 번역을 추가하거나 세계의 특정 지점을 보도록 설정하여 카메라를 조정할 수 있습니다. 또한 언제든지 두 가지 방법 중 하나를 사용할 수 있습니다. 절대 피치와 요각에 대한 우려가 없으므로 코드가 훨씬 간단합니다.

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

관련 문제