2013-03-22 19 views
5

Tôi cần một số gợi ý về cách tiếp cận tốt nhất cho nhiệm vụ xoay vòng trong OpenGL. Tôi biết cách xoay đối tượng trong không gian 3D bằng quaternions, tôi có thể dịch chúng, tất cả đều tốt và tốt.Làm thế nào để nhóm nhiều đối tượng cho mục đích quay chúng như một đơn vị?

Nhưng tôi muốn biết cách tốt nhất để xử lý tập hợp các đối tượng khác nhau như một thực thể duy nhất cho mục đích xoay vòng. Ví dụ, giả sử bạn có một bàn với các đối tượng trên đó. Mỗi bản dịch đều có bản dịch và vòng xoay riêng, nhưng bây giờ tôi muốn xoay toàn bộ bàn và mọi thứ trên đó, đồng thời giữ các đồ vật khác trong phòng tại chỗ. Điều này có nghĩa là các vật thể ở cạnh ngoài của bàn sẽ xoay và dịch xung quanh tâm của bàn, trong khi các vật ở trung tâm chỉ có thể xoay nhưng nếu không, hoặc đơn giản là không dịch nhiều, tùy thuộc vào khoảng cách của chúng. trục quay. Có vẻ như một cách khá không phù hợp để làm điều này là xoay và dịch từng đối tượng trên bàn làm việc, cũng như chính bàn làm việc, biết vị trí của trục quay. Có lẽ đây là cách tốt nhất để làm điều đó, nhưng liệu có một kỹ thuật để "nhóm" các đối tượng khác nhau cho mục đích này?

+2

Nếu bạn hỏi về OpenGL ES, * không * sử dụng thẻ OpenGL. –

+1

kỹ thuật xoay và ma trận trong ví dụ này áp dụng cho cả OpenGL và OpenGL ES. Câu hỏi này dành riêng cho OpenGL ES là gì? – johnbakers

+0

Bởi logic đó, nó không phải về * bất kỳ hình thức OpenGL nào, vì bất kỳ API đồ họa 3D nào cũng sẽ sử dụng các kỹ thuật tương tự. Do đó, nó không nên có * bất kỳ * thẻ OpenGL nào. –

Trả lời

3

Những gì bạn đang tìm kiếm là những nhân vật chuyển đổi. Các đối tượng trên bàn của bạn được định vị tương đối so với bàn làm việc hoặc nói cách khác trong hệ tọa độ của bàn làm việc. Vì vậy, hãy chỉ định M_Desk làm phép chuyển đổi xác định vị trí của bàn và hệ tọa độ cục bộ của nó. Tiếp theo là M_Pencilbox việc chuyển đổi hộp bút chì đứng trên bàn liên quan đến bàn làm việc. Và một cây bút chì trong hộp bút chì sẽ được đặt trong mối quan hệ với hộp bút chì.

Vì vậy, bút chì trải qua một loạt các biến đổi. Hãy nhớ rằng trong các ký hiệu chính cột được sử dụng bởi những thứ OpenGL "chảy" thông qua chuỗi chuyển đổi từ lần chuyển đổi cuối cùng sang đầu tiên (hoặc phải sang trái khi viết xuống).

Mỗi chuyển đổi, như M_Desk ví dụ, là một ma trận 4 × 4 có thể được xây dựng theo cách thông thường: Xoay, bản dịch, vụn vv

Vì vậy, để chuyển các đỉnh của một cây bút chì bạn muốn áp dụng chuyển đổi sau đây

… · M_Desk · M_Pencilbox · v_Pencil 

Tất nhiên bản thân bàn có thể liên quan đến thứ gì đó khác, như phòng. Ngay từ đầu của chuỗi chuyển đổi đó sẽ là chuyển đổi khung nhìn. Vì vậy, hiệu quả chúng tôi đang xây dựng một ma trận modelview ở đây.

Về mặt OpenGL hiện đại, mỗi khi bạn gặp một nhánh trong hierachy chuyển đổi (nghĩ về các thư mục trong hệ thống tệp), bạn sẽ tạo một bản sao của chuỗi chuyển đổi được xây dựng từ trước đến nay, để bạn không có để khởi động lại từ đầu cho mỗi nhánh.

