Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

10.03.2021, 01:58

ViewMatrix in einer 3d weltraum simulation.

Ich formuliere mein Problem nochmal neu, nachdem ich etwas "klüger" bin, was die Bewunderung der Problems angeht, bei gleichzeitigenm
nichtvorhandensein einer lösung ;)

Fangen wir bei der FPS Camera View Matrix an, wie sie in dem Artikel beschrieben ist. Die habe ich erfolgreich implementiert.

Da ist es ja so, dass wenn man 90° nach oben blickt (rotatnion um x-achse = pitch), und in dem zustand links rechts schaut (rotation um y-achse=yaw)
man dann eine rotation um die eigene achse sieht.

So ist es in Ich.Perspektive shootern üblich und sinnvoll, solange man einen festen bezugspunkt hat was unten ist.

Nun mache ich aber eine (weltraum)-Flugsimulation und da möchte ich etwas anderes. Wenn man da nach oben schaut, weiss man als spieler eben nicht dass das oben ist,
und dann wirkt es sehr verwirrend, wenn man links/rechts steuert und sich nur um die eigene achse dreht. Stattdessen sollte für den fall das man nach oben
blickt das passieren, was passiert, wenn man den kopf zur seite neigt.

Macht man das so mit dem kopf würde man sich das genick brechen. In meienr View matrix ist es weniger schlimm:
Bei all meine versuchen kommt es allerdings immer soweit, dasss man in irgendeiner position sich um die eigene achse dreht.

Ich denke, ich muss in abhöngigkeit der x/y rotation auch eine z rotation vollführen, komme aber nicht drauf wie man das berechnet.

So, vielleicht findet sich mit dieser Beschreibung jemand, der das Problem (ViewMatrix in flugsimulationen) kennt und nen tip hat. Danke schonmal für die Geduld derer,
die sich mit meienr ersten etwas verworrenen Problembeschreibung auseinandergesetzt haben.

Die antwort ist sicherlich ein ein-zeiler irgendwas was x y als eingabe nimmt, mit sinus cosinus oder tangens verrechnet und als ausgabe eine z rotation liefert.
Also quasi eine funktionsprototyp:
double calcZRotation(double X, double Y)

Hier der ARtikel zur FPS-Cam
https://www.3dgep.com/understanding-the-view-matrix/

Hier eine visuell unterlegte Erläuterung meines Problems:

https://youtu.be/-0BuwYOi1tw

Und hier eine aktuelle demo mit allen elementen aktiviert:
https://www.youtube.com/watch?v=EgbqFumAb-M

Nur zur Vorsorge: Ich verwende absichtlich keine Game engine, weil ich das hauptsächlich aus spass am coden mache und ich ein bisschen fitter in mathe werden will. Außerdem scheint mir eine Game Engine wenig zielführend bei meinem Konzept, so viel wie möglich per zufall generieren anstatt zu modellieren.

Hier noch der Code als pastebin-auszug:
https://pastebin.pl/view/dabf3b91

Der komplette code findet sich unter: (Klasse CharlyBeck.Mvi.Mono.GameCore.CAvatar

https://github.com/DeepSeeBee/Mvi

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »SeeBee« (10.03.2021, 02:43)


2

10.03.2021, 02:02

Achso, hallo auch erstmal in die runde. Bin neu hier und vorrangig wegen des og. problems da. Werde mich hier mal ein bisschnen umschauen :)

FSA

Community-Fossil

  • Private Nachricht senden

3

10.03.2021, 02:09

Du müsstest in deiner Kameramatrix/Berechnung einen Up-Vektor (0,1,0) haben. Diesen einfach mit der Blickrichtung (senkrecht zur Blickrichtung natürlich) mit drehen, anstatt konstant zu lassen.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

4

10.03.2021, 02:13

Du müsstest in deiner Kameramatrix/Berechnung einen Up-Vektor (0,1,0) haben. Diesen einfach mit der Blickrichtung (senkrecht zur Blickrichtung natürlich) mit drehen, anstatt konstant zu lassen.


JA, mit dem UpVector habe ich schon bekanntschaft gemacht. Ein netter geselle, um vergleich zu Quaternions und so. ;)

