OpenGL camera rotation

In OpenGL I am trying to create a free flight camera. My problem is the Y-axis rotation. The camera should always rotate in the Y-axis and not the local orientation. I have tried several matrix multiplications but all to no avail. FROM

camMatrix = camMatrix  * yrotMatrix 

      

rotates the camera along the local axis. And with

camMatrix = yrotMatrix * camMatrix

      

rotates the camera along the world axis, but always around the origin. However, the center of rotation should be the camera. Anyone have an idea?

+3


source to share


4 answers


One of the most difficult aspects of 3D programming is getting it right.

In OpenGL, each point is transformed with a model / view matrix and then with a projection matrix.

the model view matrix takes each point and translates it to where it should be from the camera's perspective. The projection matrix transforms the point coordinates so that the X and Y coordinates can be easily displayed in the window.

To get the correct mode / view matrix, you need to start with the identity matrix (one that doesn't change vertices) and then apply transformations for camera position and orientation, then object position and orientation in reverse order.

Another thing to keep in mind is the rotation is always around the axis centered at the origin (0,0,0). So when you apply rotation to the camera, whether you rotate it (how you rotate your head) or rotate it around the origin (since the earth revolves around the sun) depends on whether you previously applied the translation transform.



So, if you want to both rotate and orbit the camera, you need to:

  • Apply rotation for camera orientation
  • Apply translation (s) to post it
  • Apply rotation to orbit the camera around the origin
  • (optional) apply translation to move the camera in a given orientation to move it into orbit around a point other than (0,0,0).

Things can get more complicated if, say, you want to point the camera at a point that is not (0,0,0), as well as an orbit that points to a given distance, and the camera can also pitch or roar. See here for an example in WebGL. Find GLViewerBase.prototype.display

.

The Red Book covers conversions in more detail .

Also note the gluLookAt , which you can use to point the camera at something without having to use rotations.

+4


source


Instead of doing this with the help of the matrix, you can be easier to create a camera class that stores the position and orthonormal axis n

, u

and v

and accordingly turns them, for example. cm:

https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/GUI/Camera.java

and

https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/Math/MathUtil.java

Then you write things like:



if(m_keysDown[TURN_LEFT])
{
    m_camera.rotate(new Vector3d(0,0,1), deltaAngle);
}

      

When it's time to set the camera view, do the following:

gl.glLoadIdentity();
glu.gluLookAt(m_position.x, m_position.y, m_position.z,
              m_position.x + m_nVector.x, m_position.y + m_nVector.y, m_position.z + m_nVector.z,
              m_vVector.x, m_vVector.y, m_vVector.z);

      

If you are wondering how to rotate around any axis, for example (0,0,1)

see the MathUtil.rotate_about_axis

code above.

+3


source


If you don't want to convert based on the camera from the previous frame, my suggestion might be to just throw out the matrix recipe and recalculate it every frame. I don't think there is a way to do what you want with a single matrix as this keeps translation and rotation together.

I think if you just want only the pitch / yaw camera, just store these values ​​as two floats and then rebuild the matrix based on that. Perhaps something like pseudocode:

onFrameUpdate() {
  newPos = camMatrix * (0,0,speed) //move forward along the camera axis
  pitch += mouse_move_x;
  yaw += mouse_move_y;

  camMatrix = identity.translate(newPos)
  camMatrix = rotate(camMatrix, (0,1,0), yaw)
  camMatrix = rotate(camMatrix, (1,0,0), pitch)
}

      

+1


source


rotates the camera along the world axis, but always around the origin. However, the center of rotation should be the camera. Anyone have an idea?

I am assuming the matrix is ​​stored in memory this way (the number is the index of the element if the matrix was a linear 1d array):

0   1   2   3    //row 0
4   5   6   7    //row 1
8   9   10  11   //row 2
12  13  14  15   //row 3

      

Decision

  • Store the last row of the camera matrix in a temporary variable.
  • Set the last row of the camera matrix to (0, 0, 0, 1)
  • Use camMatrix = yrotMatrix * camMatrix

  • Restore the last row of the camera matrix from a temporary variable.
0


source







All Articles