quaternion joy.....not (Resolved)
Hi guys. I am trying to convert a 3d model format into my own format in c++, I have however hit a problem. The source file uses a Quaternion and I have no idea what I am doing with it. I have been trying all day to understand the logic on websites etc and so far I have come up with this.
Code:
COB6Vertex RotateVector(float Quarns[4], COB6Vertex *CurrentVector)
{
COB6Vertex NewV;
float t[9];
//Truespace y and z are reversed
t[0] = CurrentVector->Y;
CurrentVector->Y = CurrentVector->Z;
CurrentVector->Z = t[0];
t[0] = Quarns[0] * Quarns[1];
t[1] = Quarns[0] * Quarns[2];
t[2] = Quarns[0] * Quarns[3];
t[3] = -Quarns[1] * Quarns[1];
t[4] = Quarns[1] * Quarns[2];
t[5] = Quarns[1] * Quarns[3];
t[6] = -Quarns[2] * Quarns[2];
t[7] = Quarns[2] * Quarns[3];
t[8] = -Quarns[3] * Quarns[3];
NewV.X = 2 * ((t[6] + t[8]) * CurrentVector->X + (t[4] - t[2]) * CurrentVector->Y + (t[1] + t[5]) * CurrentVector->Z) + CurrentVector->X;
NewV.Y = 2 * ((t[2] + t[4]) * CurrentVector->X + (t[3] + t[8]) * CurrentVector->Y + (t[7] - t[0]) * CurrentVector->Z) + CurrentVector->Y;
NewV.Z = 2 * ((t[5] - t[1]) * CurrentVector->X + (t[0] + t[7]) * CurrentVector->Y + (t[3] + t[6]) * CurrentVector->Z) + CurrentVector->Z;
//Return New
return NewV;
}
I tried to do it from the wiki page about rotation using a Querternion so sorry if it seems odd.
My results seem very mixed. Sometimes one of the returns will be correct but othertimes 2 seem mixed up and with the wrong signage (aka +/-). Other times its just not right at all.
Can anyone give me some pointers, my brain feels like it might explode :sick:
P.s COB6Vertex is just a 3 float variable of x,y and z.
Re: quaternion joy.....not
Are you sure the problem is in your rotation code?
I must say I don't really know that much about quaternions, but I compared your code with this:
Code:
t2 = a*b
t3 = a*c
t4 = a*d
t5 = -b*b
t6 = b*c
t7 = b*d
t8 = -c*c
t9 = c*d
t10 = -d*d
v1new = 2*( (t8 + t10)*v1 + (t6 - t4)*v2 + (t3 + t7)*v3 ) + v1
v2new = 2*( (t4 + t6)*v1 + (t5 + t10)*v2 + (t9 - t2)*v3 ) + v2
v3new = 2*( (t7 - t3)*v1 + (t2 + t9)*v2 + (t5 + t8)*v3 ) + v3
from this wiki:
http://en.wikipedia.org/wiki/Quatern...atial_rotation
and it seems to match.
So either the wiki is wrong or your problem comes from something else. How do you know that you are getting incorrect results? You must be displaying the 3d model somewhere. Perhaps you are displaying it incorrectly..?
EDIT
The wiki mentions that your quaternion ('Quarns') must have length 1. Is that the case?
Quarns[0]^2 + Quars[1]^2 + Quars[2]^2 + Quars[3]^2 must equal 1.
Re: quaternion joy.....not
Your translation of the code Nick listed seems correct to me as well, however your swap between y and z worries me a little. It changes the handedness of your coordinate system which effectively means that you're rotating in reverse of how you think you're rotating. If you could give more details on what "Truespace y and z" means, I might be able to be more specific. In the mean time, try negating the last three components of your quaternion. This will invert the angle by which you're rotating.
That is, try adding
Code:
//Truespace y and z are reversed
t[0] = CurrentVector->Y;
CurrentVector->Y = CurrentVector->Z;
CurrentVector->Z = t[0];
//Swap coordinate system handedness
Quarns[1] = -Quarns[1];
Quarns[2] = -Quarns[2];
Quarns[3] = -Quarns[3];
Edit: Also, there was a question about quaternions a few months back where I spelled out the conjugation algorithm for rotating using quaternions. You would only need a small part of it since you already have a unit quaternion if you're using it for spacial rotations. The code you have should effectively implement the q*p*q^-1 conjugation I listed in that thread, though. If the trouble is with the Wiki code you could try implementing that conjugation. It's relatively easy since it only requires defining quaternion multiplication and translating from 3D vectors to quaternions (which is as easy as adding an extra component on the left with value 0).
Edit (again): It also occurred to me that perhaps the quaternion itself was generated out of "Truespace". In that case, you could also try swapping the 3rd and 4th components, which would correspond to the transformation you've listed between y and z axes.
That is, try adding
Code:
//Truespace y and z are reversed
t[0] = CurrentVector->Y;
CurrentVector->Y = CurrentVector->Z;
CurrentVector->Z = t[0];
t[0] = Quarns[2];
Quarns[2] = Quarns[3];
Quarns[3] = t[0];
Re: quaternion joy.....not
Hi guys thanks for the help :D
I think I now have the correct results. I needed to do 3 things
1) Most importantly I needed swap the handedness of the Quarns as suggested by Jemidiah.
Code:
//Swap coordinate system handedness
Quarns[1] = -Quarns[1];
Quarns[2] = -Quarns[2];
Quarns[3] = -Quarns[3];
2) I needed to stop being an idiot and not reverse the Z and Y. The reason I was doing this is because Truespace uses the Z as the up axis and Y as the depth. My model format is setup like most games which is Y is up and Z is depth. The reason I needed to remove the code that reversed it was because the calculation was being done on the Truespace coordinates not the game coordinates. Kinda confused myself there :blush:
3) Stop being a complete idiot and when reading float values in the IDE spot the e-008 at the end of the value that indicates the value is actually VERY VERY close to 0 as opposed to just -2.98 :blush::blush::blush::blush:
Thanks for the help guys :D
Bodwad