Wie kann ich den Klickpunkt beim Drehen unter der Maus halten? (GLM)

7

Ich habe ein sphärisches Netz mit dem Radius 1, zentriert bei (0,0,0) in Weltkoordinaten. Ich möchte die Kugel so drehen, dass der angeklickte Punkt immer unter der Maus bleibt. Ich kann jedoch keinen Algorithmus finden, der dies tut. Der angeklickte Punkt driftet immer von der Maus weg. Mein aktueller Algorithmus macht Folgendes:

Wirf einen Strahl auf eine Kugel mit Radius 1. Finde den Schnittpunkt in den Weltkoordinaten (Pa).

Nachdem die Maus bewegt wurde, werfen Sie einen weiteren Strahl und suchen Sie einen neuen Schnittpunkt. (Pb) Da sich beide 3D-Punkte auf einer Kugel mit dem Radius eins befinden und am Ursprung zentriert sind, sollten sie die Länge = 1 haben, aber nur für den Fall, dass ich beide normalisiere.

Finden Sie die Rotationsachse, indem Sie Pa x Pb ausführen. Normalisieren Sie die resultierende Achse

axis = glm::cross(Pa,Pb);
axis = glm::normalize(axis);

Finden Sie den Winkel, indem Sie Arccosin auf das Punktprodukt auftragen

float angle = glm::acos(glm::dot(Pa,Pb));  

Erstellen Sie eine Rotationsmatrix aus der Achse und dem Winkel

mat4 rotation = glm::rotate(glm::degrees(angle),axis); <-- This was the mistake glm::degrees is not needed

Multiplizieren Sie die vorhandene Modellmatrix mit dieser berechneten Matrix:

modelMatrix = rotation*modelMatrix;

Die Rotationen sind korrekt, aber der angeklickte Punkt bleibt nicht unter der Maus (ich überprüfe dies, indem ich einen schwarzen quadratischen Punkt auf die Kugeltextur zeichne, wenn das Ziehen beginnt). Wenn ich klicke und nach rechts ziehe, wird der ursprünglich angeklickte Punkt nach links verschoben (Verzögerungen).

Diagramm zur Darstellung der Drift

Jubei
quelle

Antworten:

1

Ich habe den Täter gefunden.

glm :: Grad (Winkel)

Ich hatte diese Zeile von einem Typen aus dem Internet kopiert, der aus irgendeinem Grund den Winkel in Grad umwandelte. Diese Konvertierung ist absolut nicht erforderlich.

Laut einem Benutzer von reddit: Eine Warnung zu dieser Methode verschlechtert sich Ihre Modellmatrix im Laufe der Zeit mit dieser Art von Technik (wiederholtes Multiplizieren mit einer neuen Matrix), wodurch das gerenderte Modell skaliert oder verzerrt wird. Möglicherweise möchten Sie eine Funktion zum "Fixieren" der Matrix entwickeln, indem Sie eine Technik wie das Konvertieren in ein anderes Format (Quaternion oder Euler-Winkel) und dann zurück in eine Matrix oder direkter durch Extrahieren von Matrixbasisvektoren, Orthonormalisieren und Aufkleben verwenden Werte zurück in die Matrix.

Jubei
quelle
1
Wenig verwirrt - also nimmt die glm::rotateFunktion tatsächlich Bogenmaß, nicht Grad? Ich bin mir nicht sicher, wie sich der letzte Absatz auf die endgültige Antwort bezieht.
Chaosed0
@ Chaosed0 Der letzte Absatz dient dazu, Benutzer, die diese Methode anwenden möchten, zu warnen, dass sie nicht "vollständig" ist und weitere Arbeiten erforderlich sind, um ein Verzerren / Skalieren des Modells zu vermeiden. Ich weiß nicht, was glm :: rotate braucht, da GLM sehr schlecht dokumentiert ist.
Jubei
Gotcha - habe mir gerade das Dokument für GLM angesehen, sieht aus wie ein Monster.
Chaosed0