Umschauen ala Egoshooter / Rotation Z und weiter?

M

Maab

Hallo,

ich stehe wieder vor einem neuen Problem.
Ich versuche derzeit immernoch ein umschauen im 3D-Raum zu ermöglichen.

Hier bei habe ich zwei Punkte, jeweils das Ziel und den Standort der Kamera.
Wenn ich mich horizontal bewegen möchte, bilde ich die Rotationsmatrix Z für den Zielpunkt der dann um die Kamera rotiert und demnach die Kamera in diese Richtung schaut.

Jedoch komme ich auf keinen Nenner mit der Vertikalen.
Wie berechne ich diese Vertikale, d.h. nach oben und unten schauen, wenn ich einen Winkel gegeben habe und die zwei besagten Punkte ?

Wenn ich eine Rotationsmatrix X und eine Rotationsmatrix Y bilde, diese miteinander multipliziere dann kommt irgendwie nur Müll raus.

Weiss jemand Rat ?

(Der Standort der Kamera befindet sich irgendwo im Raum, der Abstand (also der Radius) zwischen Standort und Ziel beträgt immer 2)

Grüße und Danke,
Maab.
 
Nochmal zu dem Problem:

Ich habe HIER ein Bild welches das Problem ganz gut beschreibt.

Der grüne Punkt rotiert um die Z-Achse (Rotationskreis = grau) welcher das umschauen horizontal simuliert.

Der (türkise) Viertelkreis zeigt einen Ausschnitt für das Rotieren in vertikaler Richtung.
Der (rote bzw. schwarze) Punkt auf diesem Viertelkreis ist der Punkt der um den Winkel (gelb) ,auf diesem Kreis, verschoben werden soll!

Vielleicht bringt das etwas mehr Lich in das Problem.

Grüße,
SkiD.
 
Hallo,

wenn du den Augpunkt und den Zielpunkt gegeben hast, dann baut man sich eine View-Matrix (ich nehme an die willst du berechnen?) am einfachsten über ein Orthonormalsystem zusammen. Das funktioniert in etwa so:
Code:
vorwärts <- normalisiere(zielpunkt - augpunkt)
oben <- (0, 0, 1)
rechts <- normalisiere(vorwärts × oben)
oben <- normalisiere(rechts × vorwärts)
Dabei ist × das Kreuzprodukt, für das die Rechte-Hand-Regel gelten sollte. Die Rotationsmatrix ergibt sich dann, indem man die drei Vektoren als Spalten bzw. Zeilen verwendet (je nachdem, ob du Spalten- oder Zeilenvektoren verwendest).

Wenn du keine View-Matrix berechnen willst, dann solltest du das Problem vielleicht noch etwas genauer spezifizieren.

Grüße, Matthias
 
Also wenn ich das jetzt richtig interpretiere, dass eine ViewMatrix eine Matrix ist, welches es mir erlaubt das ich mich immer um einen Punkt drehe, dann soll das genau der umgekehrte Fall sein.

Ich möchte dass sich ein Punkt um meinen Standort dreht ;)
So ähnlich wie bei der Sonne und der Erde:
Die Erde dreht sich um die Sonne (jedenfalls meistens) in einer Kreisbahn (ja ich weiss das stimmt nicht ganz, aber lassen wir unsere Erde jetzt einfach mal auf einer Kreisbahn umlaufen) , hierbei möchte ich (wenn ich jetzt die Sonne bin) die Erde immer im Blickpunkt haben, d.h. ich möchte immer in auf diesen Punkt schauen wo sich die Erde gerade befindet., bzw. in diese Richtung.

Der Sonderfall hier ist jedoch, dass die Erde sich in meinen Fall nicht auf der XY-Ebene befindet, sondern dass sich meine Erde über mich drehen soll und unter mir durch. (siehe Bild)

Wenn die ViewMatrix dieses Problem genau speziefiert, dann wäre es schon schön, wenn wir das im Detail durchgehen könnten, evtl. auch an einem Beispiel.

D.h. ich befinde mich nicht im Mittelpunkt, sondern an der Position [2, 2, 0] (= Pe = Position Eye).
Mein Blickpunkt befindet sich auf [4, 4, 4] (= Pv = Position Viewpoint).

