GLM Quaternion Camera

Started by
12 comments, last by Enalis 12 years, 8 months ago
I'm trying to switch over to glm as I quite like the glsl syntax. It is also more complete than my own math library and has quaternions, not to mention a few other nifty features. So I decided that for a space sim gimbal locks were definitely a bad thing and set off to rewrite my camera with quaternions via glm... They are actually quite pleasant to use and can't believe I didn't use them before, that is until I came across relative camera movement. Basically, if I don't rotate the camera, everything is fine, but as soon as I do, forward is sometimes backwards or strafe_left, and basically every direction is messed up. From what I understood, if you take the oritentation quaternion multiplied by the movement vector and then by the inverse of the quaternion it should rotate the vector. I've tried that, and I've also tried this little snippet below which is supposed to do the same thing I think. NOTE: Camera rotation by the mouse works great!

quite simply I'm just orienting my relative movement vector with the quaternion and adding that to my camera position:


void Camera::Move(glm::vec3 movement){
position += glm::gtx::quaternion::rotate(orientation, movement);
}


I can post the whole class if required, but I think this should be enough.
Douglas Eugene Reisinger II
Projects/Profile Site
Advertisement
People really need to stop making other people believe that Quaternions are the answer to Gimbal lock. They are completely interchangeable with rotation matrices and irrational fear of gimbal lock is NOT one of the good reasons to use them. And especially if someone DOES have issues with gimbal lock, just replacing matrices with quaternions and still basing everything on Euler angles won't help a thing.
f@dzhttp://festini.device-zero.de

People really need to stop making other people believe that Quaternions are the answer to Gimbal lock. They are completely interchangeable with rotation matrices and irrational fear of gimbal lock is NOT one of the good reasons to use them. And especially if someone DOES have issues with gimbal lock, just replacing matrices with quaternions and still basing everything on Euler angles won't help a thing.


LOL. Euler angles come with the problem of gimbal lock. Proper use of quaternions fixes that problem, and presents lots of other advantages as well. What's your deal, are you one of Euler's ancestors?
Well, you'll be happy to know I replace my euler angles with a quaternion. I'm pretty sure I'm using it in such a way to avoid said paitfalls. Thanks though for the heads up! Anyone have any ideas?
Douglas Eugene Reisinger II
Projects/Profile Site
Sounds like your movement vector isn't being tranformed into the camera's space properly - although transforming it by the camera's quaternion *should* work...

Another way to do it, assuming that you derive a matrix from the camera's position/orientation at some point (for rendering, etc), would be to pull the camera's world x/y/z out of that. so to move the camera forward, you grab the z vector fron the camera's matrix, scale it by speed*time and add it to the position.
That did the trick, now I just have to read and figure out how to restrict certain rotation directions so that I don't start "rolling" when simply turning. :)

Thanks a lot lads and possibly lasses!
Douglas Eugene Reisinger II
Projects/Profile Site
The easiest way I've found to constrain an orientation, and you are going to hate me, is to convert the quaternion back into euler angles, constrain those, and then turn it back into a quaternion again (directly - not via matrices).
I'd love to hear if anyone knows how to piecewise do that to a quaternion directly!
In C++, friends have access to your privates.
In ObjAsm, your members are exposed!
Well, if I'm contraining for a specific type of camera... ie ground based fps camera, then I shouldn't encounter a gimbal lock anyway. So that should be fine. Makes sense, I admit, I had thought of this, but I was trying to avoid it.
Douglas Eugene Reisinger II
Projects/Profile Site

That did the trick, now I just have to read and figure out how to restrict certain rotation directions so that I don't start "rolling" when simply turning. :)

Thanks a lot lads and possibly lasses!


Well you can think in terms of Euler angles, i.e. rotation around the x, y or z axes (of the camera). So to apply pitch (rotation around the x axis), you simply grab the camera's x axis from the matrix and construct a quaternion using that; I'm not familiar with glm but I assume there's a quaternion(axis, angle) function.
When I did that it restricted rotation completely...

Here's what I've done so far:

Method 1 (first mentioned)
This still rotates stuff but it still rolls as well; which makes sense because I only fill angles x and y components from the mouse for rotation.

void Camera::Rotate(glm::vec3 angles){
glm::vec3 euler_angles = glm::gtx::quaternion::eulerAngles(orientation); // orientation is my classes rotation quat
euler_angles.x += angles.x;
euler_angles.y += angles.y;
orientation = glm::quat(euler_angles);
glm::gtc::quaternion::normalize(quaternion);
}


Method 2 using the axes
This results in no rotation at all.

void Camera::Rotate(glm::vec3 angles){
glm::vec3 euler_angles = glm::gtx::quaternion::eulerAngles(orientation);
glm::quat quat_x = glm::gtx::quaternion::angleAxis(euler_angles.x * (180.0f / float(PI)), glm::vec3(view_matrix[[0][0], view_matrix[1][0], view_matrix[2][0]));
glm::quat quat_y = glm::gtx::quaternion::angleAxis(euler_angles.y * (180.0f / float(PI)), glm::vec3(view_matrix[[0][1], view_matrix[1][1], view_matrix[2][1]));
orientation = quat_x * quat_y * orientation;
glm::gtc::quaternion::normalize(quaternion);
}
Douglas Eugene Reisinger II
Projects/Profile Site

This topic is closed to new replies.

Advertisement