2012-02-02 59 views
5

Máy ảnh của tôi xoay quanh một điểm khi tôi cố thay đổi hướng. Nếu tôi xoay máy ảnh của tôi, nói, 30 độ trong trục Y, thay vì camera nhìn 30 độ về bên phải, máy ảnh xoay quanh điểm mà nó đang nhìn.Tại sao máy ảnh của tôi xoay quanh một điểm với phép toán này?

o is the camera, A and B are 3D models. The lines show line-of-sight. 
This is what I expect: 
    A B 
    | >/
    |/
    |/
    |/ 
    o 

This is what actually happens: 
    A B 
    |\ 
    | \ 
    | \ 
    | > \ 
      o 

Bây giờ, theo hiểu biết của tôi, để di chuyển camera, tôi phải di chuyển thế giới bằng nghịch đảo của số tiền đó. Vì vậy, nếu tôi muốn di chuyển +1 trong trục Z, tôi dịch thế giới -1 trong trục Z. Vì tôi đang sử dụng quaternion để đại diện cho định hướng, tôi sử dụng nghịch đảo của quaternion camera (vì định hướng luôn là quaternion đơn vị, tôi tối ưu hóa bằng cách sử dụng liên hợp thay vì tính nghịch đảo) để xoay thế giới với số lượng phù hợp.

Sau đây là cách để chuyển đổi một quaternion đến một ma trận, trong đó q là quaternion đảo ngược:

[1 - 2 * (q.y * q.y + q.z * q.z) 2 * (q.x * q.y - q.w * q.z)  2 * (q.x * q.z + q.w * q.y)   0] 
|2 * (q.x * q.y + q.w * q.z)  1 - 2 * (q.x * q.x + q.z * q.z) 2 * (q.y * q.z - q.w * q.x)   0| 
|2 * (q.x * q.z - q.w * q.y)  2 * (q.y * q.z + q.w * q.z)  1 - 2 * (q.x * q.x + q.y * q.y)  0| 
[0         0         0         1] 

Sau đó, tôi thiết lập các thành phần dịch của ma trận:

[... ... ... -x] 
|... ... ... -y| 
|... ... ... -z| 
[0  0  0  1] 

Và cuối cùng Tôi nhân nó vào ngăn xếp ma trận xem mô hình, sau đó render tất cả các đối tượng của tôi. Tôi khá chắc chắn toán học này là chính xác, nhưng nó không tạo ra kết quả mà tôi mong đợi. Rõ ràng các vectơ về phía trước và bên phải là vấn đề, vì vậy câu hỏi duy nhất của tôi là tại sao chúng sai và chúng nên được đặt như thế nào nếu tôi muốn nhận được kết quả mà tôi mong đợi. Cảm ơn.

EDIT: Tôi đã tìm thấy giải pháp từ this guy's quaternion camera class. Đầu tiên tôi xây dựng một ma trận xoay như tôi đã làm trước đây, nhưng sau đó tôi lấy các vectơ cột của ma trận từ các cột đầu tiên, thứ hai và thứ ba (tương ứng, ya và za). Sau đó, tôi thiết lập các thành phần tịnh tiến của ma trận như thế này:

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

Sau đó, ma trận kết quả có thể được nhân lên ma trận modelview ngăn xếp, và nó hoạt động hoàn hảo.

+0

Hãy chỉnh sửa giải pháp của bạn và chấp nhận giải pháp đó. Đó là cách chúng tôi đánh dấu các câu hỏi được giải quyết quanh đây. Ngoài ra tôi nghĩ rằng bạn xứng đáng với một số giải thích những gì đang xảy ra. Tôi sẽ viết một câu trả lời cho điều này. – datenwolf

Trả lời

1

EDIT: Tôi đã tìm thấy giải pháp từ lớp máy ảnh quaternion của anh chàng này. Đầu tiên tôi xây dựng một ma trận xoay như tôi đã làm trước đây, nhưng sau đó tôi lấy cột vectơ của ma trận từ cột đầu tiên, cột thứ hai và thứ ba (xa, ya và za tương ứng). Sau đó, tôi thiết lập các thành phần tịnh tiến của ma trận như thế này:

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

