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());
}
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_coordinatesInformationsquelleAutor Darestium | 2012-08-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Alle ersetzen, glm::vec3(0, 1, 0); glm::vec3(0.0 f, 1.0 f, 0.0 f);
Als für die vec-mac-Multiplikation, AquilaRapax ist Recht, dass kann man nur multiplizieren einer mat4 mit einem vec4. Da Sie aber die Multiplikation Richtungen, die 4 koordiniert werden sollte, 0.0 f, nicht 1.0 f. Diese haben die Wirkung zu ignorieren, die übersetzungen (1.0 Tekkiner Sie berücksichtigen, was Sie nicht wollen)
Sehen http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/ für details auf Matrizen.
Jedoch, es ist oft eine gute Idee zu halten vec3 statt vec4 ist, vor allem für die übersichtlichkeit (d.h., glm::vec3 mPosition statt glm::vec4 mPosition). Es ist so praktisch, um 2 Funktionen wie diese (ungetestet) :
Also ich haben werde, um meine position (und alle meine anderen Vektoren) vec4? Da muss ich verändern, zum Beispiel, wird der forward-Vektor durch die drehmatrix, dann muss ich anwenden, das gedrehte Vektor auf die position. Und in dem Fall für die Richtungen, die ich haben werde, um die 0.0 f als letzten parameter an, und für die position und die Ziele, 1.0 f?
zB. in der calculate_view Funktion ich haben werde, so etwas wie dieses: pastebin.com/6F0gh8dG ... Mein computer stürzt ab, wenn ich ausführen, dass 😐
Ersetzen +=+ ?
Wow!!! Es doesn T geben mir ein BSOD! Danke... Mein problem scheint nun zu sein, die Maus, egal in welche Richtung bewege ich die Maus auf der x-Achse habe ich immer rechts, egal in welche Richtung ich die Maus bewegen auf der y-Achse, es sieht immer nach unten... mmm...
InformationsquelleAutor Calvin1602
Ende
process::mouse
Sie speichern die Koordinaten inold_mouse_x
undold_mouse_y
aber dann bewegen Sie den cursor auf die Mitte des Bildschirms. Wenn Sie dies tunold_mouse_x
undold_mouse_y
ungültig wird. Was Sie tun müssen, ist, legen Sie diese Variablen nach der Neupositionierung des Cursors:InformationsquelleAutor bari