游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5660|回复: 11

有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

[复制链接]

20

主题

70

帖子

78

积分

注册会员

Rank: 2

积分
78
发表于 2003-10-31 15:06:00 | 显示全部楼层 |阅读模式
问题1:在Pick()函数里的,有如下代码
POINT ptCursor;
GetCursorPos( &ptCursor );
ScreenToClient( m_hWnd, &ptCursor );
D3DXVECTOR3 v;//
v.x =  ( ( 2.0f *(ptCursor.x )/ m_d3dsdBackBuffer.Width ) - 1 ) / matProj._11;//为什么这里要用2.0乘于ptCursor?然后又要除以m_d3dsdBackBuffer.Width ???想不明白它的原理
        v.y = -( ( 2.0f *(ptCursor.y )/ m_d3dsdBackBuffer.Height) - 1 ) / matProj._22;

问题2:如下代码
// Get the inverse view matrix
D3DXMATRIXA16 matView, m;
m_pd3dDevice->GetTransform( D3DTS_VIEW, &matView);//
D3DXMatrixInverse( &m, NULL, &matView );//为什么要用view矩阵的逆矩阵来运算?这个在很多的D3D例子中都有用到,没有想明白
// 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;
那位高手帮忙讲解一下,谢谢

0

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2003-10-31 17:23:00 | 显示全部楼层

Re: 有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

老兄看看 View 变换 和 Proj 变换
就知道了

应该是  x= arctan a * x0 好像是阿 可以简化为 你看到的公式、、

注意其中的 1 是 z = (fov1 -fov2)/fov1
fov1 是 fov far ,fov2 是 fov near ,一般约等于 1 ,

等我把转换程序给你吧,刚刚写了一个,呵呵,其实 DirectX 文档上都有阿.

20

主题

70

帖子

78

积分

注册会员

Rank: 2

积分
78
 楼主| 发表于 2003-10-31 17:56:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

to  trunsun2003:
对第二个问题:
我不明白为什么要用view矩阵的逆矩阵来运算而不是直接用view矩阵来运算

0

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 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),再求出射线的方向。
最后得出直线方程 (点法式);

20

主题

70

帖子

78

积分

注册会员

Rank: 2

积分
78
 楼主| 发表于 2003-11-3 10:37:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

up

20

主题

70

帖子

78

积分

注册会员

Rank: 2

积分
78
 楼主| 发表于 2003-11-3 10:41:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

to  trunsun2003:
为什么要用view矩阵的逆矩阵来运算而不是直接用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;
在上面代码中直接用view矩阵来运算为什么不行?

20

主题

70

帖子

78

积分

注册会员

Rank: 2

积分
78
 楼主| 发表于 2003-11-3 15:02:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

仔细用线性代数推导一下,终于明白过来了

0

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2005-2-21 19:31:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

vPickRayDir的坐标应该是(x,y,z,1)吧?
所以求逆这步为什么不是下面这样:
vPickRayDir.x  = v.x*m._11 + v.y*m._21 + v.z*m._31+1.0*m._41;
vPickRayDir.y  = v.x*m._12 + v.y*m._22 + v.z*m._32+1.0*m._42;
vPickRayDir.z  = v.x*m._13 + v.y*m._23 + v.z*m._33+1.0*m._43;
_________________________________________________________________
vPickRayOrig的坐标是(0,0,0,1),
才会得到vPickRayOrig的世界坐标是:
vPickRayOrig.x = 0*m._11 + 0*m._21 + 0*m._31+1.0*m._41=m._41
vPickRayOrig.y = 0*m._12 + 0*m._22 + 0*m._32+1.0*m._42=m._42
vPickRayOrig.z =0*m._13 + 0*m._23 + 0*m._33+1.0*m._43=m._43
这个问题我百思不得其解,等待哪位高人能帮我解答一下.

0

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2005-2-23 00:05:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

up一下

0

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2005-2-23 21:59:00 | 显示全部楼层

Re:有谁看过D3D的Pick例子?不怎么懂啊,那位大哥指点一下

up
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 14:45

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表