AntiTwister said:
There is a nice set of 24 unit quaternions which are spaced apart evenly, called the Hurwitz quaternions. This is a handy choice to use for a base bunch of orientations to render your object at.
If you have the quaternion representing the orientation at runtime, it is then easy to take a dot product between that orientation and all the orientations you have pictures for. Whichever dot product is the largest is the best pre-rendered picture to use!
Huh, that actually sounds interesting enough that I might end up looking into it. Thanks for the reference to the Hurwitz quaternions - it gives me a term to search for instead of trying to bruteforce search terms for what I'm doing haha.
The thing about finding the largest dot product sounded a bit brutal at first, but then I remembered that my atan2 implementation requires a division operation, which is quite slow on my target platform, so it might work out anyway.
JoeJ said:
I can't imagine what your problem might be, but hacking the function probably isn't needed. […]
Here is what the scene looks like, with the navmesh and camera:
(just pretend that the yz axes are swapped; I'm accounting for this during export)
Notice how the camera is pointed towards -z, which is what I mentioned is causing issues for this particular case (all my other tests went fine, with the camera pointed towards +z).
Now, the resulting matrix I get (after a bit of further manipulation) is:
-0.823, 0.25, -0.511
-0.07, -0.936, -0.347
0.564, 0.249, -0.787
Quick notes: The y component (second row) is negated because of some implementation details (I need y pointing down the pre-rendered image), but that's not too important. And the z component (third row) is pointing into the screen, rather than out of the screen as is standard, because that makes the most sense for me (again, not too important).
Anyway: Based off your function implementation, the z rotation angle (in x→y→z rotation order) would be -atan2(-(0.25), -0.823) = 163.1
degrees, which is very obviously wrong by comparing against the image above. If I instead use -atan2(-0.25, 0.823), though, I get 16.9 degrees, which /is/ correct. This is what I meant about the atan2 x argument being “contaminated” when the camera points in the -z direction - the y-axis rotation needed to point that way will negate the M[0][0] component (which makes sense, since you're now looking at things “backwards”).
Though now that I think about it a bit more… shouldn't it be possible to correct for his, by just inspecting the y rotation angle? ie. if cos(r_y) < 0
, then r_z = pi - r_z
? (I'd check the angle directly rather than evaluating the cosine, but just to make it clearer)