ฉันจะใช้กล้องที่มีพื้นฐานเป็น quaternion ได้อย่างไร


14

อัพเดทข้อผิดพลาดที่นี่เป็นเรื่องง่าย ฉันพลาดเรเดียนถึงการแปลงองศา ไม่จำเป็นต้องอ่านทุกอย่างถ้าคุณมีปัญหาอื่น

ฉันดูบทเรียนหลายอย่างเกี่ยวกับเรื่องนี้และเมื่อฉันคิดว่าฉันเข้าใจฉันพยายามที่จะใช้กล้องที่เป็น quaternion ปัญหาคือมันทำงานไม่ถูกต้องหลังจากหมุนไปประมาณ 10 องศากระโดดกลับไปที่ -10 องศา ฉันไม่รู้ว่าเกิดอะไรขึ้น ฉันใช้ openTK และมีคลาส quaternion อยู่แล้ว ฉันเป็น noob ที่ opengl ฉันกำลังทำเพื่อความสนุกและไม่เข้าใจ quaternions ดังนั้นฉันอาจจะทำอะไรโง่ ๆ ที่นี่ นี่คือรหัสบางส่วน: (จริงๆแล้วเกือบทั้งหมดรหัสยกเว้นวิธีการที่โหลดและวาด vbo (มันถูกนำมาจากตัวอย่าง OpenTK ที่แสดงให้เห็นถึง vbo-s))

ฉันโหลดลูกบาศก์ลงใน vbo และเริ่มต้น quaternion สำหรับกล้อง

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 สามารถใช้งานได้ (นี่คือวิธีที่ฉันเข้าใจจากบทเรียนออนไลน์ quaternion หลายบท)

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 คิวบ์จะกระโดดจากขวาไปซ้ายเมื่อคาเมอโรต์ Y เปลี่ยนสัญญาณ ฉันไม่รู้ว่านี่เป็นเรื่องปกติหรือไม่

Update2 นี่คือโครงการที่สมบูรณ์


2
ฉันไม่เข้าใจปัญหา คุณลองพิมพ์คำถามที่คุณใช้ในการเรนเดอร์ด้วยหรือไม่?
Nicol Bolas

1
ตกลงทำการดีบักค่า rx, ry และ Quaternion ของคุณ
ชะลอตัวลงขณะที่

ทำไมคุณไม่อัปโหลดโครงการทั้งหมดของคุณไปที่การแชร์อย่างรวดเร็ว จะง่ายขึ้น
bobobobo

ตกลงฉันจะอัปโหลดเมื่อกลับถึงบ้าน
gyozo kudor

คำตอบ:


9

แม้ว่าคุณจะไม่ได้แสดงรหัสที่จำเป็นเพื่อยืนยันสมมติฐานของฉันที่นี่ แต่ฉันเกือบจะรับประกันได้ว่าปัญหาของคุณคือบรรทัดนี้:

cameraRot.ToAxisAngle(out axis, out angle);

กำลังคืนค่ามุมที่แสดงเป็นเรเดียนในขณะที่

GL.Rotate(angle, axis);

ต้องการมุมที่จะให้อยู่ในองศา

ในการแก้ไขคุณต้องแปลงค่ามุมเมื่อผ่านไปยัง GL.Rotate () เช่นนี้:

GL.Rotate(angle * 180.0/3.141593, axis);

ใช่นั่นเป็นปัญหา :) ขอบคุณมาก. ฉันรู้ว่า opengl คาดหวังดีกรีฉันคิดว่า ToAxisAngle ให้ผลตอบแทนดีกรี ฉันเพิ่งดูรหัส opentk และมันเป็นเรเดียน BTW ฉันได้ให้รหัสที่สมบูรณ์ในตอนท้าย
gyozo kudor