Ich drehe den UpVector ja schon fleissig. Das führt ja dann dazu, dass man wenn man 90° nach oben blickt bei l/r dreheung eine rotation um die eigene achse wahrnimmt, anstatt - wie gewünscht - eine neigung um das was mal die z achse war. GEnau dieses verhalten bekomme ich nicht weg. Wie gesagt, die einfache FPS CAm funktioniert und mit genanntem hack funktioniert es auch so, wie ich es haben will. Nur es ist eben nicht sauber implementiert und der up vector läuft mit der zeit gegen unendlich, was ich in dem geposteten pastebin code durch einen ziemlich hässlichen workaround verschlimmbessert habe.

Jonathan

Community-Fossil

  • Private Nachricht senden

5

10.03.2021, 21:19

Naja, beim Links/Rechts drehen darf man die Kamera dann halt nicht um die globale z-Achse drehen, sondern muss sie um die lokale z-Achse drehen. Aber mit der Accumulative Methode scheinst du ja schon irgendwie sowas ähnliches zu machen. Nur verstehe ich nicht, wieso das gegen unendlich geht? Wo findet denn da der Überlauf statt?
Lieber dumm fragen, als dumm bleiben!

6

11.03.2021, 20:37

Naja, beim Links/Rechts drehen darf man die Kamera dann halt nicht um die globale z-Achse drehen, sondern muss sie um die lokale z-Achse drehen. Aber mit der Accumulative Methode scheinst du ja schon irgendwie sowas ähnliches zu machen. Nur verstehe ich nicht, wieso das gegen unendlich geht? Wo findet denn da der Überlauf statt?


Ja, genau so solls funktionieren. Allerdings bekommt man das gleiche problem ja auch beim senkrecht nach oben schauen und ein "if angle = 90°" geht ja auch nicht, das muss fliesend gehen.

2 LEute haben mich jetzt auf Gimbal Lock problmeatik und quaterniton matrix multiplikation aufmerksam gemacht, ich denke das ist die lösung. aber das geht für meine verhältnisse schon ziemlich ans eingemachte. realschulmathematik und imaginäre zahlen wollen sich noch nicht so recht vertragen bei mir. aber wird schon.

ich habs nicht genau analysiert, aber ich akkumuliere die werte auf, zudem sind die informatioenen redundant und es gibt rundungsfehler. das führt wohl dazu, dass ich erst positive/negative infinity hab, die zahlen zb. im lookat vektor werden mit jedem frame größer/kleiner. irgendwann springt der double auf infinity und wenn man das verrechnet kommt nan raus. hab das schon im debugger gesehen und die art und weise, wie ich es rechne ist nicht koscher, das war mir gleich klar. warums genau so ist, vielleicht mal den code schnippsel anschauöen, den ich geschickt hab. jeweils die methoden mit "Akkumulative" am ende des namens. da sieht man auch so einen teil der versuche die ich gemacht habe. Aber ich bin mir moementan relativ sicher, dass es ein Gimbal Lock ist und angeblich braucht man dazu eine rotation mitteln quaternions.....

Aber bevor ich mein hirn damit töte, programmier ich lieber ein bissl an meinem bonus-items system ;)

7

11.03.2021, 20:40

Naja, beim Links/Rechts drehen darf man die Kamera dann halt nicht um die globale z-Achse drehen, sondern muss sie um die lokale z-Achse drehen. Aber mit der Accumulative Methode scheinst du ja schon irgendwie sowas ähnliches zu machen. Nur verstehe ich nicht, wieso das gegen unendlich geht? Wo findet denn da der Überlauf statt?


danke auch für die begrifflichkeit "lokale z achse." immer schön wenn man für so verwirrende sachen einen namen hat, den andere auch verstehen. bei mir hat das problem bisher roter apfel geheissen ;)

FSA

Community-Fossil

  • Private Nachricht senden

8

11.03.2021, 22:01

Ich glaube nicht, dass dein Problem durch Gimbal-Lock kommt, und Quaternionen solltest du dafür auch nicht brauchen. Am besten mal nachlesen, wie man eine Rotationsmatrix um eine beliebige Achse aufstellt (angegeben durch einen Vektor); dadurch lassen sich all deine Probleme Lösen. Du gibst dann einfach die Drehachse über einen Vektor im globalen Raum an, und erstellst daraus eine Transformationsmatrix, um die Kamera zu transformieren.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Jonathan

