2014-02-08 1 views
0

Я искал долгое время и не могу найти ответ на этот, казалось бы, простой вопрос. У меня есть 3D-пространство, и у моей камеры есть переменные x, y, z, yaw, pitch и roll, и я хочу, чтобы вы могли перемещать камеру вперед к тому, что я смотрю. Большинство классов камеры есть что-то вроде этого:LWJGL Перемещение камеры к тому, что вы смотрите на

//moves the camera forward relitive to its current rotation (yaw) 
public void walkForward(float distance) 
{ 

    position.x -= distance * (float)Math.sin(Math.toRadians(yaw)); 
    position.z += distance * (float)Math.cos(Math.toRadians(yaw)); 

} 

Это хорошо работает для продвижения вперед в зависимости от вашего рыскания, но ваше положение у никогда не изменится. Как это можно изменить так же, как и относительно вашего тона, так что вы всегда будете двигаться к тому, что смотрит камера?

EDIT:

Двигаясь вперед, я имею в виду, что при перемещении вашей камеры определенное количество на каждой оси, что сумма в зависимости от вашего рыскания, тангажа и крена, что находится перед вами, появится, чтобы получить больше. Это может быть использовано:

position.x += -Math.sin(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance; 
    position.z += Math.cos(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance; 
    position.y -= -Math.sin(Math.toRadians(rotation.x)) * distance; 

Примечание: rotation.y = рыскания, rotation.x = шаг, rotation.z будет рулет. Расстояние - это просто, сколько нужно двигаться, допустим, 0,1.

Это будет работать, если вы не измените рулон камеры (вращение на оси z), иначе оно не будет. Это сообщение, вероятно, очень похоже на this сейчас, но я не знаю, как применить это матричное умножение, которое было решением в свой класс камеры, которая выглядит следующим образом

public class Camera 
{ 
// Field Of View 
private float fov; 
// Aspect Ratio 
private float aspect; 
// Near Plane 
private float zNear; 
// Far Plane 
private float zFar; 

// Projection matrix 
private Matrix4f projection; 
// View matrix 
private Matrix4f view; 

// Camera position 
private Vector3f position; 
// Camera rotation 
private Vector3f rotation; 

// Vectors for axes 
private Vector3f xAxis, yAxis, zAxis; 

/** 
* Creates a simple 3D Perspective Camera. 
* 
* @param fov The field of view in degrees. 
* @param aspect The aspect ratio. 
* @param zNear The near clipping plane. 
* @param zFar The far clipping plane. 
*/ 
public Camera(float fov, float aspect, float zNear, float zFar) 
{ 
    // Set the local variables 
    this.fov = fov; 
    this.aspect = aspect; 
    this.zNear = zNear; 
    this.zFar = zFar; 

    // Create matrices 
    projection = MatrixUtil.createPerspectiveProjection(fov, aspect, zNear, zFar); 
    view = MatrixUtil.createIdentityMatrix(); 

    // Initialize position and rotation vectors 
    position = new Vector3f(0, 0, 0); 
    rotation = new Vector3f(0, 0, 0); 

    // Create normalized axis vectors 
    xAxis = new Vector3f(1, 0, 0); 
    yAxis = new Vector3f(0, 1, 0); 
    zAxis = new Vector3f(0, 0, 1); 

    // Enable depth testing 
    glEnable(GL_DEPTH_TEST); 
} 

/** 
* Apply the camera's transformations. 
*/ 
public void apply() 
{ 
    // Make the view matrix an identity. 
    view.setIdentity(); 

    // Rotate the view 
    Matrix4f.rotate((float) Math.toRadians(rotation.x), xAxis, view, view); 
    Matrix4f.rotate((float) Math.toRadians(rotation.y), yAxis, view, view); 
    Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, view, view); 

    // Move the camera 
    Matrix4f.translate(position, view, view); 
} 

//moves the camera forward relitive to its current rotation (yaw and pitch) 
public void moveForward(float distance) 
{ 
    position.x += -Math.sin(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance; 
    position.z += Math.cos(Math.toRadians(rotation.y)) * Math.cos(Math.toRadians(rotation.x)) * distance; 
    position.y -= -Math.sin(Math.toRadians(rotation.x)) * distance; 
} 

(Этот класс камеры основан на this руководства)

Итак, как я могу заставить камеру двигаться вперед в зависимости от ее рыскания, высоты тона и рулона.

ответ

1

У вас есть 3 оборота: рулон, рыскание и высота. Их также можно представить как точки на диске, нарисованные на плоской плоскости в трехмерном пространстве: xy-plane (roll), xz-plane (yaw), zy-plane (pitch).

Чтобы помочь вам визуализировать это, представьте, что вы находитесь внутри куба. Куб имеет 6 граней, каждый с кругом, нарисованным на нем. 2 лица ниже и выше вас - это плоскости xz; справа от вас и слева - zy-самолеты; спереди и сзади - знакомые плоскости xy.

Ваш пример - вращение вокруг центра круга, нарисованного на плоскости xz. Когда самолет рыскает, он, очевидно, не меняет своего тона. Рулон (х) будет выглядеть примерно так:

position.x -= distance * (float)Math.cos(Math.toRadians(amount)); 
position.y += distance * (float)Math.sin(Math.toRadians(amount)); 

Вы, возможно, придется изменить знаки, потому что я не знаю, как это реализовано.

На плоскости xy (типичный вид 2d), если вы нарисуете круг с радиусом r, любую точку на круге под углом theta можно задать P (r * cos (theta), r * sin (theta)). В трехмерном пространстве у вас есть 3 плоскости, и вам придется применять ту же логику на всех плоскостях, чтобы найти соответствующие значения для вращения на этой плоскости.

Я не уверен, что вы подразумеваете под «перемещением камеры вперед».

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