问题
Basically, given a quaterion (qx, qy, qz, qw)... How can i convert that to an OpenGL rotation matrix? I'm also interested in which matrix row is "Up", "Right", "Forward" etc... I have a camera rotation in quaternion that I need in vectors...
回答1:
The following code is based on a quaternion (qw, qx, qy, qz), where the order is based on the Boost quaternions:
boost::math::quaternion<float> quaternion;
float qw = quaternion.R_component_1();
float qx = quaternion.R_component_2();
float qy = quaternion.R_component_3();
float qz = quaternion.R_component_4();
First you have to normalize the quaternion:
const float n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw);
qx *= n;
qy *= n;
qz *= n;
qw *= n;
Then you can create your matrix:
Matrix<float, 4>(
1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
Depending on your matrix class, you might have to transpose it before passing it to OpenGL.
回答2:
One way to do it, which is pretty easy to visualize, is to apply the rotation specified by your quaternion to the basis vectors (1,0,0), (0,1,0), and (0,0,1). The rotated values give the basis vectors in the rotated system relative to the original system. Use these vectors to form the rows of the rotation matrix. The resulting matrix, and its transpose, represent the forward and inverse transformations between the original system and the rotated system.
I'm not familiar with the conventions used by OpenGL, so maybe someone else can answer that part of your question...
回答3:
You might not have to deal with a rotation matrix at all. Here is a way that appears to be faster than converting to a matrix and multiplying a vector with it:
// move vector to camera position co (before or after rotation depending on the goal)
v -= co;
// rotate vector v by quaternion q; see info [1]
vec3 t = 2 * cross(q.xyz, v);
v = v + q.w * t + cross(q.xyz, t);
[1] http://mollyrocket.com/forums/viewtopic.php?t=833&sid=3a84e00a70ccb046cfc87ac39881a3d0
回答4:
using glm, you can simply use a casting operator. so to convert from a matrix4 to quaternion, simply write
glm::mat4_cast(quaternion_name)
来源:https://stackoverflow.com/questions/1556260/convert-quaternion-rotation-to-rotation-matrix