You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
388 lines
11 KiB
388 lines
11 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkInteractorStyleTrackballCamera.cxx,v $
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkInteractorStyleTrackballCamera.h"
|
|
|
|
#include "vtkCamera.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkRenderWindowInteractor.h"
|
|
#include "vtkRenderer.h"
|
|
|
|
vtkCxxRevisionMacro(vtkInteractorStyleTrackballCamera, "$Revision: 1.32 $");
|
|
vtkStandardNewMacro(vtkInteractorStyleTrackballCamera);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInteractorStyleTrackballCamera::vtkInteractorStyleTrackballCamera()
|
|
{
|
|
this->MotionFactor = 10.0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkInteractorStyleTrackballCamera::~vtkInteractorStyleTrackballCamera()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnMouseMove()
|
|
{
|
|
int x = this->Interactor->GetEventPosition()[0];
|
|
int y = this->Interactor->GetEventPosition()[1];
|
|
|
|
switch (this->State)
|
|
{
|
|
case VTKIS_ROTATE:
|
|
this->FindPokedRenderer(x, y);
|
|
this->Rotate();
|
|
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
|
|
break;
|
|
|
|
case VTKIS_PAN:
|
|
this->FindPokedRenderer(x, y);
|
|
this->Pan();
|
|
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
|
|
break;
|
|
|
|
case VTKIS_DOLLY:
|
|
this->FindPokedRenderer(x, y);
|
|
this->Dolly();
|
|
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
|
|
break;
|
|
|
|
case VTKIS_SPIN:
|
|
this->FindPokedRenderer(x, y);
|
|
this->Spin();
|
|
this->InvokeEvent(vtkCommand::InteractionEvent, NULL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnLeftButtonDown()
|
|
{
|
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
|
this->Interactor->GetEventPosition()[1]);
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this->Interactor->GetShiftKey())
|
|
{
|
|
if (this->Interactor->GetControlKey())
|
|
{
|
|
this->StartDolly();
|
|
}
|
|
else
|
|
{
|
|
this->StartPan();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (this->Interactor->GetControlKey())
|
|
{
|
|
this->StartSpin();
|
|
}
|
|
else
|
|
{
|
|
this->StartRotate();
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnLeftButtonUp()
|
|
{
|
|
switch (this->State)
|
|
{
|
|
case VTKIS_DOLLY:
|
|
this->EndDolly();
|
|
break;
|
|
|
|
case VTKIS_PAN:
|
|
this->EndPan();
|
|
break;
|
|
|
|
case VTKIS_SPIN:
|
|
this->EndSpin();
|
|
break;
|
|
|
|
case VTKIS_ROTATE:
|
|
this->EndRotate();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnMiddleButtonDown()
|
|
{
|
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
|
this->Interactor->GetEventPosition()[1]);
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->StartPan();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnMiddleButtonUp()
|
|
{
|
|
switch (this->State)
|
|
{
|
|
case VTKIS_PAN:
|
|
this->EndPan();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnRightButtonDown()
|
|
{
|
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
|
this->Interactor->GetEventPosition()[1]);
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->StartDolly();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnRightButtonUp()
|
|
{
|
|
switch (this->State)
|
|
{
|
|
case VTKIS_DOLLY:
|
|
this->EndDolly();
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnMouseWheelForward()
|
|
{
|
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
|
this->Interactor->GetEventPosition()[1]);
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->StartDolly();
|
|
double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
|
|
this->Dolly(pow((double)1.1, factor));
|
|
this->EndDolly();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::OnMouseWheelBackward()
|
|
{
|
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
|
this->Interactor->GetEventPosition()[1]);
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this->StartDolly();
|
|
double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
|
|
this->Dolly(pow((double)1.1, factor));
|
|
this->EndDolly();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::Rotate()
|
|
{
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
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 = (double)dx * delta_azimuth * this->MotionFactor;
|
|
double ryf = (double)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 vtkInteractorStyleTrackballCamera::Spin()
|
|
{
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
vtkRenderWindowInteractor *rwi = this->Interactor;
|
|
|
|
double *center = this->CurrentRenderer->GetCenter();
|
|
|
|
double newAngle =
|
|
atan2((double)rwi->GetEventPosition()[1] - (double)center[1],
|
|
(double)rwi->GetEventPosition()[0] - (double)center[0]);
|
|
|
|
double oldAngle =
|
|
atan2((double)rwi->GetLastEventPosition()[1] - (double)center[1],
|
|
(double)rwi->GetLastEventPosition()[0] - (double)center[0]);
|
|
|
|
newAngle *= vtkMath::RadiansToDegrees();
|
|
oldAngle *= vtkMath::RadiansToDegrees();
|
|
|
|
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
|
|
camera->Roll(newAngle - oldAngle);
|
|
camera->OrthogonalizeViewUp();
|
|
|
|
rwi->Render();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::Pan()
|
|
{
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
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((double)rwi->GetEventPosition()[0],
|
|
(double)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((double)rwi->GetLastEventPosition()[0],
|
|
(double)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 vtkInteractorStyleTrackballCamera::Dolly()
|
|
{
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
vtkRenderWindowInteractor *rwi = this->Interactor;
|
|
double *center = this->CurrentRenderer->GetCenter();
|
|
int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
|
|
double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
|
|
this->Dolly(pow((double)1.1, dyf));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::Dolly(double factor)
|
|
{
|
|
if (this->CurrentRenderer == NULL)
|
|
{
|
|
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();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkInteractorStyleTrackballCamera::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
}
|
|
|
|
|