Using directxmath, like this?

Started by
5 comments, last by cozzie 9 years, 11 months ago

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 tempCenter = XMLoadFloat3(&pAABB.Center());
	XMMATRIX tempWorldMat = XMLoadFloat4x4(&pWorldMat);
	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 tempXHalf = XMLoadFloat3(&pOBB.XHalfExtent);
	XMVECTOR tempYHalf = XMLoadFloat3(&pOBB.YHalfExtent);
	XMVECTOR tempZHalf = XMLoadFloat3(&pOBB.ZHalfExtent);

	XMVECTOR OBBcorners[8];
	OBBcorners[0] = XMVectorAdd(XMVectorAdd(	-tempXHalf,		-tempYHalf),	-tempZHalf);
	OBBcorners[1] = XMVectorAdd(XMVectorAdd(	+tempXHalf,		-tempYHalf),	-tempZHalf);
	OBBcorners[2] = XMVectorAdd(XMVectorAdd(	+tempXHalf,		+tempYHalf),	-tempZHalf);
	OBBcorners[3] = XMVectorAdd(XMVectorAdd(	-tempXHalf,		+tempYHalf),	-tempZHalf);

	OBBcorners[4] = XMVectorAdd(XMVectorAdd(	-tempXHalf,		-tempYHalf),	+tempZHalf);
	OBBcorners[5] = XMVectorAdd(XMVectorAdd(	+tempXHalf,		-tempYHalf),	+tempZHalf);
	OBBcorners[6] = XMVectorAdd(XMVectorAdd(	+tempXHalf,		+tempYHalf),	+tempZHalf);
	OBBcorners[7] = XMVectorAdd(XMVectorAdd(	-tempXHalf,		+tempYHalf),	+tempZHalf);

//	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 temp1 = XMLoadFloat3(&pv1);
	XMVECTOR temp2 = XMLoadFloat3(&pv2);

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

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

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.

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.

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.

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/
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

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

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.

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);
		XMMATRIX xmMatWorld = XMLoadFloat4x4(&mMatWorld);
		XMVECTOR xmCenterNew = XMVector3TransformCoord(xmCenterOld, xmMatWorld);
		XMStoreFloat3(&mBoundingSphere.WorldCenter, xmCenterNew);

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement