Я долго искал и не мог найти ответ на этот, казалось бы, простой вопрос. У меня есть трехмерное пространство, и моя камера имеет переменные x, y, z, yaw, pitch и roll, и я хочу иметь возможность перемещать камеру вперед в направлении того, на что я смотрю. Большинство классов камеры имеют что-то вроде этого:
//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));
}
Это хорошо работает для движения вперед в зависимости от вашего рыскания, но ваше положение по оси y никогда не изменится. Как это можно изменить, чтобы оно также соответствовало вашему тону, чтобы вы всегда двигались к тому, на что смотрит камера?
РЕДАКТИРОВАТЬ:
Под продвижением вперед я подразумеваю, что при перемещении вашей камеры на определенную величину по каждой оси эта величина, зависящая от вашего рысканья, тангажа и крена, всего, что находится перед вами, будет казаться больше. Это можно использовать:
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;
Примечание: вращение.y = рыскание, вращение.x = тангаж, вращение.z будет вращением. Расстояние - это просто то, сколько нужно двигаться, скажем, 0,1.
Это будет работать, если вы не измените поворот камеры (вращение по оси z), иначе не будет. Этот пост, вероятно, очень похож на этот теперь, но я не знаю, как применить матричное умножение, которое было решением, к моему классу камеры, который выглядит так
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;
}
(Этот класс камеры основан на этом руководстве)
Итак, как я могу заставить камеру двигаться вперед в зависимости от ее рыскания, тангажа и крена.