2013-04-01 4 views
3

Что мне нужно, чтобы вычислить, где мой векторный 3d-вектор будет основан на положении камеры, вращении Y и вращении Z, я бы предположил, что для числа, большего чем 0, будет достаточно для расстояние от камеры, чтобы посмотреть.Расчет целевой цели камеры FPS в XNA

Вот статический класс я использую для управления камерой и вычислить вид и проекционных матриц и т.д.

Члены класса, которые включают положение и поворот:

public static Vector3 Position { get; set; } //Publicly available for use outside the class 
public static Vector3 Rotation { get; set; } 
private static Vector3 camPos = new Vector3(0.0f, 200.0f, 300.0f); //However we work with these for manipulation of values 
private static Vector3 camTarget = new Vector3(0, 0, -1200.0f); 

private static float rotY = 0, rotZ = 0; //I believe that these are the correct axis following the right hand catasian coordinate system 
обновления

моей камеры функция:

public static void Update()   
{ 
    //Controls here 

    //Update Position here 
    Position = camPos;    

    //Update camTarget based on Position, rotY and rotZ <- Need help with this bit 

    //After calculating camTarget update Rotation 
    Rotation = camTarget; 

    UpdateMatrices(); 
} 

UpdateMatrices() обрабатывает все остальное и работает как надо, но здесь это только в случае, если вы хотели бы видеть:

public static void UpdateMatrices() 
{ 
    Matrix rotationMatrix = Matrix.CreateRotationX(MathHelper.ToRadians(90)); 
    Vector3 transformedReference = Vector3.Transform(Vector3.Forward, rotationMatrix); 

    View = Matrix.CreateLookAt(Position, Rotation, Vector3.Forward); 
    Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, nearClip, farClip); 
    World = Matrix.Identity; 

    CamBoundingFrustrum = new BoundingFrustum(View * Projection); 
} 

Может кто-нибудь быть любезным поделиться секретом с этим, пожалуйста?

+2

Важный вопрос, который не связан с вашим вопросом здесь: ваш «CamBoundingFrustrum» - это класс, а не структура. Это означает, что создание «нового» каждого кадра делает много мусора для сборщика мусора. Предполагаемый способ обработки изменений в усеченности каждого кадра из-за перемещения/вращения камеры состоит в том, чтобы просто обновить (каждый кадр) свойство «Матрица» объекта BoundingFrustum, которое было создано только один раз, когда камера была первоначально создана. –

ответ

3

Вместо того чтобы использовать Vector3.Forward, тянуть .Forward и .Up векторов из вашей матрицы вращения:

public void UpdateMatrices() 
    { 
     /// assumes Rotation is a Vector3 containing rotation around each axis expressed in radians 
     Matrix rotationMatrix = Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z); 
     /// View = Matrix.CreateLookAt(Position, Rotation, Vector3.Forward); 

     View = Matrix.CreateLookAt(Position, Position + rotationMatrix.Forward, rotationMatrix.Up); 
     Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, nearClip, farClip); 

     /// World matrix needs to match your translation and rotation used above 
     /// XNA expects matrices to be concatenated in SRT (scale, rotation, then translate) order: 
     World = rotationMatrix * Matrix.CreateTranslation(Position); 

     CamBoundingFrustrum = new BoundingFrustum(View * Projection); 
    } 

Обратите внимание, что вы должны добавить перевод камеры (с помощью вектора вы храните, или из мира камеры матрица .Translation) до RotationMatrix.Forward, чтобы получить реальную цель.

Матрица .Forward, .Backward, .Left, .Right, .Up и .Down свойства такие же, как эквивалентные Vector3 свойства трансформированного матрицы вращения. так, RotationMatrix.Forward точки в направлении вы смотрите, .Up ортогональна и т.д.

Если вы просто используете Vector3.Forward, вы не получите преобразованный вектор, и странные вещи могут случиться.

Другие ноты:

  1. Не делают все статические. Создайте экземпляр класса камеры во время Game.Initialize() и добавьте его как свойство. static следует использовать с осторожностью - это может вызвать всевозможные забавные проблемы с потоками, которые сбивают вас с ума.
  2. Я бы также рекомендовал переключиться на кватернион вместо yaw/roll/pitch (если вы еще этого не сделали), так как он избегает блокировки gimble, но это другая тема.
+0

Отлично, спасибо :) – TotalJargon

Смежные вопросы