OpenGL Rotation - Local and Global Axes

So, I have an object that I am trying to rotate according to the Yaw, Pitch and Roll scheme compared to the objects of its own local axes, and not to the global axes of space. According to this , I need to perform rotations in this order. I interpreted it like 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);

      

However, rotation around the Y and Z axes does not work. Rotation around the Y axis is always global space, and rotation around the rotation z axis operations around the X axis is 0, but otherwise a mess.

To be sure, I tried the reverse order too, but that doesn't work either. I think I've tried all other orders too, so the problem must be something else. may be?

This is how I get the rotations:

    ///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;
    }

      

They are then added to m_Rotation as such:

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

      

(They are passed to a function internal to the item being moved, but nothing is done with them.)

Thoughts? Is there something else I should call to make sure that all the axes that rotate around are local axes?

+3


source to share


2 answers


Garrick,

When you call glRotate (angle, x, y, z), it rotates around the vector you pass to glRotate. The vector goes from (0,0,0) to (x, y, z).

If you want to rotate an object around the local axis of the object, you need to glTranslate the object to the origin, perform your rotation, and then translate it back to where it came from.



Here's an example:

//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 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();
}

      

+1


source


Your problem is that you are storing your x, y, z rotations and adding to them cumulatively. Then, when you render, you perform generic unitary cumulative rotations (you do all rotations around the world). Comment out your ID from the render loop. And make sure you set the id when you initialize. Then

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

      



As I'm sure you found out after accepting the original answer. The order of rotation or translations does not affect the axis on which the rotation occurs, and not the point at which the rotation is performed. for example, a planet rotation of 15 degrees will rotate it on the global axis of 15 degrees. By translating it from the source and then rotating it, it will cause the origin to orbit at the translated distance (if on the same axis as the rotation translating along the x-axis, then the rotation on the y-axis will not have any mixing effects).

0


source







All Articles