昏头!被Intersect折腾了半天!

昏头!被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(  0 0 , ( void ** ) & pIndices,  0  );
 25      pVB -> Lock(  0 0 , ( 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 != 0x1111 continue ;        
 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 != 0x0011 continue ;    
 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么?

你可能感兴趣的:(昏头!被Intersect折腾了半天!)