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->y > 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么?