Commit 56eaf4e2 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit
Browse files

ENH: added framework to support animations

parent 012c2cbd
......@@ -22,6 +22,8 @@ ENDIF (UNIX)
SET( Kit_SRCS
vtkAbstractTransform.cxx
vtkAmoebaMinimizer.cxx
vtkAnimationCue.cxx
vtkAnimationScene.cxx
vtkAssemblyNode.cxx
vtkAssemblyPath.cxx
vtkAssemblyPaths.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAnimationCue.cxx
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 "vtkAnimationCue.h"
#include "vtkObjectFactory.h"
#include "vtkCommand.h"
vtkCxxRevisionMacro(vtkAnimationCue, "1.1");
vtkStandardNewMacro(vtkAnimationCue);
//----------------------------------------------------------------------------
vtkAnimationCue::vtkAnimationCue()
{
this->StartTime = this->EndTime = 0.0;
this->CueState = vtkAnimationCue::UNINITIALIZED;
this->TimeMode = VTK_ANIMATION_CUE_TIMEMODE_RELATIVE;
}
//----------------------------------------------------------------------------
vtkAnimationCue::~vtkAnimationCue()
{
}
//----------------------------------------------------------------------------
void vtkAnimationCue::StartCueInternal()
{
vtkAnimationCue::AnimationCueInfo info;
info.StartTime = this->StartTime;
info.EndTime = this->EndTime;
info.CurrentTime = 0.0;
info.DeltaTime = 0.0;
this->InvokeEvent(vtkCommand::StartAnimationCueEvent, &info);
}
//----------------------------------------------------------------------------
void vtkAnimationCue::EndCueInternal()
{
vtkAnimationCue::AnimationCueInfo info;
info.StartTime = this->StartTime;
info.EndTime = this->EndTime;
info.CurrentTime = 0.0;
info.DeltaTime = 0.0;
this->InvokeEvent(vtkCommand::EndAnimationCueEvent, &info);
}
//----------------------------------------------------------------------------
void vtkAnimationCue::TickInternal(double currenttime, double deltatime)
{
vtkAnimationCue::AnimationCueInfo info;
info.StartTime = this->StartTime;
info.EndTime = this->EndTime;
info.DeltaTime = deltatime;
info.CurrentTime = currenttime;
this->InvokeEvent(vtkCommand::AnimationCueTickEvent, &info);
}
//----------------------------------------------------------------------------
void vtkAnimationCue::Tick(double currenttime, double deltatime)
{
// Check to see if we have crossed the Cue start.
if (currenttime >= this->StartTime &&
this->CueState == vtkAnimationCue::UNINITIALIZED)
{
this->CueState = vtkAnimationCue::ACTIVE;
this->StartCueInternal();
}
// Note that Tick event is sent for both start time and
// end time.
if (this->CueState == vtkAnimationCue::ACTIVE)
{
if (currenttime <= this->EndTime)
{
this->TickInternal(currenttime, deltatime);
}
if (currenttime >= this->EndTime)
{
this->EndCueInternal();
this->CueState = vtkAnimationCue::INACTIVE;
}
}
}
//----------------------------------------------------------------------------
void vtkAnimationCue::SetTimeMode(int mode)
{
this->TimeMode = mode;
}
//----------------------------------------------------------------------------
void vtkAnimationCue::Initialize()
{
this->CueState = vtkAnimationCue::UNINITIALIZED;
}
//----------------------------------------------------------------------------
void vtkAnimationCue::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "StartTime: " << this->StartTime << endl;
os << indent << "EndTime: " << this->EndTime << endl;
os << indent << "CueState: " << this->CueState << endl;
os << indent << "TimeMode: " << this->TimeMode << endl;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAnimationCue.h
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.
=========================================================================*/
// .NAME vtkAnimationCue - a seqin an animation.
// .SECTION Description
// vtkAnimationCue and vtkAnimationScene provide the framework to support
// animations in VTK. vtkAnimationCue represents an entity that changes/
// animates with time, while vtkAnimationScene represents scene or setup
// for the animation, which consists on individual cues or other scenes.
//
// A cue has three states: UNINITIALIZED, ACTIVE and INACTIVE.
// UNINITIALIZED represents an point in time before the start time of the cue.
// The cue is in ACTIVE state at a point in time between start time and end time
// for the cue. While, beyond the end time, it is in INACTIVE state.
// When the cue enters the ACTIVE state, StartAnimationCueEvent is fired. This
// event may be handled to initialize the entity to be animated.
// When the cue leaves the ACTIVE state, EndAnimationCueEvent is fired, which
// can be handled to cleanup after having run the animation.
// For every request to render during the ACTIVE state, AnimationCueTickEvent is
// fired, which must be handled to perform the actual animation.
// .SECTION See Also
// vtkAnimationScene
#ifndef __vtkAnimationCue_h
#define __vtkAnimationCue_h
#define VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED 0
#define VTK_ANIMATION_CUE_TIMEMODE_RELATIVE 1
#include "vtkObject.h"
class VTK_HYBRID_EXPORT vtkAnimationCue: public vtkObject
{
public:
vtkTypeRevisionMacro(vtkAnimationCue,vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
static vtkAnimationCue* New();
//BTX
// Structure passed on every event invocation.
// Depending upon the cue time mode, these times are either
// normalized [0,1] or relative to the scene that contains the cue.
class AnimationCueInfo
{
public:
double StartTime;
double EndTime;
double CurrentTime; // valid only on AnimationCueTickEvent
double DeltaTime; // valid only on AnimationCueTickEvent
};
//ETX
// Description:
// Get/Set the time mode. In Normalized mode, the start and end
// times of the cue are normalized [0,1] with respect to the start and
// end times of the container scene. In Relative mode the start and end
// time of the cue are specified in offset seconds relative to the
// start time of the container scene.
virtual void SetTimeMode(int mode);
vtkGetMacro(TimeMode, int);
void SetTimeModeToRelative()
{ this->SetTimeMode(VTK_ANIMATION_CUE_TIMEMODE_RELATIVE); }
void SetTimeModeToNormalized()
{ this->SetTimeMode(VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED); }
// Description:
// Get/Set the Start time for this cue.
// When the current time is >= StartTime, the Cue is in
// ACTIVE state. if Current time i < StartTime, the Cue is in
// UNINITIALIZED state. Whenever the cue enters the ACTIVE state from
// an INACTIVE state, it triggers the StartEvent.
// The Start time is in seconds relative to the start of the
// container Scene (when in Relative time mode) or is normalized
// over the span of the container Scene (when in Normalized time mode).
vtkSetMacro(StartTime, double);
vtkGetMacro(StartTime, double);
// Description:
// Get/Set the End time for this cue.
// When the current time is > EndTime, the Cue is in
// INACTIVE state. Whenever the cue leaves an ACTIVE state to enter
// INACTIVE state, the EndEvent is triggered.
// The End time is in seconds relative to the start of the
// container Scene (when in Relative time mode) or is normalized
// over the span of the container Scene (when in Normalized time mode).
vtkSetMacro(EndTime, double);
vtkGetMacro(EndTime, double);
// Description:
// Indicates a tick or point in time in the animation.
// Triggers a Tick event if currenttime >= StartTime and
// currenttime <= EndTime.
// Whenever the state of the cue changes,
// either StartEvent or EndEvent is triggerred depending upon
// whether the cue entered Active state or quit active state respectively.
// The current time is relative to the start of the container Scene
// (when in Relative time mode) or is normalized
// over the span of the container Scene (when in Normalized time mode).
// deltatime is the time since last call to Tick. deltatime also can be in seconds
// relative to the start of the container Scene or normalized depending upon the
// cue's Time mode.
// For the first call to Tick
// after a call to Initialize(), the deltatime is 0;
virtual void Tick(double currenttime, double deltatime);
// Description:
// Called when the playing of the scene begins.
// This will set the Cue to UNINITIALIZED state.
virtual void Initialize();
// Description:
// Called when the scene reaches the end.
// Default implementation does nothing.
// However, the derrved classes can override, if necessary.
virtual void Finalize() { }
protected:
vtkAnimationCue();
~vtkAnimationCue();
//BTX
enum {
UNINITIALIZED=0,
INACTIVE,
ACTIVE
};
//ETX
double StartTime;
double EndTime;
int TimeMode;
// Description:
// Current state of the Cue.
int CueState;
// Description:
// These are the internal methods that actually trigger they
// corresponding events. Subclasses can override these to
// do extra processing at start/end or on tick.
virtual void StartCueInternal();
virtual void TickInternal(double currenttime, double deltatime);
virtual void EndCueInternal();
private:
vtkAnimationCue(const vtkAnimationCue&); // Not implemented.
void operator=(const vtkAnimationCue&); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAnimationScene.cxx
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 "vtkAnimationScene.h"
#include "vtkObjectFactory.h"
#include "vtkCollection.h"
#include "vtkCollectionIterator.h"
#include "vtkTimerLog.h"
vtkCxxRevisionMacro(vtkAnimationScene, "1.1");
vtkStandardNewMacro(vtkAnimationScene);
//----------------------------------------------------------------------------
vtkAnimationScene::vtkAnimationScene()
{
this->PlayMode = VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE;
this->FrameRate = 10.0;
this->Loop = 0;
this->InPlay = 0;
this->StopPlay = 0;
this->CurrentTime = 0.0;
this->AnimationCues = vtkCollection::New();
this->AnimationCuesIterator = this->AnimationCues->NewIterator();
this->AnimationTimer = vtkTimerLog::New();
}
//----------------------------------------------------------------------------
vtkAnimationScene::~vtkAnimationScene()
{
if (this->InPlay)
{
this->Stop();
}
this->AnimationCues->Delete();
this->AnimationCuesIterator->Delete();
this->AnimationTimer->Delete();
}
//----------------------------------------------------------------------------
void vtkAnimationScene::AddCue(vtkAnimationCue* cue)
{
if (this->AnimationCues->IsItemPresent(cue))
{
vtkErrorMacro("Animation cue already present in the scene");
return;
}
if (this->TimeMode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED &&
cue->GetTimeMode() != VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
{
vtkErrorMacro("A cue with relative time mode cannot be added to a scene "
"with normalized time mode.");
return;
}
this->AnimationCues->AddItem(cue);
}
//----------------------------------------------------------------------------
void vtkAnimationScene::RemoveCue(vtkAnimationCue* cue)
{
this->AnimationCues->RemoveItem(cue);
}
//----------------------------------------------------------------------------
void vtkAnimationScene::SetTimeMode(int mode)
{
if (mode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
{
// If noralized time mode is being set on the scene,
// ensure that none of the contained cues need relative times.
vtkCollectionIterator *it = this->AnimationCuesIterator;
for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
{
vtkAnimationCue* cue =
vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
if (cue && cue->GetTimeMode() != VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
{
vtkErrorMacro("Scene contains a cue in relative mode. It must be removed "
"or chaged to normalized mode before changing the scene time mode");
return;
}
}
}
this->Superclass::SetTimeMode(mode);
}
//----------------------------------------------------------------------------
void vtkAnimationScene::Initialize()
{
this->Superclass::Initialize();
// run thr all the cues and init them.
vtkCollectionIterator *it = this->AnimationCuesIterator;
for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
{
vtkAnimationCue* cue =
vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
if (cue)
{
cue->Initialize();
}
}
}
//----------------------------------------------------------------------------
void vtkAnimationScene::Finalize()
{
this->Superclass::Finalize();
vtkCollectionIterator *it = this->AnimationCuesIterator;
for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
{
vtkAnimationCue* cue =
vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
if (cue)
{
cue->Finalize();
}
}
}
//----------------------------------------------------------------------------
void vtkAnimationScene::Play()
{
if (this->InPlay)
{
return;
}
if (this->TimeMode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
{
vtkErrorMacro("Cannot play a scene with normalized time mode");
return;
}
this->InPlay = 1;
this->StopPlay = 0;
this->FrameRate = (!this->FrameRate)? 1.0 : this->FrameRate;
// the actual play loop, check for StopPlay flag.
do
{
double deltatime = 0.0;
double oldcurrenttime = 0.0;
double currenttime = this->CurrentTime;
if (currenttime < this->StartTime || currenttime >= this->EndTime)
{
currenttime = this->StartTime;
}
this->AnimationTimer->StartTimer();
this->Initialize();
do
{
this->Tick(currenttime, deltatime);
oldcurrenttime = currenttime;
if (this->PlayMode == VTK_ANIMATION_SCENE_PLAYMODE_REALTIME)
{
this->AnimationTimer->StopTimer();
currenttime = this->AnimationTimer->GetElapsedTime() +
this->StartTime;
}
else if (this->PlayMode == VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE)
{
currenttime += 1.0 / this->FrameRate;
}
else
{
vtkErrorMacro("Invalid Play Mode");
this->StopPlay = 1;
break;
}
deltatime = currenttime - oldcurrenttime;
deltatime = (deltatime < 0)? -1*deltatime : deltatime;
}
while (!this->StopPlay && this->CueState != vtkAnimationCue::INACTIVE);
this->Finalize();
}
while (this->Loop && !this->StopPlay);
this->StopPlay = 0;
this->InPlay = 0;
}
//----------------------------------------------------------------------------
void vtkAnimationScene::Stop()
{
if (!this->InPlay)
{
return;
}
this->StopPlay = 1;
}
//----------------------------------------------------------------------------
void vtkAnimationScene::TickInternal(double currenttime, double deltatime)
{
this->CurrentTime = currenttime;
vtkCollectionIterator* iter = this->AnimationCuesIterator;
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkAnimationCue* cue = vtkAnimationCue::SafeDownCast(
iter->GetCurrentObject());
if (cue)
{
switch(cue->GetTimeMode())
{
case VTK_ANIMATION_CUE_TIMEMODE_RELATIVE:
cue->Tick(currenttime - this->StartTime, deltatime);
break;
case VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED:
cue->Tick( (currenttime - this->StartTime) / (this->EndTime - this->StartTime),
deltatime / (this->EndTime - this->StartTime));
break;
default:
vtkErrorMacro("Invalid cue time mode");
}
}
}
this->Superclass::TickInternal(currenttime, deltatime);
}
//----------------------------------------------------------------------------
void vtkAnimationScene::SetCurrentTime(double currenttime)
{
if (this->InPlay)
{
vtkErrorMacro("SetCurrentTime cannot be called while playing");
return;
}
this->Initialize();
this->Tick(currenttime,0.0);
if (this->CueState == vtkAnimationCue::INACTIVE)
{
this->Finalize();
}
}
//----------------------------------------------------------------------------
void vtkAnimationScene::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "PlayMode: " << this->PlayMode << endl;
os << indent << "FrameRate: " << this->FrameRate << endl;
os << indent << "Loop: " << this->Loop << endl;
os << indent << "InPlay: " << this->InPlay << endl;
os << indent << "StopPlay: " << this->StopPlay << endl;
os << indent << "CurrentTime: " << this->CurrentTime << endl;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkAnimationScene.h
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.
=========================================================================*/
// .NAME vtkAnimationScene - the animation scene manager.
// .SECTION Description
// vtkAnimationCue and vtkAnimationScene provide the framework to support
// animations in VTK. vtkAnimationCue represents an entity that changes/
// animates with time, while vtkAnimationScene represents scene or setup
// for the animation, which consists on individual cues or other scenes.
//
// A scene can be played in real time mode, or as a seqence of frames
// 1/frame rate apart in time.
// .SECTION See Also
// vtkAnimationCue
#ifndef __vtkAnimationScene_h
#define __vtkAnimationScene_h
#include "vtkAnimationCue.h"
class vtkAnimationCue;
class vtkCollection;
class vtkCollectionIterator;
class vtkTimerLog;
#define VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE 0
#define VTK_ANIMATION_SCENE_PLAYMODE_REALTIME 1
class VTK_HYBRID_EXPORT vtkAnimationScene: public vtkAnimationCue
{
public:
vtkTypeRevisionMacro(vtkAnimationScene, vtkAnimationCue);
void PrintSelf(ostream& os, vtkIndent indent);
static vtkAnimationScene* New();
// Description:
// Get/Set the PlayMode for running/playing the animation scene.
// In the Sequence mode, all the frames are generated one after the other.
// The time reported to each Tick of the constituent cues (during Play) is
// incremented by 1/frame rate, irrespective of the current time.
// In the RealTime mode, time indicates the instance in time.
vtkSetMacro(PlayMode, int);
void SetModeToSequence() { this->SetPlayMode(VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE); }
void SetModeToRealTime() { this->SetPlayMode(VTK_ANIMATION_SCENE_PLAYMODE_REALTIME); }
vtkGetMacro(PlayMode, int);
// Description:
// Get/Set the frame rate (in frames per second).
// This parameter affects only in the Sequence mode. The time interval
// indicated to each cue on every tick is progressed by 1/frame-rate seconds.
vtkSetMacro(FrameRate, double);
vtkGetMacro(FrameRate, double);
// Description:
// Add/Remove an AnimationCue to/from the Scene.
// It's an error to add a cue twice to the Scene.
void AddCue(vtkAnimationCue* cue);
void RemoveCue(vtkAnimationCue* cue);
// Description:
// Starts playing the animation scene.
void Play();