Community-Fossil

  • Private Nachricht senden

9

11.03.2021, 22:22

Gimbal-Lock hast du bei Euler-Winkel, also wenn du immer um die selben globalen Achsen drehst.

"lokale Z-Achse" ist auch eher als eine Art Intuition zu verstehen, das ist nicht wirklich sauber definiert, und hängt immer ein wenig davon ab, wie man Dinge aufschreibt. Generell gibt es für fast alles in der 3D Grafik unterschiedliche Konventionen, das kann sehr verwirrend sein. Der einzige Ausweg ist es zu verstehen, was man tut, und es im eigenen Projekt immer konsistent zu halten. D.h. wenn man fremden Code sieht, wird man den oft noch an das Projekt anpassen müssen.

Soweit ich mich erinnere ist die Menge der Quaternionen (also EInheitsquaternionen die man zur Drehung verwendet) prinzipiell isomorph zur Gruppe der Drehmatrizen (vermutlich noch abzüglich der Tatsache, dass man jede Rotation durch genau zwei Quaternionen darstellen kann, usw.). Was das alles nur heißt ist: Absolut alles, was man mit Drehmatrizen tun kann, kann man genau so auch mit Quaternionen tun und umgekehrt. Quaternionen sind aber netter, da sie weniger Komponenten haben und daher weniger Speicher brauchen und vielleicht auch schneller anzuwenden sind. Zumindest ich benutze in der Praxis aber meist ganze Transformationsketten, und dafür braucht man eh Matrizen.
=> Vergiss Quaternionen einfach wieder, du wirst auf kein Problem stoßen, wofür du sie brauchst (höchstens auf welche, die man mit ihnen minimal eleganter lösen kann).

Zum Akkumulieren: Interessant, dass das bei dir numerisch so instabil ist. Macht aber nix. Du solltest einfach in jedem Schritt deine 3 Vektoren des Koordinatensystems orthonormalisieren. D.h. zuerst bringst du alle Vektoren auf die Länge 1, danach sorgst du dafür, dass alle senkrecht zueinander stehen (nimm etwa den X Vektor als Referenz und benutze 2 mal das Kreuzprodukt). Damit bist du alle numerischen Instabilitäten los, d.h. deine Werte werden niemals +-inf.
Lieber dumm fragen, als dumm bleiben!

10

12.03.2021, 01:29

Gimbal-Lock hast du bei Euler-Winkel, also wenn du immer um die selben globalen Achsen drehst.

"lokale Z-Achse" ist auch eher als eine Art Intuition zu verstehen, das ist nicht wirklich sauber definiert, und hängt immer ein wenig davon ab, wie man Dinge aufschreibt. Generell gibt es für fast alles in der 3D Grafik unterschiedliche Konventionen, das kann sehr verwirrend sein. Der einzige Ausweg ist es zu verstehen, was man tut, und es im eigenen Projekt immer konsistent zu halten. D.h. wenn man fremden Code sieht, wird man den oft noch an das Projekt anpassen müssen.

Soweit ich mich erinnere ist die Menge der Quaternionen (also EInheitsquaternionen die man zur Drehung verwendet) prinzipiell isomorph zur Gruppe der Drehmatrizen (vermutlich noch abzüglich der Tatsache, dass man jede Rotation durch genau zwei Quaternionen darstellen kann, usw.). Was das alles nur heißt ist: Absolut alles, was man mit Drehmatrizen tun kann, kann man genau so auch mit Quaternionen tun und umgekehrt. Quaternionen sind aber netter, da sie weniger Komponenten haben und daher weniger Speicher brauchen und vielleicht auch schneller anzuwenden sind. Zumindest ich benutze in der Praxis aber meist ganze Transformationsketten, und dafür braucht man eh Matrizen.
=> Vergiss Quaternionen einfach wieder, du wirst auf kein Problem stoßen, wofür du sie brauchst (höchstens auf welche, die man mit ihnen minimal eleganter lösen kann).

