c++ - ejemplo - glm:: lookAt cámara vertical voltea cuando z<= 0
glulookat como funciona (1)
Estoy trabajando en una cámara de estilo FPS para volar alrededor de mi escena 3D usando OpenGL. Estoy usando GLM para los mathmetics y calculo un vector de dirección con un glm :: rotate en el eje xy el eje y usando los movimientos del mouse. Tengo un vector estático, ya que estoy bien con ametrallamiento en el eje horizontal y realmente no necesito ningún rollo.
Sin embargo, cuando avanzo hacia la dirección z negativa y finalmente llego al punto central de la escena (z = 0) la cámara vertical se voltea (dirección y). Mover el mouse hacia abajo ahora dará como resultado un movimiento hacia arriba. Los vectores de dirección se calculan como deberían, así que supongo que tiene algo que ver con cómo glm :: look ¿Calcula su matriz de vista?
Aquí está el código relevante:
// Player movement
glm::vec3 position(0.0f, 0.0f, 5.0f);
glm::vec3 direction(0.0f, 0.0f, -1.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
float speed = 0.05f;
bool warped = false;
...
void render()
{
...
view = glm::lookAt(position, position + direction, up);
glUniformMatrix4fv(glGetUniformLocation(basicShader.shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
...
}
void handleKeyboard()
{
float speed = 0.05f;
if(keys[''w''])
position += speed * direction;
if(keys[''s''])
position -= speed * direction;
if(keys[''a''])
position -= speed * glm::cross(direction, up);
if(keys[''d''])
position += speed * glm::cross(direction, up);
if(keys[''q''])
exit(1);
}
// Set with following callbacks:
// glutMotionFunc(mouse);
// glutPassiveMotionFunc(mouse);
void mouse(int x, int y)
{
if(!warped)
{
float mouseSensitivity = 15.0f;
float horizontal = (width / 2) - x;
float vertical = (height / 2) - y;
horizontal /= mouseSensitivity;
vertical /= mouseSensitivity;
direction = glm::rotate(direction, horizontal, glm::vec3(0.0f, 1.0f, 0.0f));
direction = glm::rotate(direction, vertical, glm::vec3(1.0f, 0.0f, 0.0f));
warped = true;
glutWarpPointer((width / 2), (height / 2));
}
else
warped = false;
}
No estoy del todo seguro de cuál es el problema, pero cuando uso LookAt para una cámara FPS también incluyo un vector de unidad hacia adelante.
Por ejemplo, (copié segmentos relevantes de algún código que tengo) - usando cuaterniones (orientación), pero estoy seguro de que las matrices tendrán el mismo resultado.
static glm::vec3 defaultUpVector() { return glm::vec3(0, 1, 0); }
static glm::vec3 defaultForwardVector() { return glm::vec3(0, 0, -1); }
pUpVector = defaultUpVector() * orientation;
pLookAt = position + (defaultForwardVector() * orientation);
pView = glm::lookAt(position, pLookAt, pUpVector);
upvector y lookat son ambos vec3, y view es mat4
Espero que esto ayude.
EDITAR: Noté que estás usando una dirección, por lo que probablemente miraría en dónde usas rotar.
Esto configurará el quat para una cámara FPS sin rollo
pLocalOrientation =
glm::angleAxis(pLocalEularAngles.x, glm::vec3(1, 0, 0)) *
glm::angleAxis(pLocalEularAngles.y, glm::vec3(0, 1, 0));
Orientación pLocalOrientation == (por ejemplo)
Si decides usar quats.