MISE À JOUR L'erreur ici était assez simple. J'ai raté une conversion de radian en degrés. Pas besoin de lire le tout si vous avez un autre problème.
J'ai regardé plusieurs tutoriels à ce sujet et quand j'ai cru comprendre, j'ai essayé d'implémenter une caméra basée sur quaternion. Le problème est qu'il ne fonctionne pas correctement, après avoir tourné pendant env. 10 degrés, il revient à -10 degrés. Je n'ai aucune idée de ce qui ne va pas. J'utilise openTK et il a déjà une classe quaternion. Je suis un noob chez opengl, je fais ça juste pour le plaisir, et je ne comprends pas vraiment les quaternions, donc je fais probablement quelque chose de stupide ici. Voici du code: (En fait, presque tout le code, sauf les méthodes qui chargent et dessinent un vbo (il est tiré d'un exemple OpenTK qui illustre les vbo-s))
Je charge un cube dans un vbo et initialise le quaternion pour la caméra
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);
}
Je charge ici une projection en perspective. Ceci est chargé au début et chaque fois que je redimensionne la fenêtre.
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);
}
Ici, j'obtiens la dernière valeur de rotation et crée un nouveau quaternion qui ne représente que la dernière rotation et le multiplie avec le quaternion de la caméra. Après cela, je le transforme en axe-angle afin que opengl puisse l'utiliser. (Voici comment je l'ai compris à partir de plusieurs tutoriels quaternion en ligne)
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();
}
Voici 2 images pour mieux expliquer: je tourne un moment et à partir de là:
ça saute dedans
Toute aide est appréciée.
Update1 : je les ajoute à un streamwriter qui écrit dans un fichier:
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);
Le journal est disponible ici: http://www.pasteall.org/26133/text . À la ligne 770, le cube saute de droite à gauche lorsque camerarot.Y change de signe. Je ne sais pas si c'est normal.
Update2 Voici le projet complet.