// // WndProc // LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd); break; case WM_LBUTTONDOWN: // compute the ray in view space given the clicked screen point d3d::Ray ray = CalcPickingRay(LOWORD(lParam), HIWORD(lParam)); // transform the ray to world space D3DXMATRIX view; Device->GetTransform(D3DTS_VIEW, &view); D3DXMATRIX viewInverse; D3DXMatrixInverse(&viewInverse, 0, &view); TransformRay(&ray, &viewInverse); // test for a hit if( RaySphereIntTest(&ray, &BSphere) ) ::MessageBox(0, "Hit!", "HIT", 0); break; } return ::DefWindowProc(hwnd, msg, wParam, lParam); }
//测试射线是否与开始按钮相交 bool START::test(int x,int y) { RAY ray; ray = CalcPickingRay(x,y); if(RaySphereIntTest(&ray,&(_text_start->_sphere)) == true) return true; return false; }
void CubeMesh::DrawRay(const D3DXVECTOR2& screenPos, const D3DXMATRIX& matWorld, const D3DXMATRIX& matView, const D3DXMATRIX& matProj) { HRESULT hr = S_FALSE; GraphicsDevice* pGDevice = GraphicsDevice::getInstance(); IDirect3DDevice9* pDevice = pGDevice->m_pD3DDevice; Ray ray = CalcPickingRay((int)screenPos.x, (int)screenPos.y, pGDevice->mCubeViewport, matView, matProj ); PCVertex rayLine[] = { {D3DXVECTOR3(0.0f,0.0f,0.0f), D3DCOLOR_ARGB(255,255,0,0)}, {ray.Origin + 1000*ray.Direction, D3DCOLOR_ARGB(255,255,0,0)}, }; PCVertex intersectPoint[] = { {p, D3DCOLOR_ARGB(255,0,0,255)}, {p+D3DXVECTOR3(0.5f,0.0f,0.0f), D3DCOLOR_ARGB(255,0,0,255)}, {p+D3DXVECTOR3(0.0f,0.5f,0.0f), D3DCOLOR_ARGB(255,0,0,255)}, {p+D3DXVECTOR3(0.0f,0.0f,0.5f), D3DCOLOR_ARGB(255,0,0,255)}, {p+D3DXVECTOR3(-0.5f,0.0f,0.0f), D3DCOLOR_ARGB(255,0,0,255)}, {p+D3DXVECTOR3(0.0f,-0.5f,0.0f), D3DCOLOR_ARGB(255,0,0,255)}, {p+D3DXVECTOR3(0.0f,0.0f,-0.5f), D3DCOLOR_ARGB(255,0,0,255)}, }; pGDevice->SetViewport(pGDevice->mCubeViewport); pDevice->SetVertexShader(NULL); pDevice->SetPixelShader(NULL); V(pDevice->SetTransform(D3DTS_WORLD, &matWorld)); V(pDevice->SetTransform(D3DTS_VIEW, &matView)); V(pDevice->SetTransform(D3DTS_PROJECTION, &matProj)); V(pDevice->SetRenderState(D3DRS_LIGHTING, FALSE)); V(pDevice->SetRenderState(D3DRS_ZENABLE, FALSE)); V(pDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE)); V(pDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, rayLine, sizeof(PCVertex))); V(pDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 7, intersectPoint, sizeof(PCVertex))); V(pDevice->SetFVF(NULL)); V(pDevice->SetRenderState(D3DRS_ZENABLE, TRUE)); V(pDevice->SetRenderState(D3DRS_LIGHTING, TRUE)); pGDevice->ResetViewport(); }
LRESULT CALLBACK d3d9::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: if (wParam == VK_ESCAPE) DestroyWindow(hWnd); break; case WM_LBUTTONDOWN: { Ray ray; if (CalcPickingRay(LOWORD(lParam), HIWORD(lParam), g_pDevice, &ray)) { D3DXMATRIX view; g_pDevice->GetTransform(D3DTS_VIEW, &view); D3DXMATRIX inverse; float determinant = D3DXMatrixDeterminant(&view); D3DXMatrixInverse(&inverse, &determinant, &view); TransformRay(&ray, &inverse); if (RayHitSephere(&ray, &g_BSephere)) { MessageBox(0, "Hit!", "HIT", 0); } } break; } } return DefWindowProc(hWnd, msg, wParam, lParam); }
bool CubeMesh::Update(const D3DXVECTOR2& currentMousePos, const D3DXMATRIX& matWorld, const D3DXMATRIX& matView, const D3DXMATRIX& matProj) { GraphicsDevice* pGDevice = GraphicsDevice::getInstance(); IDirect3DDevice9* pDevice = pGDevice->m_pD3DDevice; //将屏幕坐标进行变换,变换到相对于mCubeViewport的原点的坐标 int x = int(currentMousePos.x - pGDevice->mCubeViewport.X); int y = int(currentMousePos.y - pGDevice->mCubeViewport.Y); //获取World中的射线 Ray ray = CalcPickingRay(x, y, pGDevice->mCubeViewport, matView, matProj ); //检测射线和所有三角形的相交情况 HRESULT hr = S_FALSE; UINT lSize = nPrimitive * 3 * sizeof(PCTVertex); PCTVertex* vertex = 0; V(pVB->Lock(0, 0, (void**)&vertex, 0)); FaceType lTargetFaceType = FaceType::None; //最近的Cube面 float lMinDistance = FLT_MAX; //最近的距离 for(unsigned int i = 0; i < nPrimitive * 3; i+=6) //步进6是为了遍历一个矩形的两个三角形 { FaceType lFaceType = FaceType(i/6); #ifdef DEBUG_CUBE switch(lFaceType) { case Forward: DebugPrintf("前"); break; case Backward: DebugPrintf("后"); break; case Upward: DebugPrintf("上"); break; case Downward: DebugPrintf("下"); break; case Left: DebugPrintf("左"); break; case Right: DebugPrintf("右"); break; default: break; } #endif PCTVertex& pt0 = vertex[IndexBuf.at(i)]; PCTVertex& pt1 = vertex[IndexBuf.at(i+1)]; PCTVertex& pt2 = vertex[IndexBuf.at(i+2)]; D3DXVECTOR3 v0(pt0.Pos); D3DXVECTOR3 v1(pt1.Pos); D3DXVECTOR3 v2(pt2.Pos); PCTVertex& pt3 = vertex[IndexBuf.at(i+3)]; PCTVertex& pt4 = vertex[IndexBuf.at(i+4)]; PCTVertex& pt5 = vertex[IndexBuf.at(i+5)]; D3DXVECTOR3 v3(pt3.Pos); D3DXVECTOR3 v4(pt4.Pos); D3DXVECTOR3 v5(pt5.Pos); //若与该三角形相交则加深其所在Cube面颜色 TODO:遍历完后取最近的Face float t =0.0f,u=0.0f,v=0.0f; if (Ray::Intersect(ray.Origin, ray.Direction, v0, v1, v2, &t, &u, &v) || Ray::Intersect(ray.Origin, ray.Direction, v3, v4, v5, &t, &u, &v)) { #ifdef DEBUG_CUBE DebugPrintf("√\n"); #endif if (t < lMinDistance) { lMinDistance = t; lTargetFaceType = lFaceType; } p = ray.Origin + t*ray.Direction; pt0.Color = D3DCOLOR_ARGB(0xff,0xcc,0xcc,0xcc); pt1.Color = D3DCOLOR_ARGB(0xff,0xcc,0xcc,0xcc); pt2.Color = D3DCOLOR_ARGB(0xff,0xcc,0xcc,0xcc); pt3.Color = D3DCOLOR_ARGB(0xff,0xcc,0xcc,0xcc); pt4.Color = D3DCOLOR_ARGB(0xff,0xcc,0xcc,0xcc); pt5.Color = D3DCOLOR_ARGB(0xff,0xcc,0xcc,0xcc); } else { #ifdef DEBUG_CUBE DebugPrintf("\n"); #endif pt0.Color = 0xFFFFFFFF; pt1.Color = 0xFFFFFFFF; pt2.Color = 0xFFFFFFFF; pt3.Color = 0xFFFFFFFF; pt4.Color = 0xFFFFFFFF; pt5.Color = 0xFFFFFFFF; } } V(pVB->Unlock()); return true; }