/*========================================================================= Program: ParaView Module: vtkPVCameraCueManipulator.cxx Copyright (c) Kitware, Inc. All rights reserved. See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkPVCameraCueManipulator.h" #include "vtkCamera.h" #include "vtkCameraInterpolator.h" #include "vtkObjectFactory.h" #include "vtkPVCameraAnimationCue.h" #include "vtkPVCameraKeyFrame.h" #include "vtkPVRenderView.h" #include "vtkSMSourceProxy.h" #include "vtkPVDataInformation.h" #include "vtkVector.h" #include "vtkVectorOperators.h" vtkStandardNewMacro(vtkPVCameraCueManipulator); //------------------------------------------------------------------------------ vtkPVCameraCueManipulator::vtkPVCameraCueManipulator() { this->Mode = PATH; this->CameraInterpolator = vtkCameraInterpolator::New(); this->DataSourceProxy = 0; } //------------------------------------------------------------------------------ vtkPVCameraCueManipulator::~vtkPVCameraCueManipulator() { this->CameraInterpolator->Delete(); } //------------------------------------------------------------------------------ void vtkPVCameraCueManipulator::Initialize(vtkPVAnimationCue* cue) { this->Superclass::Initialize(cue); int nos = this->GetNumberOfKeyFrames(); this->CameraInterpolator->Initialize(); this->CameraInterpolator->SetInterpolationTypeToSpline(); if (nos < 2) { vtkErrorMacro("Too few keyframes to animate."); return; } if (this->Mode == PATH || this->Mode == FOLLOW_DATA) { // No need to initialize this->CameraInterpolator in PATH or // FOLLOW_DATA mode return; } // Set up this->CameraInterpolator. for(int i=0; i < nos; i++) { vtkPVCameraKeyFrame* kf; kf = vtkPVCameraKeyFrame::SafeDownCast(this->GetKeyFrameAtIndex(i)); if (!kf) { vtkErrorMacro("All keyframes in a vtkPVCameraKeyFrame must be " "vtkPVCameraKeyFrame"); continue; } this->CameraInterpolator->AddCamera(kf->GetKeyTime(), kf->GetCamera()); } } //------------------------------------------------------------------------------ void vtkPVCameraCueManipulator::Finalize(vtkPVAnimationCue* cue) { this->Superclass::Finalize(cue); } //------------------------------------------------------------------------------ void vtkPVCameraCueManipulator::UpdateValue(double currenttime, vtkPVAnimationCue* cue) { vtkPVCameraAnimationCue* cameraCue = vtkPVCameraAnimationCue::SafeDownCast(cue); if (!cameraCue) { vtkErrorMacro("This manipulator only works with vtkPVCameraAnimationCue."); return; } vtkCamera* animatedCamera = cameraCue->GetCamera(); if (!animatedCamera) { vtkErrorMacro("No camera to animate."); return; } if (this->Mode == CAMERA) { vtkCamera* camera = vtkCamera::New(); this->CameraInterpolator->InterpolateCamera(currenttime, camera); animatedCamera->SetPosition(camera->GetPosition()); animatedCamera->SetFocalPoint(camera->GetFocalPoint()); animatedCamera->SetViewUp(camera->GetViewUp()); animatedCamera->SetViewAngle(camera->GetViewAngle()); animatedCamera->SetParallelScale(camera->GetParallelScale()); camera->Delete(); cameraCue->GetView()->ResetCameraClippingRange(); } else if(this->Mode == FOLLOW_DATA) { vtkSMSourceProxy *proxy = vtkSMSourceProxy::SafeDownCast(this->DataSourceProxy); if (proxy) { // With changes in vtkSMAnimationScene when this cue "tick" is called, // we no longer need to call UpdatePipeline(), the pipeline will already be updated. // proxy->UpdatePipeline(); // get the data bounds vtkPVDataInformation *info = proxy->GetDataInformation(); double bounds[6]; info->GetBounds(bounds); // calculate the center of the data vtkVector3d center((bounds[0] + bounds[1]) * 0.5, (bounds[2] + bounds[3]) * 0.5, (bounds[4] + bounds[5]) * 0.5); // move the camera's position and focal point based on // the data's position at the current time vtkVector3d position; cameraCue->GetCamera()->GetPosition(&position[0]); vtkVector3d focalPoint; cameraCue->GetCamera()->GetFocalPoint(&focalPoint[0]); cameraCue->GetCamera()->SetFocalPoint(¢er[0]); position = center + (position - focalPoint); cameraCue->GetCamera()->SetPosition(&position[0]); } else { vtkWarningMacro("No Data Source for Follow-Data Animation"); } } else { this->Superclass::UpdateValue(currenttime, cue); } } //------------------------------------------------------------------------------ void vtkPVCameraCueManipulator::SetDataSourceProxy(vtkSMProxy *dataSourceProxy) { if(dataSourceProxy != this->DataSourceProxy) { this->DataSourceProxy = dataSourceProxy; } } //------------------------------------------------------------------------------ void vtkPVCameraCueManipulator::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Mode:" << this->Mode << endl; }