Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL camera rotation

In OpenGL I'm trying to create a free flight camera. My problem is the rotation on the Y axis. The camera should always be rotated on the Y world axis and not on the local orientation. I have tried several matrix multiplications, but all without results. With

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 rotation center should be the camera. Somebody an idea?

like image 216
user1318091 Avatar asked Dec 17 '22 01:12

user1318091


2 Answers

One of the more tricky aspects of 3D programming is getting complex transformations right.

In OpenGL, every point is transformed with the model/view matrix and then with the projection matrix.

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

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

Another thing you need to keep in mind is, rotations are always about an axis that is centered on the origin (0,0,0). So when you apply a rotate transform for the camera, whether you are turning it (as you would turn your head) or orbiting it around the origin (as the Earth orbits the Sun) depends on whether you have previously applied a translation transform.

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

  1. Apply the rotation(s) to orient the camera
  2. Apply translation(s) to position it
  3. Apply rotation(s) to orbit the camera round the origin
  4. (optionally) apply translation(s) to move the camera in its set orientation to move it to orbit around a point other than (0,0,0).

Things can get more complex if you, say, want to point the camera at a point that is not (0,0,0) and also orbit that point at a set distance, while also being able to pitch or yaw the camera. See here for an example in WebGL. Look for GLViewerBase.prototype.display.

The Red Book covers transforms in much more detail.

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

like image 124
Michael Slade Avatar answered Dec 26 '22 14:12

Michael Slade


Rather than doing this using matrices, you might find it easier to create a camera class which stores a position and orthonormal n, u and v axes, and rotate them appropriately, e.g. see:

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 comes time to set the view for the camera, you do:

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're wondering how to rotate about an arbitrary axis like (0,0,1), see MathUtil.rotate_about_axis in the above code.

like image 39
Stuart Golodetz Avatar answered Dec 26 '22 13:12

Stuart Golodetz