Cara menghindari kunci gimbal


8

Saya mencoba menulis kode dengan memutar objek.

Saya menerapkannya sebagai:

Rotasi tentang sumbu-X diberikan oleh jumlah perubahan dalam koordinat y mouse dan Rotasi tentang sumbu-Y diberikan oleh jumlah perubahan dalam koordinat x mouse.

Metode ini sederhana dan bekerja dengan baik sampai pada sumbu bertepatan dengan sumbu Z, singkatnya terjadi kunci gimble.

Bagaimana saya bisa memanfaatkan putaran arount Z-axis untuk menghindari kunci gimbal.


Jawaban singkat: gunakan angka empat
— Robert Rouhani

4
Kuota masih rentan terhadap kunci gimbal jika Anda salah menggunakannya - bukan apa yang Anda gunakan untuk mewakili rotasi Anda, melainkan gabungan beberapa rotasi yang menyebabkannya. Jadi jangan menyatukan rotasi.
— Maximus Minimus

Mengenai komentar saya sebelumnya, lihat komentar dari Maik Semder di gamedev.stackexchange.com/questions/23540/…
— Maximus Minimus

Saya akan menulis komentar yang sama lagi, terima kasih sudah menemukannya @ mh01 :)
— Maik Semder

Jawaban:


14

Solusi sederhana adalah tidak menyimpan orientasi objek sebagai sudut di sekitar sumbu (sumbu X-, Y-, Z), seperti misalnya dalam sudut euler.

Simpan orientasi objek sebagai matriks atau angka empat.

Ini dapat menyebabkan kunci gimbal, menggunakan sudut euler:

class Object
{
    float m_angleAxisX;
    float m_angleAxisY;
    float m_angleAxisZ;
};

Tidak ada kunci gimbal:

class Object
{
    matrix m_orientation;   
};

Tidak ada kunci gimbal:

class Object
{
    quaternion m_orientation;   
};

Sekarang setiap kali mouse diubah, gandakan m_orientation dengan perubahan orientasi yang berasal dari gerakan mouse setiap frame.


0

Buku ini (rendering waktu-nyata) banyak membantu saya! Lihat di halaman 66 dan 70. Grafis dan penjelajahannya sangat bagus. Pertanyaan juga ada di halaman 72! :)

Rotasi tentang Sumbu Sewenang-wenang

Ini membuat kamera dengan rotasi dilakukan oleh input mouse:

void Camera::getVectors(D3DXVECTOR3& up, D3DXVECTOR3& lookAt)
{
    float yaw, pitch, roll;
    D3DXMATRIX rotationMatrix;

    // Setup the vector that points upwards.
    up.x = 0.0f;
    up.y = 1.0f;
    up.z = 0.0f;

    // Setup where the camera is looking by default.
    lookAt.x = 0.0f;
    lookAt.y = 0.0f;
    lookAt.z = 1.0f;

    // Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
    pitch = m_rotation.x * 0.0174532925f;
    yaw   = m_rotation.y * 0.0174532925f;
    roll  = m_rotation.z * 0.0174532925f;

    // Create the rotation matrix from the yaw, pitch, and roll values.
    D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll);

    // Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin.
    D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix);
    D3DXVec3TransformCoord(&up, &up, &rotationMatrix);
}

// The Render function uses the position and rotation of the camera to build and update the view matrix
void Camera::render()
{
    D3DXVECTOR3 up, position, lookAt;

    // Setup the position of the camera in the world.
    position = (D3DXVECTOR3)m_position;

    getVectors(up, lookAt);

    // Translate the rotated camera position to the location of the viewer.
    lookAt = position + lookAt;

    // Finally create the view matrix from the three updated vectors.
    D3DXMatrixLookAtLH(&m_viewMatrix, &position, &lookAt, &up);

    return;
}

Dengan input mouse Anda memodifikasi yaw (head), pitch and roll.


1
-1 Ini tidak menyelesaikan kunci gimbal karena menggunakan sudut euler (m_rotation) untuk penyimpanan orientasi internal. Wiki ini menjelaskan alasannya.
— Maik Semder
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.