@NickCaplinger ชี้ให้เห็นอย่างถูกต้องว่าใน C # มีMath.Piค่าคงที่พร้อมใช้งานซึ่งควรใช้เพื่อกำหนดค่าตามตัวอักษร 3.141593 ที่ฉันใช้ในการคำนวณขั้นสุดท้าย
เทรเวอร์พาวเวล

1

อย่า มันอาจดูเหมือนว่ามันจะทำงานน้อยกว่าถ้าจะมีกล้องที่สามารถจัดการได้เหมือนกับวัตถุฉากอื่น ๆ แต่ในระยะยาวมันจะดีกว่าถ้ามีกล้องที่คุณสามารถกำหนดตำแหน่งทิศทางตาและเวกเตอร์ขึ้นได้ โดยเฉพาะอย่างยิ่งเมื่อคุณเริ่มเขียนโปรแกรมแบบจำลองการเคลื่อนไหวมันเป็นความเจ็บปวดในการทำงานกับ quaternions


1
ตกลง ฉันไม่ได้เป็นแฟนของ "ถ้ามันยากที่จะออกเสียงมันจะต้องดีขึ้น" วิธีการของการออกแบบการใช้งานของฉันมากเกินไป =)
แพทริคฮิวจ์

Quaternion ยากที่จะออกเสียง?
notlesh

1
อารมณ์ขันเล็ก ๆ น้อย ๆ ไปไกล = D โดยการอนุมานฉันหมายความว่าคำถามนั้นมาจากคนที่ไม่มีความคิดว่าทำไมเขาถึงต้องการกล้อง quaternion แค่ว่ามันเป็นคำพูดที่เรียบร้อยและ OMG ฉันต้องการมันแย่มากตอนนี้! แน่นอนว่าไม่ใช่เรื่องที่ต้องแก้ไขเมื่อบางอย่างเช่นการจัดการเรเดียนและพารามิเตอร์องศาอย่างถูกต้องในโค้ดที่ใช้ไม่ได้นั้นไม่ได้รับการจัดการอย่างถูกต้อง
Patrick Hughes

3
คำถามนี้ไม่ได้เกี่ยวกับกล้องจริงๆ มันเกี่ยวกับวิธีการแสดงการหมุนในรหัสเกมและวิธีการแปลงการนำเสนอเกมเหล่านั้นเป็นรูปแบบที่ OpenGL สามารถใช้งานได้ มันเป็นคำถามที่ถูกต้องสมบูรณ์แบบและฉันไม่คิดว่าการเยาะเย้ยการขาดประสบการณ์ด้านโดเมนของ OP จะเป็นประโยชน์ แต่อย่างใด มันไม่เหมือนที่ OP ทำผิดพลาด การยืนหยัดของ OpenGL ในการใช้องศาเมื่อแสดงมุมเป็นสิ่งที่แปลกมาก ทุกคนทำสิ่งนี้ผิดพลาดเป็นครั้งแรกโดยใช้ OpenGL ดังนั้นจงลงมาจากม้าผู้คนเถิด โธ่
Trevor Powell

ฉันแค่อยากจะเข้าใจว่ากล้องที่ใช้ quaternion ทำงานอย่างไรและฉันทำโครงการนี้ในวันที่ฉันไม่มีอะไรทำ ฉันไม่มีแผนจริงกับสิ่งนี้
gyozo kudor

0

ไม่ทราบมากเกี่ยวกับการใช้งานภายในของ OpenTK จากประสบการณ์ของฉันฉันไม่เห็นไลบรารี่คณิตศาสตร์ที่มีการใช้ quat ที่เหมาะสมซึ่งต้องมีความแม่นยำ (เครื่องจักร) เพราะทั้งหมดนั้นมีผลต่อข้อผิดพลาด e ^ 2-e ^ 3 ดังนั้นเอฟเฟกต์ที่คุณเห็น: ความแม่นยำ (และค่า epsilon) มีค่าประมาณ 10 ^ -5 และ 'กระโดด' ใกล้กับศูนย์ นี่คือการเดาของฉัน :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.