DOT_THRESHOLD seems to break things
mcclure opened this issue · comments
Short version: I am getting incorrect results when composing a quaternion with a pow()ed version of another quaternion. Looking at the code in quat.lua I find
if dot > DOT_THRESHOLD then
return a:scale(s)
end
I don't understand what this means, but if I remove it, I get correct results again.
Long version:
I am generating a random quaternion with
local RQ = quat.from_angle_axis( (math.random()-0.5)*maxAngle*2, 1,0,0 )
* quat.from_angle_axis( (math.random()-0.5)*maxAngle*2, 0,1,0 )
* quat.from_angle_axis( (math.random()-0.5)*maxAngle*2, 0,0,1 )
I'm not doing anything to set the seed so I get get consistent values every time I run. I have a quaternion EQ representing the rotation of an object. For each object I am animating RQ:pow(x)*EQ with x interpolating from 0 to 1.
For one of the objects (but not the others), RQ managed to find a "cursed" quaternion CQ; if I print out the xyzq values of CQ with string.format("%f")
I get -0.014149,0.020479,-0.006684,0.999668
. If I take CQ to a power, I get wacky results. If I take it to a power around 0.05, even though CQ is a very small rotation, this small power of a small rotation results in a huge rotation essentially equivalent to flipping 180 degrees on the X axis. pow() appears to work with quaternions other than CQ.
If I modify my transformation library to automatically normalize quaternions before applying them, the object just sort of jitters and freezes in place; it turns out if I take CQ and raise it to any power less than 1, then normalize, I get -0.019496,0.026780,-0.001824,0.999450
regardless of which power I took it to:
local quatTest = quat(-0.014149,0.020479,-0.006684,0.999668)
print("QUAT TEST", quatTest, quatTest:pow(1/36):normalize(), quatTest:pow(1/2):normalize())
If I remove the if dot > DOT_THRESHOLD
block from the definition of pow(), all these problems go away.
I am totally lost. It seems there is a bug in pow(), but I feel afraid just taking the code out since I don't know why it's there?
reading the code, i'm pretty confident that the dot check is a copy paste error from slerp that wasn't tested well enough. maybe it's derived from something that made sense, but it doesn't now.
i would remove it.