directx射线法拾取3d物体数学原理.doc_第1页
directx射线法拾取3d物体数学原理.doc_第2页
directx射线法拾取3d物体数学原理.doc_第3页
directx射线法拾取3d物体数学原理.doc_第4页
directx射线法拾取3d物体数学原理.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

directx射线法拾取3d物体数学原理(1)-原创通过2D屏幕坐标在3D空间中拾取需要的场合Directx提供了固定流水线和可编程流水线,他们都是为了实现一个目标,就是把3d模型如何投射到2d屏幕坐标上,这个过程,相关文档都有了详细的介绍,今天我们来看一下他的逆向过程,比如,你如何按下鼠标选中一个离你最近的3D物体,如何让你的手枪打了一枪击中了远处的一个敌人的脑袋,cs中我们都玩过,那么如何判断的呢?我们就要从2D屏幕到3d屏幕的转化说开去。为什么使用射线法一般常规思考,我们从3d的渲染流水线逆向就应该获取到3d中的对应位置,可是我们的屏幕是2D的,仅有x,y 如何表示3d中的z呢?这是个问题,不过,不要怕,我们在流水线中也考虑了这个投影的问题,当3d的物体投射到屏幕上时,我们指定了两个参数,一个是Near,一个是,far,一般在设置投射矩阵时,使用如下函数:D3DXMATRIX * D3DXMatrixPerspectiveFovLH( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf);这个函数最终形成的矩阵是这样子的xScale 0 0 00 yScale 0 00 0 zf/(zf-zn) 10 0 -zn*zf/(zf-zn) 0其中:yScale = cot(fovY/2)xScale = yScale / Aspect通过这个函数把3d的已经渲染好的物体,投射在屏幕上。我们现在已知屏幕上 (x,y),就是说我们能通过x,y找到z为zn,zf两个值时,屏幕上x,y对应的3d空间中的点坐标。这就是形成一条空间射线的两个点的理论基础。接下来又有了新问题,我们如何将屏幕中的(x,y)转化为空间中的坐标呢?如何把屏幕的坐标转化为空间中的坐标屏幕的坐标系是这样的:左上角是0,0 右下角是w,h;而我们3d投影后形成2D坐标系是,中间(0,0),这里我们把投影后的2D坐标系标准化,转化成单位矩形(-1,-1)到(1,1),就是以中心往上下左右各给出1个单位量的大小。这样我们把屏幕坐标转化为这个单位坐标的公式如下假设屏幕高宽不一致,这样单位坐标系内,屏幕坐标的表示法如下:#define WIDTH 640.0f#define HEIGHT 480.0f#define WIDTH_DIV_2 (WIDTH*0.5f)#define HEIGHT_DIV_2 (HEIGHT*0.5f)#define ASPECT 1.3333fdx=(x/WIDTH_DIV_2-1.0f)/ASPECT;dy=1.0f-y/HEIGHT_DIV_2;建立射线的原理有了这个坐标表示,我们还得了解这个坐标系有什么意义,为什么要转化成这样?根据前边我们提到的,投影矩阵是以一个近平面和一个远平面构成的投影,屏幕上显示的就是近平面和远平面投射后的一个叠加,然后一个像素一个像素的标绘出来。这样从y轴往下看,就是一个三角形这样看,x=z*tan(FOV/2)加上我们刚才转化的坐标,我们可以得出,x=z*tan(FOV/2)* (x/WIDTH_DIV_2-1.0f)/ASPECT 同理y;这样我们通过屏幕坐标可以根据z的值得到近平面上的点和远平面上的点了,也就是就能形成一条射线。p1=D3DVECTOR(dx*NEAR,dy*NEAR,NEAR);p2=D3DVECTOR(dx*FAR,dy*FAR,FAR);示例代码#defineNEAR10.0f#define FAR4000.0f#defineFOV0.8f#defineWIDTH640.0f#defineHEIGHT480.0f#defineWIDTH_DIV_2(WIDTH*0.5f)#defineHEIGHT_DIV_2(HEIGHT*0.5f)#define ASPECT1.3333fvoid calcRay(int x,int y,D3DVECTOR &p1,D3DVECTOR &p2)float dx,dy;D3DMATRIX invMatrix,viewMatrix;dx=tanf(FOV*0.5f)*(x/WIDTH_DIV_2-1.0f)/ASPECT;dy=tanf(FOV*0.5f)*(1.0f-y/HEIGHT_DIV_2);/获取世界矩阵和观察矩阵的逆lpDevice-GetTransform(D3DTRANSFORMSTATE_VIEW,&viewMatrix);D3DMath_MatrixInvert(invMatrix,viewMatrix);/通过与逆矩阵的相乘我们得到空间中两个点的实际坐标p1=D3DVECTOR(dx*NEAR,dy*NEAR,NEAR);p2=D3DVECTOR(dx*FAR,dy*FAR,FAR);D3DMath_VectorMatrixMultiply(p1,p1,invMatrix);D3DMath_VectorMatrixMultiply(p2,p2,invMatrix);directx射线法拾取3d物体数学原理(2)-原创Directx对拾取模型的支持如果有了射线,dx中拾取模型就简单了,directx给出了一个函数,就是判断射线与模型(mesh)的交点,给出与射线相交,即射线穿过三角形面内部,的那个三角面的索引。具体函数如下(摘自directx帮助):HRESULT D3DXIntersect( LPD3DXBASEMESH pMesh, CONST D3DXVECTOR3 * pRayPos, CONST D3DXVECTOR3 * pRayDir, BOOL * pHit, DWORD * pFaceIndex, FLOAT * pU, FLOAT * pV, FLOAT * pDist, LPD3DXBUFFER * ppAllHits, DWORD * pCountOfHits);ParameterspMesh /指向模型的指针in Pointer to an ID3DXBaseMesh interface, representing the mesh to be tested. pRayPos /射线的起点in Pointer to a D3DXVECTOR3 structure, specifying the point where the ray begins. pRayDir /射线的方向,就是终点减去起点in Pointer to a D3DXVECTOR3 structure, specifying the direction of the ray. pHit /如果射线在三角形内部返回TRUEout Pointer to a BOOL. If the ray intersects a triangular face on the mesh, this value will be set to TRUE. Otherwise, this value is set to FALSE. pFaceIndex /相交平面的索引out Pointer to an index value of the face closest to the ray origin, if pHit is TRUE. pU /相交平面的U值out Pointer to a barycentric hit coordinate, U. pV /相交平面的V值out Pointer to a barycentric hit coordinate, V. pDist/交点与起点的距离out Pointer to a ray intersection parameter distance. ppAllHits /所有相交的平面信息out Pointer to an ID3DXBuffer object, containing an array of D3DXINTERSECTINFO structures. pCountOfHits /相交平面的个数(可能存在多个平面同时与射线相交)out Pointer to a DWORD that contains the number of entries in the ppAllHits array. 通过这个函数我们就能判断拾取物体了。directx射线法拾取3d物体数学原理(3)-原创自定义射线与三角形的相交函数原理如下:用射线和要检测的三角形求交点,用到的原理和公式如下。原理一:三角形内的任意一点都可以用变量u、v和其三个顶点坐标来确定,其中0u1 0v1、,0u+v1 ,vPoint = V1 + u*(V2-V1) + v*(V3-V1) ,其中V1、V2、V3为三角形的三个顶点,是已知量。原理二:射线上的任意一点可以用射线的方向向量(格式化后的)乘以其模(该向量长度)来表示,记为:vPoint =originPoint+dir * len如果和三角形相交则必定同时满足上面的两个条件所以有: (-Dir)*len+ (V2-V1)*u + (V3-V1)*v originPoint V1 相当方程组: (len ,v ,u 为变量,其它为常量)(-Dir.x)*len +(V2.x-V1.x)*u + (V3.x V1.x )*v = originPoint.x V1.x(-Dir.y)*len +(V2.y-V1.y)*u + (V3.y V1.y )*v = originPoint.y V1.y(-Dir.z)*len +(V2.z-V1.z)*u + (V3.z V1.z )*v = originPoint.z V1.z或: len【Dir,V2V1,V3V1】 u = originPoint V1 v这是一个线性方程组,根据克拉姆法则,【Dir,V2V1,V3V1】不为零。所以满足条件:0v1,0u0, ,0u+v 0 )/ tvec = orig - v0; / 从正面穿越三角形,三角形和视点相对的面为正面 else tvec = v0 - orig;/ 反面穿越三角形穿越三角形 det = -det; if( det 0.0001f )/ 接近零视为0 return FALSE; / 求u的值,求线性方程组的解展开后等同于求点积展开 *u = VEC3Dot( &tvec, &pvec ); if( *u det ) return FALSE;/ 求v的值VECTOR3 qvec; VEC3Cross( &qvec, &tvec, &edge1 ); *v = VEC3Dot( &dir, &qvec ); if( *v det ) return FALSE; / 计算t,并把t,u,v放缩为合法值*t = D3DXVec3Dot( &edge2, &qvec );/ 前面的t,v,u在计算时多乘了一个系数det FLOAT fInvDet = 1.0f / det; *t *= fInvDet; *u *= fInvDet;*v *= fInvDet;这个计算还是有些难度的,要写成程序来计算,而且用到矩阵方法来解线性方程组,克莱姆法则比较容易实现,我们给出一个微软例子中写好的函数,省的来从头写了。directx射线法拾取3d物体数学原理(4)-原创/-/ 给定射线的起点和方向,以及三角形的三个顶点,返回u,v,t值和最终判断的结果,如果在内部返回TRUE,否则false/-bool IntersectTriangle( const D3DXVECTOR3& orig, const D3DXVECTOR3& dir, D3DXVECTOR3& v0, D3DXVECTOR3& v1, D3DXVECTOR3& v2, FLOAT* t, FLOAT* u, FLOAT* v ) / Find vectors for two edges sharing vert0 D3DXVECTOR3 edge1 = v1 - v0; D3DXVECTOR3 edge2 = v2 - v0; / Begin calculating determinant - also used to calculate U parameter D3DXVECTOR3 pvec; D3DXVec3Cross( &pvec, &dir, &edge2 ); / If determinant is near zero, ray lies in plane of triangle FLOAT det = D3DXVec3Dot( &edge1, &pvec ); D3DXVECTOR3 tvec; if( det 0 ) tvec = orig - v0; else tvec = v0 - orig; det = -det; if( det 0.0001f ) return FALSE; / Calculate U parameter and test bounds *u = D3DXVec3Dot( &tvec, &pvec ); if( *u det ) return FALSE; / Prepare to test V parameter D3DXVECTOR3 qvec; D3DXVec3Cross( &qvec, &t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论