2017-02-12 5 views
0

Pour le plaisir, j'ai fait un appareil photo 3D en opengl. Cela fonctionne bien, sauf le fait que je ne peux pas comprendre comment limiter la rotation autour de l'axe des x. Si vous faites défiler trop, les commandes haut et bas s'inverseront. J'ai essayé de limiter la variable camFront.y à une valeur arbitraire, mais la caméra retournera toujours sur l'axe des x.Limiter la rotation autour de l'axe des x dans opengl

Voici mon code:

#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 

Comment puis-je résoudre ce problème?

Répondre

0

Vous devez limiter view.y et view.z valeurs avant de les affecter à camFront, être max 89 degrés et minimum -89 degrés. À 90 et -90 degrés, il commence à inverser. Donc, une approche très simple pourrait être,

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; 
}