Hi Leute,
also mal vorweg, ich habe mir das Tut dazu schon angesehen ^^ es geht mir jetzt eher darum, ob ich die Theorie darin richtig verstanden habe, oder ob ich mich auf dem Holzweg bewege.
Ich habe mir eine Camera gebaut, deren gesamte translation udn Rotation auf einer Matrix basiert. Ich hatte das ganze mal früher auf 2 Winkeln (für Rotation um x,y-Achse) und einem Vektor (für die Translation).
Jetzt habe ich also eine Matrix genommen und dabei hat mir das Nachsitzentut sehr weitergeholfen.
Translation funkt (ist ja auch ganz einfach ^^)
Meine Theorie bei der Rotation ist die folgende: Ich rufe die Funktion RotateX mit einem Winkel NAngle auf (also Rotiere um X)
In der Funktion erzeuge ich eine seperate 4*4 Einheitsmatrix, die ich nach dem Nachhilfetut mit dem Winkel bearbeite:
Code:
procedure TSE_Camera.RotateX(NAngle:Single);
var NewRot: TMatrix44;
begin
NewRot := CreateIdentityMatrix;
NewRot[6]:=Cos(AngleX*DEG2RAD);
NewRot[7]:=Sin(AngleX*DEG2RAD);
NewRot[10]:=-Sin(AngleX*DEG2RAD);
NewRot[11]:=Cos(AngleX*DEG2RAD);
fRotation := MatrixDotMatrix(NewRot,fRotation);
end;
Dann multipliziere ich die entstandene Matrix mit meiner bereits existierenden eigentlichen Basismatrix fRotation.
Code:
function MatrixDotMatrix (m1, m2: TMatrix44): TMatrix44;
Du hast leider nicht verraten, was genau falsch ist. Kandidaten sind natürlich immer, daß deine Matrix multiplikation nicht richtig implementiert ist oder daß in der falschen Reihenfolge die Matrizen multipliziert werden - welcher links und welche rechts steht und ob die Matrizen tatsächlich das tun, was sie sollen. Alles ist schwarz ist auch etwas knapp, aber du kannst ja mal ein paar Beispielmatrizen geben, für bestimmte, vorgegebene Rotationswinkel - etwa 45, und 90 Grad und dann bekommt man einen Eindruck davon, wie verkehrt die Matrizen sind. Im übrigen klappt dein @Camera.Rotation nicht bei allen arten von Arrays. Im zweifel einmal mit @Camera.Rotation[0] probieren, um nicht auf das array samt kontrollstrukturen sondern auf dessen Daten zu zeigen - dürfte aber nur bei Arrays einen Effekt haben, die dynamische länge haben.
Und checke auch, ob Du die Matrix als Modelview setzt. Eine solche Matrix im perspektive Mode dürfte ne etwas unerwarteten Effekt haben. Ansonsten hat das Kamera Tutorial auch Sourcecodes zum sehen, ob ich da sowas ähnliches gemacht habe oder Du nur eine kleinigkeit vergessen hast:
http://www.delphigl.com/do_download.php?f=3050 Allerdings wirst Du erst nach der richtigen Geometry.pas fischen gehen müssen, da war aber vor nicht allzulanger Zeit ein entsprechnder Thread, wo das genauer beschrieben wurde. Einfach mal danach suchen.
Sonst seh ich dem Code spontan keinen Fehler an.
[edit:] Ach doch:
fRotation := MatrixDotMatrix(NewRot,fRotation);
Wahrscheinlich willst Du eher
fRotation := MatrixDotMatrix(fRotation, NewRot);
haben.
[edit2] Und beim Anwenden darf die Translation auch nicht vergessen werden - eventuell soll die Translation auch nicht mitrotiert werden. Das musst aber du wissen, wie hier deine Kamera geplant ist.
Das mit der falschen Reihenfolge der Matrizen is mir vorhin auch schon aufgefallen und danach hab cih dann auch ein paar resultate gehabt
Ich habe hier mal eine Demo hochgeladen, bei der ich mal nur die drehung um die xachse gemacht hab.
Es geht komischerweise auch nur eine Drehung vorwärts ^^ aber das denke ist, ist eher ein sekundäres Problem.
Zum Winkel, um den ich drehe: Das haengt letztlich ganz von der Anzahl der Mousemotionevents ab, denn bei jeder mausbewegung in y-Richtung (wenn taste gedrueckt wurde) wird um 1 Grad gedreht.
Meine momentan noch vorhandenen Probleme sind die beiden folgenden:
Er dreht nicht rückwärts obwohl ich einmal um 1° und einmal um -1° drehen lass.
Und das andere Problem: Das Objekt selbst dreht sich, nicht aber ich. Ich habe das Problem damals schon gehabt, da hatte ich zuerst ein Translate und dann ein Rotate ausgeführt. Als ich die beiden vertauscht habe, gings dann.
Ich denke, diesmal liegts genau am selben Problem, denn ich lege die Verschiebungskoordinaten (4. Spalte der Matrix) ja manuell mit hilfe der Pfeiltasten fest. Ich müsste die ja in abhängigkeit von den ersten 3 Spalten errechnen lassen, sodass sich nicht das dreieck um sich selbst dreht, sondern ich mich ums dreieck dreh.
Also ich hatte das ganze schonmal mit GluLookAt realisiert aber das ganze war sehr umständlich und mir wurde gesagt, es würde auch so gehen. Reicht es nicht, wenn ich irgendwie den Bewegungsvektor der Matrix mit der ROtationsmatrix zusammenbringe (zb über Multiplikation), sodass es neuer Vektor rauskommt, der bereits gedreht ist?
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Jetzt haben wir uns überschnitten .
Aber Du muss Dir nur überlegen, dass es so etwas Ähnliches ist wie das allererste Ansehen eines Modells: Du schiebst es von Dir weg und dann musst Du Dich, wenn Du es nicht bloss nach vorne geschoben hast, zum Objekt umdrehen.
Also so: Du willst es zum Beispiel von links ansehen. Du musst dazu die genau umgekehrten Bewegungen machen, wie man sie sich vorstellt: Du würdest nach links gehen und Dich dann im Uhrzeigersinn drehen. Also musst Du
1) glTranslate (+X,0,0) nehmen, weil das eine Verschiebung nach rechts ist (in die positive X-Richtung).
2) und anschließend glRotate(+90,0,1,0) machen, weil das eine Drehung nach links ist. (Das positive Vorzeichen des Winkels bedeutet, das es sich um eine Drehung gegen den Uhrzeigersinn handelt und man dreht sich hier um die Y-Achse).
Weil das für mich ziemlich verwirrend war, hatte ich mir eine einfache Kamera gebaut, die das Umdrehen der Verschiebungen und Drehungen selbst übernimmt (aber man sollte nie vergessen, dass das im Hintergrund immer so zu sein hat).
Das wäre das Konzept wenn man auf dem "Boden" steht, das heisst auf der X/Z-Ebene. Man hat hier bereits unendlich viele Möglichkeiten, weil es ja nicht nur vier Richtungen gibt, sondern ein 2D-Kreis bereits unendlich viele Richtungsvektoren hat. Und dann erweitern wir das ganze auf eine Kugel. Ich nehme mal an, dann kommt man zu gluLookAt.
GluLookAt sollte das ganze im Raum schaffen, in JEDER Stellung. Aber das Prinzip ist immer das Gleiche: 1)Wegschieben 2)Hindrehen. Klingt zwar einfach, es sind aber ein paar Mathematische Hindernisse zu beachten. Aber da musst Du jetzt wirklich einen Mathematiker fragen, das kann ganz schön gefinkelt werden. (Machst Du nicht ohnehin Mathe?)
Ich hatte gestern nicht mehr geantwortet, weil ich versucht habe, gluLookAt zu verstehen. Frei nach Terry Pratchett könnte man sagen: mein Gehirn hat daraufhin versucht, aus den Ohren zu kriechen.
Traude
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Mal ne Frage am Rande. Hat es irgendwelche Geschwindigkeitsvorteile (die Kameramatrix per Hand zu berechnen und dann zu laden) gegenüber dem einfachen aufrufen von Rotate/Translate?
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Geschwindigkeitsvorteile hat es keine, wenn man aber sinnvoll in lokalen koordinaten arbeiten will, ist es notwendig in das passende Koordinatensystem zu drehen - Quaternionen oder Matrizen zur hand zu haben ist also sinnvoll. Ausserdem kann ich mit solchen immer lokal weiter drehen, wie es mir am besten passt - eine Kombination aus 3 Eulerwinkeln kann das nacht, weil die drehung abhängig davon ist, in welcher Reihenfolge vorher durch die Eulerwinkel gedreht wurde - für Egoshooter mag das noch egal sein, weil die Blickrichtung sich über die Eulerwinkel schön einschränken lässt, in einer Flugzeug- oder U-Boot-Simulation ist es essistentiell, daß sich die Sache da lokal verhält: Wenn ich den joystick nach hinten ziehe geht die nase immer lokal nach oben - die globale Richtung ist herzlich egal, wenns dun läuft würde die mich völlig auf der falschen Achse verdrehen. Man könnte sich das ganze zwar auch durch 2 Vektoren merken, die mir mein Koordinatensystem aufspannen, aber genausogut kann ich dann gleich eine Matrix nehmen - so geizig muss man nicht sein und es hat dann sofort den vorteil, daß ich mich in mein lokales Koordinatensystem umrechnen kann - wozu auch immer ich das benötige (K.I. z.B.).
Ich hab mir da immer beholfen, indem ich meinen Up-Vektor abhängig von der Blickrichtung berechnet habe. Einfach help=(Blicky, Blickx,0). und Oben=Blick x help. Geht natürlich nicht, wenn man direkt nach oben/unten schaut. dann muss man ein mü einführen, ab dem help nicht neu berechnet wird.
Oder man nimmt help grundsätzlich mit als Einheitsvektor auf der x/y Ebene, der bei Drehungen auch gedreht wird. damit kann man sich dann auch Drehungen bei Blickrichtung entlang der z-achse merken.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Hab ich ja beschrieben, daß das ohne Stress geht sich das mitzuführen. Und man kann aus den 2 Vektoren dann mit dem Kreuzprodukt zu einem 3. Ergänzen. Schreibt man die 3 Vektoren nebeneinander (wir wollen mal von orthonormalen vektoren ausgehen), hat man eine Rotationsmatrix, die das globale in das lokale überführt. Statt jedesmal wenn mans braucht das Kreuzprodukt und sonstiges rumzurechnen, kann mans auch gleich immer in einer Matrix lassen und diese im bedarfsfall transponieren, um die Inverse Abbildung zu bekommen. Es hat also durchaus seine Vorteile die Sache als Matrix zu handhaben. Die Sache mit dem mu die Du da erklärst hab ich aber jetzt nicht verstanden, wozu Du das brauchst. Man kann sich diese Konstruktion nämlich erstparen, wenn man bei deinen Help Richtungen keine 0 erzwingt. Ach ja... Eventuell sind hier grad die transponierten Matrizen vertauscht... Darüber muss man genauer nachdenken und sich aufmalen. Ich konnte mir den Basiswechsel in Linalg nie dauerhaft merken Ich verwechsel immer die Richtungen. Also alles modulo transponieren.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Wenn ich jetzt boshaft wär, würd ich sagen: das hab ICH aber nicht verstanden (bin zwar nicht blond, aber nehmen wir mal an, ich wäre es).
Traude
@Nico: Wenn ich ehrlich bin, so könnte ich durchaus Nachhilfe in Matrizenrechnung brauchen. Ich habe Deine Mathe-Tutorials so schnell ich konnte verschlungen und sie haben mir sehr geholfen. Und ich finde, eine Fortsetzung wäre ein echter Hit. Ich habe zum Beispiel an den Quaternionen herumgebissen, aber ich kann sie nicht implementieren, weil ich sie nicht begreife. Es scheint sich um eine Art Trick zu handeln, um die Schwierigkeiten zu vermeiden, die beim Lösen von Gleichungen höherer Ordnung auftreten. Ich habe statt dessen eine Lösung, wie OpenGl sie hat: eine Funktion, die eine Transformationsmatrix erzeugt und als Input einen Translationsvektor und einen Rotations"vektor" hat (bestehend aus einem Winkel und einem Vektor). Und die erzeugt nur eine Matrix, keine vier verschiedenen. Die Matrix verschiebt um einen beliebigen Vektor und rotiert um einen beliebigen Vektor. In alle meine 3D-Objekte habe ich ein Ding namens "System3D" eingebaut, das ein Orientierungssystem darstellt: Es merkt sich lokale Forward/Upward/Right-Vektoren (zwei davon würden eigentlich genügen) und den aktellen Rotations"vektor" des Objekts. In einem Skeleton hat jedes Bone so ein Orientierungssystem. Der Gimbal Lock tritt dabei nicht auf.
Mitglieder in diesem Forum: Majestic-12 [Bot] und 3 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.