Вращение OpenGL - локальные и глобальные оси - PullRequest
3 голосов
/ 14 марта 2012

Итак, у меня есть объект, который я пытаюсь вращать по схеме Yaw, Pitch and Roll, относительно собственных локальных осей объекта, а не осей глобального пространства.Согласно this , мне нужно выполнить повороты в этом порядке.Я интерпретировал это как следующее:

glRotatef(m_Rotation.y, 0.0, 1.0, 0.0);
glRotatef(m_Rotation.z, 0.0, 0.0, 1.0);
glRotatef(m_Rotation.x, 1.0, 0.0, 0.0);

Однако вращение вокруг осей Y и Z не работает.Вращение вокруг оси Y всегда относительно глобального пространства, а вращение вокруг оси z работает от вращения вокруг оси X на 0, но в противном случае портится.

Просто чтобы быть уверенным, я попробовал обратноезаказать, но это тоже не работает.Я думаю, что я пробовал все другие заказы, так что проблема должна быть в другом.это может быть?

Вот как я получаю вращения:

    ///ROTATIONS
    sf::Vector3<float> Rotation;
    Rotation.x = 0;
    Rotation.y = 0;
    Rotation.z = 0;
    //ROLL
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Up) == true)
    {
        Rotation.x -= TurnSpeed;
    }
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Down) == true)
    {
        Rotation.x += TurnSpeed;
    }
    //YAW
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Left) == true)
    {
        Rotation.y -= TurnSpeed;
    }
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Right) == true)
    {
        Rotation.y += TurnSpeed;
    }
    //PITCH
    if (m_pApp->GetInput().IsKeyDown(sf::Key::Q) == true)
    {
        Rotation.z -= TurnSpeed;
    }
    if (m_pApp->GetInput().IsKeyDown(sf::Key::E) == true)
    {
        Rotation.z += TurnSpeed;
    }

Затем они добавляются в m_Rotation следующим образом:

//Rotation
m_Rotation.x += Angle.x;
m_Rotation.y += Angle.y;
m_Rotation.z += Angle.z;

(Они передаютсяфункция, внутренняя для перемещаемой вещи, но с ними ничего не делается).

Мысли?Есть ли что-то еще, что я должен позвонить, чтобы убедиться, что все оси, которые вращаются вокруг, являются локальными осями?

Ответы [ 2 ]

1 голос
/ 18 марта 2012

Гаррик,

Когда вы вызываете glRotate (angle, x, y, z), он вращается вокруг вектора, который вы передаете в glRotate. Вектор переходит от (0,0,0) к (x, y, z).

Если вы хотите повернуть объект вокруг локальной оси объекта, вам нужно выполнить glTranslate объект в начало координат, выполнить вращение, а затем перевести его туда, откуда он пришел.

Вот пример:

//Assume your object has the following properties
sf::Vector3<float> m_rotation;
sf::Vector3<float> m_center;

//Here would be the rotate method
public void DrawRotated(sf::Vector<float> degrees) {
  //Store our current matrix 
  glPushMatrix();

  //Everything will happen in the reverse order...
  //Step 3: Translate back to where this object came from
  glTranslatef(m_center.x, m_center.y, m_center.z);

  //Step 2: Rotate this object about it's local axis
  glRotatef(degrees.y, 0, 1.0, 0);
  glRotatef(degrees.z, 0, 0, 1.0);
  glRotatef(degrees.x, 1.0, 0, 0);

  //Step 1: Translate this object to the origin
  glTranslatef(-1*m_center.x, -1*m_center.y, -1*m_center.z);

  //Render this object rotated by degrees
  Render();

  //Pop this matrix so that everything we render after this
  // is not also rotated
  glPopMatrix();
}
0 голосов
/ 06 января 2013

Ваша проблема в том, что вы сохраняете свои вращения x, y, z и добавляете их кумулятивно.Затем, когда вы выполняете рендеринг, вы выполняете совокупные вращения на матрице идентичности (вы выполняете все вращения глобально).Закомментируйте ваш идентификационный вызов из цикла рендеринга.И убедитесь, что вы установили идентичность в своей функции инициализации.Тогда

rotate as normal
m_Rotation.x = m_Rotation.y = m_Rotation.z = 0.0f; 
//clear your rotations you don't want them to accumulate between frames
glpush
translate as normal
(all other stuff)
glpop
//you should be back to just the rotations 
//glclear and start next frame as usual

Как я уверен, вы узнали об этом после того, как приняли первоначальный ответ.Порядок вращений или перемещений не влияет на то, на какой оси происходит вращение, а скорее на точку, в которой выполняется вращение.Например, вращение планеты на 15 градусов повернёт ее на глобальную ось на 15 градусов.Если перевести его из начала координат и затем повернуть, он будет вращаться вокруг источника на расстоянии, переведенном (если на той же оси, что и вращение, перемещение по оси x, а затем вращение по оси y не будет иметь каких-либо мешающих эффектов).

...