鼠标选取Pick

在3D的世界中,如何选择一个物体并触发相应事件,需要用到选取;

学习选取之前,需要先弄清楚几个概念:客户区坐标系,投影坐标系,视图坐标系,世界坐标系。


我们知道,将3D场景转换为2D图像并显示在显示器上,这一系列操作叫做渲染管线,下图是过程:


物体-->世界-->视图->(拣选、灯光、裁剪)-->投影-->视口变换-->(光栅化)


选取的过程正好相反,可表示为:鼠标所在坐标->视口变换-->投影-->视图-->世界-->是否点到了物体


第一步:

将客户坐标转换为投影坐标系步骤:

1.获取客户区(视口)坐标point(a, b),将该坐标转换视口坐标(未缩放),转换公式如下:

X = (2*a) / 宽 - 1;

Y = (-2*b) / 高 + 1; 


此时得到了投影坐标;


2.获取投影矩阵proj,将X,Y进行缩放

X = X / proj(0,0);

Y = Y / proj(1,1);

到这里为止我们终于求出了射线与近剪切面交点在观察坐标系中的坐标


我们知道射线的起点总是视图空间的原点(0,0,0),因此得到射线Ray.origin   = vector(0,0,0), Ray.direction   = vector(X,Y,1);


第二步:

将射线放转换到世界空间

因为DIRview = DIRworld*视图矩阵,所以DIRworld = DIRview / 视图矩阵DIRview * 视图矩阵的逆矩阵


1.使用GetTransform(D3DTS_VIEW, &ViewMatrix)获取视图矩阵,使用D3DXMatrixInverse(&viewInverse,0, &ViewMatrix);获取视图矩阵的逆矩阵

2.当我们向世界空间转换时,能够用D3DXVec3TransformCoord转换一个点,用D3DXVec3TransformNormal转换一个向量

D3DXVec3TransformCoord(&Ray.origin, &Ray.origin, &viewInverse);

D3DXVec3TransformNormal(&Ray.direction, &Ray.direction, &viewInverse);

然后D3DXVec3Normalize(&Ray.direction,&Ray.direction);


此时的射线Ray已经处于了世界空间中


第三步:

判断射线Ray与物体是否有交点。

注意:射线可能相交多个对象,然而离照相机近的对象会被选取。因为近距离对象遮挡了后面的对象


第一种方法:使用D3DXIntersect,判断射线与mesh是否相交


第二种方法:改日再写


经过以上三步,我们就能判断出哪个物体被选中,如果被选中,则触发相应事件








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值