Mission on Mars: Interaktive Kamera-Rotation

Lesezeit: 3 Minuten

Um weiter an meinem Mesh arbeiten zu können, muss ich mir das Mesh von allen Seiten ansehen können. Daher implementiere ich nun eine interaktive Kamera-Rotation.

Grundsätzliche Überlegung

Im Blog Mission on Mars: Interaktiver Kamera-Bezier-Zoom fahre ich die Kamera ja hoch und runter und verändere dabei den Blickwinkel. Die Kamera-Position wird dabei immer berechnet mittels des Punktes, auf den ich blicke (derzeit die Mitte des Mesh bei (0,0)) + dem Kamera-Vektor.

Das funktioniert auf der X-Achse bei 0 recht gut. Ich muss also die endgültige Kamera-Position um den Punkt rotieren können, den ich betrachte.

Weiterhin ist das eher ein zweidimensionales Problem – die Entfernung zum Objekt bzw. die Höhe der Kamera (z-Koordinate) bleibt ja gleich.

Einiges Kopfzerbrechen hat mir das Kamera-Objekt von Cocos2d-x bereitet: dem muss ich nämlich noch mitteilen, wo für die Kamera tatsächlich oben ist – layerMap::update:

Diese Normale verhindert das Rotieren der Kamera über die Tiefenkomponente und die Kamera bleibt immer „gerade“.

Rotation um einen Punkt

Die eigentliche Rotation um einen Punkt ist einfach:

Wobei vecNullCamera der Vektor ist, der aus der Bezier-Zoom-Funktion geliefert wird.

Das ist hier sehr gut beschrieben: https://de.wikipedia.org/wiki/Drehmatrix – ich benötige ja nur die Berechnungen für (x,y) – also im zweidimensionalem Raum. Die z-Komponente bleibt gleich.

Rotation um wie viel?!

Testweise kann man _viewAngle mal auf feste Werte setzen – aber aufgepasst – die Werte müssen in Radian angegeben werden – nicht in Grad. Cocos2d-x hat da zwei Helferlein für parat:

Ich möchte aber, dass ich mit zwei Fingern meine Kamera um den Blickpunkt drehen kann. Meine Idee ist, den Winkel der Geraden zu nehmen, die entsteht, wenn ich zwei Finger auf den Touch-Screen packe. Bewege ich dann einen oder beide Finger, so verändert sich auch der Winkel der verbindenden Geraden. Die Differenz dieser Beiden Geraden soll die Rotations-Änderung meiner Kamera darstellen.

Winkel einer Geraden zwischen zwei Punkten

Ich habe also zwei Punktpärchen – diese habe ich ja schon in layerMap::onTouchesMoved benutz, um zu Zoomen:

Erklärt ist das hier z. B.: https://www.mathematik-oberstufe.de/analysis/lin/gerade2d-steigungswinkel.html

Da wird allerdings nur in einem Nebensatz gesagt, dass Arkustangens die Umkehrfunktion von Tangens ist. Glücklicherweise bietet dies C++ als Standard-Funktion an.

Meine Winkeländerung ist also:

und damit ich nicht soviel mit den Fingern kurbeln muss, baue ich auch dort einen Sensitiv-Faktor ein:

Nun benötige ich noch den aktuellen Kamera-Winkel angleC.

Der Kompass soll sich drehen

Der rudimentäre Kompass aus Mission on Mars: der Kompass soll mir die Orientierung erleichtern. Dazu erweitere ich die Klasse über die Update-Funktion:

Als letztes muss der aktuelle Blickwinkel auch im AppState verfügbar sein  (getter und setter) – das erfolgt diesmal in Grad direkt in der layerMap::update Funktion, die ja auch das Positionieren der Kamera übernimmt:

Der aktuelle Winkel der Kamera zum Blickpunkt wird wieder mittels Arkustanges berechnet.

Zur Demonstration des aktuellen Entwicklungsstandes hab ich ein Video bereitgestellt:

Damit bin ich vorerst zufrieden – kann ich doch jetzt auch die Vorderseite meines Objektes begutachten.  Die abgeschrägte Ecke ist also wie angekündigt auch vorhanden! Da sie dem Licht zugewandt ist, erscheint sie auch heller.

Revision 61

Anroid, iOS

Weiterführende Links

Da ich jetzt den Kompass habe kann ich mich wieder um die serverseitige Texture kümmern. Die habe ich ja durch die Material-Datei verloren.

Ich benötige ja nun keinen auf der Textur eingezeichneten Nordpol mehr. Das beschreibe ich im nächsten Blog.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.