1

OpenGL を使用して 3D シーンを飛び回る FPS スタイルのカメラに取り組んでいます。私は数学に GLM を使用しており、マウスの動きを使用して、x 軸と y 軸に glm::rotate を使用して方向ベクトルを計算します。水平軸での機銃掃射に問題がなく、実際にロールを必要としないため、静的なアップ ベクトルがあります。

ただし、負の z 方向に向かって前進し、最終的にシーンの中心点 (z=0) に到達すると、垂直カメラが反転します (y 方向)。マウスを下に移動すると、上に移動します。方向ベクトルは本来あるべきように計算されるので、glm::lookAt がそのビュー マトリックスを計算する方法と関係があると思いますか?

関連するコードは次のとおりです。

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

1 に答える 1

4

何が問題なのか完全にはわかりませんが、FPS カムに LookAt を使用するときは、フォワード ユニット ベクトルも含めます。

例(私が持っているいくつかのコードから関連するセグメントをコピーしました)-クォータニオン(方向)を使用しますが、マトリックスは同じ結果になると確信しています)

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 で、view は mat4 です。

お役に立てれば。

編集:方向を使用していることに気付いたので、おそらく回転を使用する場所を確認します。

これにより、ロールのない FPS カムのクォートが設定されます

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

pLocalOrientation == 向き (例)

quats を使用することにした場合。

于 2013-07-23T16:29:15.380 に答える