UPDATE Der Fehler hier war ziemlich einfach. Ich habe eine Umrechnung von Bogenmaß in Grad verpasst. Sie müssen das Ganze nicht lesen, wenn Sie ein anderes Problem haben.
Ich habe mir mehrere Tutorials dazu angesehen und als ich dachte, ich verstehe, habe ich versucht, eine quaternionsbasierte Kamera zu implementieren. Das Problem ist, dass es nach ca. 10 Grad springt es auf -10 Grad zurück. Ich habe keine Ahnung, was los ist. Ich benutze openTK und es hat bereits eine Quaternion-Klasse. Ich bin ein Noob bei opengl, ich mache das nur zum Spaß und verstehe Quaternionen nicht wirklich, also mache ich hier wahrscheinlich etwas Dummes. Hier ist ein bisschen Code: (Eigentlich fast der gesamte Code außer den Methoden, die ein vbo laden und zeichnen (er stammt aus einem OpenTK-Beispiel, das vbo-s demonstriert).
Ich lade einen Würfel in ein VBO und initialisiere die Quaternion für die Kamera
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
cameraPos = new Vector3(0, 0, 7);
cameraRot = Quaternion.FromAxisAngle(new Vector3(0,0,-1), 0);
GL.ClearColor(System.Drawing.Color.MidnightBlue);
GL.Enable(EnableCap.DepthTest);
vbo = LoadVBO(CubeVertices, CubeElements);
}
Ich lade hier eine perspektivische Projektion. Dies wird zu Beginn geladen und jedes Mal, wenn ich die Fenstergröße verändere.
protected override void OnResize(EventArgs e) {
base.OnResize(e);
GL.Viewport(0, 0, Width, Height);
float aspect_ratio = Width / (float)Height;
Matrix4 perpective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect_ratio, 1, 64);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref perpective);
}
Hier erhalte ich den letzten Rotationswert und erstelle ein neues Quaternion, das nur die letzte Rotation darstellt, und multipliziere es mit dem Kameraquaternion. Danach wandle ich dies in Achsenwinkel um, damit opengl es benutzen kann. (So habe ich es aus mehreren Online-Quaternion-Tutorials verstanden.)
protected override void OnRenderFrame(FrameEventArgs e) {
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
double speed = 1;
double rx = 0, ry = 0;
if (Keyboard[Key.A]) {
ry = -speed * e.Time;
}
if (Keyboard[Key.D]) {
ry = +speed * e.Time;
}
if (Keyboard[Key.W]) {
rx = +speed * e.Time;
}
if (Keyboard[Key.S]) {
rx = -speed * e.Time;
}
Quaternion tmpQuat = Quaternion.FromAxisAngle(new Vector3(0,1,0), (float)ry);
cameraRot = tmpQuat * cameraRot;
cameraRot.Normalize();
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
Vector3 axis;
float angle;
cameraRot.ToAxisAngle(out axis, out angle);
//////////////////////////////////////////////////////////////////////
// THIS IS WHAT I DID WRONG: I NEED TO CONVERT FROM RADIANS TO DEGREES
//////////////////////////////////////////////////////////////////////
//BEFORE
//GL.Rotate(angle, axis);
//AFTER
GL.Rotate(angle * (float)180.0/(float)Math.PI, axis);
GL.Translate(-cameraPos);
Draw(vbo);
SwapBuffers();
}
Hier sind 2 Bilder zur besseren Erklärung: Ich drehe eine Weile und daraus:
es springt hinein
Jede Hilfe wird geschätzt.
Update1 : Ich füge diese einem Streamwriter hinzu, der in eine Datei schreibt:
sw.WriteLine("camerarot: X:{0} Y:{1} Z:{2} W:{3} L:{4}", cameraRot.X, cameraRot.Y, cameraRot.Z, cameraRot.W, cameraRot.Length);
sw.WriteLine("ry: {0}", ry);
Das Protokoll ist hier verfügbar: http://www.pasteall.org/26133/text . In Zeile 770 springt der Würfel von rechts nach links, wenn camerarot.Y die Vorzeichen wechselt. Ich weiß nicht, ob das normal ist.
Update2 Hier ist das komplette Projekt.
Antworten:
Obwohl Sie hier nicht den erforderlichen Code angegeben haben, um meine Vermutung zu überprüfen, kann ich fast garantieren, dass Ihr Problem tatsächlich in der folgenden Zeile besteht:
gibt einen Winkelwert im Bogenmaß zurück , während
möchte, dass der Winkel in Grad angegeben wird .
Um dies zu beheben, müssen Sie den Winkelwert konvertieren , wenn Sie ihn an GL.Rotate () übergeben:
quelle
Math.Pi
Konstante verfügbar ist, die dem Literalwert 3.141593 vorgezogen werden sollte, den ich in dieser endgültigen Berechnung verwendet habe.Nicht. Es mag den Anschein haben, als wäre es weniger arbeitsaufwendig, eine Kamera zu haben, die wie andere Szenenobjekte manipuliert werden kann. Auf lange Sicht ist es jedoch besser, eine Kamera zu haben, in der Sie Position, Blickrichtung und Aufwärtsvektor definieren können. Besonders wenn Sie anfangen, Bewegungsmodelle zu programmieren, ist es wirklich mühsam, mit Quaternionen zu arbeiten.
quelle
Ich weiß nicht viel über OpenTK-Interna. Nach meiner Erfahrung habe ich keine Mathematikbibliothek mit ordnungsgemäßer Implementierung von quat gesehen, die die erforderliche Präzision (Maschine) beibehält, da alle von ihnen e ^ 2-e ^ 3-Fehler betreffen. Der Effekt, den Sie sehen, ist also: Die Genauigkeit (und der Epsilon-Wert) liegen bei etwa 10 ^ -5, und sie springt in die Nähe von Null. Das ist meine Vermutung :)
quelle