// Created by: Anastasia BORISOVA // Copyright (c) 2016 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #ifndef _AIS_Animation_HeaderFile #define _AIS_Animation_HeaderFile #include #include #include //! Structure defining current animation progress. struct AIS_AnimationProgress { Standard_Real Pts; //!< global presentation timestamp Standard_Real LocalPts; //!< presentation within current animation Standard_Real LocalNormalized; //!< normalized position within current animation within 0..1 range AIS_AnimationProgress() : Pts (-1.0), LocalPts (-1.0), LocalNormalized (-1.0) {} }; DEFINE_STANDARD_HANDLE(AIS_Animation, Standard_Transient) //! Class represents a basic animation class. //! AIS_Animation can be used as: //! //! - Animation Implementor //! Sub-classes should override method AIS_Animation::update() to perform specific animation. //! AIS package provides limited number of such animation atoms - classes AIS_AnimationObject and AIS_AnimationCamera, which could be enough for defining a simple animation. //! In general case, application is expected defining own AIS_Animation sub-classes implementing application-specific animation logic //! (e.g. another interpolation or another kind of transformations - like color transition and others). //! The basic conception of AIS_Animation::update() is defining an exact scene state for the current presentation timestamp, //! providing a smooth and continuous animation well defined at any time step and in any direction. //! So that a time difference between two sequential drawn Viewer frames can vary from frame to frame without visual artifacts, //! increasing rendering framerate would not lead to animation being executed too fast //! and low framerate (on slow hardware) would not lead to animation played longer than defined duration. //! Hence, implementation should avoid usage of incremental step logic or should apply it very carefully. //! //! - Animation Container //! AIS_Animation (no sub-classing) can be used to aggregate a sequence of Animation items (children). //! Each children should be defined with its own duration and start time (presentation timestamp). //! It is possible defining collection of nested AIS_Animation items, so that within each container level //! children define start playback time relative to its holder. //! //! - Animation playback Controller //! It is suggested that application would define a single AIS_Animation instance (optional sub-classing) for controlling animation playback as whole. //! Such controller should be filled in by other AIS_Animation as children objects, //! and will be managed by application by calling StartTimer(), UpdateTimer() and IsStopped() methods. //! //! Note, that AIS_Animation::StartTimer() defines a timer calculating an elapsed time, not a multimedia timer executing Viewer updates at specific intervals! //! Application should avoid using implicit and immediate Viewer updates to ensure that AIS_Animation::UpdateTimer() is called before each redrawing of a Viewer content. //! Redrawing logic should be also managed at application level for managing a smooth animation //! (by defining a multimedia timer provided by used GUI framework executing updates at desired framerate, or as continuous redraws in loop). class AIS_Animation : public Standard_Transient { DEFINE_STANDARD_RTTIEXT(AIS_Animation, Standard_Transient) public: //! Creates empty animation. Standard_EXPORT AIS_Animation (const TCollection_AsciiString& theAnimationName); //! Destruct object, clear arguments Standard_EXPORT virtual ~AIS_Animation(); //! Animation name. const TCollection_AsciiString& Name() const { return myName; } public: //! @return start time of the animation in the timeline Standard_Real StartPts() const { return myPtsStart; } //! Sets time limits for animation in the animation timeline void SetStartPts (const Standard_Real thePtsStart) { myPtsStart = thePtsStart; } //! @return duration of the animation in the timeline Standard_Real Duration() const { return Max (myOwnDuration, myChildrenDuration); } //! Update total duration considering all animations on timeline. Standard_EXPORT void UpdateTotalDuration(); //! Return true if duration is defined. Standard_Boolean HasOwnDuration() const { return myOwnDuration > 0.0; } //! @return own duration of the animation in the timeline Standard_Real OwnDuration() const { return myOwnDuration; } //! Defines duration of the animation. void SetOwnDuration (const Standard_Real theDuration) { myOwnDuration = theDuration; } //! Add single animation to the timeline. //! @param theAnimation input animation Standard_EXPORT void Add (const Handle(AIS_Animation)& theAnimation); //! Clear animation timeline - remove all animations from it. Standard_EXPORT void Clear(); //! Return the child animation with the given name. Standard_EXPORT Handle(AIS_Animation) Find (const TCollection_AsciiString& theAnimationName) const; //! Remove the child animation. Standard_EXPORT Standard_Boolean Remove (const Handle(AIS_Animation)& theAnimation); //! Replace the child animation. Standard_EXPORT Standard_Boolean Replace (const Handle(AIS_Animation)& theAnimationOld, const Handle(AIS_Animation)& theAnimationNew); //! Clears own children and then copy child animations from another object. //! Copy also Start Time and Duration values. Standard_EXPORT void CopyFrom (const Handle(AIS_Animation)& theOther); //! Return sequence of child animations. const NCollection_Sequence& Children() const { return myAnimations; } public: //! Start animation with internally defined timer instance. //! Calls ::Start() internally. //! //! Note, that this method initializes a timer calculating an elapsed time (presentation timestamps within AIS_Animation::UpdateTimer()), //! not a multimedia timer executing Viewer updates at specific intervals! //! Viewer redrawing should be managed at application level, so that AIS_Animation::UpdateTimer() is called once right before each redrawing of a Viewer content. //! //! @param theStartPts starting timer position (presentation timestamp) //! @param thePlaySpeed playback speed (1.0 means normal speed) //! @param theToUpdate flag to update defined animations to specified start position //! @param theToStopTimer flag to pause timer at the starting position Standard_EXPORT virtual void StartTimer (const Standard_Real theStartPts, const Standard_Real thePlaySpeed, const Standard_Boolean theToUpdate, const Standard_Boolean theToStopTimer = Standard_False); //! Update single frame of animation, update timer state //! @return current time of timeline progress. Standard_EXPORT virtual Standard_Real UpdateTimer(); //! Return elapsed time. Standard_Real ElapsedTime() const { return !myTimer.IsNull() ? myTimer->ElapsedTime() : 0.0; } public: //! Start animation. This method changes status of the animation to Started. //! This status defines whether animation is to be performed in the timeline or not. //! @param theToUpdate call Update() method Standard_EXPORT virtual void Start (const Standard_Boolean theToUpdate); //! Pause the process timeline. Standard_EXPORT virtual void Pause(); //! Stop animation. This method changed status of the animation to Stopped. //! This status shows that animation will not be performed in the timeline or it is finished. Standard_EXPORT virtual void Stop(); //! Check if animation is to be performed in the animation timeline. //! @return True if it is stopped of finished. bool IsStopped() { return myState != AnimationState_Started; } //! Update single frame of animation, update timer state //! @param thePts [in] the time moment within [0; Duration()] //! @return True if timeline is in progress Standard_EXPORT virtual Standard_Boolean Update (const Standard_Real thePts); protected: //! Process one step of the animation according to the input time progress, including all children. //! Calls also ::update() to update own animation. Standard_EXPORT virtual void updateWithChildren (const AIS_AnimationProgress& thePosition); //! Update the own animation to specified position - should be overridden by sub-class. virtual void update (const AIS_AnimationProgress& theProgress) { (void )theProgress; } protected: //! Defines animation state. enum AnimationState { AnimationState_Started, //!< animation is in progress AnimationState_Stopped, //!< animation is finished, force stopped or not started AnimationState_Paused //!< animation is paused and can be started from the pause moment }; protected: Handle(Media_Timer) myTimer; TCollection_AsciiString myName; //!< animation name NCollection_Sequence myAnimations; //!< sequence of child animations AnimationState myState; //!< animation state - started, stopped of paused Standard_Real myPtsStart; //!< time of start in the timeline Standard_Real myOwnDuration; //!< duration of animation excluding children Standard_Real myChildrenDuration; //!< duration of animation including children }; #endif // _AIS_Animation_HeaderFile