5

私は Open GL と c++ を初めて使用し、一人称カメラを作成するという問題に遭遇しました。私は行列計算を理解していないので、それが私にとってさらに難しくなっています。これまでのところ、カメラの回転を計算するために、次のことを行いました。

void CameraFP::calculate_view()  {
    m_view = glm::rotate(m_view, this->get_rotation_x(), glm::vec3(1, 0, 0));
    m_view = glm::rotate(m_view, this->get_rotation_y(), glm::vec3(0, 1, 0));
}

その関数は、更新呼び出しごとに呼び出されます。

マウスを介してカメラの回転を処理するために、次のことを行いました。

void CameraFP::process_mouse(sf::Window *app)  {
    GLfloat mouse_x = app->GetInput().GetMouseX();
    GLfloat mouse_y = app->GetInput().GetMouseY();

    GLfloat mouse_x_delta = std::max(mouse_x, old_mouse_x) - std::min(mouse_x, old_mouse_x);
    GLfloat mouse_y_delta = std::max(mouse_y, old_mouse_y) - std::min(mouse_y, old_mouse_y);

    y_rot += mouse_x_delta / (float)app->GetWidth();
    x_rot += mouse_y_delta / (float)app->GetHeight();

    this->old_mouse_x = mouse_x;
    this->old_mouse_y = mouse_y;

    app->SetCursorPosition(app->GetWidth() / 2, app->GetHeight() / 2);
}

動きを処理するために、次のことを行いました。

void CameraFP::process_keyboard(sf::Window *app)  {
    const sf::Input *input = &app->GetInput();

    if (input->IsKeyDown(sf::Key::W))  {
        position.z += 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        position.z -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        position.x -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        position.x += 1.0f / 100.0f;
    }
}

私の問題は、私のカメラがあなたが向いている方向に動かず、回転が止まらないという事実にあります:/。また、マトリックス数学のガイドまたは何かを教えていただければ、素晴らしいでしょう:)

編集 2: '

私はちょうど新しいプロセスマウス機能を開始しました.それはカメラのy回転として画面のx軸に沿った動きです. ただし、マウスを左に動かしても右に動かしても関係ありません。どちらの動きでも右に回転します。3D 空間の x 軸と同じですが、これは下向きになります。これを引き起こしている原因についてのアイデアはありますか?

void CameraFP::process_mouse(sf::Window *app)  {
    GLfloat mouse_x = app->GetInput().GetMouseX();
    GLfloat mouse_y = app->GetInput().GetMouseY();

    GLfloat mouse_x_delta = old_mouse_x - mouse_x;
    GLfloat mouse_y_delta = old_mouse_y - mouse_y;

    if (mouse_x_delta > 0)  {
        y_rot += mouse_x_delta / (float)app->GetWidth() * 0.1f;
    } else if (mouse_x_delta < 0)  {
        y_rot -= mouse_x_delta / (float)app->GetWidth() * 0.1f;
    }
    if (mouse_y_delta > 0)  {
        x_rot += mouse_y_delta / (float)app->GetWidth() * 0.1f;
    } else if (mouse_y_delta < 0)  {
        x_rot -= mouse_y_delta / (float)app->GetWidth() * 0.1f;
    }


    if (mouse_x != old_mouse_x)  {
        m_view = glm::rotate(m_view, y_rot, glm::vec3(0, 1, 0));
    }
    if (mouse_y != old_mouse_y)  {
        m_view = glm::rotate(m_view, x_rot, glm::vec3(1, 0, 0));
    }

    this->old_mouse_x = mouse_x;
    this->old_mouse_y = mouse_y;

    app->SetCursorPosition(app->GetWidth() / 2, app->GetHeight() / 2);
}
4

2 に答える 2

0

あなたはpositionin CameraFPandの使用法を示していませんでしたが、m_viewここで問題があると思います:

void CameraFP::process_keyboard(sf::Window *app)  {
    const sf::Input *input = &app->GetInput();

    if (input->IsKeyDown(sf::Key::W))  {
        position.z += 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        position.z -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        position.x -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        position.x += 1.0f / 100.0f;
    }
}

行列をこの変換で乗算し、 を乗算する必要がありm_viewます。行列の乗算では、行列の重要な順序です。最初m_viewはメイン マトリックスであるため、m_viewローテーションから前に移動する必要があります。しかし、glm名前空間があり、glm::translateそれらが正しい順序で乗算されるメソッドがglm::vec3あり、そのメソッドのパラメーターとして作成するだけです (x、y、z の変換)。

(相対位置を使用する場合...フレーム間の違いのみ)

したがって、次のように変更する必要があります。

void CameraFP::process_keyboard(sf::Window *app)  {
    const sf::Input *input = &app->GetInput();

    glm::vec3 pos;
    if (input->IsKeyDown(sf::Key::W))  {
        pos.z += 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        pos.z -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        pos.x -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        pos.x += 1.0f / 100.0f;
    }

    //Make translation
    m_view = glm::translate(m_view, pos);

    //Values at position 12, 13, 14 are translation x, y, z
    //Save absolute position of camera
    position = glm::vec3(m_view[12], m_view[13], m_view[14]);

}

PS: 下手な英語で申し訳ありません。

于 2013-06-27T19:47:30.560 に答える
0

現時点ではカメラのコードを探す時間がありませんが、今言えることは、あなたの動きの計算が単に間違っているということです。
カメラの回転を考慮していません。次のようなことをしなければなりません:

if (input->IsKeyDown(sf::Key::W))  {
    position.z += sin(camera_rot_y);
}
else if (input->IsKeyDown(sf::Key::S))  {
    position.z -=  sin(camera_rot_y);
}

if (input->IsKeyDown(sf::Key::A))  {
    position.x -=  cos(camera_rot_y);
}
else if (input->IsKeyDown(sf::Key::D))  {
    position.x +=  cos(camera_rot_y);
}

また、同時に進むことと戻ることはできないため、"else if" を使用することもできます。^^

また、なぜ次のコードで std::min() と max() を使用しているのですか?:

GLfloat mouse_x_delta = std::max(mouse_x, old_mouse_x) - std::min(mouse_x, old_mouse_x);
GLfloat mouse_y_delta = std::max(mouse_y, old_mouse_y) - std::min(mouse_y, old_mouse_y);

反対方向に回転させたい場合は、負のデルタを取得する必要がありますが、これはコードでは不可能です。min() および max() 関数を取り除きます。

ところで: 私のカメラ コードは最も効率的ではありません (直接計算の代わりに回転を使用します) が、動作します。

于 2013-02-21T15:48:45.063 に答える