Hãy cho tôi biết nếu bạn cần làm rõ thêm.

+0

điều này rất thú vị và hữu ích; Tôi cần phải suy nghĩ về nó nhiều hơn một chút và thử một số thử nghiệm và sau đó sẽ cho bạn biết bất kỳ câu hỏi. Tôi đánh giá cao sự giải thích rất nhiều. – johnbakers

+0

Ok Tôi nghĩ mình đã hiểu, bạn có thể xác nhận không. Giả sử tôi đã chuyển đổi bàn làm việc, nó có ma trận 'M_Desk'. Bây giờ tôi muốn đặt hộp bút chì lên đó. Trong shader vertex của tôi, tôi chỉ có một bộ đồng phục cho ma trận modelview, vì vậy tôi gửi cho bộ đồng phục đó một ma trận đầu tiên được tạo ra như 'M_Pencilbox * M_Desk' - theo thứ tự đó, vì đây là mã C++ không có trong bóng đổ. Sau cuộc gọi đó, tôi lấy một bản sao của ma trận kết hợp này, chúng ta hãy gọi nó là 'M_Copy' và áp dụng nó cho mỗi bút chì như' M_Pencil * M_Copy' và gửi nó tới shader như modelview trước khi render từng bút chì. Chính xác? – johnbakers

+0

@ SebbyJohanns: Có, nhưng đơn đặt hàng phải là kết hợp phù hợp, tức là việc chuyển đổi bổ sung sẽ được áp dụng ở bên phải. Tất nhiên với các ma trận xử lý OpenGL như được sử dụng bởi một số thư viện khác khi transposed thứ tự có thể hoán đổi (A · B = transposed (B) · transposed (A)); như bạn có thể biết phép nhân ma trận không giao hoán (tức là A · B =/= B · A). – datenwolf

3

Điều này thường được thực hiện bằng cách sử dụng một số loại biểu đồ cảnh kết hợp với hệ thống phân cấp chuyển đổi.

Một phiên bản đơn giản tối thiểu sẽ là có một cây nơi mỗi nút chứa một đối tượng, một biến đổi và danh sách các nút con. Biến đổi có liên quan đến nút cha.

Vì vậy, các đối tượng trên bàn làm việc sẽ là con của chính bàn làm việc.

Biến đổi cho bất kỳ đối tượng cụ thể nào là phép nối của biến đổi của đối tượng đó với tất cả cha mẹ của nó trong cây.Có rất nhiều cách để thực hiện điều đó, nhưng chức năng GL 'trường học cũ' cung cấp một ngăn xếp ma trận cho mục đích này. Bạn nhân trong ma trận cục bộ cho một nút, vẽ hình học cho nút đó, đệ quy vẽ tất cả các nút con, và sau đó bật lại ma trận.

+0

Được đánh giá cao. Tôi sẽ nghĩ về điều này vào cuối tuần. – johnbakers

+0

Vì tôi đang sử dụng shader, không phải là stacks ma trận, và tôi sẽ thực hiện phân cấp biến đổi trong C++ và sau đó gửi biến đổi cuối cùng tới vertex shader, thay vào đó tôi sẽ làm điều gì đó trong C++ như ví dụ của bạn, nhưng với 'childMatrix * parentMatrix' và sau đó gửi ma trận đơn đã hoàn thành đó từ C++ dưới dạng ma trận modelview đơn vào bóng đổ – johnbakers

+0

Có. Tuy nhiên, bạn muốn lưu trữ/xử lý các ma trận, cách tiếp cận chung là có CPU thu gọn cấu trúc phân cấp trước khi truyền ma trận hình học và ma trận cuối cùng tới GPU. GL sử dụng một chồng, tôi thường chỉ lưu trữ ma trận toàn cầu trong cây, và/hoặc có một mảng được xử lý trước của ma trận có thể được điền và truy cập một cách hiệu quả. – JasonD

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