Die NaNs resultierten daraus, dass nach dieser Funktion alle localen Vektoren exorbitant angewachsen sind, nach kürster zeit irgendwelche riesigen werte hatten und dann auf NaN oder Infinity gesprungen sind. Durch Normalisierung des Vektors war das Behoben
Und das mit der Drehung in die Szene habe ich nun auch verstanden und wenn ich mich nun um einen Fixen Vektor (0,1,0) drehe, passiert auch genau das, was ich eigentlich erreichen wollte. Alles in allem ist es aber toll, dass ich nun um sovieles mehr flexibilitaet ereicht habe. Es scheint alles zu funktionieren, ich bastel nun die Translation noch mit rein, danke auf alle fälle für eure unermüdliche Hilfe
Hab inzwischen auch die Translation durch Keyevents eingebaut, das ist ja ziemlich einfach, ich addiere und subtrahiere lediglich die localen Vektoren von meinem Positionsvektor
Allerdings funktioniert die Multiplikation der Rotations- und translationsMatrix nicht. Bisher lade ich die Rotationsmatrix und führe danach manuell mit ogl die Translation durch.
der eigentliche Quellcode für die Kombination der beiden Matrizen:
Hab da schon verschiedenste Möglichkeiten ausgetestet. Den Postionsvektor vorher mit -1 skaliert, die Multiplation umdrehen usw. aber irgendwie scheint das doch noch fehlerhaft zu sein.
ich hatte es so verstanden, dass ich eine nuee Matrix mache, und in der w-spalte den Verschiebunsgvektor einsetze und danach die beiden Matrizen multipliziere.
Ansonsten muss ich mir jetzt noch ansehen, wie gluLookAt funktioniert, da ich diese funktionalitaet ja nun für meine Pfadbewegung nachbauen muss.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Wenn "Matrix" die bereits invertierte RotationsMatrix ist, dann kommentier die Zeile
"verschiebungsMatrix = Matrix.invert(verschiebungsMatrix);"
mal aus und versuch es nochmal.
Ich kann Dir jetzt keine genaue Erklärung dafür geben, aber bei mir funktioniert es so:
Ich glaube mal generell, dass ich Invertieren und Transponieren durcheinander werf. Transponieren ist ja Vertauschen von Spalten und Zeilen, wobei ich jetzt eben mal nach Invertieren gegooglet hab. Das ist was anders. Tja die Vektorrechnung ist doch schon etwas her ich informier mich da erstmal noch etwas, ehe ich hier weiter im Dunkeln stocher
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Das Ergebnis einer Multiplikation >> Matrix X Invertierte Matrix << ist die Einheitsmatrix, invertierte Matrizen sind also so etwas Ähnliches wie der Kehrwert der ursprünglichen Matrix.
Für orthogonale Matrizen gilt: Transponierte = Invertierte Matrix
Transponieren = Zeilen und Spalten vertauschen
Rotationsmatrizen sind orthogonal, daher sind hier Transponieren und Invertieren das Gleiche.
Wenn man eine leere Matrix 4X4 mit der Einheitsmatrix initialisiert und dann mit den Koordinatenachsen beschickt, sollte man gefahrlos transponieren können.
Und wenn deine Invertierungsprozedur noch die gleiche ist wie jene, die Du oben in den Beitrag gestellt hast: das ist eine Transponierung, keine Invertierung. Aber aus den oben genannten Gründen ist das in diesem Fall egal.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
BERICHTIGUNG
Ich berichtige mein vorletztes Post. Die Routine für die Erzeugung der Kameramatrix muss lauten:
Code:
CamMat:= MATIDENTITY;
// 3X3 Kameramatrix transponieren
CamMat[0].X:= CurRight.X;
CamMat[1].X:= CurRight.Y;
CamMat[2].X:= CurRight.Z;
CamMat[0].Y:= CurUp.X;
CamMat[1].Y:= CurUp.Y;
CamMat[2].Y:= CurUp.Z;
CamMat[0].Z:= CurForward.X;
CamMat[1].Z:= CurForward.Y;
CamMat[2].Z:= CurForward.Z;
// Invertierte Position hinzumultiplizieren
CamMat:= MatrixMultiply
(CamMat,MatrixShift(VectorInvers(CurPos)));
So ist es auch viel logischer: man nimmt die invertierte (= transponierte) Rotation
und auch die invertierte Position.
Ich bin deshalb ein wenig verwirrt gewesen, weil ich grade versuche, sowohl die Objekt- als auch die Kameratransformationen unter einen Hut (= in ein Objekt) zu bringen.
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
In wie fern versuchst du Object-Space und View-Space in ein Objekt zu bringen? Ich fürchte mich ein wenig bei der Vorstellung, weil ich nicht genau weiß was du damit bezwecken willst...
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ups, schlecht ausgedrückt. Ich verwende kein PushMatrix/Popmatrix, sondern bewege meine Objekte genauso wie die Kamera. Also, natürlich nicht genauso, die Kamera muss sich ja genau umgekehrt bewegen. Ungefähr so:
Ich habe eine Klasse TSystem3D. Das ist ein Navigationsobjekt für 3D-Objekte, mit denen man sie im Raum verschieben und verdrehen kann. Die Kamera hat auch so ein Objekt, der einzige Unterschied ist, dass bei einem normalen 3D Objekt die Achsen einfach in die Spalten hineingestellt werden und die Position so wie sie ist hinzumultipliziert wird, wohingegen bei einer Kamera die Matrix so erstellt werden muss, wie ich es oben gezeigt habe.
Die Methode TSystem3D.Rotate funktioniert ganz genauso, wie wir es oben besprochen haben.
Wie die Methode TSystem3D.Translate funktioniert, kannst Du dir sicher vorstellen, auch Shaddow hat festgestellt, dass das geradezu lächerlich einfach ist.
Das Ganze ist ist noch dazu winzig: hat rd. 90 Zeilen Code. Die Kameramatrix wird mit glLoadMatrix übergeben, die Objektmatrix mit glMultMatrix.
Also, bei mir funktionierts, getestet habe ich bisher nur Folgendes:
Objekt rotiert um seine eigene Y-Achse, Kamera kann sich ohne Einschränkungen bewegen. Rein theoretisch müsste man damit alle Objekte in jede denkbare Lage bringen können und die Kamera auch. Ist eine ganz hübsche Leistung für 90 Zeilen Code
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Öhm, ich fühle mich schuldig. Es ist natürlich keine tolle Sache, zu sagen, ich habe hier einen Source Code, und ihn gar nicht herzuzeigen. Daher hänge ich jetzt hier folgendes an:
Eine kleine Kamera-Demo in Form von Source-Code für ein lauffähiges Delphi-7-Programm. Es ist *keine* Exe dabei (aus Sicherheitsgründen) und auch die dglOpenGL.pas fehlt, denn ich nehme an, die habt ihr selber.
Die Kamera-Steuerung könnt Ihr in der Unit "CameraMain", Prozedur "TTestForm.FormKeyDown" nachsehen.
Das Ding ist mit mit einem brandneuen upgedateten Kasperski auf Viren überprüft.
Viele Güße,
Traude
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Sehr gut und einfach zu verstehen der Quellcode
Dass man daraus einmal das Rotations/Translationssystem für die Cam und auch selbiges für die Objekte bauen kann, fasziniert mich immernoch ^^
Das einzige, was ich noch nicht hinbekommen habe, ist die Camera, wie eine Camera zu rotieren. Wenn ich meine Camera drehe, sieht es immer so aus, aus würde sich das Objekt um seine Achse drehen, nicht aber die Camera um ihre Achse. Ich werd mir das morgen nochmal ansehen, auf jedenfall danke dir für den Quellcode. Mit ner netten Doku wäre das auch wirklich ein kandidat für das Wiki *find*
Okay nach einer Nacht Schlaf und nun einiger Zeit zum Drüber schaun nochmal.. hab ichs dennoch nicht hinbekommen ^^
Also nicht, dass ich nicht schon einiges sehen würde:
Wenn ich einem Objekt seine "Lokale Matrix" zuweise und es rotiere o.Ä. dann passiert das auch. Für die Camera an sich scheint das ganze aber irgendwie nicht ganz zu funktionieren. Ich bin mir inzwischen ziemlihc sicher, dass ich alles ziemlich richtig implementiert habe. Ich hatte vorher einige Änderungen im Quellcode, um das ganze mehr auf meine Bedürfnisse anzugleichen, aber als das dann nicht funktioniert hat, wie ich wollte, habe ich es nun 1:1 einfach nur in Java übersetzt. Folge ist, es sieht genauso aus wie vorher ^^ Also muss wohl doch irgendwo noch der Wurm drin sein.
Die zwei Fehler, die mir derzeit auffallen, sind:
- Manchmal bewegt sich die Camera bei einem goForward() nicht in Richtung des Forwardvektors, sondern in Richtung irgendeines anderen Vektors, der meist etwas schräg geneigt ist. Das allein irritiert mich schon, denn aus dem up, forward und left vektor wird ja auch die Matrix erstellt, die per glLoad geladen wird. Also müsste doch, da der forward-vektor eine Grundlage meiner Sicht ist, ein Schritt in Richtung des Forwardvektors immer korrekt ausgeführt werden (oder?). Es sei denn man verrechent sich bei der Addition des Forwardvektors mit dem Positionsvektor..
- Der zweite Fehler betrifft die Rotation. Eigentlich nicht wirklich ein Fehler in der Berechnung, wie es für mich scheint, denn es lassen sich ziemlich eindeutige Hinweise erkennen. Wenn ich meine Camera up/down, left/right drehe, wirkt es nicht, als drehe sich die Camera um sich selbst, sondern als drehe sich das Objekt um die Camera. Solange sich das Objekt auch wirklich um die Camera dreht, sollte es ja keinen unterschied zu dem Fall machen, dass sich die camera selbst dreht, wenn allerdings nicht die Camera das Zentrum des Kreises ist, sondern sie etwa daneben liegt (so scheint es zumindest, und ich habe keinen Schimmer warum), bemerkt man eben, dass offenbar nicht die Camera sich dreht, sondern das Objekt.
Falls euch irgendwelche Hinweise einfallen, wo man bei solchen Phänomenen schauen könnte, wäre ich sehr dankbar. Alles in allem scheint es, dass die Camera sich nie selbst dreht, sondern sich immer das Objekt um die Camera dreht
Edit: Witzig ist aber, dass ich mich, da ich mich nun ein wenig mit dem Code beschäftigt habe, einige Dinge besser verstanden habe, die hier genannt und besprochen wurden. Letztlich habe ich nun meine eigene Camera zum Laufen bekommen, auch wenn ich die Portierung deiner Cam auf Java irgendwie offenbar doch versemmelt hab^^
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Zitat:
- Manchmal bewegt sich die Camera bei einem goForward() nicht in Richtung des Forwardvektors, sondern in Richtung irgendeines anderen Vektors, der meist etwas schräg geneigt ist. Das allein irritiert mich schon, denn aus dem up, forward und left vektor wird ja auch die Matrix erstellt, die per glLoad geladen wird. Also müsste doch, da der forward-vektor eine Grundlage meiner Sicht ist, ein Schritt in Richtung des Forwardvektors immer korrekt ausgeführt werden (oder?). Es sei denn man verrechent sich bei der Addition des Forwardvektors mit dem Positionsvektor..
Ich habe mir grade das Demoprogramm nochmals angesehen. Ein solcher Fehler wäre mir aufgefallen. Hast Du Dich an die Vorgangsweise in TSystem3D.Rotate, TSystem3D.Translate UND TSystem3D.Matrix gehalten? Die Kamera-Matrix wird anders erzeugt als die Objektmatrix, siehe TSystem3D.Matrix. Dort wird die Matrix nicht etwa einfach übergeben sondern noch bearbeitet. Das hat in genau dieser Art und Weise zu erfolgen: die ersten drei Spalten und Zeilen werden transponiert, aus dem Shiftvektor wird eine Matrix erzeugt und hinzu multipliziert. Man kann z.B. nicht einfach den invertierten Spaltenvektor hinzufügen.
Zitat:
Falls euch irgendwelche Hinweise einfallen, wo man bei solchen Phänomenen schauen könnte, wäre ich sehr dankbar. Alles in allem scheint es, dass die Camera sich nie selbst dreht, sondern sich immer das Objekt um die Camera dreht
In OpenGL muss die Kamera simuliert werden, denn sie kann sich gar nicht drehen. Alle Bewegungen müssen daher in entgegengesetzter Richtung ausgeführt werden. Genau das macht eben TSystem3D.Matrix.
Zitat:
Letztlich habe ich nun meine eigene Camera zum Laufen bekommen, auch wenn ich die Portierung deiner Cam auf Java irgendwie offenbar doch versemmelt hab^^
Versemmelt?
Viele Grüße,
Traude
EDIT: Verzeihung, Ich habe mich oben etwas unklar ausgedrückt. Es soll nicht heißen:
" Man kann z.B. nicht einfach den invertierten Spaltenvektor hinzufügen." sondern
" Man kann z.B. nicht einfach den invertierten Positionsvektor hinzufügen."
Die ganze Zeit, die ich mich gewundert habe, warum hier die obskursten Dinge geschehen... lag der Fehler (es war wohl zu erwarten) an einer ganz anderen Stelle. Nachdem ich diesen Fehler nun eher durch Zufall gefunden habe, habe ich sowohl deinen Quellcode als auch meinen alten getestet und es funktioniert einfach alles..
Ich will nurmal kurz den Fehler hier darstellen, es lag schlicht daran, dass ich etwas von Java angenommen hatte, weil ich dergleichen Konstrukte schon sehr oft gesehen hatte, was aber einfach nicht der Annahme entsprach, die ich getroffen hatte...
würde bei jedem aufruf eine neue Instanz der Matrix erzeugen. Ich weiss nicht genau, warum ich das angenommen hatte, aber ich habe das Konstrukt wie gesagt schon oft gesehen und das final (bei delphi Const) hat mit darin noch etwas bestärkt.
Als ich dann aber vorhin eine Identitätsmatrix erzeugt habe, und bei jedem Renderdurchgang ausgegeben habe, die sich dann plötzlich veränderte, als ich meine Maus bewegte (Camerabewegung reagiert auf Maus), regte sich der Verdacht. Die Matrix, die ich erzeugt hatte, wurde genau einmal bei der Initialisierung mit Werten gefüllt und sonst nie wieder, und änderte aber fröhlich bei jeder Mausbewegung die Werte. Also lag der Gedanke nahe, dass die neue Matrix und die Cameramatrix ein und dieselbe waren... Darauf basierten offenbar alle fehler. Ich habe das obige Konstrukt durch eine Funktion ersetzt, die ganz sicher neuen Speicher bei jedem aufruf belegt und nicht Singletonartig bestehende Matrizen wiederverwendet. Und nun.. gehts
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.