void GERendering::screenToWorld(const GEVector* PositionScreen, GEVector* WorldPointNear, GEVector* WorldPointFar) { D3DXMATRIX matProjection; d3ddev->GetTransform(D3DTS_PROJECTION, &matProjection); D3DXMATRIX matView; d3ddev->GetTransform(D3DTS_VIEW, &matView); D3DXMATRIX matIdentity; D3DXMatrixIdentity(&matIdentity); D3DVIEWPORT9 vPort; d3ddev->GetViewport(&vPort); D3DXVECTOR3 vPositionScreen1(PositionScreen->X, PositionScreen->Y, 0.0f); D3DXVECTOR3 vPositionScreen2(PositionScreen->X, PositionScreen->Y, 1.0f); D3DXVECTOR3 vPositionWorld1; D3DXVec3Unproject(&vPositionWorld1, &vPositionScreen1, &vPort, &matProjection, &matView, &matIdentity); D3DXVECTOR3 vPositionWorld2; D3DXVec3Unproject(&vPositionWorld2, &vPositionScreen2, &vPort, &matProjection, &matView, &matIdentity); WorldPointNear->set(vPositionWorld1.x, vPositionWorld1.y, vPositionWorld1.z); WorldPointFar->set(vPositionWorld2.x, vPositionWorld2.y, vPositionWorld2.z); }
//----------------------------------------------------------------------------// void Direct3D10RenderTarget::unprojectPoint(const GeometryBuffer& buff, const Vector2& p_in, Vector2& p_out) const { if (!d_matrixValid) updateMatrix(); const Direct3D10GeometryBuffer& gb = static_cast<const Direct3D10GeometryBuffer&>(buff); D3D10_VIEWPORT vp; setupViewport(vp); D3DXVECTOR3 in_vec; in_vec.z = 0.0f; // project points to create a plane orientated with GeometryBuffer's data D3DXVECTOR3 p1; D3DXVECTOR3 p2; D3DXVECTOR3 p3; in_vec.x = 0; in_vec.y = 0; D3DXVec3Project(&p1, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); in_vec.x = 1; in_vec.y = 0; D3DXVec3Project(&p2, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); in_vec.x = 0; in_vec.y = 1; D3DXVec3Project(&p3, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); // create plane from projected points D3DXPLANE surface_plane; D3DXPlaneFromPoints(&surface_plane, &p1, &p2, &p3); // unproject ends of ray in_vec.x = vp.Width * 0.5f; in_vec.y = vp.Height * 0.5f; in_vec.z = -d_viewDistance; D3DXVECTOR3 t1; D3DXVec3Unproject(&t1, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); in_vec.x = p_in.d_x; in_vec.y = p_in.d_y; in_vec.z = 0.0f; D3DXVECTOR3 t2; D3DXVec3Unproject(&t2, &in_vec, &vp, &d_matrix, 0, gb.getMatrix()); // get intersection of ray and plane D3DXVECTOR3 intersect; D3DXPlaneIntersectLine(&intersect, &surface_plane, &t1, &t2); p_out.d_x = intersect.x; p_out.d_y = intersect.y; }
// Project the mouse cursor from screen space to object space void EditExt::ProjectScreenToWorld(D3DXVECTOR3* pOut, float screenX, float screenY, float worldZ) { D3DXVECTOR3 lineBegin, lineEnd; // Unproject the near and far points given by the screen X,Y coords D3DXVECTOR3 screenSpace(screenX, screenY, 0.0f); D3DXVec3Unproject(&lineBegin, &screenSpace, &viewport, &projection_matrix, &view_matrix, &worldMatrix); screenSpace.z = 1.0f; D3DXVec3Unproject(&lineEnd, &screenSpace, &viewport, &projection_matrix, &view_matrix, &worldMatrix); // Using a plane intersection, we can determine the object space coordinates of the screen space coords // at a certain Z depth, intersecting the line given above. orig.z = worldZ; D3DXPlaneFromPointNormal(&plane, &orig, &normal); D3DXPlaneIntersectLine(pOut, &plane, &lineBegin, &lineEnd); }
void PhysXUnProject(int xi, int yi, float depth, double &rx, double &ry, double &rz) { D3DXVECTOR3 output, input; input = D3DXVECTOR3(xi, yi, depth); D3DXVec3Unproject(&output, &input, &gViewPort, gViewerCamera.GetProjMatrix(), gViewerCamera.GetViewMatrix(), &gWorldMatrix); rx = output.x; ry = output.y; rz = output.z; }
// クライアント座標からワールド座標へ void ClientToWorld( const Vector3& screenPos, Vector3& out ) { D3DXVECTOR3 d3dxScreenCoord( screenPos.x, screenPos.y, screenPos.z ); D3DVIEWPORT9 viewPort; iexSystem::Device->GetViewport( &viewPort ); D3DXMATRIX worldMatrix; D3DXMatrixIdentity( &worldMatrix ); D3DXVECTOR3 result; D3DXVec3Unproject( &result, &d3dxScreenCoord, &viewPort, &matProjection, &matView, &worldMatrix ); out = Vector3( result.x, result.y, result.z ); }
/************************************************************************* * D3DXVec3UnprojectArray */ D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray( D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements) { UINT i; TRACE("\n"); for (i = 0; i < elements; ++i) { D3DXVec3Unproject( (D3DXVECTOR3*)((char*)out + outstride * i), (CONST D3DXVECTOR3*)((const char*)in + instride * i), viewport, projection, view, world); } return out; }
/* Unprojects the screen-space coordinate into object-space */ void D3DRenderer::Unproject(float& x, float& y, float& z) { D3DVIEWPORT9 viewport; mD3DDevice->GetViewport(&viewport); D3DXVECTOR3 in(x, y, z); D3DXVECTOR3 out; D3DXMATRIX world; D3DXMatrixIdentity(&world); D3DXVec3Unproject(&out, &in, &viewport, &mProjection, &mView, &world); x = out.x; y = out.y; z = out.z; }
//投影和逆投影 Vector3 RenderTargetD3D9::unproject( const Vector3 & v) { //world matrix D3DXMATRIX matWorldD3D ( MappingsD3D9::getMatrix( m_RenderState.m_mtxWorld ) ); //view matrix xs::Matrix4 matView( m_RenderState.m_mtxView ); matView[2][0] = -matView[2][0]; matView[2][1] = -matView[2][1]; matView[2][2] = -matView[2][2]; matView[2][3] = -matView[2][3]; D3DXMATRIX matViewD3D( MappingsD3D9::getMatrix( matView ) ); //projection matrix xs::Matrix4 matProj; convertProjectionMatrix(m_RenderState.m_mtxProjection, matProj, false); D3DXMATRIX matProjD3D( MappingsD3D9::getMatrix( matProj) ); D3DXVECTOR3 vin(v.x, v.y, v.z); D3DXVECTOR3 vout; D3DXVec3Unproject(&vout, &vin, &m_viewport, &matProjD3D, &matViewD3D, &matWorldD3D); return Vector3(vout.x, vout.y, vout.z); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Summary: Responds to key presses Parameters: [in] xDelta - Change in mouse x-axis since last frame [in] yDelta - Change in mouse y-axis since last frame [in] zDelta - Change in mouse z-axis since last frame [in] pMouseButtons - Mouse button states [in] pPressedKeys - Keyboard keys that are pressed and not locked [in] elapsedTime - Time elapsed since last frame * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void terrain3d::ProcessInput( long xDelta, long yDelta, long zDelta, BOOL* pMouseButtons, BOOL* pPressedKeys, float elapsedTime ) { float cameraSpeed = 30.0f; if ( pMouseButtons[1] ) { D3DVIEWPORT9 viewport; m_pFramework->m_pGraphics->GetDevice()->GetViewport(&viewport); D3DXVECTOR3 inP1( (float) m_pFramework->m_mouse.GetX(), (float) m_pFramework->m_mouse.GetY(), 0.1f); D3DXVECTOR3 outP1; D3DXVECTOR3 outP2; D3DXMATRIX viewMatrix; m_pFramework->m_pGraphics->GetDevice()->GetTransform( D3DTS_VIEW, &viewMatrix); D3DXMATRIX projMatrix; m_pFramework->m_pGraphics->GetDevice()->GetTransform( D3DTS_PROJECTION, &projMatrix); D3DXMATRIX worldMatrix; m_pFramework->m_pGraphics->GetDevice()->GetTransform( D3DTS_WORLD, &worldMatrix); outP1 = *m_camera.GetPosition(); inP1.z = viewport.MaxZ; D3DXVec3Unproject(&outP2, &inP1, &viewport, /*&m_camera.m_projection*/ /*m_camera.GetProjectionMatrix()*/ &projMatrix, /*&m_camera.m_view*//*m_camera.GetViewMatrix()*/&viewMatrix, /*&worldMatrix*/ /*m_terrain.GetTransform()*/&worldMatrix); //printf("DEBUG: %f, %f, %f\n", outP2.x, outP2.y, outP2.z); D3DXVECTOR3 intersection; D3DXPLANE p(0.0f, 1.0f, 0.0f, 0.0f); D3DXPlaneIntersectLine(&intersection, &p, &outP1, &outP2); //printf("DEBUG: %f, %f\n", intersection.x * 100.0f, intersection.z * 100.0f); waypoint[0] = intersection.z * 100.0f; waypoint[1] = intersection.x * 100.0f; } if ( pMouseButtons[0] ) { m_camera.Yaw( xDelta * elapsedTime * 0.1f); m_camera.Pitch( yDelta * elapsedTime * 0.1f ); updated = true; } if ( pPressedKeys[DIK_I] ) { m_camera.MoveForward( cameraSpeed * elapsedTime ); updated = true; } if ( pPressedKeys[DIK_J] ) { m_camera.Strafe( -cameraSpeed * elapsedTime ); updated = true; } if ( pPressedKeys[DIK_K] ) { m_camera.MoveForward( -cameraSpeed * elapsedTime ); updated = true; } if ( pPressedKeys[DIK_L] ) { m_camera.Strafe( cameraSpeed * elapsedTime ); updated = true; } if ( pPressedKeys[DIK_Q] ) { m_terrain.ScaleRel( 0.0f, -0.1f * elapsedTime, 0.0f ); updated = true; } if ( pPressedKeys[DIK_E] ) { m_terrain.ScaleRel( 0.0f , 0.1f * elapsedTime, 0.0f ); updated = true; } if ( pPressedKeys[DIK_F5] ) { m_pFramework->LockKey( DIK_F5 ); if ( m_pFramework != NULL ) { m_pFramework->ToggleFullscreen(); } } if ( pPressedKeys[DIK_F6] ) { m_pFramework->LockKey( DIK_F6 ); if ( m_pFramework != NULL ) { m_pFramework->ToggleWireframe(); updated = true; } } }