2017-02-12 17 views
0

Для удовольствия я сделал 3d-камеру в opengl. Он работает хорошо, за исключением того, что я не могу понять, как ограничить вращение вокруг оси x. Если вы слишком много прокручиваете, элементы управления вверх и вниз будут инвертироваться. Я попытался ограничить переменную camFront.y произвольным значением, но камера все равно перевернет ось x.Ограничение вращения вокруг оси x в opengl

Вот мой код:

#ifndef CAMERA_H 
#define CAMERA_H 

#include <GL/glew.h> 

#include <GLFW/glfw3.h> 

#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/quaternion.hpp> 
#include <glm/gtx/quaternion.hpp> 

#define WORLD_UP glm::vec3(0.0f, 1.0f, 0.0f) 

#include <iostream> 


enum CamDirection { 
    CAM_FORWARD, 
    CAM_BACKWARD, 
    CAM_LEFT, 
    CAM_RIGHT 
}; 


class Camera { 
public: 
    void cameraUpdate(); 

    glm::mat4 getViewMatrix(); 

    Camera(); 

    Camera(glm::vec3 startPosition); 

    void move(CamDirection dir, GLfloat deltaTime); 

    void look(double xOffset, double yOffset); 

    void update(); 

private: 

    glm::vec3 camPos; 
    glm::vec3 camFront; 
    glm::vec3 camUp; 
    glm::vec3 camRight; 

    const GLfloat camSpeed = 5.05f; 

}; 

glm::mat4 Camera::getViewMatrix() { 
    return glm::lookAt(camPos, camPos + camFront, camUp); 
} 

Camera::Camera(): 
    camPos (glm::vec3(0.0f, 0.0f, 0.0f)), 
    camFront(glm::vec3(0.0f, 0.0f, -1.0f)), 
    camUp (WORLD_UP) 
{} 

Camera::Camera(glm::vec3 startPos): 
    camPos (startPos), 
    camFront (glm::vec3(0.0f, 0.0f, -1.0f)), 
    camUp (WORLD_UP) 
{} 

void Camera::move(CamDirection dir, GLfloat deltaTime) { 
    const GLfloat v = camSpeed * deltaTime; 
    if (dir == CAM_FORWARD) 
     camPos += v * camFront; 
    else if (dir == CAM_BACKWARD) 
     camPos -= v * camFront; 
    else if (dir == CAM_RIGHT) 
     camPos += v * camRight; 
    else 
     camPos -= v * camRight; 
} 
void Camera::look(double xOffset, double yOffset) { 
    glm::quat startQuat = {0, camFront.x, camFront.y, camFront.z}; 

    glm::quat rotation = glm::angleAxis((GLfloat)xOffset, glm::vec3(0.0f, 1.0f, 0.0f)); 
    glm::quat view = startQuat * rotation; 

    rotation = glm::angleAxis((GLfloat)yOffset, glm::vec3(-1.0f, 0.0f, 0.0f)); 
    view = view * rotation; 

    camFront = glm::vec3(view.x, view.y, view.z); 
    std::cerr << camFront.x << ' ' << camFront.y << ' ' << camFront.z << std::endl; 

} 

void Camera::update() { 
     // Also re-calculate the Right and Up vector 
     camRight = glm::normalize(glm::cross(camFront, WORLD_UP)); // Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement. 
     camUp = glm::normalize(glm::cross(camRight, camFront)); 
} 
#endif // CAMERA_H 

Как я могу это исправить?

ответ

0

Вам необходимо ограничить view.y и view.z значениями, прежде чем назначать их camFront, чтобы они составляли максимум 89 градусов и не менее -89 градусов. При 90 и -90 градусах он начинает инвертироваться. Таким образом, может быть очень простой подход,

if(view.y > 89) 
{ 
    view.y = 89; 
} 
if(view.y < -89) 
{ 
    view.y = -89; 
} 
if(view.z > 89) 
{ 
    view.z = 89; 
} 
if(view.z < -89) 
{ 
    view.z = -89; 
}