Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Guten Abend, Ich arbeite an einer kleinen Engine in WebGl.
Vorgeschichte: Bisher funktionierte eine grobe Steuerung der Kamera ohne Probleme mit Matrizen. Jetzt wollte ich jedoch eine umschaltbare Kamera haben von First zu Third Person oder auch gänzlich frei in der Bewegung haben. Das klappte nach tagelangen Rumprobieren und Durchstöbern nicht. Irgendwie scheinen auch sehr viele Formeln/Beispiele die es im Internet gibt bei mir nicht direkt zu gehen, so wie sie sollten.
Die Spielfigur hatte ich mit Matrizen irgendwann im Griff und ich konnte sie auch korrekt steuern. Jedoch gelang es mir nicht dir Kamera auf den Spieler zu richten und gleichzeitig hinter ihm zu platzieren. Eines von beiden funktionierte immer nur. Wollte ich dann die Kamera drehen lassen, drehte sie sich immer um den Szenenursprung. Inzwischen gab es auch viele Multiplikationen und Invertierungen, weshalb ich alles auf Quaternionen umgestellt habe, was über 20% schneller und eigentlich auch einfacher nachvollziehbar ist.
Jedoch bekomme ich es immer noch nicht hin.
Probleme: 1. Der Spieler kann sich nur noch auf den Weltkoordinatenachsen bewegen, bei den Matrizen wusste ich wie ich den Translationsvektor bearbeiten muss, damit er sich auf die lokalen Koordinatenachsen des Spielerobjektes auswirkt. Bei Quaternionen leider nicht, außer ich forme sie erst in eine Matrix um, aber dann ist der ganze Witz an der Sache weg wie ich finde.
2. Die Kamera rotiert immer um den Ursprung, das Problem hatte ich schon vorher oft. Aktuell ist das Cameraquaternion nur das invertierte Spielerqquaternion. Bei den Matrizen war das Problem immer, dass die Kamera sich um eine Position etwas weiter vor sich rotierte und nicht genau um die eigene Y-Achse.
3. Wenn ich die Camera kippe um 45° um die X-Achse, dann bewegt sie sich auch nach oben oder unten weg beim bewegen, was ungewollt ist. Das liegt auch mit Problem 1 zusammen, dass ich nicht mehr weiß, wie ich an die korrekten Achsen komme. Ich hab einige Funktionen versucht die Vektoren mit den Quaternionen zu rotieren, aber dann wird alles nur noch merkwürdiger.
4. Seit ich Quaternionen einsetze scheint die Normalenmatrix nicht mehr zu stimmen, gut zu erkennen an dem einen Affenkopf, wenn das Licht auf der Z-Achse verschoben wird. Muss da etwas spezielles beachtet werden anstatt das invertierte Quaternion zu nehmen und in eine 3x3 Matrix umzuformen? Eventuell stimmen auch die Bi/Tangenten und Normalen nicht (Mit N aktivierbar).
Live-Beispiel: Damit sich das auch angeguckt werden kann, am besten in Chrome, dort sind Schieberegler vorhanden. http://tunnistava.systemcloud.de/ oben/unten/links/rechts : Pfeiltasten zum steuern (Richtungen stimmen aber irgendwie nicht) n: aktiviert die Normalen/Tagenten/Bitagenten-Ansicht a: aktiviert Antialising mit Fxaa (was noch nicht korrekt geht)
Codeausschnitte: Ich benutze Matrizen die so aufgebaut waren/sind:
Projektionsmatrix ist klar. modelviewmatrix ist meine Cameramatrix. transformationsmatrix ist die Matrix des VBO-Objektes mit Drehungen und Verschiebungen, aus Performancegründen wird die Multiplikation im Shader gemacht.
Steuerungupdate pro Frame:
Code:
this.update = function() {
this.camera.createViewport();
var fps = this.fpsCounter.getFPS();
var faktor = (fps > 0) ? fps : 1.0;
var playerMatrix = this.player.getMatrix().duplizieren();
var speed = this.player.getPhysik().getSpeed();
var newX = new Vektor4();
var newZ = new Vektor4();
var playPo = playerMatrix.holePosition();
if (this.accelerationSeitlich > 0 || this.accelerationSeitlich < 0) {
Hoffe einer hat eine clevere Idee, ich komme seit Wochen nicht wirklich voran. Nichts scheint zu helfen und ich rate mehr ins Blaue inzwischen, als dass ich mir noch etwas herleiten kann.
Grüße
_________________ System: Phenom XII X4 955 3,21Ghz , GTX 560 TI, 4GB-Ram, Windows 7 64x
bei den Matrizen wusste ich wie ich den Translationsvektor bearbeiten muss, damit er sich auf die lokalen Koordinatenachsen des Spielerobjektes auswirkt. Bei Quaternionen leider nicht, außer ich forme sie erst in eine Matrix um, aber dann ist der ganze Witz an der Sache weg wie ich finde.
Quaternionen alleine können ausschließlich Rotationen darstellen. Keine Translation und keine Skalierung. ABER, du kannst Quaternionen mit einem Translationsvektor kombinieren und das ganze in eine Klasse verpacken, so dass der Translationsvektor immer korrekt aktualisiert wird.Bei Coolmath gibt es die "Frame"-Klasse die genau das macht.
Für deine Kamera brauchst du aber eigentlich keine Quaternionen. Es sollte ausreichen dir eine LookAt-Funktion zu bauen. Dort gibt du einfach die gewünschte Kameraposition und den Punkt auf den sie blicken soll an. Außerdem noch einen Up-Vektor um anzugeben wo oben im Bild sein soll. Siehe auch http://wiki.delphigl.com/index.php/gluLookAt
In CoolMath sieht die Funktion so aus:
Code:
template<typename T, int N, int M>
Matrix<T,4,4> Matrix<T,N,M>::lookAt(const Vector<T,3>& eye, const Vector<T,3>& center, const Vector<T,3>& up)
{
STATIC_ASSERT(N==4&& M==4, "Operation only allowed for 4x4 matrices.");
Vector<T,3> f = center - eye;
f.normalize();
Vector<T,3> s = cross(f, up);
s.normalize();
Vector<T,3> u = cross(s, f);
return Matrix<T,4,4>( s.x, u.x, -f.x, 0,
s.y, u.y, -f.y, 0,
s.z, u.z, -f.z, 0,
-dot(s,eye), -dot(u,eye), dot(f,eye), 1);
}
Edit:
Zitat:
Muss da etwas spezielles beachtet werden anstatt das invertierte Quaternion zu nehmen und in eine 3x3 Matrix umzuformen?
Die Normalmatrix ist die invertierte und transponierte WorldView-Matrix. Also nicht vergessen zu transponieren. Da du aber dank Quaternionen nur Rotation und ggf. Translation hast (und keine Skalierung oder Scherungen) heben sich das invertieren und transponieren gegenseitig auf. Du kannst also einfach den 3x3-Teil der resultierenden Matrix benutzen.
Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Edit: Ich glaube die Mathematik wird an sich stimmen, aber meine Vorgehensweise wohl nicht. Vielleicht muss ich nur irgendetwas normalisieren bzw. invertieren. Diese Mathematik ist nichts für mich.
1. Auf einen Tastendruck reagieren und einen Vektor erstellen z.B. 1,0,0 für eine Bewegung in X-Richtung 2. Spielerquaterion rotieren bei Mausbewegung
Variante1 3. Auf den neuen Vektor die alten Positionen dazuaddieren 4. Die Position dem Spielerobjekt zuordnen 5. Beim Zeichnen des VBOs die Rotationsmatrix aus dem Quaterion erzeugen 6. Die Felder [12], [13], [14] auf die Vektorkoordinaten X, Y, Z setzen
Variante2 3. Den Vektor mit einer der Methoden unten drehen 4. Dann zur alten Position dazuaddieren 5. Beim Zeichnen des VBOs die Rotationsmatrix aus dem Quaterion erzeugen 6. Die Felder [12], [13], [14] auf die Vektorkoordinaten X, Y, Z setzen
Variante3 3. Auf den neuen Vektor die alten Positionen dazuaddieren 4. Die Position dem Spielerobjekt zuordnen 5. Beim Zeichnen des VBOs die Rotationsmatrix aus dem Quaterion erzeugen 6. Die Felder [12], [13], [14] auf die Vektorkoordinaten X, Y, Z setzen, welche vorher mit einer der Methoden unten gedreht werden
------------- Ich hab auch eine eigene Klasse, die beides kapselt und anpasst, jedoch klappt die Vektoranpassung einfach noch nicht.
Code:
v' = q * v * (q^-1)
q*/(magnitude(q))^2 (q* is the conjugate)
implementiert in this.rotationsVektor2
Ist die Formel die ich oft dazu finde. Hier sind alle Varianten die ich durchprobiert habe. Setze ich dann die Werte in die Matrix ein passiert oft nichts, als dass sich die Figur weiterhin auf den Weltachsen bewegt. Ich bin durch das wochenlange Ausprobieren und durchlesen einfach nur total verwirrt, dabei wird es ganz einfach sein. Wenn ich Zuerst eine Matrix erstelle aus dem Quaterion und mit einer Translationsmatrix multipliziere dann geht es. Ich hatte auch schon einige LookAt-Funktionen probiert, aber die wollten auch nicht so wirklich funktionieren. Diese scheint bisher besser zu gehen, solange die Vektoren stimmen. Danke dafür schon mal (:
Code:
this.rotationsVektor = function(vektor) {
var vec = new Vektor4(); // any constructor will do
Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Hallo, ich hab es teilweise hinbekommen mit Quaternionen, nur die Kamera will noch nicht ganz so wie sie sollte.
1. Also mit der lookAt Funktion kann ich zwar den Charakter oder in beliebiges Objekt im Fokus halten, jedoch sind die Eye-Koordinaten falsch. Selbst wenn ich etwas einsetze bewegt sich die Kamera komisch. Der Eye-Vektor wird als Abstand zum Koordinaten Ursprung genommen, so dass sie um den Ursprung dreht. 1.1 Deshalb habe ich das jetzt mit Quaternionen gemacht. Das einzige Problem was jetzt besteht, ist, dass die Kamera zwar korrekt um den Charakter kreisen kann, allerdings nicht auf ihn blickt. sondern immer in eine feste Richtung. Nach der Invertierung kann ich zwar weitere Drehungen anwenden, die sich nur auf die Kamera beziehen, jedoch werden dann auch wieder die Koordinaten beeinflusst.
Code:
var pV = playerQuat.holePositionE(10.0);
/*
this.holePositionE = function(faktor) {
var localVor = this.holeVorwaerts(); // Hole den aktuellen Vektor für die Lokale Z-Achse
localVor.x *= faktor; // Vektor skalieren für den Abstand
localVor.y *= faktor;
localVor.z *= faktor;
var gesamt = Math3D.addierenV4V4(localVor, this.vektor); // Verschiebung addieren
return gesamt;
};
*/
pV.x = pV.x*-1; // Die Invertierung wird später mal woanders gemacht werden, wenn alles klappt
pV.y = 2*-1;
pV.z = pV.z*-1;
var cameraQuat = new Quaterion(); //neues Quaternion
cameraQuat.identity(); // x,y,z =0, w =1
cameraQuat.invertieren();
cameraQuat.setzePosition(pV); // Position setzen
2. Der Charakter kann jetzt korrekt bewegt und gedreht werden. Mein Problem war, dass die falschen Achsen benutzt wurden und nicht die korrekten lokalen Y- und X-Achsen. Für alle, die das auch brauchen:
Code:
var rotQuatY = new Quaternion(); //neues Quaternion
rotQuatY.identity(); // x,y,z =0, w =1
if (this.deltaX) { //wenn Mausdrehung links/rechts
Mitglieder in diesem Forum: 0 Mitglieder 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.