vtkInteractorStyleTrackballCamera控制用户交互操作相机,场景的视点。在该类及其子类中,移动的是Camera,Actor并没有发生移动。
主要鼠标键盘操作控制:
左键按住移动:旋转
右键按住移动:缩放
滚轮按住移动:移动
ctrl +左键按住移动:快速旋转(同旋转不同)
shift +左键按住移动:移动
ctrl + shift +左键按住移动:缩放
如果有鼠标事件处理等相应的需求,可以重写该事件。
void OnMouseMove() override; //鼠标移动事件
void OnLeftButtonDown() override;//左键按下事件
void OnLeftButtonUp() override;//左键抬起事件
void OnMiddleButtonDown() override;//滚轮按下事件
void OnMiddleButtonUp() override;//滚轮抬起事件
void OnRightButtonDown() override;//右键按下事件
void OnRightButtonUp() override;//右键抬起事件
void OnMouseWheelForward() override;//滚轮向前事件
void OnMouseWheelBackward() override;//滚轮向后事件
具体事件的实现,可以查看vtk的源码查看,下面只列举几个:
void OnLeftButtonDown() override;//左键按下事件
void vtkInteractorStyleTrackballCamera::OnLeftButtonDown()
{
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1]);
if (this->CurrentRenderer == nullptr)
{
return;
}
this->GrabFocus(this->EventCallbackCommand);
if (this->Interactor->GetShiftKey())
{
if (this->Interactor->GetControlKey())
{
this->StartDolly();
}
else
{
this->StartPan();
}
}
else
{
if (this->Interactor->GetControlKey())
{
this->StartSpin();
}
else
{
this->StartRotate();
}
}
}
void OnMouseWheelForward() override;//滚轮向前事件
void vtkInteractorStyleTrackballCamera::OnMouseWheelForward()
{
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
this->Interactor->GetEventPosition()[1]);
if (this->CurrentRenderer == nullptr)
{
return;
}
this->GrabFocus(this->EventCallbackCommand);
this->StartDolly();
double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
this->Dolly(pow(1.1, factor));
this->EndDolly();
this->ReleaseFocus();
}
void Rotate() override;//旋转
void Spin() override;//快速旋转
void Pan() override;//平移
void Dolly() override;//缩放
函数实现的源码如下:
void Rotate() override;//旋转
void vtkInteractorStyleTrackballCamera::Rotate()
{
if (this->CurrentRenderer == nullptr)
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
int dx = rwi->GetEventPosition()[0] - rwi->GetLastEventPosition()[0];
int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
int *size = this->CurrentRenderer->GetRenderWindow()->GetSize();
double delta_elevation = -20.0 / size[1];
double delta_azimuth = -20.0 / size[0];
double rxf = dx * delta_azimuth * this->MotionFactor;
double ryf = dy * delta_elevation * this->MotionFactor;
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
camera->Azimuth(rxf);
camera->Elevation(ryf);
camera->OrthogonalizeViewUp();
if (this->AutoAdjustCameraClippingRange)
{
this->CurrentRenderer->ResetCameraClippingRange();
}
if (rwi->GetLightFollowCamera())
{
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
}
rwi->Render();
}
void Spin() override;//快速旋转
void vtkInteractorStyleTrackballCamera::Spin()
{
if ( this->CurrentRenderer == nullptr )
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
double *center = this->CurrentRenderer->GetCenter();
double newAngle =
vtkMath::DegreesFromRadians( atan2( rwi->GetEventPosition()[1] - center[1],
rwi->GetEventPosition()[0] - center[0] ) );
double oldAngle =
vtkMath::DegreesFromRadians( atan2( rwi->GetLastEventPosition()[1] - center[1],
rwi->GetLastEventPosition()[0] - center[0] ) );
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
camera->Roll( newAngle - oldAngle );
camera->OrthogonalizeViewUp();
rwi->Render();
}
void Pan() override;//平移
void vtkInteractorStyleTrackballCamera::Pan()
{
if (this->CurrentRenderer == nullptr)
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
double viewFocus[4], focalDepth, viewPoint[3];
double newPickPoint[4], oldPickPoint[4], motionVector[3];
// Calculate the focal depth since we'll be using it a lot
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
camera->GetFocalPoint(viewFocus);
this->ComputeWorldToDisplay(viewFocus[0], viewFocus[1], viewFocus[2],
viewFocus);
focalDepth = viewFocus[2];
this->ComputeDisplayToWorld(rwi->GetEventPosition()[0],
rwi->GetEventPosition()[1],
focalDepth,
newPickPoint);
// Has to recalc old mouse point since the viewport has moved,
// so can't move it outside the loop
this->ComputeDisplayToWorld(rwi->GetLastEventPosition()[0],
rwi->GetLastEventPosition()[1],
focalDepth,
oldPickPoint);
// Camera motion is reversed
motionVector[0] = oldPickPoint[0] - newPickPoint[0];
motionVector[1] = oldPickPoint[1] - newPickPoint[1];
motionVector[2] = oldPickPoint[2] - newPickPoint[2];
camera->GetFocalPoint(viewFocus);
camera->GetPosition(viewPoint);
camera->SetFocalPoint(motionVector[0] + viewFocus[0],
motionVector[1] + viewFocus[1],
motionVector[2] + viewFocus[2]);
camera->SetPosition(motionVector[0] + viewPoint[0],
motionVector[1] + viewPoint[1],
motionVector[2] + viewPoint[2]);
if (rwi->GetLightFollowCamera())
{
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
}
rwi->Render();
}
void Dolly() override;//缩放
void vtkInteractorStyleTrackballCamera::Dolly()
{
if (this->CurrentRenderer == nullptr)
{
return;
}
vtkRenderWindowInteractor *rwi = this->Interactor;
double *center = this->CurrentRenderer->GetCenter();
int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
double dyf = this->MotionFactor * dy / center[1];
this->Dolly(pow(1.1, dyf));
}
void vtkInteractorStyleTrackballCamera::Dolly(double factor)
{
if (this->CurrentRenderer == nullptr)
{
return;
}
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
if (camera->GetParallelProjection())
{
camera->SetParallelScale(camera->GetParallelScale() / factor);
}
else
{
camera->Dolly(factor);
if (this->AutoAdjustCameraClippingRange)
{
this->CurrentRenderer->ResetCameraClippingRange();
}
}
if (this->Interactor->GetLightFollowCamera())
{
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
}
this->Interactor->Render();
}