|
定义如下结构:
struct ray
{
D3DXVECTOR3 origin;//射线起点
D3DXVECTOR3 derction;//射线方向
};
//---------------------------------------------------------------------------------
// 根据当前鼠标的位置(x,y)计算在视坐标中的拾取光线
//---------------------------------------------------------------------------------
Ray CalcPickingRay(LPDIRECT3DDEVICE9 s_pDevice,int x, int y)
{
float px = 0.0f;
float py = 0.0f;
D3DVIEWPORT9 vp;
s_pDevice->GetViewport(&vp);//得到视口大小
D3DXMATRIX proj;
s_pDevice->GetTransform(D3DTS_PROJECTION, &proj);//转换
//计算拾取射线
px = ((( 2.0f*x) / vp.Width) - 1.0f) / proj(0, 0);
py = (((-2.0f*y) / vp.Height) + 1.0f) / proj(1, 1);
Ray ray;
ray.origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);//3维空间中的向量
ray.direction = D3DXVECTOR3(px, py, 1.0f);
return ray;
}
//---------------------------------------------------------------------------------
// 对拾取光线进行从视坐标到世界坐标的转换
//---------------------------------------------------------------------------------
void TransformRay(Ray* ray, D3DXMATRIX* T)
{
// 对原点进行变换
D3DXVec3TransformCoord(&ray->origin, &ray->origin, T);
// 对方向向量进行变换
D3DXVec3TransformNormal(&ray->direction, &ray->direction, T);
//返回3D向量的规格化向量
D3DXVec3Normalize(&ray->direction, &ray->direction);
}
//---------------------------------------------------------------------------------
// 判断鼠标当前位置pt对应的拾取光线是否与某个物体的包围球*pSphere相交
//---------------------------------------------------------------------------------
void PickSphere(LPDIRECT3DDEVICE9 s_pDevice,const POINT pt)
{
Ray ray = CalcPickingRay(s_pDevice , pt.x, pt.y);// 根据当前鼠标的位置(x,y)计算在视坐标中的拾取光线
D3DXMATRIX view;
s_pDevice->GetTransform(D3DTS_VIEW, &view);//转换
D3DXMATRIX viewInverse;
D3DXMatrixInverse(&viewInverse, NULL, &view);//D3DXMatrixInverse通常用来求视图矩阵的逆阵
TransformRay(&ray, &viewInverse);// 对拾取光线进行从视坐标到世界坐标的转换
CUnit::_origin=ray.origin;//把结果传给静态变量目的是所有类对象共存结果因为射线每频只需计算一次
CUnit::_direction=ray.direction;//把结果传给静态变量...........................................
}
//---------------------------------------------------------------------------------
// 判断拾取光线*pRay是否与某个物体的包围球*pSphere相交
//---------------------------------------------------------------------------------
bool RaySphereIntTest()
{
D3DXVECTOR3 v = CUnit::_origin - m_vPos;//3维空间中的向量
float b = 2.0f * D3DXVec3Dot(&CUnit::_direction, &v);
float c = D3DXVec3Dot(&v, &v) - (500*500);//
// 计算判别式的值
float discriminant = (b * b) - (4.0f * c);
if( discriminant < 0.0f )
{
return false;
}
discriminant = sqrtf(discriminant);
float s0 = (-b + discriminant) / 2.0f;
float s1 = (-b - discriminant) / 2.0f;
// 如果某个根 >= 0, 说明光线与包围球相交
if( s0 >= 0.0f || s1 >= 0.0f )
{
return true;
}
else
{
return false;
}
}
执行结果我点模型没有反应,但是当我点到屏幕的某个位置模型就有反应了。
[em17] |
|