Code Knight

Programming is so cool
随笔 - 52, 文章 - 0, 评论 - 14, 引用 - 0
数据加载中……

昏头!被Intersect折腾了半天!

          D3D中的PICK例程中有这样的一个检测函数,检测拾取,具体原理网上有很多,自己改了一下,却掉了两个重要的东西,不过还不是很明白是怎么一回事!修改我射线起始点的坐标有何用呢?
         
  1 BOOL IntersectTest(LPDIRECT3DVERTEXBUFFER9 pVB,
  2                    LPDIRECT3DINDEXBUFFER9 pIB,
  3                    int nStride,
  4                    int dwNumFaces,
  5                    D3DXVECTOR3* vPickRayOrig,
  6                    D3DXVECTOR3* vPickRay,
  7                    D3DXVECTOR3 *pVRet,
  8                    DWORD dwFlag=0// 主要检测与地形相交 // 此函数相当耗费CPU// 生成地形有13W个面,逐一检查是否相交
  9 {
 10     WORD*        pIndices;
 11     BYTE*        pVertices;
 12     D3DINDEXBUFFER_DESC IB_Desc;
 13 
 14     FLOAT fBary1, fBary2,fDist=1e+32f;
 15 
 16     FLOAT t_fBary1, t_fBary2,t_fDist;
 17     DWORD dwFace=-1;
 18     DWORD  dwUpperLower;    
 19 
 20     D3DXVECTOR3* pV[3];
 21     ULONG  n;
 22 
 23     pIB->GetDesc(&IB_Desc); 
 24     pIB->Lock( 00, (void**)&pIndices, 0 );
 25     pVB->Lock( 00, (void**)&pVertices,0 );
 26 
 27 
 28     for( DWORD i=0; i<dwNumFaces; i++ )
 29     {
 30         for(int j=0;j<3;j++)
 31         {
 32             if(IB_Desc.Format==D3DFMT_INDEX16)            
 33                 n=(WORD)pIndices[3*i+j];
 34             else if(IB_Desc.Format==D3DFMT_INDEX32)        
 35                 n=*(DWORD*)&pIndices[2*(3*i+j)];
 36             else 
 37                 return FALSE;
 38             pV[j]=(D3DXVECTOR3*)(pVertices+nStride*n); 
 39         }
 40 
 41         dwUpperLower=0;
 42 
 43          if(dwFlag) // 这段是必须要的,具体是怎么做到的?
 44          {
 45              if(dwFlag & INTERSECT_NEGATIVEY) 
 46              {
 47                 for(int j=0;j<3;j++)
 48                 {
 49                     dwUpperLower|=vPickRayOrig->x>pV[j]->x? 0x0010:0x0001
 50                     dwUpperLower|=vPickRayOrig->z>pV[j]->z? 0x1000:0x0100
 51 
 52                 }
 53                 if(dwUpperLower!=0x1111continue;        
 54             }
 55             else if(dwFlag & INTERSECT_HORIZENTAL) 
 56             {
 57                 for(int j=0;j<3;j++)
 58                 {
 59                     dwUpperLower|=(vPickRayOrig->> pV[j]->y)? 0x0010:0x0001;
 60                 }
 61 
 62                 if(dwUpperLower!=0x0011continue;    
 63             }
 64 
 65 
 66         }
 67 
 68 
 69 
 70         // 检测是否穿过三角形
 71         if( IntersectTriangle( *vPickRayOrig, *vPickRay, *pV[0], *pV[1], *pV[2],
 72             &t_fDist, &t_fBary1, &t_fBary2 ) )
 73         {
 74             if(    t_fDist < fDist )    //是否返回最近的一个点
 75             {
 76                 dwFace = i;
 77                 fBary1 = t_fBary1;
 78                 fBary2 = t_fBary2;
 79                 fDist  = t_fDist;
 80             }
 81         }
 82     }
 83     
 84 
 85     if(dwFace<dwNumFaces && dwFace>=0 )
 86     {
 87 
 88         for(int j=0;j<3;j++)
 89         {
 90             if(IB_Desc.Format==D3DFMT_INDEX16)            
 91                 n=(WORD)pIndices[3*dwFace +j];
 92             else if(IB_Desc.Format==D3DFMT_INDEX32)        
 93                 n=*(DWORD*)&pIndices[2*(3*dwFace+j)];
 94             else 
 95                 return FALSE;
 96             pV[j]=(D3DXVECTOR3*)(pVertices+nStride*n);
 97         }
 98         *pVRet=*pV[0+fBary1*(*pV[1]-*pV[0])+fBary2*(*pV[2]-*pV[0]);  
 99 
100 
101         pVB->Unlock();
102         pIB->Unlock();
103         return 1;
104     }
105 
106 
107     pVB->Unlock();
108     pIB->Unlock();
109 
110 
111 
112     return 0;
113 }
另一个问题,大规模的地形一般如何最大程度的优化避免对所有的面进行检测?用LOD么?

posted on 2009-02-11 17:41 Code Knight 阅读(357) 评论(0)  编辑 收藏 引用 所属分类: 图形学


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理