Wie übersetze ich Mausbewegungen in ein Rotations-Gizmo?

7

Ich muss Übersetzungs-, Skalierungs- und Rotations-Gizmos implementieren und habe Probleme mit dem Rotations-Gizmo. Grundsätzlich weiß ich nicht, wie ich die Mausbewegung übersetzen soll, um zu bestimmen, in welche Richtung das Objekt gedreht werden soll.

Mit Rotations-Gizmo (Widget) meine ich so etwas wie das Folgende:

Geben Sie hier die Bildbeschreibung ein

Für die Übersetzungs- und Skalierungs-Gizmos, die als 3 Achsen dargestellt werden, mache ich Folgendes: Ich mache einen Vektor aus der Differenz zwischen der vorherigen und der aktuellen Mausposition im Bildschirmbereich. Dann multiplizieren Sie diesen Vektor mit der Umkehrung der Ansichts- und Projektionsmatrizen, was mir einen Vektor der Mausbewegung im Weltraum gibt. Dann nehme ich das Punktprodukt des Vektors im Weltraum mit der ausgewählten Achse. Auf diese Weise kann ich feststellen, ob die Mausbewegung mit der Achse übereinstimmt oder von der Achse entfernt ist.

Aber ich kann nicht dasselbe für das Rotations-Gizmo tun. Das Rotations-Gizmo wird als 3 Kreise dargestellt, die jeweils eine Rotation um eine Achse darstellen. Sobald auf einen Kreis geklickt wird, muss ich eine Möglichkeit finden, die Mausbewegung zu verschieben, um zu bestimmen, in welche Richtung das Objekt um die ausgewählte Achse gedreht werden soll. Ich weiß nicht, wie ich das machen soll. Bitte helfen Sie.

Es ist wichtig zu beachten, dass ich die Farbauswahl und nicht das Raycasting verwende, um festzustellen, wo auf das Gizmo geklickt wurde. Dies bedeutet, dass ich nicht den Punkt habe, an dem der Strahl auf das Gizmo im Weltraum trifft, um anzufangen. Ich erwähne dies, weil ich mir Beispiele angesehen habe, die Raycasting wie libgizmo verwenden, und ich glaube nicht, dass ich das Gleiche tun kann.

Vielen Dank im Voraus für jede Hilfe.

0xfeedbacc
quelle
2
Ich brauchte eine Sekunde, um zu verstehen, was Sie mit einem Rotations-Gizmo meinten. Ich habe ein Bild von einem hinzugefügt, falls es hilfreich ist (ich denke, Sie können keine Bilder hinzufügen, bis Sie leider mehr Ruf haben!). Wenn Sie ein passenderes Bild im Sinn haben, können Sie es mich gerne wissen lassen und ich kann das Bild ändern.
Alan Wolfe
Vielen Dank für das Hinzufügen des Bildes Alan. Sie haben Recht, ich denke, es wird die Dinge klarer machen.
0xfeedbacc
Fwiw Ich denke du hast recht. Die Verwendung der farbbasierten Auswahl funktioniert hierfür nicht.
Alan Wolfe

Antworten:

2

Ordnen Sie die Mausposition dem Kreis zu, indem Sie eine imaginäre Linie zwischen der Maus und dem Mittelpunkt des Gizmos in der Ebene des aktuellen Kreises zeichnen. Tun Sie dies für die Start- und aktuellen Positionen.

Dann können Sie leicht die Quaternion-Rotation um die Mitte vom Anfang bis zum Ende erhalten, indem Sie dies tun normalize(quat(1+dot(v_1, v_2), cross(v_1, v_2))).

Dies funktioniert, weil das Punktprodukt der cos des Winkels zwischen den Vektoren ist und das Kreuz der Vektor senkrecht zu den 2 Vektoren ist (auch bekannt als der Drehwinkel) und die Länge der Sünde des Winkels zwischen den Vektoren hat. Dies bedeutet, dass Sie die doppelte Quaternion daraus erstellen können. Dann können Sie diese doppelte Quaternion mit der Einheitsquaternion verknüpfen, um die Rotation zu erhalten, die Sie benötigen.

Mit diesen Informationen können Sie jedoch einen Arcball erstellen, indem Sie die Maus auf den Ball projizieren, der das Gizmo ist, und auf diese Weise die Start- und Endvektoren verwenden.

Ratschenfreak
quelle
Diese Antwort braucht wirklich ein Bild
joojaa
2

Die Antwort von Ratchet Freak könnte funktionieren. Ich bin mir nicht sicher, ich habe nicht viel Zeit damit verbracht, weil ich nicht wusste, wie ich die Quaternion aus dem Punkt- und Kreuzprodukt wie beschrieben erstellen kann.

Was wir letztendlich gemacht haben war:

  • Projizieren Sie die Mitte des Gizmos auf den Bildschirmbereich.

  • Ermitteln Sie den Winkel zwischen den Vektoren GizmoToLastMouse und GizmoToCurrentMouse mithilfe der Punktproduktformel: acos (Punkt (GizmoToLastMouse, GizmoToCurrentMouse) / (GizmoToLastMouse.Length () * GizmoToCurrentMouse.Length ()))

  • Ermitteln Sie das Vorzeichen des Winkels, indem Sie das Kreuz aus GizmoToLastMouse und GizmoToCurrentMouse nehmen und es mit dem normalen Bildschirm punktieren.

  • Erhalten Sie ein weiteres Zeichen (mal 1.0f oder -1.0f) basierend auf der Ausrichtung des Gizmos, indem Sie das Punktprodukt zwischen der gedrehten Achse und einem Vektor von der Mitte des Gizmos zur Kamera bringen

  • Wenden Sie die Drehung basierend auf dem Winkel und den beiden Vorzeichen auf die entsprechende Achse an

Es gibt vielleicht einen besseren Weg, dies zu tun, aber dies funktioniert ziemlich gut für unsere Bedürfnisse.

0xfeedbacc
quelle
Eine Quaternion wird aufgebaut als quat(cos(angle/2), axis*sin(angle/2))und Sie wissen, dass das Punktprodukt uns gleich cos (Winkel) mal dem Produkt der Längen und das Kreuzprodukt die Achse mal sin (Winkel) mal das Produkt der Längen ist. Wenn Sie es normalisieren, erhalten Sie leicht die Quaternion derselben Drehung, jedoch mit doppeltem Winkel. Um die richtige quaternion erhalten Sie tun können , slerp(unit, quat, 0.5)die nach dem Ende nach oben als inliningnormalize(unit+quat);
Ratsche Freak