首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VC >

请高手帮小弟我指点一下这个关于网格和鼠标碰撞检测的有关问题

2012-03-12 
请高手帮我指点一下这个关于网格和鼠标碰撞检测的问题我是新手,想请大家帮忙。最近看了一段代码这部分实在

请高手帮我指点一下这个关于网格和鼠标碰撞检测的问题
我是新手,想请大家帮忙。最近看了一段代码这部分实在是看不懂了,这里是地图和鼠标的碰撞检测,   来请教大虾帮忙,代码如下,:

头文件中的内容
#ifndef   AFX_CMATH_H
#define   AFX_CMATH_H
#define   INTERSECT_NEGATIVEY0x10
#define   INTERSECT_HORIZENTAL0x30  


//Summary:
//Description:计算一个三角形和一个射线的交点
//Parameters:
//orig:射线起始点
//dir:射线的方向
//v0:三角形的第一个顶点
//v1:三角形的第二个顶点
//v2:三角形的第三个顶点
//t:交点到射线起始点的距离
//u:交点在v1-v0上的投影的位置,
//v:交点在v1-v0上的投影的位置,   交点为vRet=v0+u*(v1-v0)+v*(v2-v0)
//Returns:是否有交点

BOOL   IntersectTriangle(   const   D3DXVECTOR3&   orig,
                                                                              const   D3DXVECTOR3&   dir,   const   D3DXVECTOR3&   v0,
                                                                              const   D3DXVECTOR3&   v1,   const   D3DXVECTOR3&   v2,
                                                                              FLOAT*   t,   FLOAT*   u,   FLOAT*   v   );
//Summary:求射线和网格的交点
//Description:求射线和用顶点缓冲区和索引缓冲区定义的网格的交点
//Parameters:
//pIB:索引缓冲区
//pVB:顶点缓冲区
//nStide:每个顶点的大小
//dwNumFaces:面数
//vRayOrig:射线起始点
//vRayDir:射线的方向
//pVRet:交点
//Returns:是否有交点

BOOL   IntersectIndexBuffer(LPDIRECT3DINDEXBUFFER9   pIB,
      LPDIRECT3DVERTEXBUFFER9   pVB,
      UINT   nStride,UINT   dwNumFaces,
      const   D3DVECTOR   *vRayOrig,const   D3DVECTOR   *vRayDir,
      D3DVECTOR   *pVRet,DWORD   dwFlag=0);

#endif


CPP中的内容:


#include     <d3d9.h>
#include     <d3dx9.h>
#include   "CMath.h "


//Summary:求射线和网格的交点
//Description:求射线和用顶点缓冲区和索引缓冲区定义的网格的交点
//Parameters:
//pIB:索引缓冲区
//pVB:顶点缓冲区
//nStide:每个顶点的大小
//dwNumFaces:面数
//vRayOrig:射线起始点
//vRayDir:射线的方向
//pVRet:交点
//               dwFlag暂时不用
//Returns:是否有交点
BOOL   IntersectIndexBuffer(LPDIRECT3DINDEXBUFFER9   pIB,//实现碰撞检测   的全局函数(顶点缓冲)
      LPDIRECT3DVERTEXBUFFER9   pVB,
      UINT   nStride,UINT   dwNumFaces,
      const   D3DVECTOR   *vRayOrig,const   D3DVECTOR   *vRayDir,D3DVECTOR   *pVRet,DWORD   dwFlag)
{
                WORD*pIndices;
                BYTE*pVertices;
D3DINDEXBUFFER_DESC   IB_Desc;

FLOAT   fBary1,   fBary2,fDist=1e+32f;

FLOAT   t_fBary1,   t_fBary2,t_fDist;
DWORD   dwFace=-1;
DWORD     dwUpperLower;



D3DXVECTOR3*   pV[3];
ULONG     n;

pIB-> GetDesc(&IB_Desc);  
                pIB-> Lock(   0,   0,   (void**)&pIndices,   0   );//这里为什么前俩个参数都是0呢?
                pVB-> Lock(   0,   0,   (void**)&pVertices,0   );


for(   DWORD   i=0;   i <dwNumFaces;   i++   )
{
for(int   j=0;j <3;j++)
{
if(IB_Desc.Format==D3DFMT_INDEX16)n=(WORD)pIndices[3*i+j];//此处和下面的n的区别,具体就是16位和32位算法的区别
else   if(IB_Desc.Format==D3DFMT_INDEX32)
                    n=*(DWORD*)&pIndices[2*(3*i+j)];
else   return   FALSE;
pV[j]=(D3DXVECTOR3*)(pVertices+nStride*n);  
}

dwUpperLower=0;
if(dwFlag)
{
if(dwFlag   &   INTERSECT_NEGATIVEY)//此处请高手帮我讲解
{
for(j=0;j <3;j++)
{
dwUpperLower|=   vRayOrig-> x   >   pV[j]-> x   ?   0x0010:0x0001;  
dwUpperLower|=   vRayOrig-> z   >   pV[j]-> z   ?   0x1000:0x0100;  

}
if(dwUpperLower!=0x1111)   continue;


}
else   if(dwFlag   &   INTERSECT_HORIZENTAL)
{
for(j=0;j <3;j++)
{
dwUpperLower|=(vRayOrig-> y   >   pV[j]-> y)?   0x0010:0x0001;
}

if(dwUpperLower!=0x0011)   continue;
}


}

//   检测是否穿过三角形
if(   IntersectTriangle(   *vRayOrig,   *vRayDir,   *pV[0],   *pV[1],   *pV[2],
&t_fDist,   &t_fBary1,   &t_fBary2   )   )
{
if(t_fDist   <   fDist   )//是否返回最近的一个点
{
dwFace   =   i;
fBary1   =   t_fBary1;
fBary2   =   t_fBary2;
fDist     =   t_fDist;
}
}
}

if(dwFace <dwNumFaces   &&   dwFace> =0   )
{

for(int   j=0;j <3;j++)
{
if(IB_Desc.Format==D3DFMT_INDEX16)n=(WORD)pIndices[3*dwFace   +j];
                      else   if(IB_Desc.Format==D3DFMT_INDEX32)
                n=*(DWORD*)&pIndices[2*(3*dwFace+j)];
else   return   FALSE;
pV[j]=(D3DXVECTOR3*)(pVertices+nStride*n);
}
*pVRet=*pV[0]   +fBary1*(*pV[1]-*pV[0])+fBary2*(*pV[2]-*pV[0]);    


pVB-> Unlock();
pIB-> Unlock();
return   1;
}


                pVB-> Unlock();
                pIB-> Unlock();
       


        return   0;
}


