#pragma once
#include "..//MFC_D3D//XD3D.h"
#include <vector>
const int BOXS8_NUM = 8;
struct BOXS8_NODE
{
int iBoxID;
D3DXVECTOR3 vMin;
D3DXVECTOR3 vMax;
D3DXVECTOR3 vPos;
BOXS8_NODE* pChild[BOXS8_NUM];
BOXS8_NODE()
{
iBoxID = -1;
vMin = vMax = vPos = D3DXVECTOR3(0,0,0);
for(int i=0; i<BOXS8_NUM; i++)
pChild[i] = NULL;
}
BOXS8_NODE(const int in_iID,
const D3DXVECTOR3& in_vMin,
const D3DXVECTOR3& in_vMax,
const D3DXVECTOR3& in_vPos)
{
iBoxID = in_iID;
vMin = in_vMin;
vMax = in_vMax;
vPos = in_vPos;
for(int i=0; i<BOXS8_NUM; i++)
pChild[i] = NULL;
}
};
class BOXS8_TREE
{
public:
BOXS8_TREE():pBoxsTree(NULL){}
~BOXS8_TREE(){}
int CheckHit(const D3DXVECTOR3& in_vPoint)
{
return CheckHit(in_vPoint,pBoxsTree);
}
void CreateBOXS8(
const D3DXVECTOR3& in_vMin,
const D3DXVECTOR3& in_vMax,
const D3DXVECTOR3& in_vPos,
const int in_iPly)
{
ClearBOXS8();
int iID = 0;
CreateBOXS8(pBoxsTree,in_vMin,in_vMax,in_vPos,in_iPly,iID);
}
void GetBoxPoint(std::vector<std::vector<D3DXVECTOR3>>& out_vData)
{
GetBoxPoint(out_vData,pBoxsTree);
}
void ClearBOXS8()
{
ClearBOXS8(pBoxsTree);
}
private:
int CheckHit(const D3DXVECTOR3& in_vPoint, const BOXS8_NODE* pBox);
void CreateBOXS8(BOXS8_NODE*& pBox,
const D3DXVECTOR3& in_vMin,
const D3DXVECTOR3& in_vMax,
const D3DXVECTOR3& in_vPos,
const int in_iPly,
int& in_iIDStart);
void GetBoxPoint(std::vector<std::vector<D3DXVECTOR3>>& out_vData,
const BOXS8_NODE* pBox);
void ClearBOXS8(BOXS8_NODE*& pBox);
void GetBox(D3DXVECTOR3 o_vBox[24],
const D3DXVECTOR3& in_vMin,
const D3DXVECTOR3& in_vMax,
const D3DXVECTOR3& in_vPos);
BOXS8_NODE* pBoxsTree;
};
/////////////////////////////////
#include "BOXS8_TREE.h"
void BOXS8_TREE::CreateBOXS8(BOXS8_NODE*& pBox,
const D3DXVECTOR3& in_vMin,
const D3DXVECTOR3& in_vMax,
const D3DXVECTOR3& in_vPos,
const int in_iPly,
int& in_iIDStart)
{
pBox = new BOXS8_NODE(in_iIDStart, in_vMin,in_vMax,in_vPos);
if( in_iPly > 1)
{
D3DXVECTOR3 vMid = (in_vMin + in_vMax)/2;
D3DXVECTOR3 vPoint[BOXS8_NUM*2] =
{
D3DXVECTOR3(in_vMin.x, in_vMin.y, in_vMin.z),
D3DXVECTOR3(vMid.x, vMid.y, vMid.z),
//
D3DXVECTOR3(vMid.x, in_vMin.y, in_vMin.z),
D3DXVECTOR3(in_vMax.x, vMid.y, vMid.z),
D3DXVECTOR3(in_vMin.x, vMid.y, in_vMin.z),
D3DXVECTOR3(vMid.x, in_vMax.y, vMid.z),
D3DXVECTOR3(in_vMin.x, in_vMin.y, vMid.z),
D3DXVECTOR3(vMid.x, vMid.y, in_vMax.z),
//
D3DXVECTOR3(vMid.x, vMid.y, in_vMin.z),
D3DXVECTOR3(in_vMax.x, in_vMax.y, vMid.z),
D3DXVECTOR3(vMid.x, in_vMin.y, vMid.z),
D3DXVECTOR3(in_vMax.x, vMid.y, in_vMax.z),
D3DXVECTOR3(in_vMin.x, vMid.y, vMid.z),
D3DXVECTOR3(vMid.x, in_vMax.y, in_vMax.z),
//
D3DXVECTOR3(vMid.x, vMid.y, vMid.z),
D3DXVECTOR3(in_vMax.x, in_vMax.y, in_vMax.z),
};
for(int i=0; i<BOXS8_NUM; i++)
{
CreateBOXS8(pBox->pChild[i], vPoint[i*2],vPoint[i*2+1],in_vPos,in_iPly-1,++in_iIDStart);
}
}
}
void BOXS8_TREE::GetBoxPoint(std::vector<std::vector<D3DXVECTOR3>>& out_vData,
const BOXS8_NODE* pBox)
{
if( NULL != pBox)
{
D3DXVECTOR3 BOXPOINT[24];
GetBox(BOXPOINT,pBox->vMin,pBox->vMax, pBox->vPos);
std::vector<D3DXVECTOR3> data;
for(int i=0; i<24; i++)
data.push_back(BOXPOINT[i]);
out_vData.push_back(data);
for(int i=0; i<BOXS8_NUM; i++)
GetBoxPoint(out_vData,(const BOXS8_NODE*)pBox->pChild[i]);
}
}
void BOXS8_TREE::ClearBOXS8(BOXS8_NODE*& pBox)
{
if( NULL == pBox)
return;
else
{
for(int i=0; i<BOXS8_NUM; i++)
{
ClearBOXS8(pBox->pChild[i]);
}
delete[] pBox;
pBox = NULL;
}
}
void BOXS8_TREE::GetBox(D3DXVECTOR3 o_vBox[24],
const D3DXVECTOR3& in_vMin,
const D3DXVECTOR3& in_vMax,
const D3DXVECTOR3& in_vPos)
{
const D3DXVECTOR3 BOX_POINT[] =
{
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMin.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMin.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMin.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMax.z),
D3DXVECTOR3(in_vPos.x + in_vMax.x, in_vPos.y + in_vMax.y, in_vPos.z + in_vMax.z),
};
memcpy(o_vBox, BOX_POINT, sizeof(BOX_POINT));
}
int BOXS8_TREE::CheckHit(const D3DXVECTOR3& in_vPoint, const BOXS8_NODE* pBox)
{
if( NULL != pBox)
{
D3DXVECTOR3 vMin = pBox->vMin + pBox->vPos;
D3DXVECTOR3 vMax = pBox->vMax + pBox->vPos;
if( in_vPoint.x >= vMin.x
&& in_vPoint.x <= vMax.x
&& in_vPoint.y >= vMin.y
&& in_vPoint.y <= vMax.y
&& in_vPoint.z >= vMin.z
&& in_vPoint.z <= vMax.z)
{
for(int i=0; i<BOXS8_NUM; i++)
{
//有更准确的返回更准确的箱子
int k = CheckHit(in_vPoint, (const BOXS8_NODE*)pBox->pChild[i]);
if( -1 != k)
return k;
}
//无更准确的返回当前箱子
return pBox->iBoxID;
}
}
return -1;
}