+ -
当前位置:首页 → 问答吧 → 求助,D3Dpick的问题。

求助,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;

我感觉好像是自己对这个拾取射线理解错了,求搞过的高人解答下。

作者: jiergio   发布时间: 2011-10-18

你最后的变换怎么手工进行?很不清晰。

不过代码似乎是对的,由于不够清晰而且不知道你程序内部的其他的地方是否正确。

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

热门下载

更多