//Summary:
//Description:计算一个三角形和一个射线的交点
//Parameters:
//orig:射线起始点
//dir:射线的方向
//v0:三角形的第一个顶点
//v1:三角形的第二个顶点
//v2:三角形的第三个顶点
//t:交点到射线起始点的距离
//u:交点在v1-v0上的投影的位置,
//v:交点在v1-v0上的投影的位置,   交点为vRet=v0+u*(v1-v0)+v*(v2-v0)
//Returns:是否有交点
//Sample:
//IntersectIndexBuffer(pIB,pVB,
//dwVSize,
//dwNumFace,


//pRayOrig,pRayDir,pVRet,dwFlag);

BOOL   IntersectTriangle(   const   D3DXVECTOR3&   orig,//实现碰撞检测   的全局函数(三角面)
                                                                              const   D3DXVECTOR3&   dir,   const   D3DXVECTOR3&   v0,
                                                                              const   D3DXVECTOR3&   v1,   const   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
//交点p=edge1*u+edge2*v;

        D3DXVECTOR3   pvec;
        D3DXVec3Cross(   &pvec,   &dir,   &edge2   );//|a×b|=|a||b|sinθ

        //   如果det接近0,表明射线平行于三角形
        FLOAT   det   =   D3DXVec3Dot(   &edge1,   &pvec   );//|a   dot   b|=|a||b|cosθ


        D3DXVECTOR3   tvec;
        if(   det   >   0   )
        {
                tvec   =   orig   -   v0;

        }
        else
        {return   FALSE;//方向相反
                tvec   =   v0   -   orig;
                det   =   -det;
        }
//if(D3DXVec3Dot(&dir,&tvec)> 0)   return   FALSE;

        if(   det   <   0.0001f   )
                return   FALSE;

        //   Calculate   U   parameter   and   test   bounds
        *u   =   D3DXVec3Dot(   &tvec,   &pvec   );
        if(   *u   <   0.0f   ||   *u   >   det   )
                return   FALSE;
 
        //   Prepare   to   test   V   parameter
        D3DXVECTOR3   qvec;
        D3DXVec3Cross(   &qvec,   &tvec,   &edge1   );



        //   Calculate   V   parameter   and   test   bounds
        *v   =   D3DXVec3Dot(   &dir,   &qvec   );
        if(   *v   <   0.0f   ||   *u   +   *v   >   det   )
                return   FALSE;

        //   Calculate   t,   scale   parameters,   ray   intersects   triangle
        *t   =   D3DXVec3Dot(   &edge2,   &qvec   );

        FLOAT   fInvDet   =   1.0f   /   det;
        *t   *=   fInvDet;
        *u   *=   fInvDet;
        *v   *=   fInvDet;
if(*t <0)   return   FALSE;

        return   TRUE;
};




[解决办法]
沙发,帮楼主顶顶

热点排行