Rotasi Kamera 3D

9

Tolong, maafkan saya, tapi saya butuh bantuan dan saya sudah terjebak dalam hal ini selama beberapa minggu sekarang, saya tidak membuat kemajuan dan ke mana pun saya pergi dan saya melihat jawaban yang berbeda, semua yang saya coba tidak berhasil. Saya sudah memiliki cukup tips dan saran, sekarang saya benar-benar hanya membutuhkan seseorang untuk memberi saya jawaban bagi saya untuk bekerja mundur karena saya tidak dapat memahami hal ini.

Apa yang membuat subjek ini paling membingungkan adalah cara setiap orang menggunakan seperangkat konvensi atau aturan yang berbeda, dan jawaban mereka didasarkan pada konvensi mereka sendiri tanpa mendefinisikan apa itu.

Jadi inilah seperangkat konvensi yang saya bentuk berdasarkan apa yang tampaknya paling umum dan logis:

  1. Aturan Tangan Kanan untuk sumbu.
  2. Positif Y naik, Positif Z mengarah ke pemirsa, Positif X di sebelah kanan.
  3. Matriks-matriks baris utama, ditransformasikan ketika dikirim ke shader
    • Pitch: rotasi sekitar sumbu X
    • Yaw: rotasi tentang sumbu y
    • Roll: rotasi tentang sumbu z
  4. Urutan rotasi: Roll, Pitch, Yaw (apakah ini benar? Dapatkah seseorang memeriksa saya tentang ini?)
  5. Nilai rotasi positif, melihat ke bawah dari ujung positif sumbu, menghasilkan rotasi searah jarum jam.
  6. Arah default untuk 0 rotasi di semua sumbu adalah vektor yang mengarah ke negatif Y.

.. mengingat konvensi-konvensi itu (tentu saja perbaiki saya jika mereka salah!), bagaimana caranya:

  • Tulis fungsi LookAt? .
  • Hitung matriks rotasi. (rotasi (x, y, z))

Saya sudah mencoba menjawab dua pertanyaan ini sendiri setidaknya selama 3 minggu terakhir, saya telah menulis ulang fungsi LookAt & Rotation Matrix setidaknya 30 kali, saya telah menguji puluhan metode dan membaca materi yang telah saya lihat di ratusan situs web dan membaca banyak pertanyaan terjawab, menyalin kode orang lain, dan sejauh ini tidak ada yang berhasil, semuanya menghasilkan hasil yang salah. Beberapa di antaranya telah menghasilkan beberapa keluaran aneh yang anehnya bahkan tidak mendekati rotasi yang benar.

Saya telah mengerjakan ini setiap malam dengan pengecualian tadi malam karena saya menjadi sangat frustrasi dengan kegagalan berulang sehingga saya harus berhenti dan beristirahat.

Tolong, tunjukkan saja kepada saya apa metode yang benar sehingga saya dapat bekerja mundur dari itu dan mencari tahu cara kerjanya, saya hanya tidak mendapatkan jawaban yang benar dan ini membuat saya sedikit gila!

Saya menulis di Jawa tetapi saya akan mengambil kode yang ditulis dalam bahasa apa pun, sebagian besar kode rendering 3D saya benar-benar berfungsi dengan sangat baik, hanya saja matematika yang tidak saya mengerti.

UPDATE: ASK

Terima kasih untuk bantuannya! Saya sekarang memiliki fungsi LookAt yang berfungsi yang saya benar-benar mengerti dan saya tidak bisa lebih bahagia (jika ada yang ingin melihatnya dengan segala cara bertanya).

Saya memang mencoba lagi membuat matriks rotasi berdasarkan variabel pitch / yaw / roll dan sepertinya gagal, tapi saya memutuskan untuk tidak mencoba menggunakan sudut euler untuk kamera freelook karena sepertinya tidak cocok untuk peran, sebagai gantinya saya akan membuat kelas angka empat, mungkin lebih beruntung melalui jalan itu, kalau tidak saya akan menggunakan pitch / yaw sebagai koordinat bola dan bergantung pada fungsi LookAt yang berfungsi untuk rotasi.

Jika ada orang lain yang menghadapi masalah yang sama dan ingin bertanya kepada saya, silakan saja.

Setidaknya saya tidak terjebak lagi, terima kasih atas bantuannya!

Grady
sumber

Jawaban:

15

Apa yang Anda cari dapat ditemukan dalam penjelasan yang sangat bagus ini: http://www.songho.ca/opengl/gl_transform.html

Tetapi karena saya merasa agak membingungkan tanpa berpegangan tangan, saya akan mencoba menjelaskannya di sini.

Pada titik ini Anda perlu mempertimbangkan 5 sistem koordinat dan bagaimana mereka saling berhubungan. Ini adalah koordinat jendela, koordinat perangkat yang dinormalisasi, koordinat mata, koordinat dunia dan koordinat objek.

Koordinat jendela dapat dilihat sebagai piksel "fisik" di layar Anda. Mereka adalah koordinat yang mengacu pada sistem windowing dan jika Anda beroperasi pada resolusi asli monitor Anda, ini sebenarnya adalah piksel individual. Sistem koordinat jendela adalah bilangan bulat 2D dan relatif terhadap jendela Anda. Di sini x + kiri dan y + turun dengan asal di sudut kiri atas. Anda menemukan ini ketika misalnya Anda memanggil glViewport.

Set kedua adalah koordinat perangkat yang dinormalisasi. Ini merujuk pada pengaturan ruang oleh port tampilan aktif. Area yang terlihat dari port tampilan bergerak dari -1 ke +1 dan dengan demikian memiliki asal di tengah. X + dibiarkan dan y + naik. Anda juga memiliki z + "keluar" dari tempat kejadian. Ini yang Anda jelaskan dalam 1.

