Как заставить камеру следить за самолетом в opengl?

Я пытаюсь сделать симулятор полета в opengl, но я просто не могу заставить свою камеру правильно следить за самолетом. Я думал, что если я применю один и тот же набор трансформаций как к камере, так и к его самолету, это будет работать, но это не так. Когда я говорю о преобразованиях, я имею в виду повороты с использованием сердцевины и углов поворота (на данный момент я не учел угол крена) и сдвиги, необходимые для перемещения самолета.
Это мой класс камеры:

namespace gps {

Camera::Camera(glm::vec3 cameraPosition, glm::vec3 cameraTarget)
{
this->cameraPosition = cameraPosition;
this->cameraTarget = cameraTarget;
this->cameraDirection = glm::normalize(cameraTarget - cameraPosition);
this->cameraRightDirection = glm::normalize(glm::cross(this->cameraDirection, glm::vec3(0.0f, 1.0f, 0.0f)));
}

glm::mat4 Camera::getViewMatrix()
{
return glm::lookAt(cameraPosition, cameraPosition + cameraDirection , glm::vec3(0.0f, 1.0f, 0.0f));
}

glm::vec3 Camera::getCameraPosition()
{
return cameraPosition;
}

void Camera::move(MOVE_DIRECTION direction, float speed)
{
switch (direction) {
case MOVE_FORWARD:
cameraPosition += cameraDirection * speed;
break;

case MOVE_BACKWARD:
cameraPosition -= cameraDirection * speed;
break;

case MOVE_RIGHT:
cameraPosition += glm::normalize(glm::cross(cameraDirection, glm::vec3(0.0f, 1.0f, 0.0f))) * speed;
break;

case MOVE_LEFT:
cameraPosition -= glm::normalize(glm::cross(cameraDirection, glm::vec3(0.0f, 1.0f, 0.0f))) * speed;
break;
}
}

void Camera::rotate(float pitch, float yaw)
{
glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraDirection = glm::normalize(front);
}

}

Я создал 2 камеры: одну, которая должна следовать за самолетом, и другую, которая должна применять набор преобразований на плоскости.

gps::Camera myCamera(glm::vec3(0.0f, 0.0f, 2.5f), glm::vec3(0.0f, 0.0f, -10.0f));
gps::Camera planeCamera(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -10.0f));

Это моя функция renderScene:

void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

processMovement();

//initialize the view matrix
view = myCamera.getViewMatrix();
//send view matrix data to shader
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));

//plane
model = glm::mat4(1.0f);

model = planeCamera.getViewMatrix();

glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
normalMatrix = glm::mat3(glm::inverseTranspose(view*model));
//send normal matrix data to shader
glUniformMatrix3fv(normalMatrixLoc, 1, GL_FALSE, glm::value_ptr(normalMatrix));
planeModel.Draw(myCustomShader);
}

processMovement выглядит примерно так:

void processMovement()
{
if (pressedKeys[GLFW_KEY_W]) {
myCamera.move(gps::MOVE_FORWARD, cameraSpeed);
planeCamera.move(gps::MOVE_BACKWARD, cameraSpeed);
}

if (pressedKeys[GLFW_KEY_S]) {
myCamera.move(gps::MOVE_BACKWARD, cameraSpeed);
planeCamera.move(gps::MOVE_FORWARD, cameraSpeed);
}
...
}

И это моя модель, вид, проекционные матрицы:

model = glm::mat4(1.0f);
modelLoc = glGetUniformLocation(myCustomShader.shaderProgram, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

view = myCamera.getViewMatrix();
viewLoc = glGetUniformLocation(myCustomShader.shaderProgram, "view");
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));

normalMatrix = glm::mat3(glm::inverseTranspose(view*model));
normalMatrixLoc = glGetUniformLocation(myCustomShader.shaderProgram, "normalMatrix");
glUniformMatrix3fv(normalMatrixLoc, 1, GL_FALSE, glm::value_ptr(normalMatrix));

projection = glm::perspective(glm::radians(45.0f), (float)retina_width / (float)retina_height, 0.1f, 1000.0f);
projectionLoc = glGetUniformLocation(myCustomShader.shaderProgram, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector