Sign in to follow this  

Rotating an object with Quaternions

This topic is 407 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

I've got a bunch of directional vectors to drive the animations of a vehicle

You can assume the initial direction is facing east, (1,0,0) and goes southeast, which eventually facing south

These vectors are calculated from the pathfinder.

 

So

I wrote this code to animate the orientation of the agent.

D3DXQUATERNION qFinal, qStart, qEnd;
D3DXVECTOR3 startDir = l_transform->getDirection();
D3DXVECTOR3 endDir = l_transform->m_MotionInfo.fDir;                                                                 
D3DXQuaternionRotationYawPitchRoll(&qStart, startDir.x, startDir.y, startDir.z);
D3DXQuaternionRotationYawPitchRoll(&qEnd, endDir.x, endDir.y, endDir.z);                                                                
D3DXQuaternionSlerp(&qFinal, &qStart, &qEnd, l_transform->m_MotionInfo.fS);                                                                 
D3DXVECTOR3 finalDir;
D3DXVECTOR3 baseDir(1, 0, 0);
D3DXMATRIX matDir;
D3DXMatrixRotationQuaternion(&matDir, &qFinal);
D3DXVec3TransformCoord(&finalDir, &baseDir, &matDir);
l_transform->setOrientation(finalDir);                               

But it is not facing the correct direction

Even this code won't work

//float x = endPos.x - startPos.x;
//float z = endPos.z - startPos.z;
//float fNewDir = atan2f(-x, -z);
//m_transform->setOrientation(D3DXVECTOR3(fNewDir,0,0));                        

The difference in x is sometimes 3meters apart, and in z just about 1 meter

which makes the atan2f goes negative

 

So where does the problem lie in?

x: 0 y:0 z:0

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 1 y:0 z:2.88294e-006

x: 0.894439 y:0 z:-0.44719

x: 0.894439 y:0 z:-0.44719

x: 0.894439 y:0 z:-0.44719

x: 0.894439 y:0 z:-0.44719

x: 0.707141 y:0 z:-0.707072

x: 0.707141 y:0 z:-0.707072

x: 0.707141 y:0 z:-0.707072

x: 1.1626e-007 y:0 z:-1

x: 1.1626e-007 y:0 z:-1

x: 9.75419e-005 y:0 z:-1

x: 9.75419e-005 y:0 z:-1

x: 1 y:0 z:1.44143e-005

x: 1 y:0 z:1.44143e-005

x: 0.707124 y:0 z:-0.70709

x: 0.707124 y:0 z:-0.70709

x: 0.707124 y:0 z:-0.70709

x: 0 y:0 z:-1

x: 0 y:0 z:-1

x: 0.707107 y:0 z:-0.707107

x: 0.707107 y:0 z:-0.707107

x: 0.707107 y:0 z:-0.707107

x: 0 y:0 z:-1

x: 0 y:0 z:-1
Edited by lucky6969b

Share this post


Link to post
Share on other sites

It probably doesn't like that you are rebuilding the start quaternion each time. At the start of your rotation you should build the start quaternion and the end quaternion once. Those then should never be changed until the rotation is complete, unless you decide to cancel or alter the desired orientation. The only thing you should change each time is the 4th parameter that you pass to D3DXQuaternionSlerp which will obviously change the qFinal value too. 

 

To explain what is happening a little, imagine you are facing right (we'll call is 0 degrees) but you want to face up (90 degrees). You calculate your SLERP bit with t = 0.5. That would then give you a current orientation of 45 degrees (so far so good). The next pass around though and t might be 0.75 (which you would expect to be ~68 degrees) but because you now changed the start to be 45 degrees (the current value) you end up with 0.75 between 45 and 90 which is ~79 degrees. Eventually though it should still hit 90 degrees, it just won't be linear, it'll rapidly accelerate there but that's not what you want.

 

This might not be the only issue with it but hopefully it's a start.

Edited by Nanoha

Share this post


Link to post
Share on other sites
D3DXVECTOR3 startDir = l_transform->getDirection();
D3DXVECTOR3 endDir = l_transform->m_MotionInfo.fDir;                                                                 
D3DXQuaternionRotationYawPitchRoll(&qStart, startDir.x, startDir.y, startDir.z);
D3DXQuaternionRotationYawPitchRoll(&qEnd, endDir.x, endDir.y, endDir.z);                                                                

Unless startDir and endDir contains angles, you got a problem there.. You cannot pass a direction vector to D3DXQuaternionRotationYawPitchRoll(..) and expect it to work, that function needs radian angles :)

Share this post


Link to post
Share on other sites

This topic is 407 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this