Anda tidak memiliki kontrol bagaimana Anda dapatkan dari koordinat perangkat dinormalisasi ke koordinat jendela, ini dilakukan secara implisit untuk Anda. Satu-satunya kontrol yang Anda miliki adalah melalui glViewportatau serupa.

Saat bekerja dengan openGL, hasil akhir Anda akan selalu dalam koordinat perangkat yang dinormalisasi. Akibatnya, Anda perlu khawatir bagaimana cara membuat adegan Anda ditampilkan di sini. Jika Anda mengatur proyeksi dan matrik tampilan model ke matriks identitas, Anda dapat langsung menggambar koordinat ini. Ini misalnya dilakukan ketika menerapkan efek layar penuh.

Berikutnya adalah koordinat mata. Ini adalah dunia yang dilihat dari kamera. Hasilnya, asalnya ada di kamera dan sumbu yang sama seperti koordinat perangkat berlaku.

Untuk mendapatkan dari koordinat mata ke koordinat perangkat Anda membangun matriks proyeksi. Yang paling sederhana adalah proyeksi ortografis yang hanya menskala nilai dengan tepat. Proyeksi perspektif lebih rumit dan melibatkan perspektif simulasi.

Akhirnya Anda memiliki sistem koordinat dunia. Ini adalah sistem koordinat di mana dunia Anda didefinisikan dan kamera Anda adalah bagian dari dunia ini. Di sini penting untuk dicatat bahwa orientasi sumbu sama seperti Anda mendefinisikannya . Jika Anda lebih suka z + sebagai naik, itu sama sekali tidak masalah.

Untuk mendapatkan dari koordinat dunia ke koordinat mata, Anda menentukan matriks tampilan. Ini bisa dilakukan dengan sesuatu seperti lookAt. Apa yang dilakukan matriks ini adalah "menggerakkan" dunia sehingga kamera berada pada titik asal dan melihat ke bawah sumbu z.

Untuk menghitung tampilan matriks sangat sederhana, Anda perlu melakukan transformasi kamera. Anda pada dasarnya perlu merumuskan matriks berikut:

M.=x[1]y[1]z[1]-hal[1]x[2]y[2]z[2]-hal[2]x[3]y[3]z[3]-hal[3]0001

Vektor x, y dan z dapat langsung diambil dari kamera. Dalam hal dari tampilan Anda akan mendapatkan mereka dari target, mata (tengah) dan nilai-nilai ke atas. Seperti itu:

z=nHairmSebuahlsayaze(eye-tSebuahrget)x=nHairmSebuahlsayaze(kamuhal×z)y=zx

Tetapi jika Anda memiliki nilai-nilai ini hanya berbaring di sekitar Anda bisa mengambilnya apa adanya.

Mendapatkan p sedikit lebih rumit. Ini bukan posisi di koordinat dunia tetapi posisi di koordinat kamera. Solusi sederhana di sini adalah menginisialisasi dua matriks, satu dengan hanya x, y dan z dan yang kedua dengan -ya dan mengalikannya menjadi satu. Hasilnya adalah view matrix.

Untuk bagaimana ini terlihat dalam kode:

mat4 lookat(vec3 eye, vec3 target, vec3 up)
{
    vec3 zaxis = normalize(eye - target);    
    vec3 xaxis = normalize(cross(up, zaxis));
    vec3 yaxis = cross(zaxis, xaxis);     

    mat4 orientation(
       xaxis[0], yaxis[0], zaxis[0], 0,
       xaxis[1], yaxis[1], zaxis[1], 0,
       xaxis[2], yaxis[2], zaxis[2], 0,
         0,       0,       0,     1);

    mat4 translation(
              1,       0,       0, 0,
              0,       1,       0, 0, 
              0,       0,       1, 0,
        -eye[0], -eye[1], -eye[2], 1);

    return orientation * translation;
}

kode lengkap

Dan akhirnya demi kelengkapan, Anda juga memiliki sistem koordinat objek. Ini adalah sistem koordinat tempat jerat disimpan. Dengan bantuan matriks model, koordinat mesh diubah menjadi sistem koordinat dunia. Dalam praktiknya, model dan matriks tampilan digabungkan ke dalam apa yang disebut matriks model-view.

rioki
sumber
1
Jika saya dapat memilih jawaban ini seratus kali saya akan. Terima kasih atas jawaban yang lengkap dan lengkap untuk menjawab semua hal yang membuat saya bingung dan menyediakan kode & tautannya juga! Saya menghabiskan sepanjang hari membaca buku matematika tentang hal ini dan dengan jawaban Anda serta kode contoh dan halaman yang ditautkan, jika ini tidak cukup bagi saya untuk mencari tahu hal ini maka saya harus berhenti sekarang. Jika saya bisa meminta hanya satu klarifikasi, dalam contoh kode terakhir, apakah saya akan benar mengatakan matriks-matriks itu dalam urutan utama kolom dan yang di atas adalah dalam baris utama?
Grady
Ini agak membingungkan, matriksnya adalah kolom utama, tetapi kolomnya ada di baris. Jadi untuk memetakan matematika aktual ke kode Anda harus memasukkan matriks. Lihat github.com/rioki/glm/blob/master/src/matrix.h#l72 Ini memetakan persis ke openGL dan bagaimana jadinya jika menggunakan float[16].
rioki
Ah saya memang berpikir begitu tetapi hanya ingin memastikan, terima kasih lagi! Anda sangat membantu, saya sangat menghargainya.
Grady