作者:StrongCoding
邮箱:StrongCoding@qq.comDX群:130302441
若文中有误,请告知.十分感谢.一起加油.
这一篇将介绍网格模型的界线容积,实现用于实现碰撞检测的两个东西:包围盒和包围球.
下面是实现代码,不多说了:
ID3DXMesh* BoxMesh = 0;
struct BoundingBox{
BoundingBox();
bool isPointInside(D3DXVECTOR3& p); // 这是检测一个点是不是在这个包围盒里边实现碰撞检测
D3DXVECTOR3 _min; // 组成包围盒的最小值
D3DXVECTOR3 _max; // 组成包围盒的最大值
};
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;
}
// 下面是依据传入的MESH模型计算一个包围盒
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;
}
// 正式根据以上的配置生成一个包围盒
D3DXCreateBox(
Device,
boundingBox._max.x - boundingBox._min.x,
boundingBox._max.y - boundingBox._min.y,
boundingBox._max.z - boundingBox._min.z,
&BoxMesh,
0
);
// 最后渲染
// 先渲染正常的模型赋予材质和纹理
// 然后渲染我们的包围盒
// draw the mesh
for(int i = 0; i < Mtrls.size(); i++)
{
Device->SetMaterial( &Mtrls[i] );
Device->SetTexture(0, Textures[i]);
Mesh->DrawSubset(i);
}
Device->SetMaterial(&blue);
Device->SetTexture(0, 0); // disable texture
BoxMesh->DrawSubset(0);
======================================================================
至于如何计算包围球,与上面类似的过程,在这仅仅列举一下关键的代码:
struct BoundingSphere
{
BoundingSphere();
D3DXVECTOR3 _center;
float _radius;
};
d3d::BoundingSphere::BoundingSphere()
{
_radius = 0.0f;
}
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;
}
D3DXCreateSphere(
Device,
boundingSphere._radius,
20,
20,
&SphereMesh,
0
);
// draw the mesh
for(int i = 0; i < Mtrls.size(); i++)
{
Device->SetMaterial( &Mtrls[i] );
Device->SetTexture(0, Textures[i]);
Mesh->DrawSubset(i);
}
Device->SetMaterial(&blue);
Device->SetTexture(0, 0); // disable texture
SphereMesh->DrawSubset(0);
-----------------------------------------------------------------------------------------------------------------------
最后说一下,如何判断一个点是不是在包围盒中:
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;
}
}
网格模型基础中级篇到此为止,过段日子,一起学习骨骼动画.