Jump to content
  • Advertisement
Sign in to follow this  
Steve_Segreto

QuaternionLookRotation

This topic is 2980 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I want to emulate Unity3D's Quaternion.LookRotation() method in DirectX C++. Here is a brief description of it:

Quaternion.LookRotation()

Quaternion.LookRotation aligns the object's Z direction exactly to the forward (the first parameter) and then rotates it around that vector axis until it's Y direction is aligned as closely as possible with the supplied upward direction (the second parameter). In other words, of the two vectors, the first gets priority when they can't both be aligned exactly.

Here is my implementation:


D3DXQUATERNION *D3DXQuaternionLookRotation( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pForward, const D3DXVECTOR3 *pUp )
{
D3DXMATRIX m;
D3DXMatrixLookAtLH( &m, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), pForward, pUp );
D3DXQuaternionRotationMatrix( pOut, &m );

return pOut;
}





Can anyone tell me if my implementation is faithful to the intent of the original Quaternion.LookRotation() method?

Share this post


Link to post
Share on other sites
Advertisement
D3DXMatrixLookAtLH() generates an inverted view matrix, so you'll probably want to invert m between this line:
D3DXMatrixLookAtLH( &m, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), pForward, pUp );
And this line:
D3DXQuaternionRotationMatrix( pOut, &m );
It would probably be a little more efficient to build the matrix yourself manually (thus avoiding the inversion), but with the aforementioned change made, your function should work.

Share this post


Link to post
Share on other sites
After I get that look-at matrix and I've inverted it, before I convert it back to a quaternion, I want to sanity check it by extracting the angle around the y-axis that this rotation represents.

If m._11, m._12, m._12 is the forward vector, how can I tell how much it rotates around y-axis? Am I approaching this the correct way?

I'm testing the QuaternionLookRotation function like so:


D3DXVECTOR3 direction = targetPos - currentPos;
D3DXQUATERNION q;
D3DXQuaternionLookRotation( &q, &direction, &D3DXVECTOR3( 0, 1, 0 ) );

//
// Use this rotation for the displayed actor's world matrix.
//
D3DXMatrixRotationQuaternion( &pActors->worldMatrix, &q );

//
// Calculate desired rotation around y-axis
//
float idealFacing = (float)atan2f(direction.x, direction.z);

//
// Check this against the actual rotation around y-axis given by
// D3DXQuaternionLookRotation().... HOW TO DO THIS???
//
???

Share this post


Link to post
Share on other sites
Assuming +z is forward in local space, the forward vector will be elements 31, 32, and 33. And, assuming the function worked correctly, the extracted forward vector should be very close to the input direction vector. You can also get some idea of the 'absolute yaw' of the object by using atan2() as you're doing currently (provided the object isn't pointing nearly straight up or down), but whether this information will be useful depends on the context.

Also, it's probably worth considering whether there's any advantage to using quaternions for this. There very well may be (since I've only seen a little of your code I can't say for sure), but if you find you're building a matrix, converting it to a quaternion, and then converting that quaternion to a matrix again later, it may be that the 'quaternion' step is unnecessary.

Share this post


Link to post
Share on other sites
Thanks jyk, that perfectly explained it to me. I've rated you up, but I don't seem to have made an impact on your score, sorry.

I am converting some algorithms that come from a different math library that is quaternion-based to use in my DirectX environment, and I'm not industrious enough to just plain convert them, so I am using this admittedly less performant half-step. :(

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!