Reputation: 11
I am just starting to use DirectXMath. I want to use the Intersects function to check if two Triangles intersect. But everytime I call the function I get an exeption in it. I figure it is because I don´t create the XMVECTOR parameters the right way. I tried it two ways:
DirectX::XMVECTOR r = DirectX::XMVectorSet(m_x, m_y, m_z, 1.0f);
DirectX::XMVECTORI32 t = { m_x, m_y, m_z, 1.0f };
Both ways don´t work and since XMVECTOR doesn´t have x y z members I am having trouble understanding how this data type works.
I would really appreciate some help! Thanks in advance!
Upvotes: 1
Views: 4409
Reputation: 41107
Actually all the ways noted in the thread so far are valid ways, but have different uses and performance implications.
If you want to create a 'vectorized constant' of four floating-point constant values, the best answer is to use XMVECTORF32
:
static const XMVECTORF32 s_MyValue = { 1.f, 2.f, 3.f, 4.f };
The compiler is usually able to put this into the program's data segment so at runtime you just end up calling MOVAPS
to get the data into a SSE register.
The
XMVECTORU32
andXMVECTORI32
types do the same thing but assuming you want to initialize the elements to either anunsigned int
or anint
typically for use with bitwise or select operations since the DirectXMath library doesn't implement more than a few integer operations.
If you are storing your data in memory, a good solution is to use XMFLOAT4
in your data structures and use XMLoadFloat4
to get it into an XMVECTOR
:
XMVECTOR v = XMLoadFloat4(&myClass.myValue);
// This is equivalent in SSE to using _mm_loadu_ps
The vast majority of types in the DirectXMath library are intended to use in data structures. You use
XMVECTOR
andXMMATRIX
for all the computation, using the load and save routines to get data into and out of those types.
If you need to set a vector from a set of 4 scalar floating-point variables, that's what XMVectorSet
is for:
XMVECTOR v = XMVectorSet( m_x, m_y, m_y, 1.f );
// This is equivalent in SSE to using _mm_set_ps.
If you want a single scalar value loaded into all four positions, you'd use:
XMVECTOR v = XMVectorReplicate( m_a );
// This is equivalent in SSE to using _mm_set_ps1.
If you are wanting to load a scalar value into all four positions from a value in memory, another option is:
XMVECTOR v = XMVectorReplicatePtr( &m_a );
// This is equivalent in SSE to using _mm_load_ps1.
// If you were building with /arch:AVX, it would be _mm_broadcast_ss
There are also special-use case functions like XMVectorSetX
/ XMVectorSetXPtr
, XMVectorSetY
/ XMVectorSetYPtr
, XMVectorSetZ
/ XMVectorSetZPtr
, XMVectorSetW
/ XMVectorSetWPtr
, and the rather slow XMVectorSetByIndex
/ XMVectorSetIndexPtr
.
If you are new to DirectXMath, take some time to read through the DirectXMath Programming Guide. It's not particularly long and it's packed with information and tips.
See also Introducing DirectXMath and my other blog posts onthe subject. Also be sure to check out the GitHub project.
Some people find the SIMD-friendly alignment rules of DirectXMath a bit frustrating especially when they are first starting out, which is why I've also created the SimpleMath wrapper which is included in the DirectX Tool Kit. In this case you'd use something like
Vector4 v( m_x, m_y, m_z, 1.f );
then you can usev
wherever you'd useXMVECTOR
.
Upvotes: 7