|
|
Line 1: |
Line 1: |
| A line at the top | | A simple page. |
| <div class="floatright">[[File:VTK_Examples_Baseline_Animation_TestAnimateActors.png]]</div>
| |
| This example uses [http://www.vtk.org/doc/nightly/html/classvtkAnimationScene.html vtkAnimationScene] and [http://www.vtk.org/doc/nightly/html/classvtkAnimationCue.html vtkAnimationCue] to animate actors. The vtk Scene and Cue classes provide a powerful mechanism for animating vtk classes. However, the setup can be complicated. This example provides an ActorAnimator class that can serve as a prototype for actor animation. It tries to hide some of the complexity of scene and cue animation.
| |
| ==AnimateActors.cxx==
| |
| <source lang="cpp">
| |
| #include "AnimateActors.h"
| |
| #include <vtkSmartPointer.h>
| |
| #include <vtkAnimationCue.h>
| |
| #include <vtkRenderer.h>
| |
| #include <vtkSphereSource.h>
| |
| #include <vtkConeSource.h>
| |
| #include <vtkPolyDataMapper.h>
| |
| #include <vtkCommand.h>
| |
| #include <vtkAnimationScene.h>
| |
| #include <vtkRenderWindow.h>
| |
| #include <vtkRenderWindowInteractor.h>
| |
| #include <vtkCamera.h>
| |
| | |
| int main(int argc, char *argv[])
| |
| {
| |
| // Create the graphics structure. The renderer renders into the
| |
| // render window.
| |
| vtkSmartPointer<vtkRenderWindowInteractor> iren =
| |
| vtkSmartPointer<vtkRenderWindowInteractor>::New();
| |
| vtkSmartPointer<vtkRenderer> ren1 =
| |
| vtkSmartPointer<vtkRenderer>::New();
| |
| vtkSmartPointer<vtkRenderWindow> renWin =
| |
| vtkSmartPointer<vtkRenderWindow>::New();
| |
| renWin->SetMultiSamples(0);
| |
| iren->SetRenderWindow(renWin);
| |
| renWin->AddRenderer(ren1);
| |
|
| |
| // Generate a sphere
| |
| vtkSmartPointer<vtkSphereSource> sphereSource =
| |
| vtkSmartPointer<vtkSphereSource>::New();
| |
| vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
| |
| vtkSmartPointer<vtkPolyDataMapper>::New();
| |
| sphereMapper->SetInputConnection( sphereSource->GetOutputPort());
| |
| vtkSmartPointer<vtkActor> sphere =
| |
| vtkSmartPointer<vtkActor>::New();
| |
| sphere->SetMapper(sphereMapper);
| |
| ren1->AddActor(sphere);
| |
| | |
| // Generate a cone
| |
| vtkSmartPointer<vtkConeSource> coneSource =
| |
| vtkSmartPointer<vtkConeSource>::New();
| |
| vtkSmartPointer<vtkPolyDataMapper> coneMapper =
| |
| vtkSmartPointer<vtkPolyDataMapper>::New();
| |
| coneMapper->SetInputConnection( coneSource->GetOutputPort());
| |
| vtkSmartPointer<vtkActor> cone =
| |
| vtkSmartPointer<vtkActor>::New();
| |
| cone->SetMapper(coneMapper);
| |
| ren1->AddActor(cone);
| |
| | |
| // Create an Animation Scene
| |
| vtkSmartPointer<vtkAnimationScene> scene =
| |
| vtkSmartPointer<vtkAnimationScene>::New();
| |
| if(argc>=2 && strcmp(argv[1],"-real")==0)
| |
| {
| |
| cout << "real-time mode" << endl;
| |
| scene->SetModeToRealTime();
| |
| }
| |
| else
| |
| {
| |
| cout << "sequence mode" << endl;
| |
| scene->SetModeToSequence();
| |
| }
| |
| scene->SetLoop(0);
| |
| scene->SetFrameRate(5);
| |
| scene->SetStartTime(0);
| |
| scene->SetEndTime(20);
| |
|
| |
| vtkSmartPointer<AnimationSceneObserver> sceneObserver =
| |
| vtkSmartPointer<AnimationSceneObserver>::New();
| |
| sceneObserver->SetRenderWindow(renWin);
| |
| scene->AddObserver(vtkCommand::AnimationCueTickEvent,sceneObserver);
| |
| | |
| // Create an Animation Cue for each actor
| |
| vtkSmartPointer<vtkAnimationCue> cue1 =
| |
| vtkSmartPointer<vtkAnimationCue>::New();
| |
| cue1->SetStartTime(5);
| |
| cue1->SetEndTime(23);
| |
| scene->AddCue(cue1);
| |
| | |
| vtkSmartPointer<vtkAnimationCue> cue2 =
| |
| vtkSmartPointer<vtkAnimationCue>::New();
| |
| cue2->SetStartTime(1);
| |
| cue2->SetEndTime(10);
| |
| scene->AddCue(cue2);
| |
|
| |
| // Create an ActorAnimator for each actor;
| |
| ActorAnimator animateSphere;
| |
| animateSphere.SetActor(sphere);
| |
| animateSphere.AddObserversToCue(cue1);
| |
| | |
| ActorAnimator animateCone;
| |
| std::vector<double> endCone(3);
| |
| endCone[0] = -1;
| |
| endCone[1] = -1;
| |
| endCone[2] = -1;
| |
| animateCone.SetEndPosition(endCone);
| |
| animateCone.SetActor(cone);
| |
| animateCone.AddObserversToCue(cue2);
| |
| | |
| renWin->Render();
| |
| ren1->ResetCamera();
| |
| ren1->GetActiveCamera()->Dolly(.5);
| |
| ren1->ResetCameraClippingRange();
| |
| | |
| // Create Cue observer.
| |
| scene->Play();
| |
| scene->Stop();
| |
|
| |
| iren->Start();
| |
| return EXIT_SUCCESS;
| |
| }
| |
| </source>
| |
| ==AnimateActors.h==
| |
| <source lang="cpp">
| |
| #ifndef __AnimateActors_h
| |
| #include <vtkActor.h>
| |
| #include <vtkAnimationCue.h>
| |
| #include <vtkCommand.h>
| |
| #include <vtkRenderWindow.h>
| |
| #include <vector>
| |
| | |
| class ActorAnimator
| |
| {
| |
| public:
| |
| ActorAnimator()
| |
| {
| |
| this->Actor=0;
| |
| this->Observer = AnimationCueObserver::New();
| |
| this->Observer->Animator = this;
| |
| this->StartPosition.resize(3);
| |
| this->StartPosition.insert(this->StartPosition.begin(), 3, 0.0);
| |
| this->EndPosition.resize(3);
| |
| this->EndPosition.insert(this->EndPosition.begin(), 3, .5);
| |
| }
| |
|
| |
| ~ActorAnimator()
| |
| {
| |
| if(this->Actor)
| |
| {
| |
| this->Actor->UnRegister(0);
| |
| this->Actor=0;
| |
| }
| |
| this->Observer->UnRegister(0);
| |
| }
| |
| void SetActor(vtkActor *actor)
| |
| {
| |
| if (this->Actor)
| |
| {
| |
| this->Actor->UnRegister(0);
| |
| }
| |
| this->Actor = actor;
| |
| this->Actor->Register(0);
| |
| }
| |
| void SetStartPosition(std::vector<double> position)
| |
| {
| |
| this->StartPosition = position;
| |
| }
| |
| void SetEndPosition(std::vector<double> position)
| |
| {
| |
| this->EndPosition = position;
| |
| }
| |
| void AddObserversToCue(vtkAnimationCue *cue)
| |
| {
| |
| cue->AddObserver(vtkCommand::StartAnimationCueEvent,this->Observer);
| |
| cue->AddObserver(vtkCommand::EndAnimationCueEvent,this->Observer);
| |
| cue->AddObserver(vtkCommand::AnimationCueTickEvent,this->Observer);
| |
| }
| |
|
| |
| void Start(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info))
| |
| {
| |
| this->Actor->SetPosition(this->StartPosition[0],
| |
| this->StartPosition[1],
| |
| this->StartPosition[2]);
| |
| }
| |
|
| |
| void Tick(vtkAnimationCue::AnimationCueInfo *info)
| |
| {
| |
| double t = (info->AnimationTime - info->StartTime) / (info->EndTime - info->StartTime);
| |
| double position[3];
| |
| for (int i = 0; i < 3; i++)
| |
| {
| |
| position[i] = this->StartPosition[i] + (this->EndPosition[i] - this->StartPosition[i]) * t;
| |
| }
| |
| this->Actor->SetPosition(position);
| |
|
| |
| }
| |
|
| |
| void End(vtkAnimationCue::AnimationCueInfo *vtkNotUsed(info))
| |
| {
| |
| this->Actor->SetPosition(this->EndPosition[0],
| |
| this->EndPosition[1],
| |
| this->EndPosition[2]);
| |
| }
| |
|
| |
| protected:
| |
| class AnimationCueObserver : public vtkCommand
| |
| {
| |
| public:
| |
| static AnimationCueObserver *New()
| |
| {
| |
| return new AnimationCueObserver;
| |
| }
| |
|
| |
| virtual void Execute(vtkObject *vtkNotUsed(caller),
| |
| unsigned long event,
| |
| void *calldata)
| |
| {
| |
| if(this->Animator != 0)
| |
| {
| |
| vtkAnimationCue::AnimationCueInfo *info=
| |
| static_cast<vtkAnimationCue::AnimationCueInfo *>(calldata);
| |
| switch(event)
| |
| {
| |
| case vtkCommand::StartAnimationCueEvent:
| |
| this->Animator->Start(info);
| |
| break;
| |
| case vtkCommand::EndAnimationCueEvent:
| |
| this->Animator->End(info);
| |
| break;
| |
| case vtkCommand::AnimationCueTickEvent:
| |
| this->Animator->Tick(info);
| |
| break;
| |
| }
| |
| }
| |
| }
| |
|
| |
| AnimationCueObserver()
| |
| {
| |
| this->Animator = 0;
| |
| }
| |
| ActorAnimator *Animator;
| |
| };
| |
| | |
| vtkActor * Actor;
| |
| AnimationCueObserver * Observer;
| |
| std::vector<double> StartPosition;
| |
| std::vector<double> EndPosition;
| |
| };
| |
| | |
| class AnimationSceneObserver : public vtkCommand
| |
| {
| |
| public:
| |
| static AnimationSceneObserver *New()
| |
| {
| |
| return new AnimationSceneObserver;
| |
| }
| |
|
| |
| void SetRenderWindow( vtkRenderWindow *renWin)
| |
| {
| |
| if (this->RenderWindow)
| |
| {
| |
| this->RenderWindow->UnRegister(this);
| |
| }
| |
| this->RenderWindow = renWin;
| |
| this->RenderWindow->Register(this);
| |
| | |
| }
| |
| virtual void Execute(vtkObject *vtkNotUsed(caller),
| |
| unsigned long event,
| |
| void *vtkNotUsed(calldata))
| |
| {
| |
| if(this->RenderWindow != 0)
| |
| {
| |
| switch(event)
| |
| {
| |
| case vtkCommand::AnimationCueTickEvent:
| |
| this->RenderWindow->Render();
| |
| break;
| |
| }
| |
| }
| |
| }
| |
|
| |
| protected:
| |
| AnimationSceneObserver()
| |
| {
| |
| this->RenderWindow = 0;
| |
| }
| |
| ~AnimationSceneObserver()
| |
| {
| |
| if(this->RenderWindow)
| |
| {
| |
| this->RenderWindow->UnRegister(this);
| |
| this->RenderWindow = 0;
| |
| }
| |
| }
| |
| vtkRenderWindow *RenderWindow;
| |
| };
| |
| | |
| #endif
| |
| </source>
| |
| | |
| ==CMakeLists.txt==
| |
| <source lang="cmake">
| |
| cmake_minimum_required(VERSION 2.6)
| |
| | |
| PROJECT(AnimateActors)
| |
| | |
| FIND_PACKAGE(VTK REQUIRED)
| |
| INCLUDE(${VTK_USE_FILE})
| |
| | |
| ADD_EXECUTABLE(AnimateActors AnimateActors.cxx)
| |
| TARGET_LINK_LIBRARIES(AnimateActors vtkHybrid)
| |
| | |
| | |
| </source>
| |