• 14
• 12
• 9
• 10
• 9

# Using directxmath, like this?

This topic is 1399 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I've started 'migrating' from D3DX to DirectXmath. It takes some time to get the hang of it, but I'm starting to get the feeling.

Can someone give me some pointers or approval that the way I'm doing things below is the way to go? (or are there easier ways)

Any input is appreciated.

3 examples, using D3DX:

// OLD functions

void OBB::Update(const D3DXMATRIX &pWorldMat, const AABB &pAABB)
{
D3DXVec3TransformCoord(&Center, &pAABB.Center(), &pWorldMat);

Extents = pAABB.Extents();

D3DXVECTOR3 mAx, mAy, mAz;
// orientation: rotation/ scaling (NOT in worldspace)
mAx = D3DXVECTOR3(pWorldMat._11, pWorldMat._12, pWorldMat._13);
mAy = D3DXVECTOR3(pWorldMat._21, pWorldMat._22, pWorldMat._23);
mAz = D3DXVECTOR3(pWorldMat._31, pWorldMat._32, pWorldMat._33);

XHalfExtent = mAx * Extents.x / 2.0f;
YHalfExtent = mAy * Extents.y / 2.0f;
ZHalfExtent = mAz * Extents.z / 2.0f;
}

void AABBWORLD::Update(const OBB &pOBB)
{
/*	1. calculate the 8 corners based on the OBB half extents

E              F
/-------------|				A = -X	-Y	-Z
/ |          / |				B = +X	-Y	-Z
/  |         /  |              C = +X	+Y	-Z
A	/------------|B  |              D = -X	+Y	-Z
|   |	     |   |
|  / - - - - | - | G			E = -X	-Y	+Z
| / H        |  /				F = +X	-Y	+Z
|/           | /				G = +X	+Y	+Z
|------------|/					H = -X	+Y	+Z
D	              C
*/

D3DXVECTOR3 OBBcorners[8];

OBBcorners[0] = -pOBB.XHalfExtent -pOBB.YHalfExtent -pOBB.ZHalfExtent;
OBBcorners[1] = +pOBB.XHalfExtent -pOBB.YHalfExtent -pOBB.ZHalfExtent;
OBBcorners[2] = +pOBB.XHalfExtent +pOBB.YHalfExtent -pOBB.ZHalfExtent;
OBBcorners[3] = -pOBB.XHalfExtent +pOBB.YHalfExtent -pOBB.ZHalfExtent;

OBBcorners[4] = -pOBB.XHalfExtent -pOBB.YHalfExtent +pOBB.ZHalfExtent;
OBBcorners[5] = +pOBB.XHalfExtent -pOBB.YHalfExtent +pOBB.ZHalfExtent;
OBBcorners[6] = +pOBB.XHalfExtent +pOBB.YHalfExtent +pOBB.ZHalfExtent;
OBBcorners[7] = -pOBB.XHalfExtent +pOBB.YHalfExtent +pOBB.ZHalfExtent;

//	2. Find the min and max X Y Z of the corners to get AABB in worldspace

_Min = OBBcorners[0];
_Max = _Min;

for(int j=1;j<8;++j)
{
_Min = D3DXVECTOR3((std::min)(OBBcorners[j].x, _Min.x),
(std::min)(OBBcorners[j].y, _Min.y),
(std::min)(OBBcorners[j].z, _Min.z));

_Max = D3DXVECTOR3((std::max)(OBBcorners[j].x, _Max.x),
(std::max)(OBBcorners[j].y, _Max.y),
(std::max)(OBBcorners[j].z, _Max.z));
}

//	3. Transfom Min/Max to worldspace by adding world center to the _Min and _Max
Center = pOBB.Center;
_Min += Center;
_Max += Center;
}

/**************************************************************************************/
/***							COORD TO COORD DIST									***/
/*** ==> usage: when distance between 2 D3DX vectors is needed						***/
/*** ==> returns the distance as a float value (non squared)						***/
/**************************************************************************************/

float CoordToCoordDist(const D3DXVECTOR3 &pv1, const D3DXVECTOR3 &pv2)
{
return D3DXVec3Length(&D3DXVECTOR3(pv1 - pv2));
}



And the new versions, using Directxmath:

void OBB::Update(const XMFLOAT4X4 &pWorldMat, const AABB &pAABB)
{
XMVECTOR tempNewCenter = XMVector3TransformCoord(tempCenter, tempWorldMat);

XMStoreFloat3(&Center, tempNewCenter);
Extents = pAABB.Extents();

// orientation: rotation/ scaling (NOT in worldspace)
XMVECTOR mAx = { pWorldMat._11, pWorldMat._12, pWorldMat._13 };
XMVECTOR mAy = { pWorldMat._21, pWorldMat._22, pWorldMat._23 };
XMVECTOR mAz = { pWorldMat._31, pWorldMat._32, pWorldMat._33 };

XMVECTOR tempXHalf = XMVectorScale(XMVectorScale(mAx, Extents.x), 0.5f);
XMVECTOR tempYHalf = XMVectorScale(XMVectorScale(mAy, Extents.y), 0.5f);
XMVECTOR tempZHalf = XMVectorScale(XMVectorScale(mAy, Extents.z), 0.5f);

XMStoreFloat3(&XHalfExtent, tempXHalf);
XMStoreFloat3(&YHalfExtent, tempYHalf);
XMStoreFloat3(&ZHalfExtent, tempZHalf);
}

