Access floats of XMMatrix - () operator not working

折月煮酒 提交于 2019-12-12 12:16:10

问题


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.


回答1:


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
};



回答2:


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.




回答3:


I have found this to work, i too have based my code off the same ray picking tutorial and am moving from xnamath to directxmath.

This will select the correct values from the matrix without needing to disable SSE Intrinsics.

"projection" is an XMMATRIX containing the view matrix from the camera.

    XMVECTOR xv = projection.r[0];
    XMVECTOR yv = projection.r[1];
    PRVecX =  ((( 2.0f * mouseX) / Window::ClientWidth) - 1 ) / XMVectorGetX(xv);
    PRVecY = -((( 2.0f * mouseY) / Window::ClientHeight) - 1 ) / XMVectorGetY(yv);

Disabling intrinsics with a define is a bad idea, because it slows down your program immensely. Where possible convert your code to correctly load and store intrinsic values, as above.




回答4:


Add #define _XM_NO_INTRINSICS_ at the head of file。

#include <windows.h>
#define _XM_NO_INTRINSICS_//must before #include <DirectXMath.h>
#include <DirectXMath.h>
#include <iostream>



回答5:


You can try:

XMMATRIX i = XMMatrixIdentity();
float j = i.r[0].m128_f32[0];


来源:https://stackoverflow.com/questions/17475929/access-floats-of-xmmatrix-operator-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!