Zum Akkumulieren: Interessant, dass das bei dir numerisch so instabil ist. Macht aber nix. Du solltest einfach in jedem Schritt deine 3 Vektoren des Koordinatensystems orthonormalisieren. D.h. zuerst bringst du alle Vektoren auf die Länge 1, danach sorgst du dafür, dass alle senkrecht zueinander stehen (nimm etwa den X Vektor als Referenz und benutze 2 mal das Kreuzprodukt). Damit bist du alle numerischen Instabilitäten los, d.h. deine Werte werden niemals +-inf.


Ok das hört sich gut an. Die Frage, ob man nicht das, was man Quaternionen lösen kann, nicht auch mit "normalen" Achsen Rotationen lösen kann hatte ich mir auch schon gestellt.

Das was du schreibst, Vektor auf länge 1 bringen habe ich mit meinem aufakkumulierten ding auch probiert. (Müsste im geposteten code drin sein) Das ganze hat aber zu einem flackern geführt. Ich muss mich da nochmal mit abstand ransetzen und genau nachdenken. Das Problem scheitert momentan an meiner Vorstellungskraft.

Die Sache ist folgende ich formuliere es nochmal besser:

Ich habe mit eienr Standard FPS-CAm angefangen, den upvektor und die campos um die x achse zu rotieren, wenn ich nach oben oder unten blicke. DAs hat geklappt.
Dann habe ich die campos um die y achse gedreht, um nach rechts und links zu blicken. Das hat auch geklappt.

Fertig ist die FPS-Cam.

Dann habe ich festgestellt, dass es so reagiert, dass wenn man 90° nach oben blickt, eine rechtslinks drehung wie eine rotation um die eigene achse wirkt.
So ist das wohl auch bei den meisten FirstPersonShootern. Das nützt mir aber so nichts.

Deshalb habe angefangen mit "AxisAngle" Vektoren zu operieren, die ich mitgedreht habe. Die rotation habe ich dann nicht mehr um die x/y achse gemacht sondern um die achse, die in den gedrehten axisangles drinsteht.

Damit habe ich es dann auch hinbekommen, dass man bei 90° nach oben blicken und anschliessendem Rechts/links dreh quasi den kopf zur seiten neigt. Das war erstmal ein erfolgserlebnis, die ente kam dann, als ich feststellte das mit dieser strategie das selbe phänomen dann eben auftritt, wenn man nach 90° rechts oder links schaut, während man genau nach vorne blickt.

Und an der Stelle setzt bei mir gerade etwas die vorstellungskraft aus. Akkumulativ funktioniert es genau so wie ich will. Aber es ist eben instabil in genannter weise.

Aber es ist interesannt, dass du das mit dem "normalisieren" auf länge 1 auch vorschlägst, vl. funktioniert es ja und ich hab nur was falsch gemacht. Was ein Kreuzprodukt ist muss ich nachlesen, nennt sich das auf englisch dot produkt?

Das mit den Coding Styles ist ja eigentlich überall so. Jeder entwickelt seine eigenen Strategien die im Idealfall gut zusammenspielen. Wird man aus irgendwelchen gründen dazu gebracht, mit diesen Strategien/Konventionen zu brechen passt am ende nichts mehr zusammen. und man ist immer am hin und her drehen der Problemstellungen, was auf die Performance und auch auf die Lesbarkeit des Codes schlägt.

Ich merk das gerade ganz massiv, weil ich in dem game gerade versuche, etwas von dem Lazy-Load wegzukommen, was ich eigentlich in meinen Enterprise Projekten durchgängig verwende. Meine Bare-Metal Embedded Projekte verwenden Asap design (As Static As Possible). In dem Game jetzt mische ich beides und mache viel Instanzierungen im Konstruktor, statt über Lazy-Load beim abfragen der Property. das verträgt sich nicht immer so ideal. Aber es ist bemerkenswert, zu was CLR sprachen (vb.net, c#) leisten können, wenn man den Garbage Collector nicht beansprucht. (Ich verwende für die ganzen Objekte im spiel Objektpools, der Garbage Collector arbeite im wesentlichen für die Linq Abragen und Enumerator/Iterator-Objekte. Mal schauen, ob ich das irgendwie wegoptimiere, am ende.)

Werbeanzeige