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.

singingsingh
sumber
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.

Maik Semder
sumber
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.

Jinxi
sumber
1
-1 Ini tidak menyelesaikan kunci gimbal karena menggunakan sudut euler (m_rotation) untuk penyimpanan orientasi internal. Wiki ini menjelaskan alasannya.
Maik Semder