2
\$\begingroup\$

I'm trying to move my camera around using mouse+keyboard. I'm looking for specific camera behaviour however, and I cant figure out how to get it right. What I've found, is that to get a maya/tumble style camera, I need to multiply my xrotation in world space then my yrotation. Reversing the order it looks like this:

view = cam_move * //wasd in cam_space, this works correctly
       yrot * //before = world to camera space      
       view*
       xrot; //after = model to world space

This means my xrot(world) doesn't interfere with my yrot(eye), which avoids unwanted roll induced by regular cam-space x-rotation.

enter image description here

My problem however, is that I want the xrotation to happen around a point (as if done in eye space) but without creating unwanted roll. I do not know how to get that result.

According to my sources It should be as easy as translating inversely before xrotating, then translating back after, but its just not working. Perhaps someone knows how I can get my cam to spin (yaw) around a point, without causing the unwanted roll?

SOLUTION:

Keeping track of pitch/yaw (mouse_move.xy) seperately, as well as the camera location, and making sure to multiply the yaw before the pitch. Pitching will create unwanted roll, but yawing wont create unwanted pitch, so its a matter of which you do first here.

To move the camera in eye space, I do this:

//make a mat3 rotation matrix and multiply it with current movement
if (keys['A'] - keys['D'] || keys['W'] - keys['S']){
    camlocation += //rotated then moved
        (glm::normalize(vec3(keys['A'] - keys['D'], 0, keys['W'] - keys['S']))*move_speed)*
        mat3(glm::rotate(mat4(1.0f), pitch, vec3(1, 0, 0)))*
        mat3(glm::rotate(mat4(1.0f), yaw, vec3(0, 1, 0)));
} //which will be a value to add in world space

Then under camera update, or where I build the view matrix, I do this:

view =
    glm::rotate(mat4(1.0f), pitch, vec3(1, 0, 0))* //pitch radian float
    glm::rotate(mat4(1.0f), yaw, vec3(0, 1, 0))* //yaw also in radian
    glm::translate(mat4(1.0f), camlocation);

Just remember that in OpenGL/GLM the matrix transformations are reverse order, due to how OpenGL does column/row matrix computations. (Compared to directx it saves a transpose operation in the shader (apparently))

Making sure to yaw before pitching, and both after translating (reversed on paper) avoids the unwanted roll, wich yields the desired tumble/maya effect!

\$\endgroup\$
1
\$\begingroup\$

In general, avoid the approach where you take current camera orientation, modify it and store as the new one - you will accumulate computation errors and it can easily break after a while.

Instead, define you center point for rotation.

Define your distance from this center (can be modified by e.g. mouse wheel).

Define Yaw and Pitch values.

Do you math that will compute camera matrix from those data.

In your UI you'll change Yaw/Pitch/distance/center and compute new camera matrix.

This way you have some base params that you modify, it's easier to do more complex UI around it and your camera matrix is always correct.

Here you have some explanation why do you get an unexpected Roll: https://gamedev.stackexchange.com/a/37242/18381

\$\endgroup\$
  • 1
    \$\begingroup\$ perfect, this was the clarification I needed \$\endgroup\$ – Charlie Aug 9 '18 at 5:28
  • 1
    \$\begingroup\$ For an example of this, see OrbitCamera \$\endgroup\$ – Chuck Walbourn Aug 9 '18 at 6:51
0
\$\begingroup\$

Welcome to computer graphics, and game development :)

Sorry, I'm writing from a phone...

Yaw Pitch Roll is cool, let me call it Euler angles.

Euler angles can be used for rotating object in 3D space, but this approach can be hard to implement.

With Euler angles you can't simply compose all components of your final rotation, you must do it with "correct" for your model order. In code it is a quest.

Look at quaternion. It harder to understand, but using it you does not deal with problems of Euler angles.

If components of rotations of your model represented with quaternions it can be simply multiplied in any order to get resulting rotation.

\$\endgroup\$
  • \$\begingroup\$ I dont think my problem is using the same approach as everyone else \$\endgroup\$ – Charlie Aug 7 '18 at 6:52
  • \$\begingroup\$ haroldserrano.com/blog/quaternions-in-computer-graphics \$\endgroup\$ – Stranger in the Q Aug 7 '18 at 6:57
  • \$\begingroup\$ I dont mind sequentially ordering my matrix transformations. My problem is how to rotate around a specific point, not gimbal lock or w/e \$\endgroup\$ – Charlie Aug 7 '18 at 7:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.