|
|
发表于 2003-11-1 11:39:00
|
显示全部楼层
Re: 有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下
上面我回复的有错误更正一下。
Projection 变换是
w = (2*Znear)/Vw ;
h = (2*Znear)/Vk;
z = Zfar/(Zfar-Znear);
变换程序可以用下面的,用到了 View 变换的逆矩阵了阿。具体看程序
D3DXVECTOR3 CMainScene::ScreenPtToWorldPt(int pX,int pY)
{
D3DXVECTOR3 retVal(0,0,0);
//TRACE("(pX,pY) = (%d,%d) \n",pX,pY);
D3DXVECTOR3 vPickRayDir; // 射线方向(向量)
D3DXVECTOR3 vPickRayOrig; // 射线原点(坐标)
// 获得 Proj 变换矩阵。
D3DXMATRIXA16 matProj = m_camera.GetProjMatrix();
// 获得视区宽度,高度
FLOAT sx = (FLOAT)m_viewPort.Width;
FLOAT sy = (FLOAT)m_viewPort.Height;
//TRACE("(sx,sy) = (%f,%f) \n",sx,sy);
// Compute the vector of the pick ray in screen space
// 计算出 Proj 前的点坐标。
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * pX ) / sx ) - 1 ) / matProj._11;
v.y = -( ( ( 2.0f * pY ) / sy ) - 1 ) / matProj._22;
v.z = 100.0f / (100.0f - 1.0f);
//TRACE("v.(x,y,z) = (%f,%f,%f) \n",v.x,v.y,v.z);
// Get the inverse view matrix
// 得到 View 变换逆矩阵
D3DXMATRIXA16 m = m_camera.GetInvViewMatrix();
// Transform the screen space pick ray into 3D space
// 求逆
vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;
//TRACE("vPickRayDir.(x,y,z) = (%f,%f,%f) \n",vPickRayDir.x,vPickRayDir.y,vPickRayDir.z);
// 射线原点(eye)位置
vPickRayOrig.x = m._41;
vPickRayOrig.y = m._42;
vPickRayOrig.z = m._43;
//TRACE("vPickRayOrig.(x,y,z) = (%f,%f,%f) \n",vPickRayOrig.x,vPickRayOrig.y,vPickRayOrig.z);
// 我用的是 y=0 平面 ,所以下面是直线和平面求交点,比较简单
retVal.x = vPickRayOrig.x - ( vPickRayDir.x * vPickRayOrig.y / vPickRayDir.y);
retVal.y = 0.0f;
retVal.z = vPickRayOrig.z - ( vPickRayDir.z * vPickRayOrig.y / vPickRayDir.y);
//TRACE("retVal.(x,y,z) = (%f,%f,%f) \n",retVal.x,retVal.y,retVal.z);
// Get the inverse view matrix
return retVal;
}
具体原理是 先求出 射线 的原点(Eye),再求出射线的方向。
最后得出直线方程 (点法式); |
|