John Ratcliff's Code Suppository

A place where I insert my code into the anus of the Internet.

 

Monday, June 23, 2008

D3DXQuaternionRotationYawPitchRoll



I am going to refrain from a full blown rant here. That said, I cannot reiterate enough how f**king annoying it is that Microsoft goes as far out their way as possible to make it difficult for people to develop multi-platform code using their tools. When Microsoft released Visual Studio 2005 and had the unmitigated gall to issue a warning message for 'printf' I about blew a gasket. Now my code is littered with '#pragma warning(disable:4996)' to prevent VS2005 from throwing warnings everywhere for 100% perfectly ANSII C compliant code!!!!!!!!!!

Another problem we encounter is when people start using the D3DX library; which is not provided with source code. Recently I have needed to refactor some source that made use of the D3DX library for various math routines.

One problematic routine in particular is 'D3DXQuaternionRotationYawPitchRoll' which, for whatever reason, and at this point I don't even care, Microsoft implemented in a non-standard way. Since you don't get source code to D3DX there is no easy way to figure out what they did (turns out they flipped a couple of signs during the computation). Stepping into the disassembly just uncovers a whole bunch of cryptic SSE instructions that are not that illuminating.

Finally a very helpful Microsoft engineer posted the solution on the DirectX mailing list. I am going to repost the solution here so that anyone else who ever needs to know the formula has it.

Here is the correct formulation for D3DXQuaternionRotationYawPitchRoll.

----------------------------------------------------------------

void QuaternionRotationYawPitchRoll(float yaw,float pitch,float roll,float quat[4])
{

float sinY, cosY, sinP, cosP, sinR, cosR;

sinY = sinf(0.5f * yaw);
cosY = cosf(0.5f * yaw);

sinP = sinf(0.5f * pitch);
cosP = cosf(0.5f * pitch);

sinR = sinf(0.5f * roll);
cosR = cosf(0.5f * roll);

quat[0] = cosY * sinP * cosR + sinY * cosP * sinR;
quat[1] = sinY * cosP * cosR - cosY * sinP * sinR;
quat[2] = cosY * cosP * sinR - sinY * sinP * cosR;
quat[3] = cosY * cosP * cosR + sinY * sinP * sinR;
}

2 Comments:

  • At 6:02 AM, Anonymous Anonymous said…

    I understand your rant about MS thinking they are the C++ standard committee yet all you need to define in the project setting is _CRT_SECURE_NO_DEPRECATE rather than littering code with pragmas.

     
  • At 10:17 AM, Anonymous Anonymous said…

    And I guess quat[1] and quat[2] values are flipped.

     

Post a Comment

<< Home