Maths - Conversion Matrix to Quaternion (original) (raw)
Hi martin,
Sorry, I forgot to paste the part that recovers the signs as well. You need to do this after the sqrt().
Q.x = _copysign( Q.x, m21 - m12 )
Q.y = _copysign( Q.y, m02 - m20 )
Q.z = _copysign( Q.z, m20 - m02 )
Depdending on your convention, the signs may be reverse.
My Intel datasheet says, a sqrt() is 24 .. 40 cycles, depending on the current prescision setting in the float-control register. A division is comparable to a sqrt() in terms of cycles.
So you win the branchlessness which is better IMHO (a mispredicted branch can cost you another 50 cycles, and since we're branching on random data, it will mispredict 50% of time, the worst case).
Another pitfall you might watch out is whether _copysign() is implemented as intrinsic and not as a library call.
However, _copysign is really just the transfer of the highest bit of the floating point number, so you could write a macro that does that.
The most robust code will have an expression that consider all redundant values at once. For instance, if you know the squared length of the quaternion must be equal to the length any row- or column-vectors, then instead of picking out a signle one, better calculate something that involves all values at the same time.
Christian