Setelah banyak membaca tentang transformasi, sekarang saatnya menerapkan trackball untuk aplikasi saya. Saya mengerti saya harus membuat vektor dari asal ke tempat mouse diklik dan kemudian dari asal ke tempat mouse dilepaskan.
Pertanyaan saya adalah, apakah saya harus mengubah (x, y) pixel coords ke world-coords atau haruskah saya melakukan semuanya dalam ruang gambar (mengingat ruang gambar adalah proyeksi 2D dari adegan yang diukur dalam piksel)?
EDIT
Jawaban Richie Sams adalah jawaban yang sangat bagus. Namun, saya pikir saya mengikuti pendekatan yang sedikit berbeda, perbaiki saya jika saya salah atau saya salah mengerti sesuatu.
Dalam aplikasi saya saya memiliki SimplePerspectiveCamera
kelas yang menerima position
dari kamera, position of the target
kita melihat, yang up
vektor, yang fovy
, aspectRatio
, near
dan far
jarak.
Dengan itu saya membangun matrik Lihat dan Proyeksi saya. Sekarang, Jika saya ingin memperbesar / memperkecil, saya memperbarui bidang tampilan dan memperbarui matriks proyeksi saya. Jika saya ingin menggeser saya memindahkan posisi kamera dan melihat delta yang dihasilkan mouse.
Akhirnya, untuk rotasi saya bisa menggunakan transformasi sudut-sumbu atau angka empat. Untuk ini, saya menyimpan pixel-coords di mana mouse ditekan dan kemudian ketika mouse bergerak saya juga menyimpan pixel-coords.
Untuk setiap pasangan koordinat saya dapat menghitung nilai Z yang diberikan rumus untuk bola, yaitu, sqrt (1-x ^ 2-y ^ 2), kemudian menghitung vektor yang pergi dari target
ke PointMousePressed
dan dari target
ke PointMouseMoved
, lakukan lintas produk untuk mendapatkan sumbu rotasi dan menggunakan metode apa pun untuk menghitung posisi kamera baru.
Namun, keraguan terbesar saya adalah bahwa nilai (x, y, z) diberikan dalam pixel-coords, dan ketika menghitung vektor yang saya gunakan target
yang merupakan titik dalam world-coords. Bukankah pencampuran sistem koordinat ini mempengaruhi hasil rotasi yang saya coba lakukan?
z
nilai sebuah bola jari-jarir
, namun saya tidak yakin apakah bola itu hidup di ruang dunia atau ruang gambar dan apa implikasinya. Mungkin saya terlalu memikirkan masalah.Jawaban:
Asumsikan yang Anda maksudkan adalah kamera yang berputar berdasarkan pergerakan mouse:
Salah satu cara untuk mengimplementasikannya adalah melacak posisi kamera dan rotasinya di ruang angkasa. Koordinat bola kebetulan cocok untuk ini, karena Anda dapat mewakili sudut secara langsung.
Kamera terletak di P yang didefinisikan oleh m_theta, m_phi, dan m_radius. Kita dapat memutar dan bergerak dengan bebas ke mana pun kita inginkan dengan mengubah ketiga nilai tersebut. Namun, kami selalu melihat, dan memutar, m_target. m_target adalah asal usul bola. Namun, kita bebas untuk memindahkan asal ini ke mana pun kita inginkan di ruang dunia.
Ada tiga fungsi kamera utama:
Dalam bentuknya yang paling sederhana, Putar () dan Zoom () sepele. Hanya memodifikasi m_theta, m_phi, dan m_radius masing-masing:
Panning sedikit lebih rumit. Pan kamera didefinisikan sebagai menggerakkan kamera ke kiri / kanan dan / atau atas / bawah masing-masing ke tampilan kamera saat ini. Cara termudah yang dapat kita lakukan ini adalah mengubah tampilan kamera kita saat ini dari koordinat bola ke koordinat kartesius. Ini akan memberi kita vektor ke atas dan kanan .
Jadi, pertama, kita mengonversi sistem koordinat bola kita menjadi cartesian untuk mendapatkan vektor tampilan kita . Berikutnya, kita lakukan vektor lintas produk dengan dunia atas vektor, untuk mendapatkan hak vektor. Ini adalah vektor yang menunjuk langsung ke kanan dari tampilan kamera. Terakhir, kita lakukan vektor lain silang produk untuk mendapatkan kamera up vektor.
Untuk menyelesaikan panci, kami memindahkan m_target di sepanjang vektor ke atas dan kanan .
Satu pertanyaan yang mungkin Anda tanyakan adalah: Mengapa mengkonversi antara kartesius dan bola sepanjang waktu (Anda juga harus mengonversi untuk membuat matriks View).
Pertanyaan bagus. Saya juga punya pertanyaan ini dan mencoba menggunakan kartesian secara eksklusif. Anda berakhir dengan masalah dengan rotasi. Karena operasi floating point tidak tepat tepat, beberapa rotasi berakhir dengan akumulasi kesalahan, yang terkait dengan kamera secara perlahan, dan bergulir secara tidak sengaja.
Jadi, pada akhirnya, saya terjebak dengan koordinat bola. Untuk melawan perhitungan ekstra, saya akhirnya melakukan caching view matrix, dan hanya menghitungnya saat kamera bergerak.
Langkah terakhir adalah menggunakan kelas Kamera ini. Panggil saja fungsi anggota yang sesuai di dalam fungsi MouseDown / Atas / Gulir aplikasi Anda:
Variabel faktor m_camera * hanyalah faktor skala yang mengubah seberapa cepat kamera Anda memutar / menggeser / menggulir
Kode yang saya miliki di atas adalah versi kode semu yang disederhanakan dari sistem kamera yang saya buat untuk proyek sampingan: camera.h dan camera.cpp . Kamera mencoba meniru sistem kamera Maya. Kode ini gratis dan open source, jadi silakan menggunakannya dalam proyek Anda sendiri.
sumber
Jika Anda ingin melihat ke solusi yang siap. Saya memiliki port THREE.JS TrackBall mengontrol di C ++ dan C #
sumber