Jump to content
  • Advertisement
Sign in to follow this  
lucky6969b

Rotating an object with Quaternions

This topic is 621 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
Advertisement

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
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!