OpenGL旋转-局部轴与全局轴

OpenGL Rotation - Local vs Global Axes

本文关键字:全局 旋转 -局 OpenGL      更新时间:2023-10-16

所以我有一个对象,我试图根据偏航、俯仰和滚转方案,相对于对象自己的局部轴而不是全局空间的轴旋转。根据这个,我需要按照这个顺序进行旋转。我把它解释为:

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;

(它们被传递给被移动对象内部的函数,但不会对它们执行任何其他操作)。

想法?还有什么我应该调用的东西来确保所有旋转的轴都是局部轴吗?

Garrick,

当调用glRotate(角度,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();
}

您的问题是存储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轴上旋转不会产生任何混淆效应)。