Есть проблемы с пониманием перевода камеры в OpenGL - PullRequest
1 голос
/ 07 октября 2019

У меня возникли проблемы с пониманием перевода камеры. Я уже могу успешно вращать камеру, но я все еще не уверен в переводе камеры. Я включил код о том, как вращать камеру, так как для перевода и поворота нужно использовать функцию lookat. Домашнее задание говорит, что перевод камеры означает, что и глаз, и центр должны перемещаться с одинаковым количеством. Я понимаю, что могу изменить параметры в функции lookat, чтобы реализовать это.

Определение функции lookat приведено ниже:

Lookat(cameraPos, center, up)
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 10.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);

modelViewProjectionMatrix.Perspective(glm::radians(fov), float(width) / float(height), 0.1f, 100.0f);
modelViewProjectionMatrix.LookAt(cameraPos, center, cameraUp);
void CursorPositionCallback(GLFWwindow* lWindow, double xpos, double ypos)
{
    int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);

    if (state == GLFW_PRESS)
    {
        if (firstMouse)
        {
          lastX = xpos;
          lastY = ypos;
          firstMouse = false;
        }

        float xoffset = xpos - lastX;
        float yoffset = lastY- ypos; 
        lastX = xpos;
        lastY = ypos;

        yaw += xoffset;
        pitch += yoffset;

        glm::vec3 front;
        front.x = center[0] + 5.0f*cos(glm::radians(yaw)) * cos(glm::radians(pitch));
        front.y = center[1] + 5.0f*sin(glm::radians(pitch));
        front.z = center[1] + 5.0f*sin(glm::radians(yaw)) * cos(glm::radians(pitch));
        cameraPos = front;
    }
}

1 Ответ

1 голос
/ 07 октября 2019

Если вы хотите перевести камеру по смещению, то вы должны добавить один и тот же вектор (glm::vec3 offset) к положению камеры (cameraPos) и цели камеры (center):

center    = center    + offset;
cameraPos = cameraPos + offset;

Когда вы вычисляете новую цель камеры (center), под углом pitch и yaw, вам нужно обновить вектор вверх (cameraUp) камеры,тоже:

glm::vec3 front(
    cos(glm::radians(pitch)) * cos(glm::radians(yaw)),
    sin(glm::radians(pitch)),
    cos(glm::radians(pitch)) * sin(glm::radians(yaw))
);

glm::vec3 up(
    -sin(glm::radians(pitch)) * cos(glm::radians(yaw)),
     cos(glm::radians(pitch)),
    -sin(glm::radians(pitch)) * sin(glm::radians(yaw))
);

cameraPos = center + front * 5.0f;
cameraUp  = up;

Чтобы переместить камеру вдоль оси x (слева направо) в пространстве вида, необходимо рассчитать вектор вправо по Перекрестное произведение векторак цели (front) и вектору вверх (cameraUp или up):

glm::vec3 right = glm::cross(front, up);

Ось Y (снизу вверх) в пространстве обзора является вектором вверх.

Для перевода относительно скаляров (float trans_x) и (trans_y), масштабированный вектор right и up должен быть добавлен к положению камеры (cameraPos) и цели камеры (center):

center    = center    + right * trans_x + up * trans_y;
cameraPos = cameraPos + right * trans_x + up * trans_y;

Используйте управляемые векторы для установки матрицы вида:

modelViewProjectionMatrix.LookAt(cameraPos, center, cameraUp);
...