更新ここでのエラーは非常に単純なものでした。ラジアンから度への変換を見逃しました。他の問題がある場合は、すべてを読む必要はありません。
私はこれについていくつかのチュートリアルを見て、四元数ベースのカメラを実装しようと思って理解したと思いました。問題は、約1分間回転させた後、正しく動作しないことです。10度戻ると-10度に戻ります。何が悪いのか分かりません。私はopenTKを使用していますが、すでにクォータニオンクラスがあります。私はopenglの初心者であり、楽しみのためだけにこれをやっており、四元数を本当に理解していないので、おそらくここで愚かなことをしているでしょう。ここにいくつかのコードがあります:(実際には、vboをロードおよび描画するメソッドを除くほとんどすべてのコード(vbo-sを示すOpenTKサンプルから取得されます))
vboにキューブをロードし、カメラのクォータニオンを初期化します
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);
}
ここに透視投影をロードします。これは、最初とウィンドウのサイズを変更するたびにロードされます。
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);
}
ここで、最後の回転値を取得し、最後の回転のみを表す新しいクォータニオンを作成し、カメラクォータニオンと乗算します。この後、これを軸角度に変換して、openglが使用できるようにします。(これは、いくつかのオンラインクォータニオンチュートリアルから理解した方法です)
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();
}
よく説明する2つの画像を次に示します。しばらくすると、これから回転します。
これに飛び込む
どんな助けも大歓迎です。
Update1:ファイルに書き込むストリームライターにこれらを追加します:
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);
ログはhttp://www.pasteall.org/26133/textから入手できます。770行目では、camerarot.Yが符号を変更すると、キューブが右から左にジャンプします。これが正常かどうかはわかりません。
アップデート2は、 ここでは完全なプロジェクトです。