通过屏幕点击的坐标获取体坐标(2D->3D)
1>获取点击位置的z
z = renderer->GetZ (static_cast<int>(selectionX),
static_cast<int>(selectionY));
renderer中getZ的实现:
// Error checking
// Must clear previous errors first.
while(glGetError() != GL_NO_ERROR)
{
;
}
// Turn of texturing in case it is on - some drivers have a problem
// getting / setting pixels with texturing enabled.
glDisable( GL_SCISSOR_TEST );
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
glReadPixels( x_low, y_low,
width, height,
GL_DEPTH_COMPONENT, GL_FLOAT,
z_data );
if z is 1.0, we assume the user has picked a point on the
screen that has not been rendered into. Use the camera’s focal
point for the z value. The test value .999999 has to be used
instead of 1.0 because for some reason our SGI Infinite Reality
engine won’t return a 1.0 from the zbuffer
如果z为1,则获取相机焦点对应屏幕坐标处的z
// Get camera focal point and position. Convert to display (screen)
// coordinates. We need a depth value for z-buffer.
camera = renderer->GetActiveCamera();
camera->GetFocalPoint(cameraFP); cameraFP[3] = 1.0;
renderer->SetWorldPoint(cameraFP[0],cameraFP[1],cameraFP[2],cameraFP[3]);
renderer->WorldToDisplay();
displayCoord = renderer->GetDisplayPoint();
selectionZ = displayCoord[2];
2>通过vtkRenderer设置屏幕屏幕坐标并进行转换
renderer->SetDisplayPoint (display);
renderer->DisplayToWorld ();
DisplayToWorld 实际调用:{this->DisplayToView(); this->ViewToWorld();}
DisplayToView实现:
size = this->VTKWindow->GetSize();
if (size == NULL)
{
return;
}
sizex = size[0];
sizey = size[1];
//2* (clickX/windowwidth) - 1
vx = 2.0 * (this->DisplayPoint[0] - sizex*this->Viewport[0])/
(sizex*(this->Viewport[2]-this->Viewport[0])) - 1.0;
//2* (clickY/windowheight) - 1
vy = 2.0 * (this->DisplayPoint[1] - sizey*this->Viewport[1])/
(sizey*(this->Viewport[3]-this->Viewport[1])) - 1.0;
vz = this->DisplayPoint[2];
vx和vy一定在区间[-1,1]
ViewToWorld实现:
// get the perspective transformation from the active camera
vtkMatrix4x4 *matrix = this->ActiveCamera->
GetCompositeProjectionTransformMatrix(
this->GetTiledAspectRatio(),0,1);
// use the inverse matrix
vtkMatrix4x4::Invert(*matrix->Element, mat);
// Transform point to world coordinates
result[0] = x;
result[1] = y;
result[2] = z;
result[3] = 1.0;
vtkMatrix4x4::MultiplyPoint(mat,result,result);
ActiveCamera->GetCompositeProjectionTransformMatrix实现较为复杂,有时间再弄!!
3>通过vtkRenderer获取体坐标并转换
world = renderer->GetWorldPoint ();
for (int i=0; i < 3; i++)
{
this->PickPosition[i] = world[i] / world[3];
}