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.
417 lines
11 KiB
417 lines
11 KiB
2 years ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: $RCSfile: vtkInteractorStyleTerrain.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 "vtkInteractorStyleTerrain.h"
|
||
|
|
||
|
#include "vtkActor.h"
|
||
|
#include "vtkCamera.h"
|
||
|
#include "vtkCommand.h"
|
||
|
#include "vtkExtractEdges.h"
|
||
|
#include "vtkMath.h"
|
||
|
#include "vtkObjectFactory.h"
|
||
|
#include "vtkPolyData.h"
|
||
|
#include "vtkPolyDataMapper.h"
|
||
|
#include "vtkRenderWindow.h"
|
||
|
#include "vtkRenderWindowInteractor.h"
|
||
|
#include "vtkRenderer.h"
|
||
|
#include "vtkSphereSource.h"
|
||
|
|
||
|
vtkCxxRevisionMacro(vtkInteractorStyleTerrain, "$Revision: 1.9 $");
|
||
|
vtkStandardNewMacro(vtkInteractorStyleTerrain);
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
vtkInteractorStyleTerrain::vtkInteractorStyleTerrain()
|
||
|
{
|
||
|
this->LatLongLines = 0;
|
||
|
|
||
|
this->LatLongSphere = NULL;
|
||
|
this->LatLongExtractEdges = NULL;
|
||
|
this->LatLongMapper = NULL;
|
||
|
this->LatLongActor = NULL;
|
||
|
|
||
|
this->MotionFactor = 10.0;
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
vtkInteractorStyleTerrain::~vtkInteractorStyleTerrain()
|
||
|
{
|
||
|
if (this->LatLongSphere != NULL)
|
||
|
{
|
||
|
this->LatLongSphere->Delete();
|
||
|
}
|
||
|
|
||
|
if (this->LatLongMapper != NULL)
|
||
|
{
|
||
|
this->LatLongMapper->Delete();
|
||
|
}
|
||
|
|
||
|
if (this->LatLongActor != NULL)
|
||
|
{
|
||
|
this->LatLongActor->Delete();
|
||
|
}
|
||
|
|
||
|
if (this->LatLongExtractEdges != NULL)
|
||
|
{
|
||
|
this->LatLongExtractEdges->Delete();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnLeftButtonDown ()
|
||
|
{
|
||
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
||
|
this->Interactor->GetEventPosition()[1]);
|
||
|
if (this->CurrentRenderer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->StartRotate();
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnLeftButtonUp ()
|
||
|
{
|
||
|
switch (this->State)
|
||
|
{
|
||
|
case VTKIS_ROTATE:
|
||
|
this->EndRotate();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnMiddleButtonDown ()
|
||
|
{
|
||
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
||
|
this->Interactor->GetEventPosition()[1]);
|
||
|
if (this->CurrentRenderer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->StartPan();
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnMiddleButtonUp ()
|
||
|
{
|
||
|
switch (this->State)
|
||
|
{
|
||
|
case VTKIS_PAN:
|
||
|
this->EndPan();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnRightButtonDown ()
|
||
|
{
|
||
|
this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
|
||
|
this->Interactor->GetEventPosition()[1]);
|
||
|
if (this->CurrentRenderer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->StartDolly();
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnRightButtonUp ()
|
||
|
{
|
||
|
switch (this->State)
|
||
|
{
|
||
|
case VTKIS_DOLLY:
|
||
|
this->EndDolly();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::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 a = (double)dx / (double)size[0] * (double)180.0;
|
||
|
double e = (double)dy / (double)size[1] * (double)180.0;
|
||
|
|
||
|
if (rwi->GetShiftKey())
|
||
|
{
|
||
|
if (fabs((double)dx) >= fabs((double)dy))
|
||
|
{
|
||
|
e = (double)0.0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
a = (double)0.0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Move the camera.
|
||
|
// Make sure that we don't hit the north pole singularity.
|
||
|
|
||
|
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
|
||
|
camera->Azimuth(a);
|
||
|
|
||
|
double dop[3], vup[3];
|
||
|
|
||
|
camera->GetDirectionOfProjection(dop);
|
||
|
vtkMath::Normalize(dop);
|
||
|
camera->GetViewUp(vup);
|
||
|
vtkMath::Normalize(vup);
|
||
|
|
||
|
double angle =
|
||
|
acos(vtkMath::Dot(dop, vup)) / vtkMath::DoubleDegreesToRadians();
|
||
|
if ((angle + e) > (double)179.0 ||
|
||
|
(angle + e) < (double)1.0)
|
||
|
{
|
||
|
e = (double)0.0;
|
||
|
}
|
||
|
|
||
|
camera->Elevation(e);
|
||
|
|
||
|
if (this->AutoAdjustCameraClippingRange)
|
||
|
{
|
||
|
this->CurrentRenderer->ResetCameraClippingRange();
|
||
|
}
|
||
|
|
||
|
rwi->Render();
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::Pan()
|
||
|
{
|
||
|
if (this->CurrentRenderer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
vtkRenderWindowInteractor *rwi = this->Interactor;
|
||
|
|
||
|
// Get the vector of motion
|
||
|
|
||
|
double fp[3], focalPoint[3], pos[3], v[3], p1[4], p2[4];
|
||
|
|
||
|
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
|
||
|
camera->GetPosition(pos);
|
||
|
camera->GetFocalPoint(fp);
|
||
|
|
||
|
this->ComputeWorldToDisplay(fp[0], fp[1], fp[2],
|
||
|
focalPoint);
|
||
|
|
||
|
this->ComputeDisplayToWorld((double)rwi->GetEventPosition()[0],
|
||
|
(double)rwi->GetEventPosition()[1],
|
||
|
focalPoint[2],
|
||
|
p1);
|
||
|
|
||
|
this->ComputeDisplayToWorld((double)rwi->GetLastEventPosition()[0],
|
||
|
(double)rwi->GetLastEventPosition()[1],
|
||
|
focalPoint[2],
|
||
|
p2);
|
||
|
|
||
|
for (int i=0; i<3; i++)
|
||
|
{
|
||
|
v[i] = p2[i] - p1[i];
|
||
|
pos[i] += v[i];
|
||
|
fp[i] += v[i];
|
||
|
}
|
||
|
|
||
|
camera->SetPosition(pos);
|
||
|
camera->SetFocalPoint(fp);
|
||
|
|
||
|
if (rwi->GetLightFollowCamera())
|
||
|
{
|
||
|
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
|
||
|
}
|
||
|
|
||
|
rwi->Render();
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::Dolly()
|
||
|
{
|
||
|
if (this->CurrentRenderer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
vtkRenderWindowInteractor *rwi = this->Interactor;
|
||
|
vtkCamera *camera = this->CurrentRenderer->GetActiveCamera();
|
||
|
double *center = this->CurrentRenderer->GetCenter();
|
||
|
|
||
|
int dy = rwi->GetEventPosition()[1] - rwi->GetLastEventPosition()[1];
|
||
|
double dyf = this->MotionFactor * (double)(dy) / (double)(center[1]);
|
||
|
double zoomFactor = pow((double)1.1, dyf);
|
||
|
|
||
|
if (camera->GetParallelProjection())
|
||
|
{
|
||
|
camera->SetParallelScale(camera->GetParallelScale() / zoomFactor);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
camera->Dolly(zoomFactor);
|
||
|
if (this->AutoAdjustCameraClippingRange)
|
||
|
{
|
||
|
this->CurrentRenderer->ResetCameraClippingRange();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (rwi->GetLightFollowCamera())
|
||
|
{
|
||
|
this->CurrentRenderer->UpdateLightsGeometryToFollowCamera();
|
||
|
}
|
||
|
|
||
|
rwi->Render();
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::OnChar()
|
||
|
{
|
||
|
vtkRenderWindowInteractor *rwi = this->Interactor;
|
||
|
|
||
|
switch (rwi->GetKeyCode())
|
||
|
{
|
||
|
case 'l':
|
||
|
this->FindPokedRenderer(rwi->GetEventPosition()[0],
|
||
|
rwi->GetEventPosition()[1]);
|
||
|
this->CreateLatLong();
|
||
|
if (this->LatLongLines)
|
||
|
{
|
||
|
this->LatLongLinesOff();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
double bounds[6];
|
||
|
this->CurrentRenderer->ComputeVisiblePropBounds(bounds);
|
||
|
double radius = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) +
|
||
|
(bounds[3]-bounds[2])*(bounds[3]-bounds[2]) +
|
||
|
(bounds[5]-bounds[4])*(bounds[5]-bounds[4])) /2.0;
|
||
|
this->LatLongSphere->SetRadius(radius);
|
||
|
this->LatLongSphere->SetCenter((bounds[0]+bounds[1])/2.0,
|
||
|
(bounds[2]+bounds[3])/2.0,
|
||
|
(bounds[4]+bounds[5])/2.0);
|
||
|
this->LatLongLinesOn();
|
||
|
}
|
||
|
this->SelectRepresentation();
|
||
|
rwi->Render();
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
this->Superclass::OnChar();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::CreateLatLong()
|
||
|
{
|
||
|
if (this->LatLongSphere == NULL)
|
||
|
{
|
||
|
this->LatLongSphere = vtkSphereSource::New();
|
||
|
this->LatLongSphere->SetPhiResolution(13);
|
||
|
this->LatLongSphere->SetThetaResolution(25);
|
||
|
this->LatLongSphere->LatLongTessellationOn();
|
||
|
}
|
||
|
|
||
|
if (this->LatLongExtractEdges == NULL)
|
||
|
{
|
||
|
this->LatLongExtractEdges = vtkExtractEdges::New();
|
||
|
this->LatLongExtractEdges->SetInput(this->LatLongSphere->GetOutput());
|
||
|
}
|
||
|
|
||
|
if (this->LatLongMapper == NULL)
|
||
|
{
|
||
|
this->LatLongMapper = vtkPolyDataMapper::New();
|
||
|
this->LatLongMapper->SetInput(this->LatLongExtractEdges->GetOutput());
|
||
|
}
|
||
|
|
||
|
if (this->LatLongActor == NULL)
|
||
|
{
|
||
|
this->LatLongActor = vtkActor::New();
|
||
|
this->LatLongActor->SetMapper(this->LatLongMapper);
|
||
|
this->LatLongActor->PickableOff();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::SelectRepresentation()
|
||
|
{
|
||
|
if (this->CurrentRenderer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this->CurrentRenderer->RemoveActor(this->LatLongActor);
|
||
|
|
||
|
if (this->LatLongLines)
|
||
|
{
|
||
|
this->CurrentRenderer->AddActor(this->LatLongActor);
|
||
|
this->LatLongActor->VisibilityOn();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
this->LatLongActor->VisibilityOff();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
void vtkInteractorStyleTerrain::PrintSelf(ostream& os, vtkIndent indent)
|
||
|
{
|
||
|
this->Superclass::PrintSelf(os,indent);
|
||
|
|
||
|
os << indent << "Latitude/Longitude Lines: "
|
||
|
<< (this->LatLongLines ? "On\n" : "Off\n");
|
||
|
}
|
||
|
|
||
|
|