Sau đó, ma trận kết quả có thể được nhân lên ma trận modelview ngăn xếp, và nó hoạt động hoàn hảo.

Vâng, đây chính xác là những gì tôi đã đề xuất, chỉ khác một chút. Bạn phải hiểu rằng OpenGL không có camera, nhưng thay vào đó bạn chỉ cần di chuyển thế giới theo hướng ngược lại, vì vậy bạn cần tìm ma trận chuyển đổi nghịch đảo.

Máy ảnh chỉ xoay và di chuyển. Điều này làm cho mọi thứ rất đơn giản. Tnverse của bản dịch chỉ là cùng một vector với dấu hiệu ngược lại, và nghịch đảo của một ma trận xoay là nó chuyển vị (cột và hàng trao đổi). Bây giờ nhìn vào một ma trận biến đổi đồng nhất như OpenGL sử dụng chúng:

R t 
0 1 

phía trên bên trái 3 × 3 là phần quay, cột ngoài cùng bên phải là vector dịch. Tôi nghĩ rằng phần còn lại bạn đã tự tìm ra.

0

Thành thật mà nói, cố gắng tìm ma trận nhân với ma trận mô-đun xem thực sự phức tạp và rất dễ xảy ra lỗi. Có rất nhiều sự nhầm lẫn và trường hợp đặc biệt. Ví dụ, nếu bạn đang tìm kiếm 90 độ lên, hai trục của bạn trở nên giống nhau. Một vấn đề hợp lý là: nếu bạn đang lăn đầu của bạn trở lại, vì vậy bạn đi qua các điểm trên cùng, vector lên của bạn nên được đảo ngược, phải không? Nhưng nếu bạn bỏ lỡ nó bằng một mức độ 0,0001? sau đó bạn nên quay đầu của bạn xung quanh điểm đó để vector lên của bạn vẫn còn lên.

Theo tôi, cách tốt nhất là tiếp cận vấn đề từ góc nhìn khác. Giả sử hai trường hợp:

  • Lộn ngược không thể:
    • Giữ một điểm cho vị trí của bạn máy ảnh và vĩ độ/kinh độ cho việc định hướng. Với hoạt động tội lỗi/cos đơn giản, bạn có thể nhận được véc tơ hướng. vector của bạn lên là (0, 1, 0)
    • đảo trộn chỉ đơn giản là thay đổi vĩ độ và kinh độ
  • Lộn ngược càng tốt:
    • Bên cạnh vị trí camera, giữ cho cả hai lên và vectơ mục tiêu.
    • Khi chuyển, tính toán = target x lên và sau đó thay đổi mục tiêu thành x * right + y * lên
    • Sau đó, bạn cần chuẩn hóa vector đích và tính toán mới. Rất nhiều trường hợp xử lý .

Sau tất cả, bạn chỉ cần gọi gluLookAt.

+0

"Thành thật mà nói, cố gắng tìm một ma trận nhân với ma trận mô-đun xem thực sự phức tạp và rất dễ bị lỗi." Không, không phải. Ma trận là cách tốt nhất để suy nghĩ về định hướng tọa độ tương đối. Mỗi cột trong 3 cột đầu tiên là một trong các vectơ cơ sở của hệ tọa độ được chuyển đổi. Cột thứ 4 là bản dịch tương đối. Nó dễ dàng hơn để viết ra một máy ảnh matric từ khung nhìn và các vectơ đích, sau đó với tất cả lượng giác đó inbetween. – datenwolf

+0

Tôi biết điều đó. Điều tôi nói là, ví dụ bạn có 3 loại chuyển động khác nhau (nói, di chuyển, xoắn và cuộn) cho đến khung tiếp theo, dễ dàng hơn để làm như vậy với vị trí/vĩ độ/kinh độ và cuối cùng chuyển đổi thành ma trận, hơn là cố gắng áp dụng từng hoạt động cho ma trận của ma trận trước đó. – Shahbaz

Các vấn đề liên quan