Normalisierung um ins Zentrum zu rutschen (?):
d = Pt - Pe = [2, 2, 4] (= entspricht demnach auch den Richtungsvektor)

Vorwärts x Oben:
2 * 0 - 2 * 0 = 0
2 * 1 - 2 * 0 = 2
2 * 0 - 2 * 1 = 2

Soll hier jetzt eine Matrix oder ein Vektor rauskommen ?
Weil dann ist das nämlich eigentlich schon falsch ...

Noch etwas, wenn ich vorher schonmal eine Rotation haben sollte, bspw. eine Rotation um die Z-Achse, muss ich dann, um die neuen Koordinaten rauszubekommen, diese Matrix * die Z-Rot-Matrix * den Richtugsvektor nehmen ?

Grüße,
Maab.
 
Also wenn ich das jetzt richtig interpretiere, dass eine ViewMatrix eine Matrix ist, welches es mir erlaubt das ich mich immer um einen Punkt drehe, dann soll das genau der umgekehrte Fall sein.
Eine Viewmatrix gibt an, wie die Szene transformiert werden muss, damit der Augpunkt im Ursprung liegt und eine festgelegte Achse der Blickrichtung entspricht. Sie setzt sich in der Regel aus einer Translation und anschließender Rotation zusammen. Ist das das, was du berechnen willst, oder etwas anderes? Wenn es etwas anderes sein soll, dann erkläre doch bitte genau, was berechnet werden soll.

D.h. ich befinde mich nicht im Mittelpunkt, sondern an der Position [2, 2, 0] (= Pe = Position Eye).
Mein Blickpunkt befindet sich auf [4, 4, 4] (= Pv = Position Viewpoint).

Normalisierung um ins Zentrum zu rutschen (?):
d = Pt - Pe = [2, 2, 4] (= entspricht demnach auch den Richtungsvektor)
Hier wird nur der Richtungsvektor vom Augpunkt zum Zielpunkt berechnet. Zur Normalisierung muss der Vektor noch auf die Länge 1 gestreckt werden.

Vorwärts x Oben:
2 * 0 - 2 * 0 = 0
2 * 1 - 2 * 0 = 2
2 * 0 - 2 * 1 = 2
Was rechnest du da? Das Kreuzprodukt aus [2, 2, 4] und [0, 0, 1] ist [2 * 1 - 4 * 0, 4 * 0 - 2 * 1, 2 * 0 - 2 * 0] = [2, -2, 0]. Um das Beispiel zu komplettieren (zunächst mal ohne die Normalisierung):
Code:
Pe <- [2, 2, 0]
Pv <- [4, 4, 4]
vorwärts <- Pv - Pe // = [2, 2, 4]
oben <- [0, 0, 1]
rechts <- vorwärts × oben // = [2, -2, 0]
oben <- rechts × vorwärts // = [-8, -8, 8]
Angenommen die Kamera soll jetzt entlang der negativen y-Achse schauen, die z-Achse soll nach oben zeigen und die x-Achse nach rechts. Dann sähe eine entsprechende View-Matrix aus wie folgt:
Code:
[normalize(rechts), -normalize(vorwärts), normalize(oben)]
Wenn man jetzt Pv zuerst so transliert, dass die Kamera im Ursprung liegt (Pe abziehen) und dann die Matrix darauf anwendet, ergibt sich [0, -2*sqrt(6), 0]. Der Punkt liegt auf der negativen y-Achse, also genau was wir erreichen wollten.

Soll hier jetzt eine Matrix oder ein Vektor rauskommen ?
Das Kreuzprodukt ergibt immer einen Vektor.

Noch etwas, wenn ich vorher schonmal eine Rotation haben sollte, bspw. eine Rotation um die Z-Achse, muss ich dann, um die neuen Koordinaten rauszubekommen, diese Matrix * die Z-Rot-Matrix * den Richtugsvektor nehmen ?
Was sollen denn die „neuen Koordinaten“ sein? Wenn du die beschriebene Rechnung ausführst, wird der Vektor zuerst um die z-Achse rotiert und dann mit der neuen Matrix transformiert.

Grüße, Matthias
 
Ja also ich denke du machst genau dass, was ich auch mache, nur ich nutze Matrizen dazu.

