Drehen eines Open GL Kamera korrekt mit GLM

Ich habe eine Kamera-Klasse, die initialisiert wird, etwa so:

CameraFP::CameraFP()  {
    this->aspect_ratio = 800.0f / 600.0f;
    this->fov = 45.0f;
    this->near_plane = 0.1f;
    this->far_plane = 1000.0f;
    this->position = glm::vec3(0, 0, 0);
    this->target = position + glm::vec3(0, 0, -1);
    this->up = glm::vec3(0, 1, 0);
    this->m_rotation = glm::mat4(1.0);

    m_view = glm::lookAt(position, target, up);
    m_projection = glm::perspective(fov, aspect_ratio, near_plane, far_plane);
}

Und hier sind andere Funktionen importieren:

void CameraFP::update(sf::Window *app)  {
    process_keyboard(app);
    process_mouse(app);

    calculate_view();
}

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

    up = m_rotation * glm::vec3(0, 1, 0);

    glm::vec3 forward = glm::vec3(0, 0, -1);
    glm::vec3 forward_rotated = m_rotation * forward;

    glm::vec3 right = glm::vec3(1, 0, 0);
    glm::vec3 right_rotated = m_rotation * right;

    if (input->IsKeyDown(sf::Key::W))  {
        position += forward_rotated;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        position -= forward_rotated;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        position -= right_rotated;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        position += right_rotated;
    }
}

void CameraFP::process_mouse(sf::Window *app)  {
    //TODO: Make the below constants, and take framerate into account
    GLfloat SPEED_X = 0.000001f;
    GLfloat SPEED_Y = 0.000001f;

    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 ||
        mouse_y_delta != 0)  {
        if (mouse_x_delta != 0)  {
            y_rot += mouse_x_delta * SPEED_X;

            m_rotation = glm::rotate(m_rotation, y_rot, glm::vec3(0, 1, 0));
        }
        if (mouse_y_delta != 0)  {
            x_rot += mouse_y_delta * SPEED_Y;

            m_rotation = glm::rotate(m_rotation, 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);
}


void CameraFP::calculate_view()  {
    glm::vec3 forward = glm::vec3(0, 0, -1);
    glm::vec3 forward_rotated = m_rotation * forward;

    target = position += glm::normalize(forward_rotated);

    m_view = glm::lookAt(position, target, up);
}

Mein problem ist, dass wenn ich das Projekt kompilieren, wird der compiler gibt eine Fehlermeldung:

\CameraFP.cpp|59|error: no match for 'operator*' in '((CameraFP*)this)->CameraFP::m_rotation * glm::detail::tvec3<float>(((const int&)((const int*)(&0))), ((const int&)((const int*)(&1))), ((const int&)((const int*)(&0))))'|

Was ich verstehen vec = mat4 * vec Rendite einer gedrehten Vektor? Da ich nicht in der Lage diesen code zu testen, ich weiß nicht, ob die Funktion ordnungsgemäß funktioniert.

Bearbeiten

Aktualisiert code anhand der Kommentare und awnsers. Mein problem ist jetzt, ich bekomme ein BSOD, irgendwo in der render-Funktion...

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

    up = m_rotation * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f);

    glm::vec4 forward = glm::vec4(0.0f, 0.0f, -1.0f, 0.0f);
    glm::vec4 forward_rotated = m_rotation * forward;

    glm::vec4 right = glm::vec4(1.0f, 0.0f, 0.0f, 0.0f);
    glm::vec4 right_rotated = m_rotation * right;

    if (input->IsKeyDown(sf::Key::W))  {
        position += forward_rotated;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        position -= forward_rotated;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        position -= right_rotated;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        position += right_rotated;
    }
}