void AABBWORLD::Update(const OBB &pOBB)
{
/*	1. calculate the 8 corners based on the OBB half extents

E              F
/-------------|				A = -X	-Y	-Z
/ |          / |				B = +X	-Y	-Z
/  |         /  |              C = +X	+Y	-Z
A	/------------|B  |              D = -X	+Y	-Z
|   |	     |   |
|  / - - - - | - | G			E = -X	-Y	+Z
| / H        |  /				F = +X	-Y	+Z
|/           | /				G = +X	+Y	+Z
|------------|/					H = -X	+Y	+Z
D	              C
*/

XMVECTOR OBBcorners[8];

//	2. Find the min and max X Y Z of the corners to get AABB in worldspace

XMStoreFloat3(&_Min, OBBcorners[0]);
_Max = _Min;

for(int j=1;j<8;++j)
{
_Min = XMFLOAT3((std::min)(XMVectorGetX(OBBcorners[j]), _Min.x),
(std::min)(XMVectorGetY(OBBcorners[j]), _Min.y),
(std::min)(XMVectorGetZ(OBBcorners[j]), _Min.z));

_Max = XMFLOAT3((std::max)(XMVectorGetX(OBBcorners[j]), _Max.x),
(std::max)(XMVectorGetY(OBBcorners[j]), _Max.y),
(std::max)(XMVectorGetZ(OBBcorners[j]), _Max.z));
}

//	3. Transfom Min/Max to worldspace by adding world center to the _Min and _Max
Center = pOBB.Center;
_Min = XMFLOAT3(_Min.x + Center.x, _Min.y + Center.y, _Min.z + Center.z);
_Max = XMFLOAT3(_Max.x + Center.x, _Max.y + Center.y, _Max.z + Center.z);
}

float CoordToCoordDist(const XMFLOAT3 &pv1, const XMFLOAT3 &pv2)
{

XMVECTOR result = XMVector3Length(XMVectorSubtract(temp1, temp2));
return XMVectorGetX(result);
}



##### Share on other sites

I would like to hear people's opinions on that, too. When I started to use DIrectXMath it was really uncomfortable for me. I thought that I was missing something, since I did a lot of repetitive things, like loading and storing vectors every time I needed to do some calculations and my lines became ridiculously long with all those DXMath calls.

##### Share on other sites

I would like to hear people's opinions on that, too. When I started to use DIrectXMath it was really uncomfortable for me. I thought that I was missing something, since I did a lot of repetitive things, like loading and storing vectors every time I needed to do some calculations and my lines became ridiculously long with all those DXMath calls.

Those store/loads are there because of the SEE implementation of the library. It is needed because of the memory alignment needed by the __m128 type (used for XMVECTOR XMMATRIX).

About the code... Usage of the library depends on your target platform. I suggest you to read carefully this http://msdn.microsoft.com/en-us/library/windows/desktop/ee418730(v=vs.85).aspx and a paper focused on data alignment.

Edited by imoogiBG

##### Share on other sites

Do you really need XHalfExtent. YHalfExtent and ZHalfExtent as XMFLOATx ?

I use XMStoreTypex and XMLoadTypex only when I need to store/load values to/from external objects. For internal class values I always use __m128 type. Yes, if the class object is dynamically allocated I need to align it to 16-byte, but that's not a big deal.

Edited by Alessio1989

##### Share on other sites
Thanks for the replies.
@Alessio: I need to save them to be able to use them for culling and collisions later on. For now my classes and structs only keep XMFLOATxx types, because of alignment issues if I don't save them as XMVECTOR's etc. As members. I might look into "anual alignment" later on, so I can have the class members also as XMVECTOR and XMMATRIX types

##### Share on other sites

I would like to hear people's opinions on that, too. When I started to use DIrectXMath it was really uncomfortable for me. I thought that I was missing something, since I did a lot of repetitive things, like loading and storing vectors every time I needed to do some calculations and my lines became ridiculously long with all those DXMath calls.

Those store/loads are there because of the SEE implementation of the library. It is needed because of the memory alignment needed by the __m128 type (used for XMVECTOR XMMATRIX).

About the code... Usage of the library depends on your target platform. I suggest you to read carefully this http://msdn.microsoft.com/en-us/library/windows/desktop/ee418730(v=vs.85).aspx and a paper focused on data alignment.

I know the reason why we load and store data and SSE behind it. However, the usage of the library becomes really tedious when you do that each time you want to process XMFLOAT. If you nest operations they become very long very quickly and there is lots of redundant code flying around. Thats why I am curios if everyone uses DXMath library like that or if they have found the ways to overcome those downsides.

##### Share on other sites

Hi. I've finished my migration from d3dx to directxmath the way we described above.

And actually it's not so bad when you get used to I. After some time, you'll find ways to get clean code.

For example, for the temporary XMVECTOR and XMMATRIX types, I now use a var name starting with xm, this really helps.

Like this:

		XMVECTOR xmCenterOld = XMLoadFloat3(&mSphereCenterModel);