外接体
第一步
在空间d3d中添加类
///////外接体///////////
struct BoundingBox
{
BoundingBox();
bool isPointInside(D3DXVECTOR3& p);
D3DXVECTOR3 _min;
D3DXVECTOR3 _max;
};
struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
float _radius;
};
//-------常量-------------------
const float INFINITY = FLT_MAX; //最大浮点数
const float EPSILON = 0.001f; //一个很小的值
struct BoundingBox
{
BoundingBox();
bool isPointInside(D3DXVECTOR3& p);
D3DXVECTOR3 _min;
D3DXVECTOR3 _max;
};
struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
float _radius;
};
//-------常量-------------------
const float INFINITY = FLT_MAX; //最大浮点数
const float EPSILON = 0.001f; //一个很小的值
第二步:
实现类里面的函数:
d3d::BoundingBox::BoundingBox()
{
// infinite small
_min.x = d3d::INFINITY;
_min.y = d3d::INFINITY;
_min.z = d3d::INFINITY;
_max.x = -d3d::INFINITY;
_max.y = -d3d::INFINITY;
_max.z = -d3d::INFINITY;
}
bool d3d::BoundingBox::isPointInside(D3DXVECTOR3& p)
{
if( p.x >= _min.x && p.y >= _min.y && p.z >= _min.z &&
p.x <= _max.x && p.y <= _max.y && p.z <= _max.z )
{
return true;
}
else
{
return false;
}
}
d3d::BoundingSphere::BoundingSphere()
{
_radius = 0.0f;
}
{
// infinite small
_min.x = d3d::INFINITY;
_min.y = d3d::INFINITY;
_min.z = d3d::INFINITY;
_max.x = -d3d::INFINITY;
_max.y = -d3d::INFINITY;
_max.z = -d3d::INFINITY;
}
bool d3d::BoundingBox::isPointInside(D3DXVECTOR3& p)
{
if( p.x >= _min.x && p.y >= _min.y && p.z >= _min.z &&
p.x <= _max.x && p.y <= _max.y && p.z <= _max.z )
{
return true;
}
else
{
return false;
}
}
d3d::BoundingSphere::BoundingSphere()
{
_radius = 0.0f;
}
第三步
函数的运用:
ComputeBoundingSphere(Mesh, &boundingSphere);
ComputeBoundingBox(Mesh, &boundingBox);
D3DXCreateSphere(Device, boundingSphere._radius, 20, 10, &SphereMesh, 0);
D3DXCreateBox(Device, boundingBox._max.x - boundingBox._min.x,
boundingBox._max.y - boundingBox._min.y,
boundingBox._max.z - boundingBox._min.z, &BoxMesh, 0);
ComputeBoundingBox(Mesh, &boundingBox);
D3DXCreateSphere(Device, boundingSphere._radius, 20, 10, &SphereMesh, 0);
D3DXCreateBox(Device, boundingBox._max.x - boundingBox._min.x,
boundingBox._max.y - boundingBox._min.y,
boundingBox._max.z - boundingBox._min.z, &BoxMesh, 0);
第四步:
对函数ComputeBoundingSphere()和ComputeBoundingBox()的实现。
bool ComputeBoundingSphere(ID3DXMesh* mesh, d3d::BoundingSphere* sphere)
{
HRESULT hr = 0;
BYTE* v = 0;
mesh->LockVertexBuffer(0, (void**)&v);
//计算外接球
hr = D3DXComputeBoundingSphere(
(D3DXVECTOR3*)v,
mesh->GetNumVertices(),
D3DXGetFVFVertexSize(mesh->GetFVF()),
&sphere->_center,
&sphere->_radius);
mesh->UnlockVertexBuffer();
if( FAILED(hr) )
return false;
return true;
}
bool ComputeBoundingBox(ID3DXMesh* mesh, d3d::BoundingBox* box)
{
HRESULT hr = 0;
BYTE* v = 0;
mesh->LockVertexBuffer(0, (void**)&v);
//计算外接体
hr = D3DXComputeBoundingBox(
(D3DXVECTOR3*)v,
mesh->GetNumVertices(),
D3DXGetFVFVertexSize(mesh->GetFVF()),
&box->_min,
&box->_max);
mesh->UnlockVertexBuffer();
if( FAILED(hr) )
return false;
return true;
}
{
HRESULT hr = 0;
BYTE* v = 0;
mesh->LockVertexBuffer(0, (void**)&v);
//计算外接球
hr = D3DXComputeBoundingSphere(
(D3DXVECTOR3*)v,
mesh->GetNumVertices(),
D3DXGetFVFVertexSize(mesh->GetFVF()),
&sphere->_center,
&sphere->_radius);
mesh->UnlockVertexBuffer();
if( FAILED(hr) )
return false;
return true;
}
bool ComputeBoundingBox(ID3DXMesh* mesh, d3d::BoundingBox* box)
{
HRESULT hr = 0;
BYTE* v = 0;
mesh->LockVertexBuffer(0, (void**)&v);
//计算外接体
hr = D3DXComputeBoundingBox(
(D3DXVECTOR3*)v,
mesh->GetNumVertices(),
D3DXGetFVFVertexSize(mesh->GetFVF()),
&box->_min,
&box->_max);
mesh->UnlockVertexBuffer();
if( FAILED(hr) )
return false;
return true;
}
还有最后一步:
即在Device->BeginScene()和Device->EndScene()之间填入
SphereMesh->DrawSubset(0)
或
BoxMesh->DrawSubset(0)
外接球或外接体常用于加速可见性检测和碰撞检测。
计算一个网格的外接体和外接球的函数。
HRESULT WINAPI D3DXCompteBoundingSphere(
const D3DXVECTOR3 * pFirstPosition,
DWORD NumVertices,
DWORD dwStride,
D3DXVECTOR3 * pCenter,
FLOAT *pRadius
);
说明一下:
·pFirstPosition 指向顶点数组(该数组的每个元素都描述了对应顶点)中第一
个顶点的位置向量的指针。
·NumVertices 该顶点数组中顶点的个数。
·dwStride 每个顶点有大小,单位为字节。
·pCenter 返回外接球的球心位置。
·pRadius 返回外接球的半径。
HRESULT D3DXCreateBox(
LPDIRECT3DDEVICE9 pDevice,
FLOAT Width,
FLOAT Height,
FLOAT Depth,
LPD3DXMESH *ppMesh,
LPD3DXBUFFER *ppAdjacency
);
最后两个参数 为外接体的最大点和最小点。
江西理工大学 FangSH 2010-5-5