void CameraFP::process_mouse(sf::Window *app)  {
    //TODO: Make the below constants, and take framerate into account
    GLfloat SPEED_X = 0.000001f;
    GLfloat SPEED_Y = 0.000001f;

    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 ||
        mouse_y_delta != 0)  {
        if (mouse_x_delta != 0)  {
            y_rot += mouse_x_delta * SPEED_X;

            m_rotation = glm::rotate(m_rotation, y_rot, glm::vec3(0.0f, 1.0f, 0.0f));
        }
        if (mouse_y_delta != 0)  {
            x_rot += mouse_y_delta * SPEED_Y;

            m_rotation = glm::rotate(m_rotation, x_rot, glm::vec3(1.0f, 0.0f, 0.0f));;
        }
    }

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

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

void CameraFP::calculate_view()  {
    glm::vec4 forward = glm::vec4(0.0f, 0.0f, -1.0f, 0.0f);
    glm::vec4 forward_rotated = m_rotation * forward;

    target = position += forward_rotated;

    m_view = glm::lookAt(v4tov3(position), v4tov3(target), v4tov3(up));
}

glm::vec3 v4tov3(glm::vec4 v1)  {
    return glm::vec3(v1.x, v1.y, v1.z);
}

Edit 2

Problem ist jetzt mit der rotation der Kamera mit der Maus, es funktioniert einfach nicht, für einige Grund änderungen auf der x-Achse oft ein Wechsel auf dem y und Umgekehrt. Außerdem, wenn ich bewegen Sie die Maus rechts oder Links auf der x-Achse (y-rotation), die Kamera dreht sich nach Links...

void CameraFP::process_mouse(sf::Clock *clock, sf::Window *app)  {
    //TODO: Make the below constants, and take framerate into account
    GLfloat SPEED_X = 0.25f;
    GLfloat SPEED_Y = 0.25f;

    GLfloat screen_x = app->GetWidth();
    GLfloat screen_y = app->GetHeight();

    GLfloat mouse_x = float(screen_x / 2 - app->GetInput().GetMouseX());
    GLfloat mouse_y = float(screen_y / 2 - app->GetInput().GetMouseY());

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

    GLfloat current_time = clock->GetElapsedTime();
    GLfloat delta_time = current_time - last_time;

    this->last_time = current_time;

    if (mouse_x_delta != 0 ||
        mouse_y_delta != 0)  {
        if (mouse_x_delta != 0)  {
            y_rot += glm::radians(delta_time * SPEED_X * mouse_x);

            m_rotation = glm::rotate(m_rotation, y_rot, glm::vec3(0.0f, 1.0f, 0.0f));

            std::cout << "Y Rotation: " << y_rot << "\n";
        }
        if (mouse_y_delta != 0)  {
            x_rot += glm::radians(delta_time * SPEED_Y * mouse_y);

            m_rotation = glm::rotate(m_rotation, x_rot, glm::vec3(1.0f, 0.0f, 0.0f));

            std::cout << "X rotation: " << x_rot << "\n";
        }
    }

    app->SetCursorPosition(screen_x / 2, screen_y / 2);

    this->old_mouse_x = float(screen_x / 2 - app->GetInput().GetMouseX());
    this->old_mouse_y = float(screen_y / 2 - app->GetInput().GetMouseY());
}
Der operator * für mat4*vec3 nicht gefunden. m_rotation ist ein mat4 und forward ist ein vec3. Ich denke, es sollte eine vec4.
Aber, bin ich nicht gemeint, um Positionen zu vertreten, als vec3s? Ich glaube nicht, dass ich sollte halten Gießen zwischen glm::vec3 und glm::vec4 die ganze Zeit. Soll ich mich mit einem glm::mat3 repräsentieren meine rotation?
Normalerweise homogene Koordinaten verwendet werden, und damit alle Vektoren und Matrizen haben die dimension 4. Für die Vektoren der letzten Koordinate aufgerufen wird w-koordinieren und zu 1. So brauchen Sie nicht zu werfen vec3, vec4. Verwenden Sie einfach vec4, und legen Sie die 4. Koordinate 1. Für weitere Informationen schauen Sie unter en.wikipedia.org/wiki/Homogeneous_coordinates

InformationsquelleAutor Darestium | 2012-08-27

Schreibe einen Kommentar