Làm cách nào để triển khai máy ảnh dựa trên bộ tứ?


14

CẬP NHẬT Lỗi ở đây là một lỗi khá đơn giản. Tôi đã bỏ lỡ một radian để chuyển đổi độ. Không cần phải đọc toàn bộ nếu bạn có một số vấn đề khác.

Tôi đã xem xét một số hướng dẫn về điều này và khi tôi nghĩ rằng tôi hiểu tôi đã cố gắng thực hiện một máy ảnh dựa trên tứ phương. Vấn đề là nó không hoạt động chính xác, sau khi xoay khoảng. 10 độ nó nhảy trở lại -10 độ. Tôi không biết có chuyện gì. Tôi đang sử dụng openTK và nó đã có một lớp bậc bốn. Tôi là một người không biết gì về opengl, tôi làm việc này chỉ để giải trí và không thực sự hiểu được các mối quan hệ, vì vậy có lẽ tôi đang làm điều gì đó ngu ngốc ở đây. Đây là một số mã: (Trên thực tế hầu như tất cả các mã ngoại trừ các phương thức tải và vẽ vbo (nó được lấy từ một mẫu OpenTK thể hiện vbo-s))

Tôi tải một khối lập phương vào một vbo và khởi tạo bộ tứ cho máy ảnh

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);
}

Tôi tải một hình chiếu phối cảnh ở đây. Điều này được tải ở đầu và mỗi khi tôi thay đổi kích thước cửa sổ.

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);
}

Ở đây tôi nhận được giá trị xoay cuối cùng và tạo ra một phần tư mới chỉ đại diện cho phần xoay cuối cùng và nhân nó với phần tư của máy ảnh. Sau đó, tôi chuyển đổi nó thành góc trục để opengl có thể sử dụng nó. (Đây là cách tôi hiểu nó từ một số hướng dẫn tứ phương trực tuyến)

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();
}

Dưới đây là 2 hình ảnh để giải thích rõ hơn: Tôi xoay một lúc và từ đây:

điều này

nó nhảy vào đây

nhập mô tả hình ảnh ở đây

Bất kỳ trợ giúp được đánh giá cao.

Update1 : Tôi thêm những thứ này vào một streamwriter ghi vào một tệp:

    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);

Nhật ký có sẵn ở đây: http://www.pasteall.org/26133/text . Tại dòng 770, khối lập phương nhảy từ phải sang trái, khi người quay phim.Y thay đổi dấu hiệu. Tôi không biết nếu điều này là bình thường.

Update2 Đây là dự án hoàn chỉnh.


2
Tôi không hiểu vấn đề. Bạn đã thử in ra các phần tư mà bạn đang sử dụng để kết xuất chưa?
Nicol Bolas

1
Đồng ý, gỡ lỗi các giá trị rx, ry và Quancyion của bạn.
giảm tốc

Tại sao bạn không tải lên toàn bộ dự án của mình ở đâu đó để quickshare? Sẽ dễ dàng hơn.
bobobobo

OK tôi sẽ tải nó lên khi tôi về nhà.
gyozo kudor

Câu trả lời:


9

Mặc dù bạn chưa hiển thị mã cần thiết để xác minh giả định của tôi ở đây, tôi gần như có thể đảm bảo rằng vấn đề của bạn thực sự là dòng này:

cameraRot.ToAxisAngle(out axis, out angle);

đang trả về một giá trị góc được biểu thị bằng radian , trong khi

GL.Rotate(angle, axis);

muốn góc được cung cấp theo độ .

Để sửa nó, bạn cần chuyển đổi giá trị góc khi chuyển nó sang GL.Rotate (), như thế này:

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

Vâng, đó là vấn đề. :) Cảm ơn rất nhiều. Tôi biết opengl mong đợi độ, tôi giả định rằng ToAxisAngle trả lại độ. Tôi chỉ nhìn vào mã opentk và đó là radian. BTW Tôi đã cung cấp mã nguồn đầy đủ vào cuối.
gyozo kudor

@NickCaplinger chỉ ra một cách chính xác rằng trong C #, có một Math.Pihằng số khả dụng, nên được sử dụng theo sở thích đối với giá trị bằng chữ 3.141593 mà tôi đã sử dụng trong phép tính cuối cùng đó.
Trevor Powell

1

Đừng. Có vẻ như sẽ ít hoạt động hơn khi có một máy ảnh có thể được thao tác như các đối tượng cảnh khác, nhưng về lâu dài sẽ tốt hơn khi có một máy ảnh trong đó bạn có thể xác định vị trí, hướng mắt và hướng lên trên. Đặc biệt là khi bạn bắt đầu lập trình các mô hình chuyển động, thực sự rất khó để làm việc với các bộ tứ.


1
Đã đồng ý. Tôi không phải là người hâm mộ phương pháp "nếu khó phát âm thì nó phải tốt hơn" để thiết kế các ứng dụng của tôi, quá =)
Patrick Hughes

Đệ tứ khó phát âm?
thịt

1
Một chút hài hước đi một chặng đường dài = D Theo suy luận tôi ngụ ý rằng câu hỏi đến từ một người không biết tại sao anh ta muốn có một máy ảnh tứ phương, chỉ là đó là một từ thông dụng gọn gàng và OMG tôi muốn nó bây giờ thật tệ! Đây chắc chắn không phải là một vấn đề cần giải quyết khi một cái gì đó như xử lý radian và các tham số độ chính xác trong mã bị hỏng ở trên không được xử lý đúng cách.
Patrick Hughes

3
Câu hỏi này không thực sự về máy ảnh; đó là về cách biểu diễn các phép quay trong mã trò chơi và cách chuyển đổi các biểu diễn trò chơi đó thành một hình thức để OpenGL có thể sử dụng chúng. Đây là một câu hỏi hoàn toàn chính đáng và tôi không nghĩ việc chế giễu việc thiếu kinh nghiệm tên miền của OP là hữu ích theo bất kỳ cách nào. Nó không giống như OP đã phạm một sai lầm ngu ngốc; Sự khăng khăng của OpenGL về việc sử dụng độ khi thể hiện các góc là hết sức kỳ quái. Mọi người đều mắc lỗi này lần đầu tiên khi sử dụng OpenGL. Vì vậy, xuống ngựa cao của bạn, mọi người. Trời ạ.
Trevor Powell

Tôi chỉ muốn hiểu làm thế nào một máy ảnh dựa trên tứ phương hoạt động và tôi đã thực hiện dự án này trong một ngày khi tôi không có gì khác để làm. Tôi không có kế hoạch thực sự với điều này.
gyozo kudor

0

Không biết nhiều về nội bộ OpenTK. Theo kinh nghiệm của tôi, tôi đã không thấy thư viện toán học với việc thực hiện đúng quat mà giữ độ chính xác cần thiết (máy), bởi vì tất cả chúng đều ảnh hưởng đến e ^ 2-e ^ 3 lỗi. Vì vậy, hiệu ứng bạn thấy: độ chính xác (và giá trị epsilon) là khoảng 10 ^ -5 và nó 'nhảy' gần bằng không. Đây là dự đoán của tôi :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.