ich verzweifel grad ein wenig daran mir eine Kamera Steuerung wie in Maya zu basteln. Ich dachte eigentlich das sei nicht sonderlich schwer, aber irgendwie klappt es grad garnicht.. hab nen knoten im Gehirn.
Zuersteinmal zweifle ich grad daran ob es richtig ist das ich die Kamera-Transformation in der Modelview Matrix mache statt in der Projection Matrix.. das hatte ich damals gemacht da so ein paar licht berechnungen im Shader einfacher wurden.
Ich versuche z.B. ein "Pan" zu realisieren, also die kamera horizontal und vertikal bewegen.
Im grunde einfach:
Code:
position = position + upVector * y + rightVector * x;
Und als up und side Vector nehme ich einfach die erste, bzw zweite Spalte der Matrix.
Meine Matrix berechne ich so:
Code:
matrix.identity(); matrix.rotate(rx, ry, rz); matrix.translate(tx, ty, tz); // Im Local Space, also ich mache eine neue IdentityMatrix, setze die PositionSpalte und multipliziere diese mit der aktuellen.
das ganze binde ich dann bevor ich meine Scene zeichne so:
Code:
glMultMatrix(matrix.getInverted());
In der Modelview Matrix.
Wenn ich die Kamera nun rotiere dreht sie sich wie sie soll um den punkt (0, 0, 0).. aber das "Pan"-en funktioniert nicht... der Right/Up-Vector stimmt nicht, je nach rotieren kommt das Objekt im Weltmittelpunkt entweder auf mich zu oder bewegt sich seitlich... also das Pannen funktioniert nur wenn ich frontal drauf schaue..
Da ich grad schon daran zweifel ob meine Methode die KameraMatrix zu laden (im Modelview) und ob ich sie tatsächlich Invertieren muß, ist es etwas unpraktisch weiter an den Matrix-Berechnungen rumzufriemeln.. :/
Hat jemand einen Tipp für mich..? Oder falls jemand Maya hat/kennt.. ich möchte die Kamera Steuerung genau wie dort realisieren. z.B. wenn man Rotiert ändert sich in Maya nicht nur die rotation der Kamera sondern auch die Position.. wie wird das berechnet??
funktioniert es perfekt wie es soll.. mit position.x und position.y kann ich pannen, ohne das ich den Up/Right Vektor verrechnen muß. (Ich invertiere die matrix auch nichtmehr vor dem binden).
Allerdings will ich beim Pannen erreichen das man wenn ich z.B. um 20 Einheiten nach links panne, der punkt um den ich rotiere ebenfalls 20 einheiten weiter links liegt. Also ich immer um den viewport-mittelpunkt rotiere.
Denn die rotatiosnwerte werden addiert, aber der rotationspunkt ändert sich aufeinmal...
Also muß es in Maya irgendwie so gelöst sein das die Matrix ständig weiter transformiert wird und die werte die im UI stehen als Translation und Rotation nur aus dieser Matrix errechnet werden.
Nur.. wie?
Wenn ich die Matrix direkt transformiere bekomme ich sehr schnell einen GimbleLock (2 rotationsachsen liegen aufeinander, so das ich in eine richtung nichtmehr rotieren kann).. das ließe sich afaik nur vermeiten indem ich Quaternions für die Rotation benutze.. aber davon hab ich keine Ahnung
Und, das größte Probem ist glaube ich das ich meine Matrix immer komplett neu berechne aus Position, Rotation und Focus Punkt.
Hilfe~
Aya
Ich habe erst kürzlich selbst ein ähnliches Problem gehabt. Ich wollte eine Kamera realisieren, die um jede Achse beliebig rotierbar ist und auf jeder daraus resultierenden lokalen Achse auch translatierbar. Hat lange gedauert, viel gelesen, viel gezeichnet ... letztendlich habe ich es aber dann doch noch geschafft. Also kann ich mich jetzt frei im Raum bewegen und drehen - je nach belieben. Ich muss sagen, dass es als Anfänger recht schwer ist, sich das alles im Kopf vorzustellen - wie wo wann was berechnet wird etc.
Zu deinem Problem: Du kannst natürlich nicht mit einer gegebenen Position und Rotationswinkel jedesmal deine Matrix neu erstellen - da ja vorherige Rotationen bzw. Translationen berücksichtigt werden müssen, und zwar in der richtigen Reihenfolge.
Es macht beispielsweise einen wesentlichen Unterschied, ob ich mich erst um 90 Grad um meine eigene Körperlängsachse drehe (entspricht der y-Achse) und mich dann auf den Rücken lege (entspricht 90 Grad drehung um x-Achse), oder ob ich mich erst auf den Rücken lege und mich dann 90 Grad um meine Körperachse drehe. Im ersten Fall würde ich nämlich an die Decke schauen, im zweiten Fall würde ich eine Wand anschauen (parallel zum Fussboden).
Ich kann dir kurz erläutern wie ich vorgegangen bin (kann dir keinen code präsentieren, da ich in C++ programmiere): - grundsätzlich: es gibt keine Kamera, aber sie wird eben dadurch simuliert, dass die komplette Szene entsprchend transformiert wird. (ob ich eine Kamera an 2,0,0 aufstelle, oder die komkplette Szene um -2,0,0 verschiebe macht für den Betrachter ja keinen Unterschied. - ich habe mir eine Klasse geschrieben, die eine Kamera repräsentiert. Dort werden gespeichert:
aktuelle Position
Vorwärtsvektor
Up-Vektor
- Die beiden Vektoren sind bei mir ständig normalisierte Richtungsvektoren. - Daraus errechnet sich:
der Vektor für die Z-Achse als Skalarprodukt des Vorwärtsvektors mit -1
Vektor für die X-Achse: als Kreuzprodukt von up-Vektor und z-Vektor oder alternativ als Kreuzprodukt von Vorwärtsvektor und up-Vektor (Reihenfolge ist relevant)
- soll ein "strafen" möglich sein (also seitliche Bewegung) wird entsprechend der X-Vektor statt dem Vorwärtsvektor genommen und für vertikale Bewegungen der up-Vektor.
- fehlt noch das Setzen der Matrix. Über die beiden gespeicherten Vektoren lässt sich wie oben beschrieben der dritte Vektor errechnen (also der X-Achsen-Vektor). Aus diesen drei Vektoren kann eine Matrix erzeugt werden (bei mir ein array der Grösse 16). Entscheidend hierbei ist, dass die Werte der Vektoren an den richtigen Stellen im array stehen. - Array sieht wie folgt aus:
- genau dies war lange Zeit mein Problem, da ich die Werte in anderer Reihenfolge eingefügt hatte (gemäss meiner falschen Vorstellung) - in der render-Funktion rufst du nach glLoadIdentity() also nun entweder ein glMultMatrixf(matrixname); oder ein glLoadMatrixf(matrixname); auf - nun muss noch Translatiert werden durch ein glTranslatef(-Position.x, -Position.y, -Positon.z)
- Zu beachten ist, dass ich den Fokus (bzw. center oder wie auch immer man es bezeichnet - also den Punkt wohin man schaut) nicht als Werte des Weltkoordinatensystems gespeichert habe sondern eben nur als Richtungsvektor. - Möchte man die Kamera über gluLookAt setzen, muss dies bedacht werden:
Wenn ich die Matrix direkt transformiere bekomme ich sehr schnell einen GimbleLock (2 rotationsachsen liegen aufeinander, so das ich in eine richtung nichtmehr rotieren kann).. das ließe sich afaik nur vermeiten indem ich Quaternions für die Rotation benutze.. aber davon hab ich keine Ahnung
Nun, du könntest hin und wieder sicherstellen, dass die Achsen noch normal aufeinander sind. Jedenfalls, wenn nur Rotationen und Translationen erwünscht sind
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
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.