Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access floats of XMMatrix - () operator not working

I'm trying to do some 3D stuff in DirectX (I'm migrating from OpenGL) and I've hit a snag.

I want to access the values of an XMMATRIX and looking at the Microsoft documentation there should be an () operator:

    float&  operator ()(
  size_t Row,
  size_t Column
);

So I tried using as such:

XMMATRIX i = XMMatrixIdentity();
float j = i(0,0);

But Intellisense gives me the error:

IntelliSense: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type.

If I ignore Intellisense and compile anyway I get the compile-time error:

error C2064: term does not evaluate to a function taking 2 arguments

Anybody have any idea of why this is happening? Or another way to access the elements of the Matrix?

Thanks for your time.

P.S. I am creating a C++/DirectX Modern UI App for Windows 8 if this information helps at all.

like image 257
poncho Avatar asked Dec 12 '22 13:12

poncho


2 Answers

Check this MSDN link and you'll see that it depends on which DirectX or XNA math header you have and the pre-processor definitions in force at the time. By default, and for optimisation reasons, the matrix and vector structures will be implemented using SSE and intrinsics, which makes it difficult and expensive to provide row/col access.

Try defining _XM_NO_INTRINSICS_ in the pre-processor directive of the C++ entry of your project properties, or #define _XM_NO_INTRINSICS_ before you #include any DirectX headers.

This excerpt from DirectXMath.h on my Windows 8 VS2012 system shows why you get this error:

struct XMMATRIX
{
    // ... code removed for clarity

#ifdef _XM_NO_INTRINSICS_
    float       operator() (size_t Row, size_t Column) const { return m[Row][Column]; }
    float&      operator() (size_t Row, size_t Column) { return m[Row][Column]; }
#endif

    // ... code removed for clarity
};
like image 114
Roger Rowland Avatar answered Dec 14 '22 01:12

Roger Rowland


Individual element access for XMVECTOR and XMMATRIX is very inefficient due to the underlying SIMD instruction set, so the DirectXMath library doesn't support it through member methods. There are a number of ways to achieve this depending on your need.

If you just need the (0,0) element, you can use:

float j = XMVectorGetX( i.r[0] );

If you are going to access most or all of the individual elements of an XMMATRIX, the best solution is to dump it to an XMFLOAT4X4:

XMFLOAT4X4 tmp;
XMStoreFloat4x4( &tmp, i );
float j = tmp.m[0][0]; // or float j = tmp._11

I will file a doc bug because the operator() mentioned on MSDN is actually "XNAMath", not "DirectXMath". See this blog post for some background.

If you are finding DirectXMath a little too hard-core for your needs, you might want to consider using SimpleMath in the DirectX Tool Kit.

like image 42
Chuck Walbourn Avatar answered Dec 14 '22 02:12

Chuck Walbourn