求助,D3Dpick的问题。
时间:2011-10-18
来源:互联网
我照着D3D 的pick例子复制到自己的程序里但是生成的拾取射线总是指向世界的原点附近。 但是我鼠标点的并不是原点附近。
请问这是哪一步错了?
这是我复制的代码
POINT ptCursor;
GetCursorPos( &ptCursor );
ScreenToClient( DXUTGetHWND(), &ptCursor );
// Compute the vector of the Pick ray in screen space
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * ptCursor.x ) / pd3dsdBackBuffer->Width ) - 1 ) / pmatProj->_11;
v.y = -( ( ( 2.0f * ptCursor.y ) / pd3dsdBackBuffer->Height ) - 1 ) / pmatProj->_22;
v.z = 1.0f;
// Get the inverse view matrix
const D3DXMATRIX matView = *g_Camera.GetViewMatrix();
const D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix();
D3DXMATRIX mWorldView = matWorld * matView;
D3DXMATRIX m;
D3DXMatrixInverse( &m, NULL, &mWorldView );
// 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;
vPickRayOrig.x = m._41;
vPickRayOrig.y = m._42;
vPickRayOrig.z = m._43;
我感觉好像是自己对这个拾取射线理解错了,求搞过的高人解答下。
请问这是哪一步错了?
这是我复制的代码
POINT ptCursor;
GetCursorPos( &ptCursor );
ScreenToClient( DXUTGetHWND(), &ptCursor );
// Compute the vector of the Pick ray in screen space
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * ptCursor.x ) / pd3dsdBackBuffer->Width ) - 1 ) / pmatProj->_11;
v.y = -( ( ( 2.0f * ptCursor.y ) / pd3dsdBackBuffer->Height ) - 1 ) / pmatProj->_22;
v.z = 1.0f;
// Get the inverse view matrix
const D3DXMATRIX matView = *g_Camera.GetViewMatrix();
const D3DXMATRIX matWorld = *g_Camera.GetWorldMatrix();
D3DXMATRIX mWorldView = matWorld * matView;
D3DXMATRIX m;
D3DXMatrixInverse( &m, NULL, &mWorldView );
// 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;
vPickRayOrig.x = m._41;
vPickRayOrig.y = m._42;
vPickRayOrig.z = m._43;
我感觉好像是自己对这个拾取射线理解错了,求搞过的高人解答下。
作者: jiergio 发布时间: 2011-10-18
你最后的变换怎么手工进行?很不清晰。
不过代码似乎是对的,由于不够清晰而且不知道你程序内部的其他的地方是否正确。
m._41,_m._42,m._43其实就是相机的世界坐标。
给你个比较清晰的代码:
C/C++ code
其中的d3d::Ray是一个自定义的射线结构体。CalcPickingRay获得世界坐标中的射线,TransformRay将射线转换到世界坐标。
不过代码似乎是对的,由于不够清晰而且不知道你程序内部的其他的地方是否正确。
m._41,_m._42,m._43其实就是相机的世界坐标。
给你个比较清晰的代码:
C/C++ code
d3d::Ray CalcPickingRay(int x, int y) { float px = 0.0f; float py = 0.0f; D3DVIEWPORT9 vp; Device->GetViewport(&vp); D3DXMATRIX proj; Device->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); d3d::Ray ray; ray._origin = D3DXVECTOR3(0.0f, 0.0f, 0.0f); ray._direction = D3DXVECTOR3(px, py, 1.0f); return ray; } void TransformRay(d3d::Ray* ray, D3DXMATRIX* T) { // transform the ray's origin, w = 1. D3DXVec3TransformCoord( &ray->_origin, &ray->_origin, T); // transform the ray's direction, w = 0. D3DXVec3TransformNormal( &ray->_direction, &ray->_direction, T); // normalize the direction D3DXVec3Normalize(&ray->_direction, &ray->_direction); }
其中的d3d::Ray是一个自定义的射线结构体。CalcPickingRay获得世界坐标中的射线,TransformRay将射线转换到世界坐标。
作者: xujiezhige 发布时间: 2011-10-21
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28