Ich versuche, eine Kamera um einen Punkt im Raum, so etwas zu drehen:um die falsche Achse dreht
Wo der rote Punkt das Zentrum das so etwas wie ein sein, wird in der Regel gehen Objekt.
Der Benutzer kann die Kamera mit der Maus drehen, wobei sich die vertikale Bewegung vertikal (x-Achse) und die horizontale horizontal (y-Achse) drehen sollte.
Was ich
Rotationen auf der y-Achse wollen, sind immer auf die offensichtlich y-Achse der Kamera und gleichen mit x. Wenn der Benutzer beispielsweise die Maus nach oben bewegt, sollte er immer so aussehen, als ob Sie sich über das Objekt bewegen, auf das sich die Kamera konzentriert. Wenn der Benutzer die Maus von links nach rechts bewegt, sollte es so aussehen, als ob sich das Objekt auf seiner Y-Achse dreht (oder dass sich die Kamera um ihre Y-Achse bewegt).
Wenn also der Benutzer die Maus ein wenig nach links bewegt und dann anfängt, ihn nach oben zu bewegen, sollte er immer noch so aussehen, als würde er aus der neuen Perspektive über das Objekt hinausgehen, statt sich in einem Winkel zu drehen die tatsächliche x-Achse der Welt.
Dies scheint Standard in den meisten 3D-Software, die ich zum Beispiel verwendet habe.
Was ich versucht habe
Mit Hilfe von vielen Fragen hier, habe ich ziemlich nahe gekommen, was ich will, aber nicht ganz.
Für folgende Bits des Codes: view_
die Matrix 4x4 Ansicht ist, origin_
die Stelle im Bild würden wir um sind zu drehen, ist position_
die blaue Linie in dem Bild darstellt, wie weit zurück die Kamera vom Ursprung (oder ein Kameraschwenk, aber das ist noch nicht implementiert), und pitch
, yaw
und roll
sind die Beträge, die wir drehen möchten (in diesem Fall ist roll immer Null).
Mein bestes Ergebnis war bisher mit diesem:
// rotation_ is a vec3 here
rotation_ += glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll));
glm::mat4 rot = glm::rotate(glm::mat4(1.0f), rotation_.x, glm::vec3(1.0f, 0.0f, 0.0f));
rot = glm::rotate(rot, rotation_.y, glm::vec3(0.0f, 1.0f, 0.0f));
rot = glm::rotate(rot, rotation_.z, glm::vec3(0.0f, 0.0f, 1.0f));
view_ = glm::translate(glm::translate(glm::mat4(1.0f), position_) * rot, origin_);
schließen, aber Drehen von ~ 90 Grad entlang der x-Achse verursacht weitere Drehungen um die y-Achse erscheinen um die z-Achse zu sein. Ich kann das nicht mit der y-Achse zur x-Achse replizieren, also bin ich neugierig, ob das tatsächlich eine kardanische Sperre oder etwas anderes ist.
Um dies zu lösen, habe ich versucht, rotation_
als Quaternion, und bekam die Rotation wie folgt zu speichern:
// rotation_ is a quaternion here.
rotation_ *= glm::fquat(glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll)));
glm::vec3(1.0f, 0.0f, 0.0f));
view_ = glm::translate(glm::translate(glm::mat4(1.0f), position_) * rot, origin_);
Dies ist eigentlich noch schlimmer. Es sieht so aus, als würde ich immer um die Achsen der Welt rotieren und nicht durch die Ausrichtung der Kamera, was ich nicht will.
Wie kann ich die Kamera auf immer schauen, wie es vertikal dreht, wenn die Maus/unten nach oben bewegt, und immer schauen, wie es horizontal dreht, wenn nach links/rechts zu verschieben?
@immibis Falls Sie es verpasst haben, habe ich eine Quaternion-Lösung versucht, und ich vermute, dass die Antwort wahrscheinlich Quaternionen beinhalten wird. Ich gebe zu, dass ich nicht das tiefste Verständnis von Quaternionen habe, aber ich kenne die Grundlagen und habe sie schon mehrmals benutzt. – Claytorpedo