Pass auf, ich dachte mir das so:
Zuerst nehme ich diesen Richtungsvektor ,der von Ursprung zum Punkt führt, und verschiebe diesen auf die X-Achse.

Ungefähr so:
Punktkoordinaten = [2,2,2] = vec(p)
Derzeitiger Standort = [0,0,0] = vec(s)

X-Achsen-Vektor = [1, 0, 0] = vec(x)
Richtungsvektor = [2,2,2] - [0,0,0] = [2,2,2] = vec(r)

Ich berechne das Azimuth:
cos(gamma) = vec(r) * vec(x) / ( betrag(vec(r)) * betrag(vec(x)) )
azimuth = acos(gamma)

Dann bilde ich hier raus die Rotationsmatrix um die Z-Achse:

Zr = [ [cos(azimuth), -sin(azimuth, 0)], [sin(azimuth), cos(azimuth), 9], [0,0,1] ]

Dann bilde ich die Rotationsmatrix für die Rotation um Y

Yr = [ [cos(beta), 0, sin(beta)], [0,1,0], [-sin(beta), 0, cos(beta)] ]

Dann die Inverse von Zr

Zi = Zr^(-1)

Anschließend multipliziere ich die Matrizen der Reihe nach mit den Richtungsvektor:

vec(rneu) = Zr * Yr * Zi * vec(r)

Und verschiebe den ganzen Kram zurück

Neue Koordinaten = [ rneu[0] + s[0], rneu[1] + s[1], rneu[2] + s[2]]

So hätte ich mir das gedacht, bin mir nicht sicher ob das so funktionieren würde.
Bzw. es funktioniet in meiner Anwendung nicht, da die Rotation irgendwie von ihren "Kurs" abkommt.

Im großen und ganzen dürfte dass der ViewMatrix entsprechen.
Deiner ausführlichen Erklärung, wie man das nun genau berechnet, werde ich jetzt mal nachgehen.

Grüße,
MaaB.
 
Pass auf, ich dachte mir das so:
Zuerst nehme ich diesen Richtungsvektor ,der von Ursprung zum Punkt führt, und verschiebe diesen auf die X-Achse.

Ungefähr so:
Punktkoordinaten = [2,2,2] = vec(p)
Derzeitiger Standort = [0,0,0] = vec(s)

X-Achsen-Vektor = [1, 0, 0] = vec(x)
Richtungsvektor = [2,2,2] - [0,0,0] = [2,2,2] = vec(r)

Ich berechne das Azimuth:
cos(gamma) = vec(r) * vec(x) / ( betrag(vec(r)) * betrag(vec(x)) )
azimuth = acos(gamma)
Das ist nicht das Azimut, sondern der Winkel zwischen r und x. Der Unterschied sollte klar werden, wenn du zum Beispiel vec(p) = [2, 0, 2] wählst. Da der Punkt „über der x-Achse“ liegt, ist der Azimut 0, deine Rechnung ergibt allerdings 45°. Du musst den Punkt zuerst orthogonal auf die xy-Ebene projezieren (z = 0 setzen), wenn du das Azimut berechnen willst.

Dann bilde ich hier raus die Rotationsmatrix um die Z-Achse:

Zr = [ [cos(azimuth), -sin(azimuth, 0)], [sin(azimuth), cos(azimuth), 9], [0,0,1] ]

Dann bilde ich die Rotationsmatrix für die Rotation um Y

Yr = [ [cos(beta), 0, sin(beta)], [0,1,0], [-sin(beta), 0, cos(beta)] ]
Was ist beta? Der Polarwinkel?

Dann die Inverse von Zr

Zi = Zr^(-1)

Anschließend multipliziere ich die Matrizen der Reihe nach mit den Richtungsvektor:

vec(rneu) = Zr * Yr * Zi * vec(r)
Ich dachte du wolltest den Punkt auf die x-Achse verschieben? Wo passiert das?

So ganz hab ich immer noch nicht verstanden, was du eigentlich machen willst…

Grüße, Matthias
 
Ohne jetzt alles gelesen zu haben, aber warum benutzt du nicht ne fertige Engine?
Irrlicht wäre da zu empfehlen, aber es gibt auch 100e von anderen guten 3D-Engines
 
Zurück