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