# Issues implementing arcball viewer

My scene has a simple cube, and a camera built with the lookAt function (I'm using OpenGL). The scene renders fine, and I'm sure I have my model/view/projection matrices set up correctly.

Now I'm trying to implement arcball rotation for my camera, but I'm having some trouble. I've got it down to calculating the angle/axis rotation for a virtual sphere in normalized screen coordinates. That means when I move my mouse left to right, I get an angle around the Y axis... and moving my mouse up/down will get me an angle about X.

I'm not sure where to go from here -- what do I need to do with my axis so I can apply the angle to simulate camera rotation about its viewpoint?

If I try directly applying the axis/angle rotation the camera/view transform I get what you'd expect. The view is rotated about the world axes which the mouse moving over the virtual sphere on the screen corresponds to. So if I move the mouse up/down the view rotates about the world's X axis (what I get reminds me of a first-person view)... but this isn't what I want.

I think I need the axis I get to be transformed so it passes through the camera viewpoint and is oriented correct in reference to the camera... but I don't know if that's right or how to do that.

I presume that this is the camera that you want.

This type of camera is composed of two components: a rotation and an offset. The rotation is over yaw (left and right) and pitch (up and down).

The first thing you have to realize is that matrix math is not commutative, which is a fancy mathematical term for "A * B != B * A".

If you were to rotate a matrix and then translate it, you'd get a different matrix than if you were to first translate it and then rotate it.

What you want in your case (an arcball camera) is to first translate the camera matrix by its offset and then rotate it around its angles. In code:

// http://glm.g-truc.net - OpenGL Mathematics library

glm::vec3 camera_offset = GetCameraOffset();
glm::vec2 camera_rotation = GetCameraYawAndPitch();

// construct an arcball camera matrix

glm::mat4 camera_transform;
camera_transform = glm::translate(camera_transform, camera_offset);
camera_transform = glm::rotate(camera_transform, camera_rotation.x, glm::vec3(0.f, 1.f, 0.f)); // add yaw
camera_transform = glm::rotate(camera_transform, camera_rotation.y, glm::vec3(0.f, 0.f, 1.f)); // add pitch


Now you should have an arcball centered around the world's root (0.0, 0.0, 0.0). However, what if you want to move your camera to some other position? Simply add these lines:

glm::vec3 camera_position = GetCameraPosition();
camera_transform = glm::translate(camera_transform, camera_position);

• I'm still confused. The offset would allow me to rotate around the viewpoint... but I don't understand what you did with glm::rotate. What are camera_rotation.x and y? And why are you rotating about the world 'y' and 'z' axes? – Pris Jun 22 '12 at 13:59
• glm::rotate takes a 4x4 matrix and adds a rotation to it. In this case we are rotating over the world y axis (the yaw) and the world z axis (the pitch). camera_rotation is a 2D vector that contains the rotation values for yaw and pitch, as defined by the mouse. – knight666 Jun 22 '12 at 14:01
• Why would we want to rotate about the global x and y though? At the end of my routine I get a single axis and a single angle. Don't I want to rotate about that axis, just 'corrected' for the camera orientation? See this horribly drawn picture: sketchia.com/draw.html#fPdcGEU. If I get a rotation of 20 degrees about Y from the mouse, doesn't that mean I want to actually rotate the camera by 20 degrees about its up vector? – Pris Jun 22 '12 at 14:36
• Also going through your response again, its not clear to me what camera_offset is or what I should do with camera_transform. Do I pre or post multiply it with my view transform? – Pris Jun 22 '12 at 21:00
• I'll draw you a picture in the morning (7 hours from now). – knight666 Jun 22 '12 at 21:20