C# Rotation einer Kamera im 3D Raum zur Ebene

Rossibaer

Lieutenant
Registriert
Apr. 2007
Beiträge
754
Hallo zusammen,

ich versuche mich gerade an einem "Spiel". Ich verwende OpenTK. Bin da auf ein für mich unlösbares Problem gestossen. Hier der Code erstmal:

Code:
        private void Rotate(Plane plane)
        {
            Quaternion orientation = _camera.Orientation;
            Vector3 normal = plane.Normal;
            Vector3 dir = Vector3.UnitY;
            Vector3.Transform(ref dir, ref orientation, out dir);
            dir = dir.Normalized();
            float cos = MathUtil.Dot(ref dir, ref normal);
            if (Math.Abs(cos) > 0.999f || Math.Abs(cos) < 0.001f)
                return;
            Vector3 axis = MathUtil.Cross(ref dir, ref normal);
            if (axis.Equals(Vector3.Zero))
                return;
            Quaternion rotation = new Quaternion(axis.X, axis.Y, axis.Z, cos);
            rotation.W += rotation.Length;
            rotation = rotation.Normalized();
            _camera.Rotate(rotation);
        }

Es soll ein Autorennspiel aus der Ich-Perspektive werden, d.h. die Sicht ist aus dem Auto heraus.

Nun "fahre" ich einen Berg hoch. Die Kamera soll sich nun parallel zur Ebene drehen. Aus diesem Zweck dachte ich mir, ich nehme den Einheitsvektor von Y (dir) und berechne die Drehung aus dem Winkel zwischen "dir" und Normale der Ebene (plane). Ich dachte mir, dass ich vor dieser Berechnung noch "dir" gem. der Kamera Orientierung drehen muss. Soweit so gut.

Der Berg hat 4 Seiten, die ich aus einem Modell erechne, wo ich dieses Modell dann drehe um die 4 Seiten zu erhalten.

Meine Kamera verhält sich nun wie folgt: Auf der Seite des Berges, die nicht gedreht wurde, wird die neue Ausrichtung der Kamera korrekt berechnet, wenn ich auf den Berg herauffahre bzw. herunterfahre. Alles in Ordnung. Auf der gegenüber liegenden Seite des Berges, d.h. die Seite, die um 180 Grad gedreht wurde, dreht sich beim Auffahren die Kamera automatisch um 180 Grad zur Y-Achse.

Merkwürdig ist, dass, wenn ich an dieser Seite (180 Grad gedreht) rückwärts auf den Berg fahre, erfolgt die Drehung der Kamera wie gewünscht. An der Seite die um 90 Grad gedreht wurde, dreht sich die Kamera um 90 Grad zur Y-Achse, bei der Seite die um 270 Grad gedreht wurde, dreht sich die Kamera ebenfalls 270 Grad zur Y-Achse.

Ich dachte erst die Normalen der Seiten wären nicht entsprechend gedreht, aber diese Berechnung der Normalen mache ich erst nach der Drehung der Seiten, d.h. sie sind aktuell. Desweiteren verhält es sich bei der Berechnung der Drehachse (axis) so, dass wenn ich "dir" und "normale" tausche, dann ändert sich das Verhalten der Kamera so, dass bei der um 180 gedrehten Seite die Berechung der Drehung der Kamera ok ist, während bei der Seite, die nicht gedreht wurde, dann die Kamera dann ebenfalls um 180 Grad zur Y-Achse gedreht wird.

Vielleicht findet sich jemand, der mir den entscprechenden Hinweis geben kann, wo es bei meinen Berechnungen noch hakt. Falls Fragen sind, werde ich diese auch schnellstmöglich beantworten...

Viele Grüße
Rossibaer
Ergänzung ()

Hab das Problem nun selber lösen können.
Für die, die es interessiert, hier meine Lösung:

Code:
        private void Rotate(Plane plane)
        {
            Quaternion rotation = _camera.Orientation;
            Quaternion rotInv = rotation.Inverted();
            Vector3 dir = Vector3.UnitY;
            Vector3.Transform(ref dir, ref rotation, out dir);
            float angle = (float)Math.Acos(MathUtil.Dot(ref dir, ref plane.Normal));
            Vector3 axis = MathUtil.Cross(ref dir, ref plane.Normal);
            if (axis.LengthSquared < MathUtil.Unsharpness)
                return;
            Vector3.Transform(ref axis, ref rotInv, out axis);
            rotation = Quaternion.FromAxisAngle(axis, angle);
            _camera.Rotate(rotation);
        }

Der Trick dabei war, die berechnete Achse um die gedreht werden soll, selbst nochmal entgegen der Rotation der Kamera zu drehen.
 
Zuletzt bearbeitet:
Zurück
Oben