游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3371|回复: 8

鼠标拾取的问题

[复制链接]

36

主题

109

帖子

111

积分

注册会员

Rank: 2

积分
111
发表于 2007-10-19 23:12:00 | 显示全部楼层 |阅读模式
//计算拾取射线相关变量声明
POINT        ptCursor;  //鼠标位置
D3DXMATRIX   matWorld, matView, pmatProj, modeview;//模型矩阵,视图矩阵,投影矩阵,模型视图矩阵
        D3DXVECTOR3  vPickRayOrig, vPickRayDir;//拾取线原点和方向
        int          iWidth, iHeight;//视图区宽度和高度

        //获取后台缓冲区的宽度和高度
        iWidth = DXUTGetBackBufferSurfaceDesc()->Width;
        iHeight = DXUTGetBackBufferSurfaceDesc()->Height;

        //获取当前鼠标在窗口客户区中的位置
        GetCursorPos( &ptCursor );
        ScreenToClient( DXUTGetHWND(), &ptCursor );
       
        //获取当前设备的变换矩阵
        pd3dDevice->GetTransform( D3DTS_WORLD, &matWorld );
        pd3dDevice->GetTransform( D3DTS_VIEW, &matView );
        pd3dDevice->GetTransform( D3DTS_PROJECTION, &pmatProj );

        //计算世界观察矩阵的逆矩阵
        D3DXMATRIX mWorldView = matWorld * matView;);//这里不明白为什么还乘以世界变换矩阵

        D3DXMATRIX mWorldView =  matView;
        D3DXMatrixInverse( &modeview, NULL, &mWorldView)       
        //计算拾取射线在视图空间的方向
        D3DXVECTOR3 vTemp;
        vTemp.x =  ((( 2.0f * ptCursor.x ) / iWidth  ) - 1 ) / pmatProj._11;
        vTemp.y = -((( 2.0f * ptCursor.y ) / iHeight ) - 1 ) / pmatProj._22;
        vTemp.z =  1.0f;
           //计算拾取射线在世界空间中的方向
        vPickRayDir.x  = vTemp.x*m._11 + vTemp.y*m._21 + vTemp.z*m._31;
        vPickRayDir.y  = vTemp.x*m._12 + vTemp.y*m._22 + vTemp.z*m._32;
        vPickRayDir.z  = vTemp.x*m._13 + vTemp.y*m._23 + vTemp.z*m._33;
          //计算观察点在世界坐标系中的位置
        vPickRayOrig.x = m._41;
        vPickRayOrig.y = m._42;
        vPickRayOrig.z = m._43;

        //计算被拾取到的三角形, 得到拾取到三角形的索引
        BOOL               bHit;
        LPD3DXBUFFER       pBuffer = NULL;
        D3DXINTERSECTINFO* pIntersectInfoArray;
       
        V_RETURN( D3DXIntersect( pMesh, &vPickRayOrig, &vPickRayDir, &bHit,
                                     NULL, NULL, NULL, NULL,
                                    &pBuffer, &g_dwNumIntersections ));


上面是D3D中的例子,这里我不明白的是,当我们得到视图矩阵中的方向vTemp后,其实直接乘以视图矩阵的逆矩阵matView就是在世界坐标系中的方向了,但是上面为什么是乘以模型视图矩阵modeview的逆矩阵哪,这里死也想不通了, 请大家说说 [em7]

7

主题

438

帖子

438

积分

中级会员

Rank: 3Rank: 3

积分
438
发表于 2007-10-20 14:14:00 | 显示全部楼层

Re:鼠标拾取的问题

因为计算模型中的三角形和射线交点时,三角形是模型空间的座标。

实际上你有两种选择,一是把三角形转换到世界空间,二是把射线转换到模型空间。显然二开销小。

36

主题

109

帖子

111

积分

注册会员

Rank: 2

积分
111
 楼主| 发表于 2007-10-20 15:48:00 | 显示全部楼层

Re:鼠标拾取的问题

哦,MESH是模型空间的, 难怪,谢谢

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2007-10-20 19:29:00 | 显示全部楼层

Re:鼠标拾取的问题

应该先把射线从视图空间转换到世界空间
即:乘view的逆矩阵

然后变换到被拾取模型的local空间
即:乘被拾取对象的世界变换的逆矩阵

这样才能正确计算拾取

36

主题

109

帖子

111

积分

注册会员

Rank: 2

积分
111
 楼主| 发表于 2007-10-20 22:11:00 | 显示全部楼层

Re:鼠标拾取的问题

比如说我画了3个物体,分别为A,B,C。每个物体我都用不同的世界变换矩阵把他们变换到了世界空间,当我要检测和其中的一个物体是否相交的时候,比如我要检测是否选种了A,楼上是不是说我只能乘以A的逆矩阵转换到local空间才正确,如果我得到世界空间的射线后,乘以B的逆矩阵,然后检测和A是否相交其实是错误的,是吗?
也就是说我上面D3DXMATRIX mWorldView = matWorld * matView这种直接计算逆矩阵的方法是不严谨的对吗,因为他计算出的其实是最后画的一个物体的local空间,而不是我要检测的那个物体的local空间,不知道我理解的对不对?

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2007-10-20 22:32:00 | 显示全部楼层

Re:鼠标拾取的问题

没错!
射线变换到世界空间以后
你需要检测哪个对象的拾取
就必须去乘那个对象的世界变换的逆矩阵,原理其实很清晰了啊。
只是多了一个逆矩阵的变换而已。微软的pick的例子就是少了后面这个变换

36

主题

109

帖子

111

积分

注册会员

Rank: 2

积分
111
 楼主| 发表于 2007-10-20 22:50:00 | 显示全部楼层

Re:鼠标拾取的问题

难怪微软的例子中正确,是因为他只画了一个物体,所以直接乘以modelview的逆矩阵就恰好是那个物体的local空间了,非常感谢楼上

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2007-10-20 23:06:00 | 显示全部楼层

Re:鼠标拾取的问题

微软的例子的对象正好摆在坐标原点,即被拾取对象的local坐标空间正好是world世界坐标空间,所以没有做后面那个变换

我也曾经被这个问题困扰过一段时间,也不用那么客气,呵呵。。

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2007-11-19 17:58:00 | 显示全部楼层

Re:鼠标拾取的问题

vTemp.x =  ((( 2.0f * ptCursor.x ) / iWidth  ) - 1 ) / pmatProj._11;
vTemp.y = -((( 2.0f * ptCursor.y ) / iHeight ) - 1 ) / pmatProj._22;
vTemp.z =  1.0f;
这一段是什么意思? 为什么用2.0乘? 这是什么公式吗?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-17 23:12

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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