
a to convert a matrix to a quaternion
Hi everyone
I am new to the forum and just learning and in top of that I am not a native english speaker so please bear with me.
I am working with some animation and want to make a mesh move and rotate according to a bezier path I have manage to make it move but the way I came with to make it rotate is to make a lookat matrix look from the current to the next position in the bezier curve, I'm not very good at math so, I don't know how to make a lookat quaternion so I use lookat matrix and convert it to a quaternion. All my rotation need to be in quaternion because all the interpolation is already done that way my scene graph, I tested my lookat matrix and is fine but the conversion to quaternion is wrong the function I am using is the one I have been seen around the web every where
void CQuaternion::FromMatrix(CMatrix& m)
{
float trace = 1 + m.m11 + m.m22 + m.m33;
float s = 0;
if (trace > 0.0000001)
{
s = (float)sqrt(trace) * 2;
x = (m.m23  m.m32) / s;
y = (m.m31  m.m13) / s;
z = (m.m12  m.m21) / s;
w = 0.25f * s;
}
else
{
if (m.m11 > m.m22 && m.m11 > m.m33)
{
// Column 0:
s = (float)sqrt(1.0 + m.m11  m.m22  m.m33) * 2;
x = 0.25f * s;
y = (m.m12 + m.m21) / s;
z = (m.m31 + m.m13) / s;
w = (m.m23  m.m32) / s;
}
else if (m.m22 > m.m33)
{
// Column 1:
s = (float)sqrt(1.0 + m.m22  m.m11  m.m33) * 2;
x = (m.m12 + m.m21) / s;
y = 0.25f * s;
z = (m.m23 + m.m32) / s;
w = (m.m31  m.m13) / s;
}
else
{
// Column 2:
s = (float)sqrt(1.0 + m.m33  m.m11  m.m22) * 2;
x = (m.m31 + m.m13) / s;
y = (m.m23 + m.m32) / s;
z = 0.25f * s;
w = (m.m12  m.m21) / s;
}
}
}
and this is my lookat matrix method just to be more clear
void CMatrix::LookAt(CVector3 Pos, CVector3 Target, CVector3 y)
{
CVector3 x, z;
z = Target  Pos;
z.Normalize();
if(!z.x && z.y == 1.0f && !z.z)
{
Rotate(1.5707963267948966f, 0.0f, 0.0f);
// Translate( Pos.x, Pos.y, Pos.z);
return;
}else
if(!z.x && z.y == 1.0f && !z.z)
{
Identity();
Rotate(1.5707963267948f, 0.0f, 0.0f);
// Translate( Pos.x, Pos.y, Pos.z);
return;
}
x.CrossProduct(z, y);
//x.Normalize();
y.CrossProduct(x, z);
y.Normalize();
m11 = x.x;
m12 = x.y;
m13 = x.z;
m21 = y.x;
m22 = y.y;
m23 = y.z;
m31 = z.x;
m32 = z.y;
m33 = z.z;
/*don't need position
m14 = m24 = m34 = 0;
m41 = Pos[0];
m42 = Pos[1];
m43 = Pos[2];*/
m44 = 1.0f;
}
please help, and thank you

You Matrix  Quaternion is quite different to mine. Are you sure the matrix is from OpenGL and not DirectX. You may need to find the original maths; mine is based on Allan and Mark Watt's "Advanced Animation and Rendering Techniques".

Senior Member
OpenGL Guru
Looking at your MatrixToQuat code, looks nearly equivalent to what I'm using (regrouping terms, of course). Two differences. One is my if/elif conditions for the nested if (i.e. those in the trace <= 0 case) are >= instead of > (a minor point). And second is that for greater numerical stability, it's better for the first if if you check for (trace1) > 0, not trace > 0. This corresponds to a w^2 > 1/4 case as opposed to the w^2 > 0. Additionally, this gets rid of the need for that 0.0000001 you're using to test against.
Note that the above routine presumes "rowmajor operatorontheright " math order (e.g. y=x*M), which generates the same results as OpenGL's "columnmajor operatorontheleft" math order (y=M*x).
Haven't sifted your LookAt code. Cut it out of the picture and do some MatrixToQuat followed by QuatToMatrix  make sure you get the same thing back out. That's a pretty good test.

it was basically what you mansion darkphoton I just realize my FromMatrix was row major while the lookat matrix was column major the funny thing was that I thought about it and decided to swap the column before using my FromMatrix method and the result were wrong too until I realize that by negating the z vector of my lookat matrix plus swapping from row to column major on the FromMatrix works fine.
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules