• Advertisement
Sign in to follow this  


Recommended Posts

Can someone explain why matrices m1 and m2 are not the same, and what m1 is actually doing since m1 is even different from m3?


According to msdn:

XMMatrixRotationRollPitchYaw receives the following parameters pitch -> yaw -> roll (formal parameter order),

which represents rotation around x -> y -> z (formal parameter order),

which is applied as roll -> pitch -> yaw (matrix multiplication order),

which represents rotation around z -> x -> y (matrix multiplication order).


So transformation matrix T = Ry * Rx * Rz = Ry * Rx (matrix m2), transforms a vector v as Tv.


XMFLOAT4X4 m1, m2, m3;
DirectX::XMStoreFloat4x4(&m1, XMMatrixRotationRollPitchYaw(XM_PIDIV4, XM_PIDIV2, 0.0f));
DirectX::XMStoreFloat4x4(&m2, XMMatrixRotationY(XM_PIDIV2) * XMMatrixRotationX(XM_PIDIV4));
DirectX::XMStoreFloat4x4(&m3, XMMatrixRotationX(XM_PIDIV4) * XMMatrixRotationY(XM_PIDIV2));
Edited by matt77hias

Share this post

Link to post
Share on other sites

Matrices m1 and m3 are more or less equal, as expected, and look something like this, if you print them out:

|-0.00  0.00 -1.00  0.00|
| 0.71  0.71 -0.00  0.00|
| 0.71 -0.71 -0.00  0.00|
| 0.00  0.00  0.00  1.00|

DirectXMath uses row-vector convention under the hood, so you would transform a vector like so: v*M1*M2*M3. Matrix concatenation order is then M1*M2*M3. Since XMMatrixRotationRollPitchYaw rotates first around X, then around Y, your m3 matrix holds the expected transform. Here is a great article about row vs column-vector convention: link.

Now to that "more or less" part. Transforming a vector by either m1 or m3 should produce visually indistinguishable results, however, these matrices aren't equal up to binary representation. That's easy to see, if we inspect the memory, where the matrices are located, or even simply add a few decimal places to the print out:
| 0.000000089 -0.000000030 -0.999999821  0.000000000|
| 0.707106709  0.707106829 -0.000000089  0.000000000|
| 0.707106650 -0.707106709  0.000000119  0.000000000|
| 0.000000000  0.000000000  0.000000000  1.000000000|
|-0.000000119  0.000000000 -0.999999881  0.000000000|
| 0.707106709  0.707106709 -0.000000084  0.000000000|
| 0.707106650 -0.707106769 -0.000000084  0.000000000|
| 0.000000000  0.000000000  0.000000000  1.000000000|

I believe, that is due to the fact, that m1 and m3 were constructed differently and hence went through a different number of different floating point operations. XMMatrixRotationRollPitchYaw doesn't actually use matrix multiplication at all, but rather goes through an intermediate quaternion representation to compute the resulting rotation matrix. And floating point operations tend to accumulate error, which eventually leads to slightly different results.

Edited by dietrich

Share this post

Link to post
Share on other sites

DirectXMath uses row-vector convention under the hood

Thank you for pointing this out. Already was suspicious when I looked at the formal parameter order in XMVector3Transform, but msdn lacks essential documentation.

Share this post

Link to post
Share on other sites

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  

  • Advertisement