Announcement

Collapse
No announcement yet.

Kamerarotation um Ursprung (Quaternionen)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Kamerarotation um Ursprung (Quaternionen)

    Hallo,

    ich habe mir im Internet schon einige Quellen zu Quaternionen angesehen, aber irgendwie hat es noch nicht klick gemacht bzw. habe ich nichts gefunden, was den Bedürfnissen meines Spiels entspricht. Also folgendes:

    Ich habe eine Sphäre im Ursprung und hätte gern eine Kamera, die um die Sphäre herumkreisen kann und immer in Richtung Ursprung (0,0,0) schaut. Ähnlich wie bei Super Mario Galaxy, nur halt mit nur einem Planeten. (Im Grunde steuert der Spieler ein Objekt, dass sich auf dem Planeten bewegt und die Kamera folgt diesem Objekt.)

    Ich gehe mal davon aus, dass ich die Position der Kamera als Quaternion (plus Entfernung vom Ursprung?) speichern kann. Aber wie wende ich die Bewegungen an? (Rauf-runter und links-rechts. Natürlich relativ zur Kamera, nicht zum Planeten/Weltkoordinaten.) Und wie errechne ich mir daraus die ViewMatrix und Kameraposition in kartesischen Koordinaten? Quaternion in Matrix umrechnen kann ich schon, aber ist das schon die ViewMatrix (die ich benötige)? Oder brauche ich das konjugierte Quaternion?

    Mein Ziel ist natürlich u.a. Gimbal Lock zu vermeiden und deswegen habe ich mir mal (noch) nichts mit Euler Winkeln angesehen.


    Oder liege ich überhaupt ganz falsch?

    Danke schon einmal im Voraus!

    Lg,
    Marko

    PS: Also im Grunde brauche ich moveUp(angle), moveRight(angle), moveNear(distance), getViewMatrix() und getLocation(). Nur eben die Implementierung ist mir unklar.
    Last edited by mkmc; 10-04-2012, 16:32.

  • #2
    Also ich habe es bei uns (noch) nicht implementiert, aber dies sollte auch mit glm:lookAt(..) möglich sein. Zumindest werde ich es mal mit diesem Ansatz versuchen. Die Kameraposition auf einem Kreis zu bewegen ist ja nicht so schwer. Der Zielpunkt wäre dann eben fix.
    Aaaaaaaaaaaaaaaaaaaaaaaaaaaaahc++aaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaah ich hasse dich!

    Comment


    • #3
      Ja, EIN Kreis ist kein Problem.

      Ich habe auch gerade das gefunden: http://www.xnawiki.com/index.php?title=Arc-Ball_Camera
      Ich werde mal probieren das zu implementieren, bis mir eventuell jemand meine Fragen beantworten kann. Sind zwar keine Quaternionen, aber was soll's ...

      Comment


      • #4
        Eine Kugel sollte dann mit Rotationen um 2 Kreise Abdeckbar sein
        Aaaaaaaaaaaaaaaaaaaaaaaaaaaaahc++aaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaah ich hasse dich!

        Comment


        • #5
          Man braucht 3.

          Angenommen bei einer Rotation um die X-Achse:
          Bei 0° muss ich, um nach oben zu gehen, um die Y-Achse rotieren.
          Bei 90° dann aber um die Z-Achse. Um die Y-Achse zu rotieren bringt nichts, weil ich mich dann auf ihr befinde.
          Bei 180° dann halt wieder um die Y-Achse, aber in die verkehrte Richtung.
          etc.

          Außerdem dreht sich die Kamera um (Up-Vector ist ja (1,0,0)), wenn man die Y-Z-Ebene quert.

          Um eben diese Probleme zu beseitigen, dachte ich, dass ich gleich Quaternionen verwenden, weil die anscheinend das Allheilmittel sind.

          Comment


          • #6
            Hallo,

            Bewegungen auf einer Kugel lassen sich immer mit 2 Winkeln beschreiben. Du darfst halt nicht immer um die globalen Achsen drehen, sondern musst die lokalen Achsen verwenden. Bsp.: Du kannst immer zuerst um die globale Y-Achse drehen (links-rechts) und dann mit dem zweiten Winkel um die lokale X-Achse (das ist dann rauf-runter).
            Was du dann noch berücksichtigen musst, ist was passieren soll wenn |X-Rotation| > 90° wird, da musst du ev. die Kamera dann umdrehen.
            Bernhard Steiner
            [CGUE Übungsleitung]

            Comment


            • #7
              Bisher habe ich ja einfach lookAt( (matrix*vec4(0,0,0,1)).xyz , vec3(0,0,0), vec3(1,0,0) ) verwendet und matrix mit rotateX und rotateY transformiert, weil das für den Anfang ja gereicht hat.

              Comment


              • #8
                Originally posted by BDL! View Post
                Hallo,

                Bewegungen auf einer Kugel lassen sich immer mit 2 Winkeln beschreiben. Du darfst halt nicht immer um die globalen Achsen drehen, sondern musst die lokalen Achsen verwenden. Bsp.: Du kannst immer zuerst um die globale Y-Achse drehen (links-rechts) und dann mit dem zweiten Winkel um die lokale X-Achse (das ist dann rauf-runter).
                Was du dann noch berücksichtigen musst, ist was passieren soll wenn |X-Rotation| > 90° wird, da musst du ev. die Kamera dann umdrehen.
                Ich verstehe nicht, was mir die Rotation um die lokale x-Achse bringt. Wenn ich um die lokale Achse rotiere, dann ändert sich ja die Position nicht?

                Comment


                • #9
                  Bisher habe ich ja einfach lookAt( (matrix*vec4(0,0,0,1)).xyz , vec3(0,0,0), vec3(1,0,0) ) verwendet und matrix mit rotateX und rotateY transformiert, weil das für den Anfang ja gereicht hat.
                  Das ist die praktische Anwendung des oben beschriebenen Ansatzes. Du musst nur aufpassen in welcher Reihenfolge du die Matrix zusammenmultiplizierst.
                  Bernhard Steiner
                  [CGUE Übungsleitung]

                  Comment


                  • #10
                    Ich verstehe nicht, was mir die Rotation um die lokale x-Achse bringt. Wenn ich um die lokale Achse rotiere, dann ändert sich ja die Position nicht?
                    Angenommen deine Kamera steht am Anfang bei [0,0,-1]. Wenn du jetzt um 90° an der globalen Y-Achse rotierst steht deine Kamera bei [1,0,0] und die lokale X-Achse = die globale Z-Achse. Wenn du jetzt um diese Rotierst wird sich die Kamera nach oben/unten bewegen.
                    Bernhard Steiner
                    [CGUE Übungsleitung]

                    Comment


                    • #11
                      Ich nehme mal an, dass ich dafür die Translation nach außen entsprechend lokal machen muss?

                      Comment


                      • #12
                        Ich nehme mal an, dass ich dafür die Translation nach außen entsprechend lokal machen muss?
                        Ok. Jetzt seh ich dein Problem . Ich würde zuerst eine konstante Translation machen, dann um die Y-Achse rotieren und dann um die X-Achse.

                        Allgemein dazu: Du kannst dir die Unterlagen der CG1 LU anschauen, dort haben wir genau diese Sachen durchgemacht.
                        Bernhard Steiner
                        [CGUE Übungsleitung]

                        Comment


                        • #13
                          Ich nehme mal an, dass ich dafür die Translation nach außen entsprechend lokal machen muss?
                          Ok. Jetzt seh ich dein Problem . Ich würde zuerst eine Konstante Translation machen (z.B.: [0,0,-Abstand]), dann um die Y-Achse rotieren und dann um die X-Achse.

                          Allgemein dazu: Du kannst dir die Unterlagen der CG1 LU anschauen, dort haben wir genau diese Sachen durchgemacht.
                          Bernhard Steiner
                          [CGUE Übungsleitung]

                          Comment


                          • #14
                            Die Frage ist ob Du wirklich Quaternionen brauchst.

                            Der einzige usecase in dem sie nuetzlich sind, ist wenn Du Rotationen interpolierst. Z.b. in Skeletal animation. Da konvertiert man die Rotation in quaternionen, interpoliert sie und konvertiert das ergebnis wieder zurueck in eine Transformationsmatrix. Hier kannst Du im Grunde Quaternions als black box betrachten ohne sie wirklich verstehen zu muessen. Quaternionrotation mit q * v * q^-1 macht so gut wie niemand heutzutage.

                            Gimbal lock laesst sich wesentlich einfacher vermeiden indem Du die Orientierung deiner Objekte als 3x3 Matrix speicherst. Wenn Du dann rotierst multiplizierst Du einfach eine Rotationsmatrix zur Matrix dazu. Da kann kein Gimbal lock entstehen.

                            Gimbal lock kann es nur geben, wenn Du die orientierung als 3 Eulerwinkel speicherst und modifizierst. Davon rate ich euch aber generell ab.

                            Comment


                            • #15
                              Für die Nachwelt, ich habe es jetzt so gelöst, wie hier im Post von Samaursa beschrieben:

                              http://gamedev.stackexchange.com/que...s-target-point


                              BDL!s Lösungsvorschlag hat mir leider nicht geholfen, trotzdem danke.

                              Comment

                              Working...
                              X