GÜNCELLEME Buradaki hata oldukça basitti. Derece dönüşümü için bir radyanı kaçırdım. Başka bir sorununuz varsa her şeyi okumaya gerek yok.
Bununla ilgili birkaç öğreticiye baktım ve anladığımı düşündüğümde kuaterniyon tabanlı bir kamera uygulamaya çalıştım. Sorun yakl. 10 derece geri -10 dereceye atlar. Neyin yanlış olduğu hakkında hiçbir fikrim yok. OpenTK kullanıyorum ve zaten bir quaternion sınıfı var. Ben opengl'de bir çaylağım, bunu sadece eğlence için yapıyorum ve kuaterniyonları gerçekten anlamıyorum, bu yüzden muhtemelen burada aptalca bir şey yapıyorum. İşte bazı kod: (Aslında bir vbo yükleyen ve çizen yöntemler dışında neredeyse tüm kod (vbo-s gösteren bir OpenTK örneğinden alınır)
Bir vbo'ya bir küp yüklerim ve kamera için kuaterniyonu başlatırım
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);
}
Buraya bir perspektif projeksiyonu yüklüyorum. Bu başlangıçta yüklenir ve pencereyi her yeniden boyutlandırdığımda.
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);
}
Burada son dönüş değerini alıyorum ve sadece son dönüşü temsil eden yeni bir kuaterniyon oluşturuyorum ve kamera kuaterniyonu ile çarpıyorum. Bundan sonra bunu eksen açısına dönüştürüyorum ki opengl bunu kullanabilsin. (Bunu birkaç çevrimiçi quaternion dersinden anladım)
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();
}
İşte daha iyi açıklamak için 2 resim: Bir süre döndürüyorum ve bundan:
buna atlar
Herhangi bir yardım takdir.
Update1 : Bunları bir dosyaya yazan bir streamwriter'a ekliyorum:
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);
Günlüğü şu adreste bulabilirsiniz: http://www.pasteall.org/26133/text . 770 satırında, camerarot.Y işaretleri değiştiğinde küp sağdan sola atlar. Bunun normal olup olmadığını bilmiyorum.
Güncelleme2 İşte tam proje.