Bagaimana cara mengimplementasikan translasi, skala, rotasi gizmos untuk memanipulasi transformasi objek 3D?

11

Saya sedang dalam proses mengembangkan editor 3D dasar. Ini menggunakan OpenGL untuk merender dunia 3D. Saat ini adegan saya hanya beberapa kotak dengan ukuran berbeda dan saya berada pada tahap di mana saya ingin dapat memilih setiap kotak dan kemudian memindahkan / skala / putar untuk mencapai setiap transformasi yang saya inginkan.

Bagaimana saya bisa menyelesaikan masalah penerapan rendering gizmos alat ini (atau pegangan, atau bagaimana orang biasa menyebutnya), dan juga memilih mereka pada setiap sumbu untuk melakukan perubahan dalam transformasi dengan mouse saya? Untuk kejelasan: masukkan deskripsi gambar di sini

Penelitian saya sejauh ini menyarankan pendekatan paling bersih adalah dengan memiliki kotak kotak panah selaras melengkung di alat dan satu lagi per persegi (orang-orang yang memindahkan objek dalam pesawat daripada sumbu tunggal) dan kemudian melemparkan sinar dari mouse posisi dan lihat apa yang bertabrakan. Tapi ini masih terlalu abstrak untuk saya, saya akan sangat menghargai panduan lebih lanjut tentang bagaimana algoritma ini berjalan (pseudocode lebih dari cukup)

Grimshaw
sumber
1
Biasanya Anda akan raycast ke dunia dengan posisi mouse dan lihat apakah Anda menekan alat. Anda juga dapat mengubah alat menjadi ruang layar melakukan deteksi tabrakan di sana. Biasanya meskipun Anda hanya melakukan jarak dari ray ke jenis segmen garis hal. Rotasi biasanya dilakukan sebagai track ball virtual. Lihat Melax di Permata Pemrograman Game 1. Penerjemahan cukup banyak produk titik, dan begitu juga skala.
RandyGaul

Jawaban:

9

Pada titik waktu saya di e-on, saya telah mempertahankan perangkat lini produk Vue .
Saya dapat memberitahu Anda, itu akan membawa Anda beberapa hari, penuh waktu.
Kecuali Anda menemukan pustaka atau cara super pintar, cara klasik adalah dengan mendapatkan koordinat mouse di jendela ketika Anda mengklik, jika itu relatif berkoordinasi dengan viewport, Anda dapat membagi x dan y dengan lebar dan tinggi, Anda dapatkan vektor (float 2d) dalam kisaran [0,1]. kurangi (0,5,0,5) untuk mencapai kisaran [-0,5, 0,5] untuk x dan y.
Kemudian, Anda membuat sinar dari koordinat ini dengan menggunakan x dan y hanya sebagai ray x dan y, dan Anda mengatur z ke jarak fokus. kadang-kadang aspek rasio adalah rasa sakit di pantat dalam operasi ini. Sedikit biola dan kesalahan uji coba akan membuat Anda diperbaiki.
Kemudian, Anda perlu memeriksa persimpangan dengan elemen gizmos Anda, apakah Anda memiliki mesh yang Anda hasilkan, atau dimodelkan dalam blender atau DCC lainnya, atau bagian mesh yang dapat saling mengartikulasikan ... Hanya gunakan bagian mesh tersebut sebagai sinar / kueri persimpangan segitiga.
Atau jika Anda memilikinya, ray / silinder, ray / bola sesuai dengan tampilan dan bagian alat Anda.
Anda perlu memiliki persimpangan rutin yang mampu menerapkan matriks transformasi pada primitif yang bertabrakan . Sangat penting karena alat Anda akan menerjemahkan dengan objek yang dilayaninya bergerak, akan berputar, dan akan menskala dengan kebalikan dari jarak ke kamera, sehingga ia menjaga ukuran yang diproyeksikan tetap di layar.
Kemudian Anda memiliki bagian interaksi, yang paling mudah adalah mengambil delta titik saat mouse pertama kali "mouse down" event, dan posisi "Mouse move" saat ini, dalam 2D ​​murni, dan gunakan delta ini sebagai gerakan sumbu saat ini di ruang dunia, dikalikan dengan beberapa kyang Anda putuskan secara empiris. Menurut unit internal Anda versus piksel versus skala zoom saat ini dll.
Langkah terakhir adalah hanya menerapkan matriks gizmo ke objek yang dimanipulasi, sehingga mengikutinya.

Saya memberi tahu Anda bahwa ini adalah perjalanan yang sangat sulit untuk diterapkan, dan jika Anda melakukannya di waktu luang, perkirakan lebih dari satu minggu. Beberapa minggu jika Anda benar-benar menemukan bidangnya. Lebih dari satu bulan jika akhir pekan Anda sibuk dengan kegiatan lain :)

Saya sarankan Anda mengunduh Embree 2.0 dari intel untuk melakukan kueri persimpangan / segitiga untuk Anda, jadi Anda tidak perlu khawatir tentang pengkodean itu. Atau Anda tanpa ampun dapat menyalin / menempel dan mengadaptasi kode dari blender ... Saya pikir mereka pindah ke lisensi Apache? Seharusnya dimungkinkan secara hukum.

v.oddou
sumber
1
Terima kasih banyak atas jawaban Anda. Ini memang membantu. Saya tahu saya tidak gila ketika saya merasa kewalahan oleh tugas yang tampaknya mudah. Saya meremehkan kesulitannya dan akhirnya terjebak pada masalah yang sama selama berhari-hari .. Lain kali saya pergi dan menangani ini, saya pasti akan membuat rencana yang baik. Terima kasih
Grimshaw
0

Untuk manipulator-penerjemah saya menggunakan algoritma berikut:

1) Saat mouse turun, kita perlu memeriksa apakah sinar berpotongan panah. Misalnya kita menganggap panah X. Kami membangun Ray di ruang dunia (berdasarkan frustrasi kamera dan posisi mouse). Kami membangun bidang di mana sumbu x terletak: normalnya sama dengan V lintas X lintas V, di mana V - vektor dari pusat ke kamera, X - mewakili sumbu x. Lalu kami memotong sinar dengan pesawat dan karena itu kami menemukan titik persimpangan di koordinat dunia. Kemudian kami memproyeksikan segmen sumbu x dan titik yang dihasilkan kembali ke layar, menemukan jarak antara segmen yang diproyeksikan dan titik yang diproyeksikan di layar. jika kurang dari beberapa piksel, mouse akan melihat sumbu. Kami juga menghitung vektor delta ruang dunia antara pusat seleksi dan persimpangan kami.

Prosedur ini kami lakukan untuk 3 sumbu, jadi kami menemukan jarak ke semua sumbu. Temukan jarak minimum. jadi kami menemukan sumbu yang memotong mouse.

2) Saat mouse bergerak. kita tahu dengan sumbu apa objek bergerak (dari 1). kami menemukan persimpangan ruang dunia dari sinar dengan pesawat (seperti pada 1). selain itu kami memproyeksikan titik persimpangan pada garis objek bergerak. Posisi manipulator akhir = persimpangan + delta.

tekan рор
sumber