所谓拾取,是根据你在屏幕上的一个点与你空间中的mesh是否相交。
而你的空间是三维的,屏幕上的点是二维的。这就需要一个逆投影的过程,也就涉及到了视口变换矩阵

三维空间中的点p(Px, Py, Pz)通过p视口变换后为s(Sx, Sy)
其中 Sx = Px * Width / 2 + X + Width / 2
Sy = -Py * Height / 2 + Y + Height / 2;
而z的话不作为二维图像的一部分。
反过来也就可以得到
Px = (2 * Sx - 2 * X - Width) / Width
Py = (-2 * Sy + 2 * Y + Height) / Height;
而一般情况下X,Y的值为0;
Px = 2 * Sx / Width -1
Py = -2 * Sy / Height + 1
Pz = 1;
这是因为投影窗口与z = 1重合;
依国际贯例上代码:
Ray CalClickRay(int x, int y)
{
float rx = 0.0f;
float ry = 0.0f;
D3DVIEWPORT9 view;
m_device->GetViewport(&view);
D3DXMATRIX proj;
m_device->GetTransform(D3DTS_PROJECTION, &proj);
rx = ((2.0f * x) / view.Width - 1.0f) * (1.0f / proj(0,0));
ry = ((-2.0f * y) / view.Height + 1.0f) * (1.0f / proj(1, 1));
Ray r;
r.origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
r.direction = D3DXVECTOR3(rx, ry, 1.0f);
return r;
}其中Ray的定义为
struct Ray
{
D3DXVECTOR3 origin;
D3DXVECTOR3 direction;
};经上叙步骤后得到的摄线是在观察坐标系中的,仍需要进一步转换
void TranformRay(Ray* ray, D3DXMATRIX* T)
{
D3DXVec3TransformCoord(&ray->origin, &ray->origin, T);
D3DXVec3TransformNormal(&ray->direction, &ray->direction, T);
D3DXVec3Normalize(&ray->direction, &ray->direction);
}其中矩阵T为观察矩阵的逆矩阵。
4645

被折叠的 条评论
为什么被折叠?



