XMQuaternionRotationRollPitchYaw
fido9dido opened this issue · comments
I am trying to use DirectXMath but I am not sure how it is suppose to be used,
Now I want to convert vector Rot to a quaternion
This is what doc says
XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYaw(
float Pitch,
float Yaw,
float Roll
);
Parameters
PitchAngle of rotation around the x-axis, in radians.
Yaw
Angle of rotation around the y-axis, in radians.
Roll
XMVECTOR XM_CALLCONV XMQuaternionRotationRollPitchYawFromVector(
FXMVECTOR Angles
);
Parameters
Angles3D vector containing the Euler angles in the order pitch, yaw, roll.
Angle of rotation around the z-axis, in radians.
I have vcRot= {fRotX,fRotY,fRotZ}, now these are the pitch yaw roll respectively,
Now I am using any dummy data say
float fRotX = 6.f, fRotY = 5.f, fRotZ = 7.f;
DirectX::XMVECTOR vcRot = DirectX::XMVectorSet(fRotX , fRotY,fRotZ,0);
DirectX::XMVECTOR qQuat= DirectX::XMQuaternionRotationRollPitchYawFromVector(vcRot);
I get
{0.313706458, 0.515175998, -0.199125499, -0.772354245}
I noticed if I used YZXW
DirectX::XMVECTOR vcRot = DirectX::XMVectorSet(fRotY, fRotZ,fRotX ,0);
I get {0.594493330, -0.199125484, -0.101959631, -0.772354245}
Which is the expected result but in YZWX but I dont understand why
in physx SDK they have EulerAngleToQuat(const physx::PxVec3& rot) and if I used it with the same dummy data as follows
physx::PxVec3 vcRot(radToDeg(6.f), radToDeg(5.f), radToDeg(7.f));
physx::PxQuat mQuat = EulerAngleToQuat(vcRot);
I get {x=-0.101959720 y=0.594493270 z=-0.199125603 ...}
and I have an old math library, it shows the same result as physx and I am showing physx as an example so no one say that my code is wrong
so if function like XMQuaternionRotationRollPitchYaw takes x y z or Pitch Yaw Roll why do i have to put y z x or Yaw Roll Pitch and why the quaternion is ordered in y z x w or y x z w and not x y z w
according to Chuck Walbourn's blog
D3DXQuaternionRotationYawPitchRoll | XMQuaternionRotationRollPitchYaw (Note the order of parameters is different: D3DXMath takes yaw, pitch, roll, DirectXMath takes pitch, yaw, roll)
Both D3DXQuaternionRotationYawPitchRoll
and XMQuaternionRotationRollPitchYaw
compute the same value for the same rotation descriptions. The difference was simply in the naming scheme for describing the concatenation order.
Both functions compute the rotations in the order: roll first, then pitch, then yaw.
Where exactly did the EulerAngleToQuat
function come from? It doesn't seem to be in the PhysX docs.
Also, 6, 5, and 7 in radians is going to be confusing because it's more than full rotation. Try using values in the range of 0 to PI.
Where exactly did the
EulerAngleToQuat
function come from? It doesn't seem to be in the PhysX docs.
True It's not in their documentation but EulerAngleToQuat can be found in SampleCharacterHelpers.cpp and radToDeg and degToRad can be found here
Also, 6, 5, and 7 in radians is going to be confusing because it's more than full rotation. Try using values in the range of 0 to PI.
Sorry, I was using any pseudo random values to check whether the return of my function were correct. How about
using this range gives similar results in the X,Z, and the y is a tad off
DirectX::XMVECTOR vcRot = DirectX::XMVectorSet(fRotX, fRotY, fRotZ, 0);
DirectX::XMVECTOR qQuat = DirectX::XMQuaternionRotationRollPitchYawFromVector(vcRot);
Result
fRotX = 1.f, fRotY =3.f, fRotZ = 2.f;
{0.754933715, 0.444435090, -0.206149250, 0.435952753}
fRotX = 2.f, fRotY =3.f, fRotZ = 2.f;
{0.485670298, 0.241108164, -0.421349198, 0.726949632}
fRotX = 2.f, fRotY =3.f, fRotZ = 3.f;
{0.541809201, -0.0212504417, -0.0212504417, 0.839963913}
physx::PxVec3 pxvcRot(radToDeg(1.f), radToDeg(3.f), radToDeg(2.f));
physx::PxQuat mQuat = EulerAngleToQuat(pxvcRot);
fRotX = 1.f, fRotY =3.f, fRotZ = 2.f;
{x=-0.718287051 y=0.501509070 z=-0.206149220, w=0.435952842}
fRotX = 2.f, fRotY =3.f, fRotZ = 2.f;
{x=-0.421349227 y=0.341282398 z=-0.421349198, w=0.726949751}
fRotX = 2.f, fRotY =3.f, fRotZ = 3.f;
{x=-0.533388197 y=0.0974979252 z=-0.0212504603, w=0.839963913}
OK, I've done some more digging, and I believe I have an answer for you.
The computation done by XMQuaternionRotationRollPitchYawFromVector
is the one from Wikipedia, i.e. the classic computation:
// cp = cos(pitch / 2);
// sp = sin(pitch / 2);
// cy = cos(yaw / 2);
// sy = sin(yaw / 2);
// cr = cos(roll / 2);
// sr = sin(roll / 2);
// q.w = cr * cp * cy + sr * sp * sy
// q.x = cr * sp * cy + sr * cp * sy
// q.y = cr * cp * sy - sr * sp * cy
// q.z = sr * cp * cy - cr * sp * sy
The Wikipedia code is a slightly different axis order of the same formulas.
q.w = cr * cp * cy + sr * sp * sy;
q.x = sr * cp * cy - cr * sp * sy;
q.y = cr * sp * cy + sr * cp * sy;
q.z = cr * cp * sy - sr * sp * cy;
The difference is one of convention. The Wikipedia formulation from the NASA paper defines the axes labels as is common in aerospace modeling:
- roll as x-axis
- pitch as y-axis
- yaw as z-axis
However, the DirectXMath convention follows the one more often used in games and was used in D3DXMath.
- pitch as x-axis
- yaw as y-axis
- roll as z-axis