glm :: look当垂直相机在z <= 0时翻转 [英] glm::lookAt vertical camera flips when z &lt;= 0

查看:243
本文介绍了glm :: look当垂直相机在z <= 0时翻转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个FPS风格的相机,使用OpenGL在我的3D场景。我使用GLM的数学,我计算一个方向矢量与glm ::旋转在x轴和y轴使用鼠标移动。我有一个静态向上的向量,因为我很好在横轴上strafing,并不需要任何卷。



但是,当我向前走向负z方向,我最终到达场景的中心点(z = 0),垂直相机翻转(y方向)。向下移动鼠标现在将导致向上运动。方向向量是像他们应该这样计算的,我猜猜它与glm :: lookAt如何计算其视图矩阵?



这里是相关的代码:

  //玩家移动
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 + =速度*方向;
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);
}

//设置以下回调函数:
// glutMotionFunc(mouse);
// glutPassiveMotionFunc(mouse);
void mouse(int x,int y)
{
if(!warped)
{
float mouseSensitivity = 15.0f;

float horizo​​ntal =(width / 2) - x;
float vertical =(height / 2) - y;

horizo​​ntal / = mouseSensitivity;
vertical / = mouseSensitivity;

direction = glm :: rotate(direction,horizo​​ntal,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;
}


解决方案

我不完全确定问题是,但是当我使用LookAt的FPS凸轮我还包括一个正向单位向量。



例如(复制相关段从我有一些代码)但是我确定矩阵将有相同的结果)

  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和lookat都是vec3,视图是mat4



希望这有帮助。



编辑:我注意到你正在使用一个方向,所以我可能看看你在哪里使用旋转。 b
$ b

这将设置没有滚动的FPS凸轮的季度

  pLocalOrientation = 
glm :: angleAxis(pLocalEularAngles.x,glm :: vec3(1,0,0))*
glm :: angleAxis(pLocalEularAngles.y,glm :: vec3(0,1,0));

pLocalOrientation ==方向(示例)



如果您决定使用quats。


I'm working on a FPS style camera to fly around my 3D scene using OpenGL. I'm using GLM for the mathmetics and I calculate a direction vector with a glm::rotate on the x-axis and the y-axis using mouse movements. I have a static up vector since I'm fine with strafing on the horizontal axis and don't really need any rolls.

However, when I move forward towards the negative z direction and I eventually reach the center point of the scene (z=0) the vertical camera flips (y direction). Moving the mouse downwards will now result in an upward motion. The direction vectors are calculated like they should so I'm guessing it has something to do with how glm::lookAt calculates its view Matrix?

Here is the relevant code:

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

解决方案

I'm not entirely sure what the problem is, but when I use LookAt for an FPS cam I also include a forward unit vector.

E.g (copied relevant segments from some code I have) - using quaternions (orientation), but I'm sure matrices will have the same result)

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 and lookat are both vec3, and view is mat4

Hope this helps.

EDIT: I notice you are using a direction, so I would probably look at where you use rotate.

This will set the quat for an FPS cam with no roll

pLocalOrientation = 
    glm::angleAxis(pLocalEularAngles.x, glm::vec3(1, 0, 0)) *
    glm::angleAxis(pLocalEularAngles.y, glm::vec3(0, 1, 0));

pLocalOrientation == orientation (for the example)

If you decide to use quats.

这篇关于glm :: look当垂直相机在z <= 0时翻转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